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.core.lookup;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.util.Iterator;
047: import javax.swing.Action;
048: import junit.framework.AssertionFailedError;
049: import org.netbeans.Module;
050: import org.netbeans.ModuleManager;
051: import org.netbeans.core.startup.ModuleHistory;
052: import org.netbeans.junit.NbTestCase;
053: import org.openide.ErrorManager;
054: import org.openide.filesystems.FileObject;
055: import org.openide.filesystems.Repository;
056: import org.openide.loaders.DataObject;
057: import org.openide.util.Lookup;
058: import org.openide.util.LookupEvent;
059: import org.openide.util.LookupListener;
060: import org.openide.util.Mutex;
061: import org.openide.util.MutexException;
062:
063: /** Test InstanceDataObject's behavior in conjunction with module
064: * installation and uninstallation.
065: * Run each test in its own VM, since otherwise tests can affect
066: * their siblings (static vars are evil!).
067: * @author Jesse Glick
068: * @see issue #16327
069: */
070: public abstract class InstanceDataObjectModuleTestHid extends
071: NbTestCase {
072: protected ErrorManager ERR;
073:
074: static {
075: org.netbeans.core.startup.MainLookup.register(new ErrManager());
076: }
077:
078: protected InstanceDataObjectModuleTestHid(String name) {
079: super (name);
080: }
081:
082: private ModuleManager mgr;
083: protected Module m1, m2;
084:
085: protected void runTest() throws Throwable {
086: ErrManager.messages.setLength(0);
087: ErrManager.log = getLog();
088: try {
089: super .runTest();
090: } catch (Error err) {
091: AssertionFailedError newErr = new AssertionFailedError(err
092: .getMessage()
093: + "\n" + ErrManager.messages);
094: newErr.initCause(err);
095: throw newErr;
096: }
097: }
098:
099: protected void setUp() throws Exception {
100: ERR = ErrManager.getDefault().getInstance("TEST-" + getName());
101:
102: mgr = org.netbeans.core.startup.Main.getModuleSystem()
103: .getManager();
104: final File jar1 = toFile(InstanceDataObjectModuleTestHid.class
105: .getResource("data/test1.jar"));
106: final File jar2 = toFile(InstanceDataObjectModuleTestHid.class
107: .getResource("data/test2.jar"));
108: try {
109: mgr.mutex().writeAccess(new Mutex.ExceptionAction() {
110: public Object run() throws Exception {
111: m1 = mgr.create(jar1, new ModuleHistory(jar1
112: .getAbsolutePath()), false, false, false);
113: if (!m1.getProblems().isEmpty())
114: throw new IllegalStateException(
115: "m1 is uninstallable: "
116: + m1.getProblems());
117: m2 = mgr.create(jar2, new ModuleHistory(jar2
118: .getAbsolutePath()), false, false, false);
119: return null;
120: }
121: });
122: } catch (MutexException me) {
123: throw me.getException();
124: }
125:
126: ERR.log("setup finished");
127: }
128:
129: protected static File toFile(java.net.URL url)
130: throws java.io.IOException {
131: File f = new File(url.getPath());
132: if (f.exists()) {
133: return f;
134: }
135:
136: String n = url.getPath();
137: int indx = n.lastIndexOf('/');
138: if (indx != -1) {
139: n = n.substring(indx + 1);
140: }
141: n = n + url.getPath().hashCode();
142:
143: f = File.createTempFile(n, ".jar");
144: java.io.FileOutputStream out = new java.io.FileOutputStream(f);
145: org.openide.filesystems.FileUtil.copy(url.openStream(), out);
146: out.close();
147: f.deleteOnExit();
148:
149: return f;
150: }
151:
152: protected void tearDown() throws Exception {
153: ERR.log("going to teardown");
154: try {
155: mgr.mutex().writeAccess(new Mutex.ExceptionAction() {
156: public Object run() throws Exception {
157: del(m1);
158: del(m2);
159: return null;
160: }
161:
162: private void del(Module m) throws Exception {
163: if (m.isEnabled()) {
164: // Test presumably failed halfway.
165: if (m.isAutoload() || m.isEager()
166: || m.isFixed()) {
167: // Tough luck, can't get rid of it easily.
168: return;
169: }
170: mgr.disable(m);
171: }
172: mgr.delete(m);
173: }
174: });
175: } catch (MutexException me) {
176: Exception e = me.getException();
177: throw e/*new Exception(e + " [Messages:" + ErrManager.messages + "]", e)*/;
178: } catch (RuntimeException e) {
179: // Debugging for #52689:
180: throw e/*new Exception(e + " [Messages:" + ErrManager.messages + "]", e)*/;
181: }
182: m1 = null;
183: m2 = null;
184: mgr = null;
185: }
186:
187: protected static final int TWIDDLE_ENABLE = 0;
188: protected static final int TWIDDLE_DISABLE = 1;
189: protected static final int TWIDDLE_RELOAD = 2;
190:
191: protected void twiddle(final Module m, final int action)
192: throws Exception {
193: try {
194: mgr.mutex().writeAccess(new Mutex.ExceptionAction() {
195: public Object run() throws Exception {
196: switch (action) {
197: case TWIDDLE_ENABLE:
198: mgr.enable(m);
199: break;
200: case TWIDDLE_DISABLE:
201: mgr.disable(m);
202: break;
203: case TWIDDLE_RELOAD:
204: mgr.disable(m);
205: mgr.enable(m);
206: break;
207: default:
208: throw new IllegalArgumentException(
209: "bad action: " + action);
210: }
211: return null;
212: }
213: });
214: } catch (MutexException me) {
215: throw me.getException();
216: }
217: }
218:
219: protected boolean existsSomeAction(Class c) {
220: return existsSomeAction(c, Lookup.getDefault().lookupResult(c));
221: }
222:
223: protected boolean existsSomeAction(Class c, Lookup.Result r) {
224: assertTrue(Action.class.isAssignableFrom(c));
225: boolean found = false;
226: ERR.log("Begin iterate");
227: Iterator it = r.allInstances().iterator();
228: while (it.hasNext()) {
229: Action a = (Action) it.next();
230: ERR.log("First action read: " + a);
231: assertTrue("Assignable to template class: c=" + c.getName()
232: + " a.class=" + a.getClass().getName()
233: + " loaders: c1=" + c.getClassLoader()
234: + " a.class=" + a.getClass().getClassLoader(), c
235: .isInstance(a));
236: if ("SomeAction".equals(a.getValue(Action.NAME))) {
237: found = true;
238: ERR.log("Action with correct name found: " + a);
239: break;
240: }
241: }
242: ERR.log("existsSomeAction finished: " + found);
243: return found;
244: }
245:
246: protected DataObject findIt(String name) throws Exception {
247: FileObject fo = Repository.getDefault().getDefaultFileSystem()
248: .findResource(name);
249: assertNotNull("Found " + name, fo);
250: return DataObject.find(fo);
251: }
252:
253: protected static void assertSameDataObject(String msg,
254: DataObject obj1, DataObject obj2) {
255: assertNotNull(msg, obj1);
256: assertNotNull(msg, obj2);
257: assertEquals("They have the same primary file: " + msg, obj1
258: .getPrimaryFile(), obj2.getPrimaryFile());
259: assertSame(msg, obj1, obj2);
260: }
261:
262: protected static final class LookupL implements LookupListener {
263: public int count = 0;
264:
265: public synchronized void resultChanged(LookupEvent ev) {
266: count++;
267: notifyAll();
268: }
269:
270: public synchronized boolean gotSomething()
271: throws InterruptedException {
272: ErrorManager.getDefault().log("gotSomething: " + count);
273: if (count > 0)
274: return true;
275: ErrorManager.getDefault().log("gotSomething: do wait");
276: wait(23000);
277: ErrorManager.getDefault().log(
278: "gotSomething: wait done: " + count);
279: return count > 0;
280: }
281: }
282:
283: protected static void deleteRec(File f, boolean this too)
284: throws IOException {
285: if (f.isDirectory()) {
286: File[] kids = f.listFiles();
287: if (kids == null)
288: throw new IOException("Could not list: " + f);
289: for (int i = 0; i < kids.length; i++) {
290: deleteRec(kids[i], true);
291: }
292: }
293: if (this too && !f.delete())
294: throw new IOException("Could not delete: " + f);
295: }
296:
297: private static final class ErrManager extends
298: org.openide.ErrorManager {
299: public static final StringBuffer messages = new StringBuffer();
300: public static java.io.PrintStream log = System.err;
301:
302: private String prefix;
303:
304: public ErrManager() {
305: this ("");
306: }
307:
308: private ErrManager(String s) {
309: prefix = s;
310: }
311:
312: public Throwable annotate(Throwable t, int severity,
313: String message, String localizedMessage,
314: Throwable stackTrace, java.util.Date date) {
315: return t;
316: }
317:
318: public Throwable attachAnnotations(Throwable t,
319: org.openide.ErrorManager.Annotation[] arr) {
320: return t;
321: }
322:
323: public org.openide.ErrorManager.Annotation[] findAnnotations(
324: Throwable t) {
325: return null;
326: }
327:
328: public org.openide.ErrorManager getInstance(String name) {
329: return new ErrManager(prefix + name);
330: }
331:
332: public void log(int severity, String s) {
333: if (prefix == null) {
334: return;
335: }
336:
337: if (messages.length() > 500000) {
338: messages.delete(0, 250000);
339: }
340: messages.append('[');
341: log.print('[');
342: messages.append(prefix);
343: log.print(prefix);
344: messages.append(']');
345: log.print(']');
346: messages.append(s);
347: log.print(s);
348: messages.append('\n');
349: log.println();
350: }
351:
352: public void notify(int severity, Throwable t) {
353: if (prefix == null) {
354: return;
355: }
356:
357: messages.append(t.getMessage());
358: t.printStackTrace(log);
359: }
360:
361: }
362:
363: }
|