1 19 20 package org.netbeans.modules.form.palette; 21 22 import com.sun.source.tree.ClassTree; 23 import com.sun.source.tree.Tree; 24 import com.sun.source.util.TreePath; 25 import java.lang.ref.WeakReference ; 26 import java.util.jar.*; 27 import java.util.*; 28 import java.io.*; 29 import java.lang.reflect.Modifier ; 30 import java.text.MessageFormat ; 31 import java.util.logging.Level ; 32 import java.util.logging.Logger ; 33 import javax.lang.model.element.Element; 34 import javax.lang.model.element.ElementKind; 35 import javax.lang.model.element.ExecutableElement; 36 import javax.lang.model.element.TypeElement; 37 import org.netbeans.api.java.source.CancellableTask; 38 import org.netbeans.api.java.source.CompilationController; 39 import org.netbeans.api.java.source.JavaSource; 40 import org.netbeans.api.java.source.JavaSource.Phase; 41 import org.netbeans.modules.classfile.ClassFile; 42 import org.netbeans.modules.classfile.Method; 43 44 import org.openide.*; 45 import org.openide.nodes.Node; 46 import org.openide.filesystems.*; 47 import org.openide.loaders.DataObject; 48 49 import org.netbeans.modules.form.project.*; 50 51 56 57 public final class BeanInstaller { 58 59 private static WeakReference wizardRef; 60 61 private BeanInstaller() { 62 } 63 64 66 68 public static void installBeans(String sourceType) { 69 AddToPaletteWizard wizard = getAddWizard(); 70 if (wizard.show(sourceType)) 71 createPaletteItems(sourceType, 72 wizard.getSelectedBeans(), 73 wizard.getSelectedCategory()); 74 } 75 76 78 public static void installBeans(Node[] nodes) { 79 final List<ClassSource> beans = new LinkedList<ClassSource>(); 80 final List<String > unableToInstall = new LinkedList<String >(); 81 for (int i=0; i < nodes.length; i++) { 82 DataObject dobj = (DataObject) nodes[i].getCookie(DataObject.class); 83 if (dobj == null) 84 continue; 85 86 final FileObject fo = dobj.getPrimaryFile(); 87 JavaClassHandler handler = new JavaClassHandler() { 88 public void handle(String className) { 89 ClassSource classSource = 90 ClassPathUtils.getProjectClassSource(fo, className); 91 if (classSource == null) { 92 unableToInstall.add(className); 94 } else { 95 beans.add(classSource); 96 } 97 } 98 }; 99 scanFileObject(fo.getParent(), fo, handler); 100 } 101 102 if (unableToInstall.size() > 0) { 103 Iterator iter = unableToInstall.iterator(); 104 StringBuffer sb = new StringBuffer (); 105 while (iter.hasNext()) { 106 sb.append(iter.next()+", "); } 108 sb.delete(sb.length()-2, sb.length()); 109 String messageFormat = PaletteUtils.getBundleString("MSG_cannotInstallBeans"); String message = MessageFormat.format(messageFormat, new Object [] {sb.toString()}); 111 NotifyDescriptor nd = new NotifyDescriptor.Message(message); 112 DialogDisplayer.getDefault().notify(nd); 113 if (beans.size() == 0) return; 114 } 115 116 if (beans.size() == 0) { 117 NotifyDescriptor nd = new NotifyDescriptor.Message(PaletteUtils.getBundleString("MSG_noBeansUnderNodes")); DialogDisplayer.getDefault().notify(nd); 119 return; 120 } 121 122 String category = CategorySelector.selectCategory(); 123 if (category == null) 124 return; 126 final FileObject categoryFolder = PaletteUtils.getPaletteFolder() 127 .getFileObject(category); 128 try { 129 Repository.getDefault().getDefaultFileSystem().runAtomicAction( 130 new FileSystem.AtomicAction () { 131 public void run() { 132 Iterator it = beans.iterator(); 133 while (it.hasNext()) { 134 ClassSource classSource = (ClassSource)it.next(); 135 try { 136 PaletteItemDataObject.createFile(categoryFolder, classSource); 137 } 139 catch (java.io.IOException ex) { 140 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 141 } 142 } 143 } 144 }); 145 } 146 catch (java.io.IOException ex) {} } 148 149 152 static List findJavaBeansInJar(File[] jarFiles) { 153 Map beans = null; 154 155 for (int i=0; i < jarFiles.length; i++) { 156 Manifest manifest; 157 try { 158 manifest = new JarFile(jarFiles[i]).getManifest(); 159 } 160 catch (java.io.IOException ex) { 161 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 162 continue; 163 } 164 if (manifest == null) 165 continue; 166 167 String jarPath = jarFiles[i].getAbsolutePath(); 168 Map entries = manifest.getEntries(); 169 Iterator it = entries.entrySet().iterator(); 170 while (it.hasNext()) { 171 Map.Entry entry = (Map.Entry)it.next(); 172 String key = (String )entry.getKey(); 173 if (!key.endsWith(".class")) continue; 175 176 String value = ((Attributes)entry.getValue()).getValue("Java-Bean"); if (!"True".equalsIgnoreCase(value)) continue; 179 180 String classname = key.substring(0, key.length()-6) .replace('\\', '/').replace('/', '.'); 182 if (classname.startsWith(".")) classname = classname.substring(1); 184 185 ItemInfo ii = new ItemInfo(); 186 ii.classname = classname; 187 ii.source = jarPath; 188 189 if (beans == null) 190 beans = new HashMap(100); 191 beans.put(ii.classname, ii); 192 } 193 } 194 195 return beans != null ? new ArrayList(beans.values()) : null; 196 } 197 198 202 static List findJavaBeans(File[] roots) { 203 Map beans = new HashMap(100); 204 205 for (int i=0; i < roots.length; i++) { 206 FileObject foRoot = FileUtil.toFileObject(roots[i]); 207 if (foRoot != null) { 208 if (FileUtil.isArchiveFile(foRoot)) 209 foRoot = FileUtil.getArchiveRoot(foRoot); 210 if (foRoot != null && foRoot.isFolder()) { 211 scanFolderForBeans(foRoot, beans, roots[i].getAbsolutePath()); 212 } 213 } 214 } 215 216 return new ArrayList(beans.values()); 217 } 218 219 222 223 private static void createPaletteItems(final String sourceType, 224 final ItemInfo[] beans, 225 String category) 226 { 227 if (beans.length == 0) 228 return; 229 230 final FileObject categoryFolder = 231 PaletteUtils.getPaletteFolder().getFileObject(category); 232 if (categoryFolder == null) 233 return; 234 235 try { 236 Repository.getDefault().getDefaultFileSystem().runAtomicAction( 237 new FileSystem.AtomicAction () { 238 public void run() { 239 String [] cpTypes = new String [] { sourceType }; 240 for (int i=0; i < beans.length; i++) 241 try { 242 PaletteItemDataObject.createFile( 243 categoryFolder, 244 new ClassSource(beans[i].classname, 245 cpTypes, 246 new String [] { beans[i].source} )); 247 } 249 catch (java.io.IOException ex) { 250 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 251 } 252 } 253 }); 254 } 255 catch (java.io.IOException ex) {} } 257 258 260 private static void scanFolderForBeans(FileObject folder, final Map beans, final String root) { 261 JavaClassHandler handler = new JavaClassHandler() { 262 public void handle(String className) { 263 ItemInfo ii = new ItemInfo(); 264 ii.classname = className; 265 ii.source = root; 266 beans.put(ii.classname, ii); 267 } 268 }; 269 270 FileObject[] files = folder.getChildren(); 271 for (int i=0; i < files.length; i++) { 272 FileObject fo = files[i]; 273 if (fo.isFolder()) { 274 scanFolderForBeans(fo, beans, root); 275 } 276 else try { 277 if ("class".equals(fo.getExt()) && (DataObject.find(fo) != null)) 279 { 280 scanFileObject(folder, fo, handler); 281 } 282 } 283 catch (org.openide.loaders.DataObjectNotFoundException ex) {} } 285 } 286 287 private static void scanFileObject(FileObject folder, final FileObject fileObject, final JavaClassHandler handler) { 288 if ("class".equals(fileObject.getExt())) { processClassFile(fileObject, handler); 290 } else if ("java".equals(fileObject.getExt())) { processJavaFile(fileObject, handler); 292 } 293 } 294 295 300 public static String findJavaBeanName(FileObject file) { 301 final String [] fqn = new String [1]; 302 scanFileObject(null, file, new JavaClassHandler() { 303 public void handle(String className) { 304 fqn[0] = className; 305 } 306 }); 307 return fqn[0]; 308 } 309 310 private static void processJavaFile(final FileObject javaFO, final JavaClassHandler handler) { 311 try { 312 JavaSource js = JavaSource.forFileObject(javaFO); 313 js.runUserActionTask(new CancellableTask<CompilationController>() { 314 public void cancel() { 315 } 316 317 public void run(CompilationController ctrl) throws Exception { 318 ctrl.toPhase(Phase.ELEMENTS_RESOLVED); 319 TypeElement clazz = findClass(ctrl, javaFO.getName()); 320 if (clazz != null && isDeclaredAsJavaBean(clazz)) { 321 handler.handle(clazz.getQualifiedName().toString()); 322 } 323 } 324 }, true); 325 } catch (IOException ex) { 326 Logger.getLogger(BeanInstaller.class.getClass().getName()). 327 log(Level.SEVERE, javaFO.toString(), ex); 328 } 329 } 330 331 private static TypeElement findClass(CompilationController ctrl, String className) { 332 for (Tree decl : ctrl.getCompilationUnit().getTypeDecls()) { 333 if (className.equals(((ClassTree) decl).getSimpleName().toString())) { 334 TreePath path = ctrl.getTrees().getPath(ctrl.getCompilationUnit(), decl); 335 TypeElement clazz = (TypeElement) ctrl.getTrees().getElement(path); 336 return clazz; 337 } 338 } 339 return null; 340 } 341 342 private static void processClassFile(FileObject classFO, JavaClassHandler handler) { 343 try { 344 InputStream is = null; 346 ClassFile clazz; 347 try { 348 is = classFO.getInputStream(); 349 clazz = new ClassFile(is, false); 350 } finally { 351 if (is != null) { 352 is.close(); 353 } 354 } 355 if (clazz != null && isDeclaredAsJavaBean(clazz)) { 356 handler.handle(clazz.getName().getExternalName()); 357 } 358 } catch (IOException ex) { 359 Logger.getLogger(BeanInstaller.class.getClass().getName()). 360 log(Level.SEVERE, classFO.toString(), ex); 361 } 362 363 } 364 365 public static boolean isDeclaredAsJavaBean(TypeElement clazz) { 366 Set<javax.lang.model.element.Modifier> mods = clazz.getModifiers(); 367 if (ElementKind.CLASS != clazz.getKind() || 368 !mods.contains(javax.lang.model.element.Modifier.PUBLIC) || 369 mods.contains(javax.lang.model.element.Modifier.ABSTRACT)) { 370 return false; 371 } 372 373 for (Element member : clazz.getEnclosedElements()) { 374 mods = member.getModifiers(); 375 if (ElementKind.CONSTRUCTOR == member.getKind() && 376 mods.contains(javax.lang.model.element.Modifier.PUBLIC) && 377 ((ExecutableElement) member).getParameters().isEmpty()) { 378 return true; 379 } 380 } 381 382 return false; 383 } 384 385 public static boolean isDeclaredAsJavaBean(ClassFile clazz) { 386 int access = clazz.getAccess(); 387 388 if (!Modifier.isPublic(access) || Modifier.isAbstract(access) || 389 Modifier.isInterface(access) || clazz.isAnnotation() || 390 clazz.isEnum() || clazz.isSynthetic() ) { 391 return false; 392 } 393 394 for (Object omethod : clazz.getMethods()) { 395 Method method = (Method) omethod; 396 if (method.isPublic() && method.getParameters().isEmpty() && 397 "<init>".equals(method.getName())) { return true; 399 } 400 } 401 return false; 402 } 403 404 private static AddToPaletteWizard getAddWizard() { 405 AddToPaletteWizard wizard = null; 406 if (wizardRef != null) 407 wizard = (AddToPaletteWizard) wizardRef.get(); 408 if (wizard == null) { 409 wizard = new AddToPaletteWizard(); 410 wizardRef = new WeakReference (wizard); 411 } 412 return wizard; 413 } 414 415 417 static class ItemInfo implements Comparable { 418 String classname; 419 String source; 421 public int compareTo(Object o) { 422 ItemInfo ii = (ItemInfo) o; 423 int i; 424 i = classname.lastIndexOf('.'); 425 String name1 = i >= 0 ? classname.substring(i+1) : classname; 426 i = ii.classname.lastIndexOf('.'); 427 String name2 = i >= 0 ? ii.classname.substring(i+1) : ii.classname; 428 return name1.compareTo(name2); 429 } 430 } 431 432 private interface JavaClassHandler { 433 public void handle(String className); 434 } 435 436 } 437 | Popular Tags |