001/**
002 * Copyright 2010-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.common.util.log.log4j.model;
017
018import java.util.Collections;
019import java.util.List;
020
021import javax.xml.bind.annotation.XmlAccessType;
022import javax.xml.bind.annotation.XmlAccessorType;
023import javax.xml.bind.annotation.XmlAttribute;
024import javax.xml.bind.annotation.XmlElement;
025import javax.xml.bind.annotation.XmlRootElement;
026import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
027
028import org.kuali.common.util.Assert;
029import org.kuali.common.util.CollectionUtils;
030import org.kuali.common.util.ListUtils;
031import org.kuali.common.util.log.log4j.jaxb.DebugAdapter;
032import org.kuali.common.util.log.log4j.jaxb.RepositoryThresholdAdapter;
033import org.kuali.common.util.xml.jaxb.adapter.OmitFalseAdapter;
034
035@XmlRootElement(name = "log4j:configuration")
036@XmlAccessorType(XmlAccessType.FIELD)
037public final class Log4JConfiguration {
038
039        @XmlAttribute(name = "xmlns:log4j")
040        private final String namespace;
041
042        @XmlElement(name = "appender")
043        private final List<Appender> appenders;
044
045        @XmlElement
046        private final Logger root;
047
048        @XmlElement(name = "logger")
049        private final List<Logger> loggers;
050
051        @XmlAttribute
052        @XmlJavaTypeAdapter(OmitFalseAdapter.class)
053        private final Boolean reset;
054
055        @XmlAttribute
056        @XmlJavaTypeAdapter(DebugAdapter.class)
057        private final Debug debug;
058
059        @XmlAttribute
060        @XmlJavaTypeAdapter(RepositoryThresholdAdapter.class)
061        private final Threshold threshold;
062
063        // Only expose an unmodifiable version of our internal list
064        public List<Logger> getLoggers() {
065                return Collections.unmodifiableList(loggers);
066        }
067
068        // Only expose an unmodifiable version of our internal list
069        public List<Appender> getAppenders() {
070                return Collections.unmodifiableList(appenders);
071        }
072
073        public boolean getReset() {
074                return reset;
075        }
076
077        public Debug getDebug() {
078                return debug;
079        }
080
081        public Threshold getThreshold() {
082                return threshold;
083        }
084
085        public Logger getRoot() {
086                return root;
087        }
088
089        public String getNamespace() {
090                return namespace;
091        }
092
093        public static class Builder {
094
095                // Required
096                private final Logger root;
097
098                // Optional
099                private String namespace = "http://jakarta.apache.org/log4j/";
100                private List<Appender> appenders = Appender.EMPTY;
101                private List<Logger> loggers = Logger.EMPTY;
102                private boolean reset = false;
103                private Debug debug = Debug.DEFAULT_VALUE;
104                private Threshold threshold = Threshold.DEFAULT_REPOSITORY_VALUE;
105
106                public Builder(Logger root) {
107                        Assert.noNulls(root);
108                        this.root = root;
109                }
110
111                public Builder appenders(List<Appender> appenders) {
112                        this.appenders = appenders;
113                        return this;
114                }
115
116                public Builder appender(Appender appender) {
117                        this.appenders = CollectionUtils.singletonList(appender);
118                        return this;
119                }
120
121                public Builder namespace(String namespace) {
122                        this.namespace = namespace;
123                        return this;
124                }
125
126                public Builder logger(Logger logger) {
127                        this.loggers = CollectionUtils.singletonList(logger);
128                        return this;
129                }
130
131                public Builder loggers(List<Logger> loggers) {
132                        this.loggers = loggers;
133                        return this;
134                }
135
136                public Builder reset(boolean reset) {
137                        this.reset = reset;
138                        return this;
139                }
140
141                public Builder debug(Debug debug) {
142                        this.debug = debug;
143                        return this;
144                }
145
146                public Builder threshold(Threshold threshold) {
147                        this.threshold = threshold;
148                        return this;
149                }
150
151                private Builder finish() {
152
153                        // Ensure we are being configured correctly
154                        Assert.noNulls(root, appenders, loggers, debug, threshold);
155                        Assert.isFalse(Logger.isThresholdNull(root), "root logging threshold is null");
156                        Assert.noBlanks(namespace);
157
158                        // Defensive copies of the 2 lists we were passed
159                        this.appenders = ListUtils.newArrayList(appenders);
160                        this.loggers = ListUtils.newArrayList(loggers);
161
162                        // Return the fully configured Builder
163                        return this;
164                }
165
166                public Log4JConfiguration build() {
167                        finish(); // Finish setting things up
168                        return new Log4JConfiguration(this);
169                }
170        }
171
172        // This is a concession to JAXB so it can unmarshal the object from XML
173        private Log4JConfiguration() {
174                this(new Builder(Logger.DEFAULT).finish());
175        }
176
177        private Log4JConfiguration(Builder builder) {
178                this.root = builder.root;
179                this.appenders = builder.appenders;
180                this.loggers = builder.loggers;
181                this.reset = builder.reset;
182                this.debug = builder.debug;
183                this.threshold = builder.threshold;
184                this.namespace = builder.namespace;
185        }
186
187}