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}