001    package org.kuali.common.util.log.log4j.model;
002    
003    import java.util.Collections;
004    import java.util.List;
005    
006    import javax.xml.bind.annotation.XmlAccessType;
007    import javax.xml.bind.annotation.XmlAccessorType;
008    import javax.xml.bind.annotation.XmlAttribute;
009    import javax.xml.bind.annotation.XmlElement;
010    import javax.xml.bind.annotation.XmlRootElement;
011    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
012    
013    import org.kuali.common.util.Assert;
014    import org.kuali.common.util.CollectionUtils;
015    import org.kuali.common.util.ListUtils;
016    import org.kuali.common.util.log.log4j.jaxb.DebugAdapter;
017    import org.kuali.common.util.log.log4j.jaxb.RepositoryThresholdAdapter;
018    import org.kuali.common.util.xml.jaxb.adapter.OmitFalseAdapter;
019    
020    @XmlRootElement(name = "log4j:configuration")
021    @XmlAccessorType(XmlAccessType.FIELD)
022    public 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    }