ceki 2004/11/22 09:49:43 Modified: src/java/org/apache/log4j/joran/util XMLUtil.java src/java/org/apache/log4j/joran JoranConfigurator.java Log: Joran now checks to see if the XML document is well-forwed to avoid processing ill-formed documents. Revision Changes Path 1.2 +85 -38 logging-log4j/src/java/org/apache/log4j/joran/util/XMLUtil.java Index: XMLUtil.java =================================================================== RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/util/XMLUtil.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- XMLUtil.java 22 Nov 2004 17:07:08 -0000 1.1 +++ XMLUtil.java 22 Nov 2004 17:49:43 -0000 1.2 @@ -1,4 +1,20 @@ /* + * Copyright 1999,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* * Created on Nov 22, 2004 * * To change the template for this generated file go to @@ -6,14 +22,21 @@ */ package org.apache.log4j.joran.util; +import org.apache.joran.ExecutionContext; + +import org.apache.log4j.spi.ErrorItem; + +import org.xml.sax.InputSource; + +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.net.URL; + import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; -import org.apache.log4j.spi.ErrorItem; -import org.xml.sax.InputSource; /** @@ -23,48 +46,72 @@ * Window>Preferences>Java>Code Generation>Code and Comments */ public class XMLUtil { - public static final int CANT_SAY = 0; - public static final int WELL_FORMED = 1; - public static final int ILL_FORMED = 2; - public static final int UNRECOVERABLE_ERROR = 3; + public static final int CANT_SAY = 0; + public static final int WELL_FORMED = 1; + public static final int ILL_FORMED = 2; + public static final int UNRECOVERABLE_ERROR = 3; + + public static int checkIfWellFormed(String filename, List errorList) { + int returnCode; + + FileInputStream fis = null; + try { + fis = new FileInputStream(filename); + returnCode = checkIfWellFormed(new InputSource(fis), errorList); + } catch (IOException ioe) { + String errMsg = "Could not open [" + filename + "]."; + errorList.add(new ErrorItem(errMsg, ioe)); + returnCode = UNRECOVERABLE_ERROR; + } finally { + if (fis != null) { + try { + fis.close(); + } catch (java.io.IOException e) { + } + } + } + return returnCode; + } - public static int checkIfWellFormed(InputStream is, List errorList) { - int result; + public static int checkIfWellFormed(URL url, List errorList) { + int returnCode; + InputStream in = null; - if(is.markSupported()) { - System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); - try { - is.mark(64*1024*1024); - InputSource inputSource = new InputSource(is); - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setValidating(false); - SAXParser saxParser = spf.newSAXParser(); - - int oldSize = errorList.size(); - saxParser.parse(inputSource, new WellfomednessChecker(errorList)); - int newSize = errorList.size(); - - if(newSize > oldSize) { - result = ILL_FORMED; - } else { - result = WELL_FORMED; - } - } catch(Exception ex) { - errorList.add(new ErrorItem("Problem while hecking well-formedness", ex)); - result = ILL_FORMED; - } finally { + try { + in = url.openStream(); + returnCode = checkIfWellFormed(new InputSource(in), errorList); + } catch (IOException ioe) { + String errMsg = "Could not open [" + url + "]."; + errorList.add(new ErrorItem(errMsg, ioe)); + returnCode = UNRECOVERABLE_ERROR; + } finally { + if (in != null) { try { - is.reset(); - } catch(IOException e) { - result = UNRECOVERABLE_ERROR; + in.close(); + } catch (java.io.IOException e) { } } - } else { - System.out.println("XXXXXXXXXXXXX markSupported NOT supported"); - return CANT_SAY; } - + return returnCode; + } + + private static int checkIfWellFormed(InputSource inputSource, List errorList) { + int result; + try { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setValidating(false); + SAXParser saxParser = spf.newSAXParser(); + + saxParser.parse(inputSource, new WellfomednessChecker(errorList)); + result = WELL_FORMED; + } catch(org.xml.sax.SAXParseException se) { + result = ILL_FORMED; + } catch (Exception ex) { + errorList.add( + new ErrorItem("Problem while checking well-formedness", ex)); + result = UNRECOVERABLE_ERROR; + } + return result; } - } 1.21 +92 -56 logging-log4j/src/java/org/apache/log4j/joran/JoranConfigurator.java Index: JoranConfigurator.java =================================================================== RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/JoranConfigurator.java,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- JoranConfigurator.java 22 Nov 2004 17:07:08 -0000 1.20 +++ JoranConfigurator.java 22 Nov 2004 17:49:43 -0000 1.21 @@ -13,18 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.log4j.joran; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.HashMap; -import java.util.List; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; +package org.apache.log4j.joran; import org.apache.joran.ExecutionContext; import org.apache.joran.Interpreter; @@ -34,6 +24,7 @@ import org.apache.joran.action.NewRuleAction; import org.apache.joran.action.ParamAction; import org.apache.joran.helper.SimpleRuleStore; + import org.apache.log4j.config.ConfiguratorBase; import org.apache.log4j.joran.action.ActionConst; import org.apache.log4j.joran.action.AppenderAction; @@ -52,23 +43,36 @@ import org.apache.log4j.spi.ErrorItem; import org.apache.log4j.spi.LoggerRepository; import org.apache.log4j.xml.Log4jEntityResolver; + import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import java.net.URL; + +import java.util.HashMap; +import java.util.List; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + /** - * - * A JoranConfigurator instance should not be used more than once to + * + * A JoranConfigurator instance should not be used more than once to * configure a LoggerRepository. - * + * * @author Ceki Gülcü */ public class JoranConfigurator extends ConfiguratorBase { - Interpreter joranInterpreter; LoggerRepository repository; boolean listAppnderAttached = false; - + public JoranConfigurator() { selfInitialize(); } @@ -78,6 +82,18 @@ this.repository = repository; ExecutionContext ec = joranInterpreter.getExecutionContext(); + List errorList = ec.getErrorList(); + + int result = XMLUtil.checkIfWellFormed(url, errorList); + switch (result) { + case XMLUtil.ILL_FORMED: + case XMLUtil.UNRECOVERABLE_ERROR: + errorList.add( + new ErrorItem( + "Problem parsing XML document. See previously reported errors. Abandoning all furhter processing.")); + return; + } + String errMsg; try { InputStream in = url.openStream(); @@ -93,17 +109,30 @@ public List getErrorList() { return getExecutionContext().getErrorList(); } - + /** * Configure a repository from a configuration file passed as parameter. */ public void doConfigure(String filename, LoggerRepository repository) { // This line is needed here because there is logging from inside this method. this.repository = repository; - - FileInputStream fis = null; + getLogger(repository).info( + "in JoranConfigurator doConfigure {}", filename); + ExecutionContext ec = joranInterpreter.getExecutionContext(); - getLogger(repository).info("in JoranConfigurator doConfigure {}", filename); + List errorList = ec.getErrorList(); + + int result = XMLUtil.checkIfWellFormed(filename, errorList); + switch (result) { + case XMLUtil.ILL_FORMED: + case XMLUtil.UNRECOVERABLE_ERROR: + errorList.add( + new ErrorItem( + "Problem parsing XML document. See previously reported errors. Abandoning all furhter processing.")); + return; + } + + FileInputStream fis = null; try { fis = new FileInputStream(filename); doConfigure(fis, repository); @@ -116,43 +145,35 @@ try { fis.close(); } catch (java.io.IOException e) { - getLogger(repository).error("Could not close [" + filename + "].", e); + getLogger(repository).error( + "Could not close [" + filename + "].", e); } } } } - + /** * Configure a repository from the input stream passed as parameter */ public void doConfigure(InputStream in, LoggerRepository repository) { - List errorList = getErrorList(); - - int result = XMLUtil.checkIfWellFormed(in, errorList); - switch(result) { - case XMLUtil.ILL_FORMED: - errorList.add(new ErrorItem("Ill formed XML document. Abandoning all furhter processing.")); - break; - case XMLUtil.CANT_SAY: - case XMLUtil.WELL_FORMED: - doConfigure(new InputSource(in), repository); - } - + doConfigure(new InputSource(in), repository); } /** * All doConfigure methods evenually call this form. - * */ - public void doConfigure(InputSource inputSource, LoggerRepository repository) { + * */ + public void doConfigure( + InputSource inputSource, LoggerRepository repository) { this.repository = repository; ExecutionContext ec = joranInterpreter.getExecutionContext(); ec.pushObject(repository); String errMsg; try { attachListAppender(repository); - + getLogger(repository).debug("Starting to parse input source."); SAXParserFactory spf = SAXParserFactory.newInstance(); + // we want non-validating parsers spf.setValidating(false); SAXParser saxParser = spf.newSAXParser(); @@ -173,35 +194,51 @@ } } - - protected void selfInitialize() { RuleStore rs = new SimpleRuleStore(); rs.addRule(new Pattern("log4j:configuration"), new ConfigurationAction()); - rs.addRule(new Pattern("log4j:configuration/substitutionProperty"), new SubstitutionPropertyAction()); - rs.addRule(new Pattern("log4j:configuration/repositoryProperty"), new RepositoryPropertyAction()); + rs.addRule( + new Pattern("log4j:configuration/substitutionProperty"), + new SubstitutionPropertyAction()); + rs.addRule( + new Pattern("log4j:configuration/repositoryProperty"), + new RepositoryPropertyAction()); rs.addRule(new Pattern("log4j:configuration/plugin"), new PluginAction()); rs.addRule(new Pattern("log4j:configuration/logger"), new LoggerAction()); - rs.addRule(new Pattern("log4j:configuration/logger/level"), new LevelAction()); - rs.addRule(new Pattern("log4j:configuration/logger/priority"), new PriorityAction()); - rs.addRule(new Pattern("log4j:configuration/root"), new RootLoggerAction()); - rs.addRule(new Pattern("log4j:configuration/root/level"), new LevelAction()); - rs.addRule(new Pattern("log4j:configuration/root/priority"), new PriorityAction()); - rs.addRule(new Pattern("log4j:configuration/logger/appender-ref"), new AppenderRefAction()); - rs.addRule(new Pattern("log4j:configuration/root/appender-ref"), new AppenderRefAction()); - rs.addRule(new Pattern("log4j:configuration/appender"), new AppenderAction()); - rs.addRule(new Pattern("log4j:configuration/appender/layout"), new LayoutAction()); - rs.addRule(new Pattern("log4j:configuration/appender/layout/conversionRule"), new ConversionRuleAction()); - rs.addRule(new Pattern("log4j:configuration/newRule"), new NewRuleAction()); + rs.addRule( + new Pattern("log4j:configuration/logger/level"), new LevelAction()); + rs.addRule( + new Pattern("log4j:configuration/logger/priority"), new PriorityAction()); + rs.addRule( + new Pattern("log4j:configuration/root"), new RootLoggerAction()); + rs.addRule( + new Pattern("log4j:configuration/root/level"), new LevelAction()); + rs.addRule( + new Pattern("log4j:configuration/root/priority"), new PriorityAction()); + rs.addRule( + new Pattern("log4j:configuration/logger/appender-ref"), + new AppenderRefAction()); + rs.addRule( + new Pattern("log4j:configuration/root/appender-ref"), + new AppenderRefAction()); + rs.addRule( + new Pattern("log4j:configuration/appender"), new AppenderAction()); + rs.addRule( + new Pattern("log4j:configuration/appender/layout"), new LayoutAction()); + rs.addRule( + new Pattern("log4j:configuration/appender/layout/conversionRule"), + new ConversionRuleAction()); + rs.addRule( + new Pattern("log4j:configuration/newRule"), new NewRuleAction()); rs.addRule(new Pattern("*/param"), new ParamAction()); joranInterpreter = new Interpreter(rs); - + // We need to bother with an entity resolver in order to be compatible // with config files written for DOMConfigurator containing the following: // <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> joranInterpreter.setEntityResolver(new Log4jEntityResolver()); - + // The following line adds the capability to parse nested components joranInterpreter.addImplcitAction(new NestComponentIA()); ExecutionContext ec = joranInterpreter.getExecutionContext(); @@ -209,9 +246,8 @@ HashMap omap = ec.getObjectMap(); omap.put(ActionConst.APPENDER_BAG, new HashMap()); } - + public ExecutionContext getExecutionContext() { return joranInterpreter.getExecutionContext(); } } -
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]