001package org.andromda.core.common;
002
003import java.io.InputStream;
004import java.net.URL;
005import org.andromda.core.configuration.Namespaces;
006import org.apache.commons.lang.StringUtils;
007import org.apache.log4j.BasicConfigurator;
008import org.apache.log4j.LogManager;
009import org.apache.log4j.Logger;
010import org.apache.log4j.xml.DOMConfigurator;
011
012/**
013 * This is the logger used to write <em>AndroMDA</em> prefixed messages so that our informational logging is nice
014 * looking.
015 *
016 * @author <a href="http://www.mbohlen.de">Matthias Bohlen </a>
017 * @author Chad Brandon
018 * @author Bob Fields
019 * @since 26.11.2003
020 */
021public class AndroMDALogger
022{
023    /**
024     * The default name to give the logger (if one isn't set)
025     */
026    private static final String DEFAULT_LOGGER_NAME = "AndroMDA";
027    private static Logger logger = Logger.getLogger(DEFAULT_LOGGER_NAME);
028
029    /**
030     * Configures logging for the AndroMDA application from the the xml resource "log4j.xml" found within the same
031     * package as this class.
032     */
033    public static void initialize()
034    {
035        String defaultConfiguration = "log4j.xml";
036        URL url = null;
037        final String configuration = loggingConfigurationUri;
038        if (StringUtils.isNotBlank(configuration))
039        {
040            try
041            {
042                url = new URL(configuration);
043                InputStream stream = url.openStream();
044                stream.close();
045
046                configure(url);
047                logger.info("Logging configured from external source --> '" + configuration + '\'');
048            }
049            catch (Throwable throwable)
050            {
051                url = AndroMDALogger.class.getResource(defaultConfiguration);
052                configure(url);
053                logger.warn("Invalid logging configuration uri --> '" + configuration + '\'');
054            }
055        }
056        if (url == null)
057        {
058            url = AndroMDALogger.class.getResource(defaultConfiguration);
059            configure(url);
060        }
061        if (url == null)
062        {
063            throw new RuntimeException(
064                "Could not find default logging configuration file '" + defaultConfiguration + '\'');
065        }
066    }
067
068    /**
069     * The URI to an external logging configuration file.
070     */
071    private static String loggingConfigurationUri = null;
072
073    /**
074     * Sets the URI to an external logging configuration file. This will override the default log4j.xml.
075     *
076     * @param loggingConfigurationUri the URI to the logging configuration file.
077     */
078    public static void setLoggingConfigurationUri(final String loggingConfigurationUri)
079    {
080        AndroMDALogger.loggingConfigurationUri = loggingConfigurationUri;
081    }
082
083    /**
084     * Configures the Logger from the passed in logConfigurationXml
085     *
086     * @param logConfigurationXml
087     */
088    protected static void configure(final URL logConfigurationXml)
089    {
090        try
091        {
092            DOMConfigurator.configure(logConfigurationXml);
093        }
094        catch (Exception ex)
095        {
096            //noinspection UseOfSystemOutOrSystemErr
097            System.err.println(
098                "Unable to initialize logging system " + "with configuration file '" + logConfigurationXml +
099                "' --> using basic configuration.");
100            BasicConfigurator.configure();
101        }
102    }
103
104    /**
105     * Retrieves the namespace logger (if one is available) otherwise returns the root logger.
106     *
107     * @param namespaceName the name of the namespace for which we'll retrieve the logger instance.
108     * @return the namespace or root logger instance.
109     */
110    public static Logger getNamespaceLogger(final String namespaceName)
111    {
112        Logger logger;
113        if (namespaceName != null && !Namespaces.DEFAULT.equals(namespaceName))
114        {
115            logger = Logger.getLogger(getNamespaceLoggerName(namespaceName));
116        }
117        else
118        {
119            logger = Logger.getRootLogger();
120        }
121        return logger;
122    }
123
124    /**
125     * Gets the name of the logger.
126     *
127     * @param namespace the name of the namespace for which this logger is used.
128     * @return the logger name.
129     */
130    public static String getNamespaceLoggerName(final String namespace)
131    {
132        return "org.andromda.namespaces." + namespace;
133    }
134
135    /**
136     * Gets the name of the file to which namespace logging output will be written.
137     *
138     * @param namespace the name of the namespace for which this logger is used.
139     * @return the namespace logging file name.
140     */
141    public static String getNamespaceLogFileName(final String namespace)
142    {
143        return "andromda-" + namespace + ".log";
144    }
145
146    /**
147     * Allows us to add a suffix to the logger name.
148     *
149     * @param suffix the suffix to append to the logger name.
150     */
151    public static void setSuffix(final String suffix)
152    {
153        logger = getSuffixLogger(suffix);
154    }
155
156    /**
157     * Gets a logger with suffixed name
158     * @param suffix the suffix to append to the logger name.
159     * @return Logger instance
160     */
161    public static Logger getSuffixLogger(final String suffix)
162    {
163        return Logger.getLogger(DEFAULT_LOGGER_NAME + ':' + suffix);
164    }
165
166    /**
167     * Returns true if the logger is debug enabled. Use before AndroMDALogger.debug calls
168     * where String concatenation or object manipulation in the method call occurs.
169     * @return true if the underlying logger is debug enabled
170     */
171    public static boolean isDebugEnabled()
172    {
173        return logger.isDebugEnabled();
174    }
175
176    /**
177     * Resets the logger to the default name.
178     */
179    public static void reset()
180    {
181        logger = Logger.getLogger(DEFAULT_LOGGER_NAME);
182    }
183
184    /**
185     * Shuts down the logger and releases any resources.
186     */
187    public static void shutdown()
188    {
189        LogManager.shutdown();
190    }
191
192    /**
193     * @param object
194     */
195    public static void debug(Object object)
196    {
197        logger.debug(object);
198    }
199
200    /**
201     * @param object
202     */
203    public static void info(Object object)
204    {
205        logger.info(object);
206    }
207
208    /**
209     * @param object
210     */
211    public static void warn(Object object)
212    {
213        logger.warn(object);
214    }
215
216    /**
217     * @param object
218     */
219    public static void error(Object object)
220    {
221        logger.error(object);
222    }
223}