001// SECTION-START[License Header]
002// <editor-fold defaultstate="collapsed" desc=" Generated License ">
003/*
004 *   Java Object Management and Configuration
005 *   Copyright (C) Christian Schulte, 2005-206
006 *   All rights reserved.
007 *
008 *   Redistribution and use in source and binary forms, with or without
009 *   modification, are permitted provided that the following conditions
010 *   are met:
011 *
012 *     o Redistributions of source code must retain the above copyright
013 *       notice, this list of conditions and the following disclaimer.
014 *
015 *     o Redistributions in binary form must reproduce the above copyright
016 *       notice, this list of conditions and the following disclaimer in
017 *       the documentation and/or other materials provided with the
018 *       distribution.
019 *
020 *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
021 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
022 *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
023 *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
024 *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
025 *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
026 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
027 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
028 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
029 *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
030 *
031 *   $JOMC: DefaultListener.java 4588 2012-06-03 06:01:30Z schulte2005 $
032 *
033 */
034// </editor-fold>
035// SECTION-END
036package org.jomc.ri;
037
038import java.io.BufferedReader;
039import java.io.IOException;
040import java.io.PrintStream;
041import java.io.PrintWriter;
042import java.io.StringReader;
043import java.io.StringWriter;
044import java.util.logging.Level;
045import org.jomc.spi.Listener;
046
047// SECTION-START[Documentation]
048// <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
049/**
050 * Default {@code Listener} implementation.
051 *
052 * <dl>
053 *   <dt><b>Identifier:</b></dt><dd>org.jomc.ri.DefaultListener</dd>
054 *   <dt><b>Name:</b></dt><dd>JOMC RI</dd>
055 *   <dt><b>Abstract:</b></dt><dd>No</dd>
056 *   <dt><b>Final:</b></dt><dd>No</dd>
057 *   <dt><b>Stateless:</b></dt><dd>No</dd>
058 * </dl>
059 *
060 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 1.1
061 * @version 1.1
062 */
063// </editor-fold>
064// SECTION-END
065// SECTION-START[Annotations]
066// <editor-fold defaultstate="collapsed" desc=" Generated Annotations ">
067@javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" )
068// </editor-fold>
069// SECTION-END
070public class DefaultListener implements Listener
071{
072    // SECTION-START[DefaultListener]
073
074    /** Constant holding the platforms line separator. */
075    private static final String LINE_SEPARATOR = System.getProperty( "line.separator", "\n" );
076
077    /** Flag indicating the listener is enabled by default. */
078    private static volatile Boolean defaultEnabled;
079
080    /** Flag indicating the listener is enabled. */
081    private Boolean enabled;
082
083    /**
084     * Gets a flag indicating the listener is enabled by default.
085     * <p>The default enabled flag is controlled by system property
086     * {@code org.jomc.ri.DefaultListener.defaultEnabled} holding a value indicating the listener is enabled by default.
087     * If that property is not set, the {@code true} default is returned.</p>
088     *
089     * @return {@code true}, if the listener is enabled by default; {@code false}, if the listener is disabled by
090     * default.
091     *
092     * @see #setDefaultEnabled(java.lang.Boolean)
093     */
094    public static boolean isDefaultEnabled()
095    {
096        if ( defaultEnabled == null )
097        {
098            defaultEnabled = Boolean.valueOf( System.getProperty(
099                "org.jomc.ri.DefaultListener.defaultEnabled", Boolean.toString( true ) ) );
100
101        }
102
103        return defaultEnabled;
104    }
105
106    /**
107     * Sets the flag indicating the listener is enabled by default.
108     *
109     * @param value The new value of the flag indicating the listener is enabled by default or {@code null}.
110     *
111     * @see #isDefaultEnabled()
112     */
113    public static void setDefaultEnabled( final Boolean value )
114    {
115        defaultEnabled = value;
116    }
117
118    /**
119     * Gets a flag indicating the listener is enabled.
120     *
121     * @return {@code true}, if the listener is enabled; {@code false}, if the listener is disabled.
122     *
123     * @see #isDefaultEnabled()
124     * @see #setEnabled(java.lang.Boolean)
125     */
126    public final boolean isEnabled()
127    {
128        if ( this.enabled == null )
129        {
130            this.enabled = isDefaultEnabled();
131        }
132
133        return this.enabled;
134    }
135
136    /**
137     * Sets the flag indicating the listener is enabled.
138     *
139     * @param value The new value of the flag indicating the listener is enabled or {@code null}.
140     *
141     * @see #isEnabled()
142     */
143    public final void setEnabled( final Boolean value )
144    {
145        this.enabled = value;
146    }
147
148    /**
149     * Gets called on logging.
150     * <p>This method prints messages to the "standard" system streams. Messages with a level greater than
151     * {@code WARNING} are printed to the system error stream. All other messages are printed to the system output
152     * stream.</p>
153     *
154     * @param level The level of the event.
155     * @param message The message of the event or {@code null}.
156     * @param throwable The throwable of the event or {@code null}.
157     *
158     * @throws NullPointerException if {@code level} is {@code null}.
159     *
160     * @see #isEnabled()
161     */
162    public void onLog( final Level level, final String message, final Throwable throwable )
163    {
164        if ( level == null )
165        {
166            throw new NullPointerException( "level" );
167        }
168
169        if ( this.isEnabled() )
170        {
171            // JDK: As of JDK 6, "System.console().writer()".
172            final PrintStream out = level.intValue() > Level.WARNING.intValue() ? System.err : System.out;
173
174            try
175            {
176                if ( message != null )
177                {
178                    out.print( this.splitLines( level, message ) );
179                    out.flush();
180                }
181
182                if ( throwable != null )
183                {
184                    final StringWriter stringWriter = new StringWriter();
185                    final PrintWriter printWriter = new PrintWriter( stringWriter );
186                    throwable.printStackTrace( printWriter );
187                    printWriter.close();
188                    out.print( this.splitLines( level, stringWriter.toString() ) );
189                    out.flush();
190                }
191            }
192            catch ( final IOException e )
193            {
194                e.printStackTrace();
195            }
196        }
197    }
198
199    private StringBuilder splitLines( final Level level, final String message ) throws IOException
200    {
201        BufferedReader reader = null;
202        boolean suppressExceptionOnClose = true;
203
204        try
205        {
206            final String linePrefix = "[" + level.getLocalizedName() + "] ";
207            final StringBuilder b = new StringBuilder( message.length() );
208            reader = new BufferedReader( new StringReader( message ) );
209
210            String line;
211            while ( ( line = reader.readLine() ) != null )
212            {
213                b.append( linePrefix ).append( line ).append( LINE_SEPARATOR );
214            }
215
216            suppressExceptionOnClose = false;
217            return b;
218        }
219        finally
220        {
221            try
222            {
223                if ( reader != null )
224                {
225                    reader.close();
226                }
227            }
228            catch ( final IOException e )
229            {
230                if ( !suppressExceptionOnClose )
231                {
232                    throw e;
233                }
234            }
235        }
236    }
237
238    // SECTION-END
239    // SECTION-START[Constructors]
240    // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
241    /** Creates a new {@code DefaultListener} instance. */
242    @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" )
243    public DefaultListener()
244    {
245        // SECTION-START[Default Constructor]
246        super();
247        // SECTION-END
248    }
249    // </editor-fold>
250    // SECTION-END
251    // SECTION-START[Dependencies]
252    // SECTION-END
253    // SECTION-START[Properties]
254    // SECTION-END
255    // SECTION-START[Messages]
256    // SECTION-END
257}