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: import java.net.URL;
046: import org.apache.tools.ant.module.run.LoggerTrampoline;
047: import org.openide.windows.OutputListener;
048:
049: /**
050: * Represents one Ant build session, possibly consisting of multiple targets,
051: * subprojects, and so on.
052: * A session may be shared by several {@link AntLogger}s.
053: * @author Jesse Glick
054: * @since org.apache.tools.ant.module/3 3.12
055: */
056: public final class AntSession {
057:
058: static {
059: LoggerTrampoline.ANT_SESSION_CREATOR = new LoggerTrampoline.Creator() {
060: public AntSession makeAntSession(
061: LoggerTrampoline.AntSessionImpl impl) {
062: return new AntSession(impl);
063: }
064:
065: public AntEvent makeAntEvent(
066: LoggerTrampoline.AntEventImpl impl) {
067: throw new AssertionError();
068: }
069:
070: public TaskStructure makeTaskStructure(
071: LoggerTrampoline.TaskStructureImpl impl) {
072: throw new AssertionError();
073: }
074: };
075: }
076:
077: private final LoggerTrampoline.AntSessionImpl impl;
078:
079: private AntSession(LoggerTrampoline.AntSessionImpl impl) {
080: this .impl = impl;
081: }
082:
083: /**
084: * Get the Ant script originally invoked.
085: * Note that due to subproject support some events may come from other scripts.
086: * @return the Ant script which was run to start with
087: */
088: public File getOriginatingScript() {
089: return impl.getOriginatingScript();
090: }
091:
092: /**
093: * Get the Ant targets originally run.
094: * @return a list of one or more targets (but may be empty during {@link AntLogger#buildInitializationFailed})
095: */
096: public String[] getOriginatingTargets() {
097: return impl.getOriginatingTargets();
098: }
099:
100: /**
101: * Get optional data stored by the logger in this session.
102: * @param logger the logger which wishes to retrieve data
103: * @return any optional data, or null initially
104: */
105: public Object getCustomData(AntLogger logger) {
106: return impl.getCustomData(logger);
107: }
108:
109: /**
110: * Store custom data associated with this session.
111: * May be used by the logger to keep some information that will persist
112: * for the lifetime of the session.
113: * @param logger the logger which wishes to store data
114: * @param data some custom data to retain
115: */
116: public void putCustomData(AntLogger logger, Object data) {
117: impl.putCustomData(logger, data);
118: }
119:
120: /**
121: * Print a line of text to the Ant output.
122: * @param message a message to print (newline will be appended automatically)
123: * @param err true to send to the error stream, false for regular output
124: * @param listener an output listener suitable for hyperlinks, or null for a plain print
125: * @see #createStandardHyperlink
126: */
127: public void println(String message, boolean err,
128: OutputListener listener) {
129: impl.println(message, err, listener);
130: }
131:
132: /**
133: * Deliver a message logged event to all matching loggers.
134: * <p>
135: * Loggers will receive {@link AntLogger#messageLogged} with an event
136: * similar to the original event except for the message and log level;
137: * also the exception will always be null and the event will initially
138: * be unconsumed.
139: * </p>
140: * <p>
141: * This call blocks until all loggers have processed the nested event.
142: * Note that this logger may also receive the event so it must be reentrant.
143: * </p>
144: * <p class="nonnormative">
145: * Loggers are discouraged from using this facility merely to create hyperlinks
146: * for which the target is known. Use {@link #println} instead. This method
147: * is primarily intended for use from the standard logger to deliver stack
148: * trace lines to other loggers which may be able to hyperlink them.
149: * </p>
150: * @param originalEvent the original event received by the calling logger
151: * @param message a message to log (see {@link AntEvent#getMessage})
152: * @param level the level to log it at (see {@link AntEvent#getLogLevel})
153: */
154: public void deliverMessageLogged(AntEvent originalEvent,
155: String message, int level) {
156: impl.deliverMessageLogged(originalEvent, message, level);
157: }
158:
159: /**
160: * Marks an exception as having been processed by a logger.
161: * <p>
162: * A single build-halting exception can traverse any number of Ant events
163: * as it progresses outwards, typically from the failing task to the failing
164: * target (possibly several times due to subprojects) and finally to the build failure.
165: * </p>
166: * <p class="nonnormative">
167: * Consuming the exception permits a logger to indicate to other loggers that it
168: * has already handled the problem in an appropriate manner. Since the standard
169: * logger may print an exception (possibly with stack trace) that is part of
170: * a {@link AntLogger#buildFinished} event, loggers which deal with the exception
171: * in some other way should consume it before returning from the callback.
172: * </p>
173: * @param t an exception to mark as consumed
174: * @throws IllegalStateException if it was already consumed
175: */
176: public void consumeException(Throwable t)
177: throws IllegalStateException {
178: impl.consumeException(t);
179: }
180:
181: /**
182: * Tests whether a given exception has already been consumed by some logger.
183: * <p>
184: * Note that if an exception is consumed, any exception with that exception
185: * as its {@link Throwable#getCause} (possibly recursively) is also considered
186: * consumed. This is useful because Ant's <code>ProjectHelper.addLocationToBuildException</code>
187: * will annotate <code>BuildException</code>s with location information by constructing
188: * wrapper exceptions.
189: * </p>
190: * @param t an exception
191: * @return true if it (or a nested exception) has already been consumed by {@link #consumeException}
192: */
193: public boolean isExceptionConsumed(Throwable t) {
194: return impl.isExceptionConsumed(t);
195: }
196:
197: /**
198: * Get the (user-requested) verbosity level for this session.
199: * Generally only messages logged at this or lesser level (higher priority) should be displayed.
200: * @return the verbosity, e.g. {@link AntEvent#LOG_INFO}
201: */
202: public int getVerbosity() {
203: return impl.getVerbosity();
204: }
205:
206: /**
207: * Get a display name used for the session as a whole.
208: * @return a user-presentable display name appropriate for session-scope messaging
209: */
210: public String getDisplayName() {
211: return impl.getDisplayName();
212: }
213:
214: /**
215: * Convenience method to create a standard hyperlink implementation.
216: * The GUI of the hyperlink will be oriented toward error messages and
217: * may involve editor annotations.
218: * Line and column numbers start at 1.
219: * @param file a file to link to (may or may not exist, but hyperlink will not work if it does not)
220: * @param message a message to use e.g. for the status bar when clicking on the hyperlink,
221: * or for annotation tool tips
222: * @param line1 the starting line number, or -1 if there is no associated line number
223: * @param column1 the starting column number, or -1 if there is no associated column number
224: * (must be -1 if line1 is -1)
225: * @param line2 the ending line number, or -1 for a single-line link
226: * (must be -1 if line1 is -1)
227: * @param column2 the ending column number, or -1 if not applicable
228: * (must be -1 if either line2 or column1 is -1)
229: * @return a standard hyperlink suitable for {@link #println}
230: */
231: public OutputListener createStandardHyperlink(URL file,
232: String message, int line1, int column1, int line2,
233: int column2) {
234: return impl.createStandardHyperlink(file, message, line1,
235: column1, line2, column2);
236: }
237:
238: @Override
239: public String toString() {
240: return impl.toString();
241: }
242:
243: }
|