001package org.kuali.common.util.log.log4j.model;
002
003import java.util.Collections;
004import java.util.List;
005
006import javax.xml.bind.annotation.XmlAccessType;
007import javax.xml.bind.annotation.XmlAccessorType;
008import javax.xml.bind.annotation.XmlAttribute;
009import javax.xml.bind.annotation.XmlElement;
010import javax.xml.bind.annotation.XmlRootElement;
011import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
012
013import org.kuali.common.util.Assert;
014import org.kuali.common.util.CollectionUtils;
015import org.kuali.common.util.ListUtils;
016import org.kuali.common.util.log.log4j.jaxb.DebugAdapter;
017import org.kuali.common.util.log.log4j.jaxb.RepositoryThresholdAdapter;
018import org.kuali.common.util.xml.jaxb.adapter.OmitFalseAdapter;
019
020@XmlRootElement(name = "log4j:configuration")
021@XmlAccessorType(XmlAccessType.FIELD)
022public final class Log4JConfiguration {
023
024        @XmlAttribute(name = "xmlns:log4j")
025        private final String namespace;
026
027        @XmlElement(name = "appender")
028        private final List<Appender> appenders;
029
030        @XmlElement
031        private final Logger root;
032
033        @XmlElement(name = "logger")
034        private final List<Logger> loggers;
035
036        @XmlAttribute
037        @XmlJavaTypeAdapter(OmitFalseAdapter.class)
038        private final Boolean reset;
039
040        @XmlAttribute
041        @XmlJavaTypeAdapter(DebugAdapter.class)
042        private final Debug debug;
043
044        @XmlAttribute
045        @XmlJavaTypeAdapter(RepositoryThresholdAdapter.class)
046        private final Threshold threshold;
047
048        // Only expose an unmodifiable version of our internal list
049        public List<Logger> getLoggers() {
050                return Collections.unmodifiableList(loggers);
051        }
052
053        // Only expose an unmodifiable version of our internal list
054        public List<Appender> getAppenders() {
055                return Collections.unmodifiableList(appenders);
056        }
057
058        public boolean getReset() {
059                return reset;
060        }
061
062        public Debug getDebug() {
063                return debug;
064        }
065
066        public Threshold getThreshold() {
067                return threshold;
068        }
069
070        public Logger getRoot() {
071                return root;
072        }
073
074        public String getNamespace() {
075                return namespace;
076        }
077
078        public static class Builder {
079
080                // Required
081                private final Logger root;
082
083                // Optional
084                private String namespace = "http://jakarta.apache.org/log4j/";
085                private List<Appender> appenders = Appender.EMPTY;
086                private List<Logger> loggers = Logger.EMPTY;
087                private boolean reset = false;
088                private Debug debug = Debug.DEFAULT_VALUE;
089                private Threshold threshold = Threshold.DEFAULT_REPOSITORY_VALUE;
090
091                public Builder(Logger root) {
092                        Assert.noNulls(root);
093                        this.root = root;
094                }
095
096                public Builder appenders(List<Appender> appenders) {
097                        this.appenders = appenders;
098                        return this;
099                }
100
101                public Builder appender(Appender appender) {
102                        this.appenders = CollectionUtils.singletonList(appender);
103                        return this;
104                }
105
106                public Builder namespace(String namespace) {
107                        this.namespace = namespace;
108                        return this;
109                }
110
111                public Builder logger(Logger logger) {
112                        this.loggers = CollectionUtils.singletonList(logger);
113                        return this;
114                }
115
116                public Builder loggers(List<Logger> loggers) {
117                        this.loggers = loggers;
118                        return this;
119                }
120
121                public Builder reset(boolean reset) {
122                        this.reset = reset;
123                        return this;
124                }
125
126                public Builder debug(Debug debug) {
127                        this.debug = debug;
128                        return this;
129                }
130
131                public Builder threshold(Threshold threshold) {
132                        this.threshold = threshold;
133                        return this;
134                }
135
136                private Builder finish() {
137
138                        // Ensure we are being configured correctly
139                        Assert.noNulls(root, appenders, loggers, debug, threshold);
140                        Assert.isFalse(Logger.isThresholdNull(root), "root logging threshold is null");
141                        Assert.noBlanks(namespace);
142
143                        // Defensive copies of the 2 lists we were passed
144                        this.appenders = ListUtils.newArrayList(appenders);
145                        this.loggers = ListUtils.newArrayList(loggers);
146
147                        // Return the fully configured Builder
148                        return this;
149                }
150
151                public Log4JConfiguration build() {
152                        finish(); // Finish setting things up
153                        return new Log4JConfiguration(this);
154                }
155        }
156
157        // This is a concession to JAXB so it can unmarshal the object from XML
158        private Log4JConfiguration() {
159                this(new Builder(Logger.DEFAULT).finish());
160        }
161
162        private Log4JConfiguration(Builder builder) {
163                this.root = builder.root;
164                this.appenders = builder.appenders;
165                this.loggers = builder.loggers;
166                this.reset = builder.reset;
167                this.debug = builder.debug;
168                this.threshold = builder.threshold;
169                this.namespace = builder.namespace;
170        }
171
172}