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.netbeans.xtest.plugin.ide;
043:
044: import java.io.IOException;
045: import java.lang.reflect.Method;
046: import java.util.Iterator;
047: import java.util.logging.Logger;
048: import junit.framework.AssertionFailedError;
049: import junit.framework.Test;
050: import junit.framework.TestListener;
051: import junit.framework.TestResult;
052: import org.netbeans.core.execution.Install;
053: import org.netbeans.xtest.plugin.ide.services.XTestErrorManager;
054: import org.netbeans.xtest.testrunner.JUnitTestRunner;
055:
056: /**
057: * Portion of Main that needs to run with access to Execution API & impl.
058: * @author Jan Chalupa, Jesse Glick
059: */
060: public class MainWithExec implements Main.MainWithExecInterface {
061:
062: private static final Logger LOGGER = Logger
063: .getLogger(MainWithExec.class.getName());
064:
065: /* Terminates all pending tasks.
066: * It calls org.netbeans.core.execution.Install.killPendingTasks() method.
067: */
068: public void killPendingTasks() {
069: try {
070: Class.forName("org.netbeans.core.execution.Install");
071: } catch (ClassNotFoundException cnfe) {
072: // class is not available
073: return;
074: }
075: try {
076: Method killPendingTasksMethod = Install.class
077: .getDeclaredMethod("killPendingTasks", null);
078: killPendingTasksMethod.setAccessible(true);
079: killPendingTasksMethod.invoke(null, null);
080: // better sleep for a sec, so they can be really killed
081: Thread.sleep(2000);
082: } catch (Exception e) {
083: e.printStackTrace();
084: }
085: }
086:
087: /** Discards all changes in modified files. */
088: public void discardChanges() {
089: Object[] dobs = org.openide.loaders.DataObject.getRegistry()
090: .getModifiedSet().toArray();
091: if (dobs.length > 0) {
092: LOGGER.info(new java.util.Date().toString()
093: + ": discarding changes in unsaved files:");
094: for (int i = 0; i < dobs.length; i++) {
095: org.openide.loaders.DataObject obj = (org.openide.loaders.DataObject) dobs[i];
096: LOGGER
097: .info(" "
098: + obj.getPrimaryFile().getPath());
099: obj.setModified(false);
100: }
101: }
102: }
103:
104: public void exit() {
105: org.openide.LifecycleManager.getDefault().exit();
106: }
107:
108: public void run() throws Exception {
109: try {
110: if ("true".equals(System
111: .getProperty("xtest.ide.error.manager"))
112: || "true".equals(System
113: .getProperty("xtest.ide.handler"))) {
114: // install xtest error manager
115: MyJUnitTestRunner testRunner = new MyJUnitTestRunner();
116: testRunner.runTests();
117: } else {
118: JUnitTestRunner testRunner = new JUnitTestRunner(null,
119: System.out);
120: testRunner.runTests();
121: }
122: } catch (Throwable t) {
123: System.out
124: .println("Error - during test run caught exception: "
125: + t.getMessage());
126: t.printStackTrace();
127: }
128: }
129:
130: /** This class adds XTestResultListener to be able to track exceptions
131: * caugth by XTestErrorManager.
132: */
133: private class MyJUnitTestRunner extends JUnitTestRunner {
134:
135: public MyJUnitTestRunner() throws IOException {
136: super (null, System.out);
137: if ("true".equals(System.getProperty("xtest.ide.handler"))) {
138: // adds handler to track exceptions thrown by logger
139: Logger.getLogger("").addHandler(new XTestIDEHandler());
140: }
141: }
142:
143: protected void addTestListeners(TestResult testResult) {
144: // [pzajac] XTestErrorListenr listener must be first
145: testResult.addListener(new XTestResultListener(testResult));
146: super .addTestListeners(testResult);
147: }
148: }
149:
150: /** This TestListener reports error for a exceptions from ErrorManager
151: */
152: private static class XTestResultListener implements TestListener {
153:
154: private TestResult result;
155: private boolean checkXTestErrorManager = "true".equals(System
156: .getProperty("xtest.ide.error.manager"));
157: private boolean errorInTest = false;
158:
159: public XTestResultListener(TestResult result) {
160: this .result = result;
161: }
162:
163: /** An error occurred. */
164: public void addError(Test test, Throwable t) {
165: // report this error and ignore possible additional errors from IDE
166: errorInTest = true;
167: }
168:
169: /** A failure occurred.*/
170: public void addFailure(Test test, AssertionFailedError t) {
171: };
172:
173: /* A test ended. */
174: public void endTest(Test test) {
175: if (!errorInTest) {
176: try {
177: Iterator it = XTestErrorManager.getExceptions()
178: .iterator();
179: if (checkXTestErrorManager && it.hasNext()) {
180: // exception was thrown => add the first found exception as
181: // an error (i.e. its stack trace will be printed in results)
182: result.addError(test, (Throwable) it.next());
183: XTestErrorManager.clearExceptions();
184: } else {
185: // check XTestIDEHandler
186: Iterator itHandler = XTestIDEHandler
187: .getExceptions().iterator();
188: if (itHandler.hasNext()) {
189: // exception was thrown => add the first found exception as
190: // an error (i.e. its stack trace will be printed in results)
191: result.addError(test, (Throwable) itHandler
192: .next());
193: XTestIDEHandler.clearExceptions();
194: }
195: }
196: } catch (Exception e) {
197: // ClassNotFound exception, etc
198: e.printStackTrace();
199: }
200: }
201: errorInTest = false;
202: }
203:
204: /** A test started. */
205: public void startTest(Test test) {
206: };
207:
208: } // XTestResultListener
209: }
|