001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.log4j.config; 019 020import org.apache.log4j.Appender; 021import org.apache.log4j.Category; 022import org.apache.log4j.Level; 023import org.apache.log4j.LogManager; 024import org.apache.log4j.Logger; 025 026import java.io.PrintWriter; 027import java.util.Enumeration; 028import java.util.Hashtable; 029 030/** 031 Prints the configuration of the log4j default hierarchy 032 (which needs to be auto-initialized) as a propoperties file 033 on a {@link PrintWriter}. 034 035 @author Anders Kristensen 036 */ 037public class PropertyPrinter implements PropertyGetter.PropertyCallback { 038 protected int numAppenders = 0; 039 protected Hashtable appenderNames = new Hashtable(); 040 protected Hashtable layoutNames = new Hashtable(); 041 protected PrintWriter out; 042 protected boolean doCapitalize; 043 044 public 045 PropertyPrinter(PrintWriter out) { 046 this(out, false); 047 } 048 049 public 050 PropertyPrinter(PrintWriter out, boolean doCapitalize) { 051 this.out = out; 052 this.doCapitalize = doCapitalize; 053 054 print(out); 055 out.flush(); 056 } 057 058 protected 059 String genAppName() { 060 return "A" + numAppenders++; 061 } 062 063 /** 064 * Returns true if the specified appender name is considered to have 065 * been generated, that is, if it is of the form A[0-9]+. 066 */ 067 protected 068 boolean isGenAppName(String name) { 069 if (name.length() < 2 || name.charAt(0) != 'A') return false; 070 071 for (int i = 0; i < name.length(); i++) { 072 if (name.charAt(i) < '0' || name.charAt(i) > '9') return false; 073 } 074 return true; 075 } 076 077 /** 078 * Prints the configuration of the default log4j hierarchy as a Java 079 * properties file on the specified Writer. 080 * 081 * <p>N.B. print() can be invoked only once! 082 */ 083 public 084 void print(PrintWriter out) { 085 printOptions(out, Logger.getRootLogger()); 086 087 Enumeration cats = LogManager.getCurrentLoggers(); 088 while (cats.hasMoreElements()) { 089 printOptions(out, (Logger) cats.nextElement()); 090 } 091 } 092 093 /** 094 * @since 1.2.15 095 */ 096 protected 097 void printOptions(PrintWriter out, Category cat) { 098 Enumeration appenders = cat.getAllAppenders(); 099 Level prio = cat.getLevel(); 100 String appenderString = (prio == null ? "" : prio.toString()); 101 102 while (appenders.hasMoreElements()) { 103 Appender app = (Appender) appenders.nextElement(); 104 String name; 105 106 if ((name = (String) appenderNames.get(app)) == null) { 107 108 // first assign name to the appender 109 if ((name = app.getName()) == null || isGenAppName(name)) { 110 name = genAppName(); 111 } 112 appenderNames.put(app, name); 113 114 printOptions(out, app, "log4j.appender."+name); 115 if (app.getLayout() != null) { 116 printOptions(out, app.getLayout(), "log4j.appender."+name+".layout"); 117 } 118 } 119 appenderString += ", " + name; 120 } 121 String catKey = (cat == Logger.getRootLogger()) 122 ? "log4j.rootLogger" 123 : "log4j.logger." + cat.getName(); 124 if (appenderString != "") { 125 out.println(catKey + "=" + appenderString); 126 } 127 if (!cat.getAdditivity() && cat != Logger.getRootLogger()) { 128 out.println("log4j.additivity." + cat.getName() + "=false"); 129 } 130 } 131 132 protected void printOptions(PrintWriter out, Logger cat) { 133 printOptions(out, (Category) cat); 134 } 135 136 protected 137 void printOptions(PrintWriter out, Object obj, String fullname) { 138 out.println(fullname + "=" + obj.getClass().getName()); 139 PropertyGetter.getProperties(obj, this, fullname + "."); 140 } 141 142 public void foundProperty(Object obj, String prefix, String name, Object value) { 143 // XXX: Properties encode value.toString() 144 if (obj instanceof Appender && "name".equals(name)) { 145 return; 146 } 147 if (doCapitalize) { 148 name = capitalize(name); 149 } 150 out.println(prefix + name + "=" + value.toString()); 151 } 152 153 public static String capitalize(String name) { 154 if (Character.isLowerCase(name.charAt(0))) { 155 if (name.length() == 1 || Character.isLowerCase(name.charAt(1))) { 156 StringBuffer newname = new StringBuffer(name); 157 newname.setCharAt(0, Character.toUpperCase(name.charAt(0))); 158 return newname.toString(); 159 } 160 } 161 return name; 162 } 163 164 // for testing 165 public static void main(String[] args) { 166 new PropertyPrinter(new PrintWriter(System.out)); 167 } 168}