Index: org/netbeans/modules/java/JavaNode.java =================================================================== RCS file: /cvs/java/src/org/netbeans/modules/java/JavaNode.java,v retrieving revision 1.93 diff -c -r1.93 JavaNode.java *** org/netbeans/modules/java/JavaNode.java 30 Jan 2003 11:18:10 -0000 1.93 --- org/netbeans/modules/java/JavaNode.java 3 Feb 2003 17:43:18 -0000 *************** *** 31,36 **** --- 31,37 ---- import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyEditor; + import java.io.InputStream; import org.openide.util.*; import org.openide.src.*; *************** *** 49,54 **** --- 50,59 ---- import org.netbeans.modules.java.tools.BadgeCache; import org.netbeans.modules.java.parser.JavaParser; import org.netbeans.modules.java.settings.JavaSettings; + + import org.apache.regexp.RE; + import org.apache.regexp.StreamCharacterIterator; + import org.apache.regexp.RESyntaxException; /** The node representation of JavaDataObject for Java sources. *************** *** 123,128 **** --- 128,135 ---- */ private boolean parserInitialized; + private transient static RE mainRE; + /** Create a node for the Java data object using the default children. * @param jdo the data object to represent */ *************** *** 136,149 **** * updates is attached when the parser is acquired for the first time. */ private JavaParser findParser() { ! JavaParser result = (JavaParser)getDataObject().getCookie(JavaParser.class); ! if (!parserInitialized && (result != null)) { parserInitialized = true; ! result.addChangeListener(WeakListener.change(mixedListener, result)); } ! return result; } // T.B.: Workaround for issue #28623 - aggresively creating source element, classloading private static final class JavaSourceChildren extends SourceChildren { JavaDataObject jdo; --- 143,188 ---- * updates is attached when the parser is acquired for the first time. */ private JavaParser findParser() { ! return (JavaParser)getDataObject().getCookie(JavaParser.class); ! } ! ! private JavaParser registerParserListener() { ! JavaParser p=findParser(); ! if (!parserInitialized && (p != null)) { parserInitialized = true; ! p.addChangeListener(WeakListener.change(mixedListener, p)); } ! return p; } + private boolean fastMainCheck() { + boolean match=true; + InputStream is=null; + if (mainRE==null) + try { + mainRE=new RE("\\smain\\s*\\("); + } catch (RESyntaxException ex) { + ErrorManager.getDefault().notify(ex); + return true; + } + try { + is=Util.createInputStream(getDataObject().getPrimaryFile(),false,false); + match=mainRE.match(new StreamCharacterIterator(is),0); + } catch (IOException ex) { + ErrorManager.getDefault().notify(ex); + } + finally { + try { + if (is!=null) + is.close(); + } catch (IOException ex) { + ErrorManager.getDefault().notify(ex); + } + } + return match; + } + + // T.B.: Workaround for issue #28623 - aggresively creating source element, classloading private static final class JavaSourceChildren extends SourceChildren { JavaDataObject jdo; *************** *** 450,459 **** // schedule a background reparse so the icon for runnable classes // are updated in the background: // the listener will be notified after the parse is completed. SourceElement source = getJavaDataObject().getSource(); if (getDataObject().isValid() && source.getStatus() == SourceElement.STATUS_NOT) { ! JavaParser p = findParser(); ! if (p != null) p.parse(JavaParser.PRIORITY_BACKGROUND, false, false); // schedule a background reparse so the icon for runnable classes // are updated in the background: --- 489,498 ---- // schedule a background reparse so the icon for runnable classes // are updated in the background: // the listener will be notified after the parse is completed. + JavaParser p=registerParserListener(); SourceElement source = getJavaDataObject().getSource(); if (getDataObject().isValid() && source.getStatus() == SourceElement.STATUS_NOT) { ! if (p != null && fastMainCheck()) p.parse(JavaParser.PRIORITY_BACKGROUND, false, false); // schedule a background reparse so the icon for runnable classes // are updated in the background: Index: org/netbeans/modules/java/settings/JavaSettings.java =================================================================== RCS file: /cvs/java/src/org/netbeans/modules/java/settings/JavaSettings.java,v retrieving revision 1.58 diff -c -r1.58 JavaSettings.java *** org/netbeans/modules/java/settings/JavaSettings.java 26 Jun 2002 13:37:24 -0000 1.58 --- org/netbeans/modules/java/settings/JavaSettings.java 3 Feb 2003 17:43:19 -0000 *************** *** 22,27 **** --- 22,29 ---- import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; + import java.util.HashMap; + import java.util.Map; import org.openide.cookies.InstanceCookie; import org.openide.filesystems.FileObject; *************** *** 50,61 **** import org.netbeans.modules.java.JavaThreadExecutor; import org.netbeans.modules.java.imptool.ImpToolSettings; import org.netbeans.modules.java.ClassPathConfigurator; /** Settings for java data loader and java source parser * * @author Ales Novak, Petr Hamernik */ ! public class JavaSettings extends ContextSystemOption { private static final int currentVersion = 1; /** serial uid */ --- 52,65 ---- import org.netbeans.modules.java.JavaThreadExecutor; import org.netbeans.modules.java.imptool.ImpToolSettings; import org.netbeans.modules.java.ClassPathConfigurator; + import org.openide.util.LookupEvent; + import org.openide.util.LookupListener; /** Settings for java data loader and java source parser * * @author Ales Novak, Petr Hamernik */ ! public class JavaSettings extends ContextSystemOption implements LookupListener { private static final int currentVersion = 1; /** serial uid */ *************** *** 125,130 **** --- 129,136 ---- private boolean source14Enabled = true; private static JavaSettings javaSettings; + + private transient Map serviceMap,lookupResultMap; /** If true then external execution is used */ public String displayName () { *************** *** 138,143 **** --- 144,151 ---- public JavaSettings() { addOption(getJavaSynchronizationSettings()); addOption(getImpToolSettings()); + serviceMap=new HashMap(); + lookupResultMap=new HashMap(); } public boolean isGlobal() { *************** *** 158,166 **** if (type != null) return type; } ! type = (CompilerType)findDefaultRegistration("Services/CompilerType/JavaExternalCompiler.settings", ! JavaCompilerType.class); ! if (type != null) return type; Class c = org.netbeans.modules.java.JavaExternalCompilerType.class; type = (CompilerType)Lookup.getDefault().lookup(c); --- 166,173 ---- if (type != null) return type; } ! type=(CompilerType)findDefaultRegistration(org.netbeans.modules.java.JavaExternalCompilerType.class,"SL[/CompilerType/JavaExternalCompiler"); ! if (type!=null) return type; Class c = org.netbeans.modules.java.JavaExternalCompilerType.class; type = (CompilerType)Lookup.getDefault().lookup(c); *************** *** 190,197 **** if (ex != null) return ex; } ! ex = (Executor)findDefaultRegistration("Services/Executor/JavaExternalExecutor.settings", ! JavaProcessExecutor.class); if (ex != null) return ex; --- 197,203 ---- if (ex != null) return ex; } ! ex = (Executor)findDefaultRegistration(JavaProcessExecutor.class,"SL[/Executor/JavaExternalExecutor"); if (ex != null) return ex; *************** *** 200,222 **** return ex == null ? Executor.getDefault() : ex; } ! static Object findDefaultRegistration(String regName, Class service) { ! FileObject fo = Repository.getDefault().getDefaultFileSystem().findResource(regName); ! if (fo == null) ! return null; ! try { ! DataObject d = DataObject.find(fo); ! InstanceCookie.Of ic = (InstanceCookie.Of)d.getCookie(InstanceCookie.Of.class); ! if (ic == null || !ic.instanceOf(service)) ! return null; ! return ic.instanceCreate(); ! } catch (DataObjectNotFoundException ex) { ! return null; ! } catch (IOException ex) { ! return null; ! } catch (ClassNotFoundException ex) { ! return null; } } /** sets an executor */ --- 206,228 ---- return ex == null ? Executor.getDefault() : ex; } ! Object findDefaultRegistration(Class service, String serviceId) { ! Object serviceObj=serviceMap.get(serviceId); ! ! if (serviceObj!=null) { ! Lookup.Template temp=new Lookup.Template(service,serviceId,null); ! Lookup.Result res=Lookup.getDefault().lookup(temp); ! Object[] instances; ! ! res.removeLookupListener(this); ! res.addLookupListener(this); ! instances=res.allInstances().toArray(); ! if (instances.length==1) ! serviceObj=instances[0]; ! serviceMap.put(serviceId,serviceObj); ! lookupResultMap.put(res,serviceId); } + return serviceObj; } /** sets an executor */ *************** *** 468,473 **** --- 474,481 ---- * to IDE's own runtime classes. */ public Collection getParserBootPathFS() { + if (keepBootPath!=null) + return keepBootPath; NbClassPath pbcp = getParserBootPath(); if (pbcp == null || "".equals(pbcp.getClassPath())) *************** *** 485,490 **** --- 493,499 ---- return; NbClassPath old = parserBootPath; parserBootPath = path; + keepBootPath = null; firePropertyChange(PROP_PARSER_BOOTPATH, old, path); // NOI18N } *************** *** 575,578 **** --- 584,602 ---- public boolean isSource14Enabled() { return source14Enabled; } + + /** A change in lookup occured. Please note that this method + * should never block since it might be called from lookup implementation + * internal threads. If you block here you are in risk that the thread + * you wait for might in turn to wait for the lookup internal thread to + * finish its work. + * @param ev event describing the change + * + */ + public void resultChanged(LookupEvent ev) { + Lookup.Result res=(Lookup.Result)ev.getSource(); + Object serviceId=lookupResultMap.get(res); + serviceMap.remove(serviceId); + } + }