001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.apache.tools.ant.module.spi;
043:
044: import java.io.File;
045:
046: /**
047: * A pluggable logger that can listen to {@link AntEvent}s during
048: * one or more {@link AntSession}s.
049: * <p>
050: * There can be several loggers active on a given session,
051: * so {@link AntEvent#consume} may be used to cooperate.
052: * Implementations may be registered to default {@link org.openide.util.Lookup}.
053: * Loggers are notified of events in the order of their registration in lookup.
054: * </p>
055: * <p>
056: * A logger will always first be asked if it is interested in a given session;
057: * if it declines, it will receive no further events for that session.
058: * Otherwise it will normally receive {@link #buildStarted}; then some combination of
059: * target, task, and message logged events; then {@link #buildFinished}.
060: * (Or it may receive just {@link #buildInitializationFailed}.)
061: * A logger may <em>not</em> assume that target and task events are properly
062: * nested in any way, due to Ant's <code><parallel></code> task and
063: * other complexities such as <code><import></code> handling. Events may
064: * also be delivered from the originating script or any subscripts, again with
065: * no guaranteed nesting behavior. A logger may not assume that it will not
066: * receive any events after {@link #buildFinished}.
067: * </p>
068: * <p>
069: * Various mask methods permit loggers to declare themselves uninterested in
070: * some kinds of events. Such events will not be delivered to them. Loggers should
071: * declare themselves interested only in events they will actually use in some way,
072: * to permit the Ant engine to minimize the number of events delivered. Note that
073: * loggers which do not declare themselves interested in the given session will
074: * not receive {@link #buildStarted}, {@link #buildFinished}, or
075: * {@link #buildInitializationFailed} at all, and loggers not additionally interested
076: * in all scripts will not receive {@link #buildInitializationFailed}.
077: * </p>
078: * <p>
079: * A logger should not keep any state as a rule; this would be a memory leak, and
080: * also a logger may be called from multiple threads with different sessions.
081: * Use {@link AntSession#getCustomData} and {@link AntSession#putCustomData} instead.
082: * Loggers may not make calls to the session, event, or task structure objects outside
083: * the dynamic scope of an event callback.
084: * </p>
085: * <p>
086: * This is an abstract class so that new event types or masks may be added in the future.
087: * To prevent possible conflicts, implementors are forbidden to define other methods
088: * which take a single parameter of type {@link AntEvent} or which have a name beginning
089: * with the string <code>interested</code>.
090: * </p>
091: * <div class="nonnormative">
092: * <p>
093: * The Ant module registers one logger at position 100 in META-INF/services lookup
094: * which may or may not handle any events which have not already been consumed
095: * (marking them consumed itself) and will typically process message logged events
096: * by printing them to the output somehow, using hyperlinks for common file error
097: * patterns such as <samp>/path/to/File.java:34: some message</samp>. It may also
098: * handle sequences of messages logged within a task in the format
099: * </p>
100: * <pre> /path/to/File.java:34: you cannot throw a bogus exception here
101: * throw new Exception("bogus!");
102: * ^</pre>
103: * <p>
104: * by linking to the column number indicated by the caret (<samp>^</samp>).
105: * </p>
106: * </div>
107: * @author Jesse Glick
108: * @see <a href="http://www.netbeans.org/issues/show_bug.cgi?id=42525">Issue #42525</a>
109: * @since org.apache.tools.ant.module/3 3.12
110: */
111: public abstract class AntLogger {
112:
113: /** No-op constructor for implementors. */
114: protected AntLogger() {
115: }
116:
117: /**
118: * Special constant indicating the logger is not interested in receiving
119: * any target events.
120: * @see #interestedInTargets
121: */
122: public static final String[] NO_TARGETS = {};
123:
124: /**
125: * Special constant indicating the logger is interested in receiving
126: * all target events.
127: * @see #interestedInTargets
128: */
129: public static final String[] ALL_TARGETS = {};
130:
131: /**
132: * Special constant indicating the logger is not interested in receiving
133: * any task events.
134: * @see #interestedInTasks
135: */
136: public static final String[] NO_TASKS = {};
137:
138: /**
139: * Special constant indicating the logger is interested in receiving
140: * all task events.
141: * @see #interestedInTasks
142: */
143: public static final String[] ALL_TASKS = {};
144:
145: /**
146: * Fired only if the build could not even be started.
147: * {@link AntEvent#getException} will be non-null.
148: * The default implementation does nothing.
149: * @param event the associated event object
150: */
151: public void buildInitializationFailed(AntEvent event) {
152: }
153:
154: /**
155: * Fired once when a build is started.
156: * The default implementation does nothing.
157: * @param event the associated event object
158: */
159: public void buildStarted(AntEvent event) {
160: }
161:
162: /**
163: * Fired once when a build is finished.
164: * The default implementation does nothing.
165: * @param event the associated event object
166: * @see AntEvent#getException
167: */
168: public void buildFinished(AntEvent event) {
169: }
170:
171: /**
172: * Fired when a target is started.
173: * It is <em>not</em> guaranteed that {@link AntEvent#getTargetName}
174: * will be non-null (as can happen in some circumstances with
175: * <code><import></code>, for example).
176: * The default implementation does nothing.
177: * @param event the associated event object
178: */
179: public void targetStarted(AntEvent event) {
180: }
181:
182: /**
183: * Fired when a target is finished.
184: * It is <em>not</em> guaranteed that {@link AntEvent#getTargetName}
185: * will be non-null.
186: * The default implementation does nothing.
187: * @param event the associated event object
188: */
189: public void targetFinished(AntEvent event) {
190: }
191:
192: /**
193: * Fired when a task is started.
194: * It is <em>not</em> guaranteed that {@link AntEvent#getTaskName} or
195: * {@link AntEvent#getTaskStructure} will be non-null, though they will
196: * usually be defined.
197: * {@link AntEvent#getTargetName} might also be null.
198: * The default implementation does nothing.
199: * @param event the associated event object
200: */
201: public void taskStarted(AntEvent event) {
202: }
203:
204: /**
205: * Fired when a task is finished.
206: * It is <em>not</em> guaranteed that {@link AntEvent#getTaskName} or
207: * {@link AntEvent#getTaskStructure} will be non-null.
208: * {@link AntEvent#getTargetName} might also be null.
209: * The default implementation does nothing.
210: * @param event the associated event object
211: */
212: public void taskFinished(AntEvent event) {
213: }
214:
215: /**
216: * Fired when a message is logged.
217: * The task and target fields may or may not be defined.
218: * The default implementation does nothing.
219: * @param event the associated event object
220: */
221: public void messageLogged(AntEvent event) {
222: }
223:
224: /**
225: * Mark whether this logger is interested in a given Ant session.
226: * @param session a session which is about to be start
227: * @return true to receive events about it; by default, false
228: */
229: public boolean interestedInSession(AntSession session) {
230: return false;
231: }
232:
233: /**
234: * Mark whether this logger is interested in any Ant script.
235: * If true, no events will be masked due to the script location.
236: * Note that a few events have no defined script and so will only
237: * be delivered to loggers interested in all scripts; typically this
238: * applies to debugging messages when a project is just being configured.
239: * @param session the relevant session
240: * @return true to receive events for all scripts; by default, false
241: */
242: public boolean interestedInAllScripts(AntSession session) {
243: return false;
244: }
245:
246: /**
247: * Mark whether this logger is interested in a given Ant script.
248: * Called only if {@link #interestedInAllScripts} is false.
249: * Only events with a defined script according to {@link AntEvent#getScriptLocation}
250: * which this logger is interested in will be delivered.
251: * Note that a few events have no defined script and so will only
252: * be delivered to loggers interested in all scripts; typically this
253: * applies to debugging messages when a project is just being configured.
254: * Note also that a single session can involve many different scripts.
255: * @param script a particular build script
256: * @param session the relevant session
257: * @return true to receive events sent from this script; by default, false
258: */
259: public boolean interestedInScript(File script, AntSession session) {
260: return false;
261: }
262:
263: /**
264: * Mark which kinds of targets this logger is interested in.
265: * This applies to both target start and finish events, as well as any other
266: * events for which {@link AntEvent#getTargetName} is not null, such as task
267: * start and finish events, and message log events.
268: * If {@link #NO_TARGETS}, no events with specific targets will be sent to it.
269: * If a specific list, only events with defined target names included in the list
270: * will be sent to it.
271: * If {@link #ALL_TARGETS}, all events not otherwise excluded will be sent to it.
272: * @param session the relevant session
273: * @return a nonempty (and non-null) list of target names; by default, {@link #NO_TARGETS}
274: */
275: public String[] interestedInTargets(AntSession session) {
276: return NO_TARGETS;
277: }
278:
279: /**
280: * Mark which kinds of tasks this logger is interested in.
281: * This applies to both task start and finish events, as well as any other
282: * events for which {@link AntEvent#getTaskName} is not null, such as
283: * message log events.
284: * If {@link #NO_TASKS}, no events with specific tasks will be sent to it.
285: * If a specific list, only events with defined task names included in the list
286: * will be sent to it.
287: * If {@link #ALL_TASKS}, all events not otherwise excluded will be sent to it.
288: * @param session the relevant session
289: * @return a nonempty (and non-null) list of task names; by default, {@link #NO_TASKS}
290: */
291: public String[] interestedInTasks(AntSession session) {
292: return NO_TASKS;
293: }
294:
295: /**
296: * Mark which kinds of message log events this logger is interested in.
297: * This applies only to message log events and no others.
298: * Only events with log levels included in the returned list will be delivered.
299: * @param session the relevant session
300: * @return a list of levels such as {@link AntEvent#LOG_INFO}; by default, an empty list
301: * @see AntSession#getVerbosity
302: */
303: public int[] interestedInLogLevels(AntSession session) {
304: return new int[0];
305: }
306:
307: }
|