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    
018    package org.apache.geronimo.system.logging.log4j;
019    
020    import java.io.BufferedReader;
021    import java.io.IOException;
022    import java.io.InputStreamReader;
023    import java.io.FileNotFoundException;
024    import java.net.URL;
025    import java.net.URLConnection;
026    
027    import org.apache.commons.logging.Log;
028    import org.apache.commons.logging.LogFactory;
029    import org.apache.log4j.LogManager;
030    import org.apache.log4j.PropertyConfigurator;
031    import org.apache.log4j.spi.Configurator;
032    import org.apache.log4j.spi.LoggerRepository;
033    import org.apache.log4j.xml.DOMConfigurator;
034    
035    /**
036     * Handles the details of configuring Log4j from a URL.
037     *
038     * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
039     */
040    public class URLConfigurator implements Configurator {
041        private static final Log log = LogFactory.getLog(URLConfigurator.class);
042    
043        public static void configure(final URL url) {
044            new URLConfigurator().doConfigure(url, LogManager.getLoggerRepository());
045        }
046    
047        private Configurator getConfigurator(final URL url) throws FileNotFoundException {
048            String contentType = null;
049    
050            // Get the content type to see if it is XML or not
051            URLConnection connection = null;
052            try {
053                connection = url.openConnection();
054                contentType = connection.getContentType();
055                if (log.isTraceEnabled()) {
056                    log.trace("Content type: " + contentType);
057                }
058            } catch (FileNotFoundException e) {
059                throw e;
060            } catch (IOException e) {
061                log.warn("Could not determine content type from URL; ignoring", e);
062            }
063            if (contentType != null) {
064                if (contentType.toLowerCase().endsWith("/xml")) {
065                    return new DOMConfigurator();
066                }
067            }
068    
069            // Check thr file name
070            String filename = url.getFile().toLowerCase();
071            if (filename.endsWith(".xml")) {
072                return new DOMConfigurator();
073            } else if (filename.endsWith(".properties")) {
074                return new PropertyConfigurator();
075            }
076    
077            // Check for <?xml in content
078            if (connection != null) {
079                try {
080                    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
081                    try {
082                        String head = reader.readLine();
083                        if (head.startsWith("<?xml")) {
084                            return new DOMConfigurator();
085                        }
086                    } finally {
087                        reader.close();
088                    }
089                } catch (IOException e) {
090                    log.warn("Failed to check content header; ignoring", e);
091                }
092            }
093    
094            log.warn("Unable to determine content type, using property configurator");
095            return new PropertyConfigurator();
096        }
097    
098        public void doConfigure(final URL url, final LoggerRepository repo) {
099            if (log.isDebugEnabled()) {
100                log.debug("Configuring from URL: " + url);
101            }
102    
103            // Get the config delegate and target repository to config with
104            Configurator delegate = null;
105            try {
106                delegate = getConfigurator(url);
107            } catch (FileNotFoundException e) {
108                return;
109            }
110    
111            if (log.isTraceEnabled()) {
112                log.trace("Configuring Log4j using configurator: " +
113                        delegate + ", repository: " + repo);
114            }
115    
116            // Now actually configure Log4j
117            delegate.doConfigure(url, repo);
118        }
119    }