1 19 20 package org.netbeans.core.startup; 21 22 import java.beans.Beans ; 23 import java.util.LinkedList ; 24 import java.util.List ; 25 import java.util.StringTokenizer ; 26 import java.util.jar.Attributes ; 27 import org.netbeans.Events; 28 import org.netbeans.InvalidException; 29 import org.netbeans.Module; 30 import org.netbeans.Util; 31 import org.openide.util.Exceptions; 32 import org.openide.util.actions.SystemAction; 33 import org.openide.util.datatransfer.ExClipboard; 34 import org.openide.util.SharedClassObject; 35 import org.openide.util.Lookup; 36 37 39 44 public abstract class ManifestSection<T> { 45 46 private final Object superclazz; 47 48 private final String name; 49 50 private final String className; 51 52 private Class <?> clazz; 53 54 private Object result; 55 56 private Exception problem; 57 58 private final Module module; 59 60 67 protected ManifestSection(String name, Module module, Object superclazz) throws InvalidException { 68 this.name = name; 69 this.module = module; 70 this.superclazz = superclazz; 71 try { 72 className = Util.createPackageName(name); 73 } catch (IllegalArgumentException iae) { 74 InvalidException ie = new InvalidException(module, iae.toString()); 75 ie.initCause(iae); 76 throw ie; 77 } 78 } 79 80 81 public final Module getModule() { 82 return module; 83 } 84 85 86 protected final ClassLoader getClassLoader() { 87 return module != null ? module.getClassLoader() : getClass().getClassLoader(); 88 } 89 90 93 public final boolean isDefaultInstance() { 94 return name.endsWith(".class"); } 96 97 101 public final Class <?> getSectionClass() throws Exception { 102 if (clazz != null) { 103 return clazz; 104 } 105 if (problem != null) { 106 throw problem; 107 } 108 if (isDefaultInstance()) { 109 try { 110 clazz = getClassLoader().loadClass(className); 111 if (! getSuperclass().isAssignableFrom(clazz)) { 112 throw new ClassCastException ("Class " + clazz.getName() + " is not a subclass of " + getSuperclass().getName()); } 114 if (clazz.getClassLoader() != getClassLoader()) { Events ev = module.getManager().getEvents(); 119 ev.log(Events.WRONG_CLASS_LOADER, module, clazz, getClassLoader()); 120 } 121 return clazz; 122 } catch (ClassNotFoundException cnfe) { 123 Exceptions.attachMessage(cnfe, 124 "Loader for ClassNotFoundException: " + 125 getClassLoader()); 126 problem = cnfe; 127 throw problem; 128 } catch (Exception e) { 129 problem = e; 130 throw problem; 131 } catch (LinkageError t) { 132 problem = new ClassNotFoundException (t.toString(), t); 133 throw problem; 134 } 135 } else { 136 return (clazz = getInstance().getClass()); 137 } 138 } 139 140 144 public String getSectionClassName() throws Exception { 145 if (isDefaultInstance()) { 146 return className; 147 } else { 148 return getSectionClass().getName(); 149 } 150 } 151 152 156 protected final Object createInstance() throws Exception { 157 if (! isDefaultInstance()) { 158 try { 159 Object o = Beans.instantiate(getClassLoader(), className); 160 clazz = o.getClass(); 161 if (! getSectionClass().isAssignableFrom(clazz)) { 162 throw new ClassCastException ("Class " + clazz.getName() + " is not a subclass of " + getSuperclass().getName()); } 164 return o; 165 } catch (ClassNotFoundException cnfe) { 166 Exceptions.attachMessage(cnfe, 167 "Loader for ClassNotFoundException: " + 168 getClassLoader()); 169 throw cnfe; 170 } catch (LinkageError le) { 171 throw new ClassNotFoundException (le.toString(), le); 172 } 173 } else { 174 getSectionClass(); if (SharedClassObject.class.isAssignableFrom(clazz)) { 176 return SharedClassObject.findObject(clazz.asSubclass(SharedClassObject.class), true); 177 } else { 178 return clazz.newInstance(); 179 } 180 } 181 } 182 183 187 public final Object getInstance() throws Exception { 188 if (problem != null) { 189 problem.fillInStackTrace(); throw problem; 191 } 192 if (result == null) { 193 try { 194 result = createInstance(); 195 } catch (Exception ex) { 196 problem = ex; 198 throw problem; 199 } catch (LinkageError t) { 200 problem = new ClassNotFoundException (t.toString(), t); 201 throw problem; 202 } 203 } 204 return result; 205 } 206 207 210 public final Class <?> getSuperclass() { 211 if (superclazz instanceof Class ) { 212 return (Class )superclazz; 213 } else { 214 try { 215 return getClazz ((String )superclazz, module); 216 } catch (InvalidException ex) { 217 throw (IllegalStateException )new IllegalStateException (superclazz.toString()).initCause (ex); 218 } 219 } 220 } 221 222 225 public void dispose() { 226 result = null; 227 problem = null; 228 clazz = null; 229 } 230 231 232 public String toString() { 233 return "ManifestSection[" + className + "]"; } 235 236 243 public static ManifestSection create(String name, Attributes attr, Module module) throws InvalidException { 244 String sectionName = attr.getValue("OpenIDE-Module-Class"); if (sectionName == null) { 246 return null; 248 } else if (sectionName.equalsIgnoreCase("Action")) { return new ActionSection(name, module); 250 } else if (sectionName.equalsIgnoreCase("Option")) { warnObsolete(sectionName, module); 252 return null; 253 } else if (sectionName.equalsIgnoreCase("Loader")) { return new LoaderSection(name, attr, module); 255 } else if (sectionName.equalsIgnoreCase("Filesystem")) { warnObsolete(sectionName, module); 257 return null; 258 } else if (sectionName.equalsIgnoreCase("Node")) { warnObsolete(sectionName, module); 260 Util.err.warning("(See http://www.netbeans.org/issues/show_bug.cgi?id=19609, last comment, for howto.)"); 261 return null; 262 } else if (sectionName.equalsIgnoreCase("Service")) { warnObsolete(sectionName, module); 264 return null; 265 } else if (sectionName.equalsIgnoreCase("Debugger")) { warnObsolete(sectionName, module); 268 return new DebuggerSection(name, module); 269 } else if (sectionName.equalsIgnoreCase("ClipboardConvertor")) { warnObsolete(sectionName, module); 272 return new ClipboardConvertorSection(name, module); 273 } else { 274 throw new InvalidException(module, "Illegal manifest section type: " + sectionName); } 276 } 277 278 private static void warnObsolete(String sectionName, Module module) { 279 Util.err.warning("Use of OpenIDE-Module-Class: " + sectionName + " in " + module.getCodeNameBase() + " is obsolete."); 280 Util.err.warning("(Please use layer-based installation of objects instead.)"); 281 } 282 283 286 public static final class ActionSection extends ManifestSection { 287 ActionSection(String name, Module module) throws InvalidException { 288 super(name, module, SystemAction.class); 289 } 290 } 291 292 294 public static final class LoaderSection extends ManifestSection { 295 298 private final String [] installAfter; 299 302 private final String [] installBefore; 303 304 LoaderSection(String name, Attributes attrs, Module module) throws InvalidException { 305 super (name, module, "org.openide.loaders.DataLoader"); String val = attrs.getValue("Install-After"); StringTokenizer tok; 308 List <String > res; 309 if (val != null) { 311 tok = new StringTokenizer (val, ", "); res = new LinkedList <String >(); 313 while (tok.hasMoreTokens()) { 314 String clazz = tok.nextToken(); 315 if (! clazz.equals("")) res.add(clazz); 317 } 318 installAfter = res.toArray(new String [res.size()]); 319 } else { 320 installAfter = null; 321 } 322 val = attrs.getValue("Install-Before"); if (val != null) { 324 tok = new StringTokenizer (val, ", "); res = new LinkedList <String >(); 326 while (tok.hasMoreTokens()) { 327 String clazz = tok.nextToken(); 328 if (! clazz.equals("")) res.add(clazz); 330 } 331 installBefore = res.toArray(new String [res.size()]); 332 } else { 333 installBefore = null; 334 } 335 } 336 337 340 public String [] getInstallAfter() { 341 return installAfter; 342 } 343 344 347 public String [] getInstallBefore() { 348 return installBefore; 349 } 350 } 351 352 354 @Deprecated 355 public static final class DebuggerSection extends ManifestSection { 356 DebuggerSection(String name, Module module) throws InvalidException { 357 super(name, module, getClazz("org.openide.debugger.Debugger", module)); } 359 } 360 361 363 @Deprecated 364 public static final class ClipboardConvertorSection extends ManifestSection { 365 ClipboardConvertorSection(String name, Module module) throws InvalidException { 366 super(name, module, ExClipboard.Convertor.class); 367 } 368 } 369 370 372 static Class <?> getClazz(String name, Module m) throws InvalidException { 373 try { 374 return Lookup.getDefault().lookup(ClassLoader .class).loadClass(name); 375 } catch (ClassNotFoundException cnfe) { 376 InvalidException e = new InvalidException(m, "Unable to locate class: " + name + " maybe you do not have its module enabled!?"); e.initCause(cnfe); 378 throw e; 379 } 380 } 381 382 } 383 | Popular Tags |