diff options
author | cbateman | 2007-09-12 23:15:34 +0000 |
---|---|---|
committer | cbateman | 2007-09-12 23:15:34 +0000 |
commit | b283621277c68d360830a8aab53c3cc91ad91546 (patch) | |
tree | 355d68baabba3e6494f9674e8f2d90ba3a82b142 | |
parent | ad039ea3a020f741ac6189eb444906b1cd01ec6e (diff) | |
download | webtools.jsf-b283621277c68d360830a8aab53c3cc91ad91546.tar.gz webtools.jsf-b283621277c68d360830a8aab53c3cc91ad91546.tar.xz webtools.jsf-b283621277c68d360830a8aab53c3cc91ad91546.zip |
PMC approved 2.0.1 stream fixes:v20070912
Patch 2 for https://bugs.eclipse.org/bugs/show_bug.cgi?id=199480
Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=147729
4 files changed, 141 insertions, 36 deletions
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/resource/LifecycleListener.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/resource/LifecycleListener.java index e587857df..2cb476be4 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/resource/LifecycleListener.java +++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/resource/LifecycleListener.java @@ -51,10 +51,9 @@ public class LifecycleListener implements IResourceChangeListener, IResourceDelt // be triggered during the remainder of dispose ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); - synchronized(_listeners) - { - _listeners.clear(); - } + // don't clear the listener list currently because of + // concurrent change problems. + _isDisposed = true; } } @@ -152,15 +151,28 @@ public class LifecycleListener implements IResourceChangeListener, IResourceDelt case IResourceChangeEvent.POST_CHANGE: { - IResourceDelta delta = event.getDelta(); - try - { - delta.accept(this); - } - catch (CoreException ce) + // only bother continuing if the resource we are tracking + // is not a project since post-change events on projects + // that we care about won't occur + if (_res.getType() != IResource.PROJECT) { - // can't do anything but log - JSFCommonPlugin.log(new Throwable(ce)); + IResourceDelta delta = event.getDelta(); + // only care about post change events to resources + // that we are tracking + delta = delta.findMember(_res.getFullPath()); + + try + { + if (delta != null) + { + delta.accept(this); + } + } + catch (CoreException ce) + { + // can't do anything but log + JSFCommonPlugin.log(new Throwable(ce)); + } } } break; diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/DesignTimeApplicationManager.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/DesignTimeApplicationManager.java index 79abedc2f..5c6b21ec8 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/DesignTimeApplicationManager.java +++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/DesignTimeApplicationManager.java @@ -80,7 +80,7 @@ public final class DesignTimeApplicationManager private static final String DEFAULT_METHOD_RESOLVER_ID = "org.eclipse.jst.jsf.core.methodresolver.default"; //$NON-NLS-1$ - + /** * @param project * @return the app manager associated with project @@ -96,16 +96,23 @@ public final class DesignTimeApplicationManager { synchronized(project) { - Object manager = - project.getSessionProperty(SESSION_PROPERTY_KEY_PROJECT); - + DesignTimeApplicationManager manager = + (DesignTimeApplicationManager) project.getSessionProperty(SESSION_PROPERTY_KEY_PROJECT); + if (manager == null) { manager = new DesignTimeApplicationManager(project); project.setSessionProperty(SESSION_PROPERTY_KEY_PROJECT, manager); } - - return (DesignTimeApplicationManager) manager; + // bug 147729: if project was renamed, the project param will be + // valid, but it will not be in sync with the one for _project + // unfortunately, since we are using session propertie + else if (!project.equals(manager._project)) + { + manager._project = project; + } + + return manager; } } catch (CoreException ce) @@ -117,7 +124,9 @@ public final class DesignTimeApplicationManager } // instance definition - private final IProject _project; + // _project must be writable in case the manager needs to be retargetted + // after a rename/move etc. + private IProject _project; private final IExternalContextFactoryLocator _locator; private DesignTimeApplicationManager(IProject project) diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/jsp/JSPModelProcessor.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/jsp/JSPModelProcessor.java index 490fc06db..879933185 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/jsp/JSPModelProcessor.java +++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/jsp/JSPModelProcessor.java @@ -28,6 +28,10 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.jst.jsf.common.JSFCommonPlugin; +import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent; +import org.eclipse.jst.jsf.common.internal.resource.IResourceLifecycleListener; +import org.eclipse.jst.jsf.common.internal.resource.LifecycleListener; +import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent.EventType; import org.eclipse.jst.jsf.common.metadata.Trait; import org.eclipse.jst.jsf.common.metadata.internal.TraitValueHelper; import org.eclipse.jst.jsf.common.metadata.query.ITaglibDomainMetaDataModelContext; @@ -149,13 +153,14 @@ public class JSPModelProcessor private final IFile _file; private final DOMModelForJSP _model; private final ModelListener _modelListener; - private boolean isDisposed; + private final LifecycleListener _resourceListener; + private boolean _isDisposed; private Map<Object, ISymbol> _requestMap; private Map<Object, ISymbol> _sessionMap; private Map<Object, ISymbol> _applicationMap; private Map<Object, ISymbol> _noneMap; private long _lastModificationStamp; - private AtomicInteger _refCount = new AtomicInteger(0); + private AtomicInteger _refCount = new AtomicInteger(0); // used to avoid infinite recursion in refresh. Must never be null private final CountingMutex _lastModificationStampMonitor = new CountingMutex(); @@ -171,12 +176,29 @@ public class JSPModelProcessor _modelListener = new ModelListener(); _model.addModelLifecycleListener(_modelListener); _file = file; - // a negative value guarantees that refresh(false) will + _resourceListener = new LifecycleListener(file); + _resourceListener.addListener(new IResourceLifecycleListener() + { + public EventResult acceptEvent(ResourceLifecycleEvent event) + { + EventResult result = new EventResult(); + + if (event.getEventType() == EventType.RESOURCE_INACCESSIBLE) + { + dispose(_file); + result.setDisposeAfterEvent(true); + } + + return result; + } + }); + // a negative value guarantees that refresh(false) will // force a refresh on the first run _lastModificationStamp = -1; + } - private DOMModelForJSP getModelForFile(final IFile file) + private DOMModelForJSP getModelForFile(final IFile file) throws CoreException, IOException { final IModelManager modelManager = @@ -195,17 +217,24 @@ public class JSPModelProcessor model.releaseFromRead(); } - throw new CoreException(new Status(IStatus.ERROR, "org.eclipse.blah", 0, //$NON-NLS-1$ - "model not of expected type", new Throwable())); //$NON-NLS-1$ + throw new CoreException + (new Status(IStatus.ERROR + , "org.eclipse.blah" + , 0 //$NON-NLS-1$ + ,"model not of expected type" + , new Throwable())); //$NON-NLS-1$ } private void dispose() { - if (!isDisposed) + if (!_isDisposed) { _model.releaseFromRead(); _model.removeModelLifecycleListener(_modelListener); - + + // ensure the resource listener is disposed + _resourceListener.dispose(); + if (_requestMap != null) { _requestMap.clear(); @@ -232,7 +261,7 @@ public class JSPModelProcessor _refCount.set(0); // mark as disposed - isDisposed = true; + _isDisposed = true; } } @@ -240,9 +269,9 @@ public class JSPModelProcessor * @return true if this model processor has been disposed. Disposed * processors should not be used. */ - boolean isDisposed() + public boolean isDisposed() { - return isDisposed; + return _isDisposed; } /** @@ -263,6 +292,13 @@ public class JSPModelProcessor */ public void refresh(final boolean forceRefresh) { + if (isDisposed()) + { + // TODO: should we throw exception? return false? + JSFCorePlugin.log(IStatus.WARNING, "Attempt to refresh a disposed processor", new Throwable("Exception is only to get a stack trace, not an error")); + return; + } + synchronized(_lastModificationStampMonitor) { if (_lastModificationStampMonitor.isSignalled()) diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/symbols/ResourceBundleMapSource.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/symbols/ResourceBundleMapSource.java index 975c257ef..2e454c0f9 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/symbols/ResourceBundleMapSource.java +++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/symbols/ResourceBundleMapSource.java @@ -22,10 +22,15 @@ import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IStorage; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jst.jsf.common.internal.resource.IResourceLifecycleListener; +import org.eclipse.jst.jsf.common.internal.resource.LifecycleListener; +import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent; +import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent.EventType; import org.eclipse.jst.jsf.core.internal.JSFCorePlugin; import org.eclipse.jst.jsf.core.internal.tld.LoadBundleUtil; @@ -42,13 +47,18 @@ class ResourceBundleMapSource extends AbstractMap { if (project != null) { - return (IFile) getBundleFileCache(project).get(baseName); + Map bundleFileCache = getBundleFileCache(project); + + if (bundleFileCache != null) + { + return (IFile) bundleFileCache.get(baseName); + } } return null; } - private static Map getBundleFileCache(IProject project) + private static Map getBundleFileCache(final IProject project) { synchronized(project) { @@ -62,6 +72,34 @@ class ResourceBundleMapSource extends AbstractMap if (bundleFileCache == null) { bundleFileCache = new HashMap(); + LifecycleListener listener = new LifecycleListener(project); + listener.addListener(new IResourceLifecycleListener() + { + public EventResult acceptEvent(ResourceLifecycleEvent event) + { + EventResult result = new EventResult(); + + if (event.getEventType() == EventType.RESOURCE_INACCESSIBLE) + { + try + { + Map bundleCache = + (Map) project.getSessionProperty(SESSION_PROPERTY_KEY_PROJECT); + bundleCache.clear(); + project.setSessionProperty(SESSION_PROPERTY_KEY_PROJECT, null); + } + catch (CoreException ce) + { + JSFCorePlugin.log("Error clearing bundle file cache", ce); //$NON-NLS-1$ + } + result.setDisposeAfterEvent(true); + } + + return result; + } + } + ); + project.setSessionProperty(SESSION_PROPERTY_KEY_PROJECT, bundleFileCache); } } @@ -78,7 +116,8 @@ class ResourceBundleMapSource extends AbstractMap final String resourcePathStr) throws IOException, CoreException { - IStorage storage = LoadBundleUtil.getLoadBundleResource(project, resourcePathStr); + IStorage storage = + LoadBundleUtil.getLoadBundleResource(project, resourcePathStr); IFile bundleRes = null; @@ -119,14 +158,17 @@ class ResourceBundleMapSource extends AbstractMap { if (_bundleFile.isAccessible()) { - if (_resourceBundle == null + if (_resourceBundle == null // doesn't exist yet + // exists but ws is out of sync + || !_bundleFile.isSynchronized(IResource.DEPTH_ZERO) + // exists but user has changed in workspace || _bundleFile.getModificationStamp() != _lastModificationStamp) { InputStream bundleStream = null; try { - // force refresh if out of sync + // force refresh if out of sync bundleStream = _bundleFile.getContents(true); _resourceBundle = new Properties(); _resourceBundle.load(bundleStream); @@ -161,9 +203,15 @@ class ResourceBundleMapSource extends AbstractMap // bundle no longer exists so remove it Map bundleFileCache = getBundleFileCache(_bundleFile.getProject()); - if (bundleFileCache.containsKey(_resourcePathStr)) + if (bundleFileCache != null && + bundleFileCache.containsKey(_resourcePathStr)) { bundleFileCache.remove(_resourcePathStr); + } + // in either case, clear the bundle entry + if (_resourceBundle != null) + { + _resourceBundle.clear(); _resourceBundle = null; } } |