Index: org/netbeans/modules/java/JavaNode.java =================================================================== RCS file: /cvs/java/src/org/netbeans/modules/java/JavaNode.java,v retrieving revision 1.94 diff -c -r1.94 JavaNode.java *** org/netbeans/modules/java/JavaNode.java 31 Jan 2003 12:35:34 -0000 1.94 --- org/netbeans/modules/java/JavaNode.java 4 Feb 2003 13:06:29 -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. *************** *** 83,89 **** */ protected static final String ICON_ATTR_ERROR = "error"; // NOI18N ! private transient boolean preparsed = false; static final ResourceBundle bundle = NbBundle.getBundle(JavaNode.class); --- 88,97 ---- */ protected static final String ICON_ATTR_ERROR = "error"; // NOI18N ! /** ! * True, if th parser was already initialized (and listener attached to it). ! */ ! private transient boolean resolverInitialied = false; static final ResourceBundle bundle = NbBundle.getBundle(JavaNode.class); *************** *** 117,127 **** private int upToDate = 2; private Object keepAlive; ! ! /** ! * True, if th parser was already initialized (and listener attached to it). ! */ ! private boolean parserInitialized; /** Create a node for the Java data object using the default children. * @param jdo the data object to represent --- 125,132 ---- private int upToDate = 2; private Object keepAlive; ! ! private transient static RE mainRE; /** Create a node for the Java data object using the default children. * @param jdo the data object to represent *************** *** 132,149 **** } /** ! * Locates a parser for the java source. #28623 (T.B.): listener informing about ! * 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; --- 137,186 ---- } /** ! * Locates a parser for the java source. */ private JavaParser findParser() { ! return (JavaParser)getDataObject().getCookie(JavaParser.class); ! } ! ! /** ! * #28623 (T.B.): listener informing about updates is attached to parser ! */ ! private JavaParser registerParserListener() { ! JavaParser p=findParser(); ! if (p != null) { ! 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; *************** *** 285,296 **** iconRefreshTask = null; iconResolver = null; } ! if (!detectCompile) { ! StateUpdater.getInstance().updateNode(JavaNode.this); ! } else { upToDate=JavaNode.this.getJavaDataObject().isUpToDate().booleanValue()?1:0; - StateUpdater.getInstance().updateNode(JavaNode.this); } } } --- 322,331 ---- iconRefreshTask = null; iconResolver = null; } ! if (detectCompile) { upToDate=JavaNode.this.getJavaDataObject().isUpToDate().booleanValue()?1:0; } + StateUpdater.getInstance().updateNode(JavaNode.this); } } *************** *** 426,432 **** public Image getIcon(int type) { String[] badges=null; if (!getDataObject().isTemplate()) { ! preparseSource(); // assume setIconBase was already called. badges = getBadges(); } --- 461,467 ---- public Image getIcon(int type) { String[] badges=null; if (!getDataObject().isTemplate()) { ! initializeIconResolver(); // assume setIconBase was already called. badges = getBadges(); } *************** *** 436,463 **** public Image getOpenedIcon(int type) { String[] badges = null; if (!getDataObject().isTemplate()) { ! preparseSource(); badges = getBadges(); } return iconCache.getIcon(super.getOpenedIcon(type), badges); } ! protected void preparseSource() { ! if (preparsed || ! !JavaSettings.getDefault().getPrescanSources()) return; ! preparsed = true; ! // 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: } } /** Get the icon base. --- 471,502 ---- public Image getOpenedIcon(int type) { String[] badges = null; if (!getDataObject().isTemplate()) { ! initializeIconResolver(); badges = getBadges(); } return iconCache.getIcon(super.getOpenedIcon(type), badges); } ! protected void initializeIconResolver() { ! if (resolverInitialied) return; ! resolverInitialied = true; ! if (JavaSettings.getDefault().getPrescanSources()) { ! // 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(); ! if (p!=null) { ! SourceElement source = getJavaDataObject().getSource(); ! if (getDataObject().isValid() && source.getStatus() == SourceElement.STATUS_NOT) { ! if (fastMainCheck()) ! p.parse(JavaParser.PRIORITY_BACKGROUND, false, false); ! // schedule a background reparse so the icon for runnable classes ! // are updated in the background: ! } ! } } + requestResolveIcons(); } /** Get the icon base. 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 4 Feb 2003 13:06:37 -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); + } + }