Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcbateman2009-01-28 20:15:13 +0000
committercbateman2009-01-28 20:15:13 +0000
commite33d29414032f61180a9da5d1b27aee9eeae69b6 (patch)
tree2bcf942e57e377289514b587239c20d3e67549c5
parent94b12541ad85d307dde7068fb779c5f51685fe22 (diff)
downloadwebtools.jsf-e33d29414032f61180a9da5d1b27aee9eeae69b6.tar.gz
webtools.jsf-e33d29414032f61180a9da5d1b27aee9eeae69b6.tar.xz
webtools.jsf-e33d29414032f61180a9da5d1b27aee9eeae69b6.zip
Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=255987.
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/jsp/JSPModelProcessor.java423
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/jsp/StartupHandler.java103
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/symbols/JSPTagVariableSymbolSourceProvider.java4
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/messages.properties1
4 files changed, 353 insertions, 178 deletions
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 d64a6ecd4..71a766d69 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
@@ -7,7 +7,7 @@
*
* Contributors:
* Cameron Bateman/Oracle - initial API and implementation
- *
+ *
********************************************************************************/
package org.eclipse.jst.jsf.designtime.internal.jsp;
@@ -22,10 +22,19 @@ import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.ILock;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.internal.resource.IResourceLifecycleListener;
import org.eclipse.jst.jsf.common.internal.resource.LifecycleListener;
@@ -48,7 +57,7 @@ import org.eclipse.jst.jsf.context.symbol.source.ISymbolConstants;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.designtime.DesignTimeApplicationManager;
import org.eclipse.jst.jsf.designtime.context.DTFacesContext;
-import org.eclipse.wst.html.core.internal.document.DOMStyleModelImpl;
+import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
@@ -60,28 +69,63 @@ import org.w3c.dom.NodeList;
/**
* Processes a JSP model to determine information of interest about it such
- * as what tags are currently in use. Listens to the model and updates it's
+ * as what tags are currently in use. Listens to the model and updates it's
* information when the model changes.
- *
+ *
* @author cbateman
*
*/
public class JSPModelProcessor
{
- private final static Map<IFile, JSPModelProcessor> RESOURCE_MAP =
+ /**
+ * Pass to force refresh arguments
+ */
+ public final static boolean FORCE_REFRESH = true;
+
+ /**
+ * Pass to runAfter argument of refresh to indicate there is nothing
+ * to run when the refresh job completes.
+ */
+ public final static Runnable NO_RUN_AFTER = null;
+
+ /**
+ * Pass to runAfter argument of refresh to indicate that the caller
+ * should be blocked until the job completes.
+ */
+ public final static Runnable RUN_ON_CURRENT_THREAD = new Runnable()
+ {
+ public void run()
+ {
+ // do nothing
+ }
+ };
+
+ /**
+ * An init-time setting that is used to stop the model processor from
+ * automatically refreshing when the file it is tracking changes. The can
+ * only be set once at init is permanent for the static life timpe of
+ * JSPModelProcessor.
+ *
+ * Note that it does not turn off listening for file delete events because
+ * the singleton management still needs to know if it can dispose of an
+ * instance.
+ */
+ private final static boolean DISABLE_WKSPACE_CHANGE_REFRESH = System
+ .getProperty("org.eclipse.jst.jsf.jspmodelprocessor.disable.wkspace.change.refresh") != null; //$NON-NLS-1$
+ private final static Map<IFile, JSPModelProcessor> RESOURCE_MAP =
new HashMap<IFile, JSPModelProcessor>();
private final static java.util.concurrent.locks.Lock CRITICAL_SECTION =
new ReentrantLock();
private static LifecycleListener LIFECYCLE_LISTENER;
/**
- * @param file The file to get the model processor for
+ * @param file The file to get the model processor for
* @return the processor for a particular model, creating it if it does not
* already exist
* @throws CoreException if an attempt to get the model associated with file
* fails due to reasons other than I/O problems
*/
- public static JSPModelProcessor get(IFile file) throws CoreException
+ public static JSPModelProcessor get(final IFile file) throws CoreException
{
CRITICAL_SECTION.lock();
try
@@ -120,26 +164,26 @@ public class JSPModelProcessor
* Disposes of the JSPModelProcessor associated with model
* @param file the model processor to be disposed
*/
- private static void dispose(IFile file)
+ private static void dispose(final IFile file)
{
CRITICAL_SECTION.lock();
try
{
- JSPModelProcessor processor = RESOURCE_MAP.get(file);
+ final JSPModelProcessor processor = RESOURCE_MAP.get(file);
if (processor != null)
{
RESOURCE_MAP.remove(file);
-
+
if (!processor.isDisposed())
{
processor.dispose();
LIFECYCLE_LISTENER.removeResource(file);
}
-
+
}
- if (RESOURCE_MAP.size() == 0)
+ if (RESOURCE_MAP.isEmpty())
{
// if we no longer have any resources being tracked,
// then dispose the lifecycle listener
@@ -156,38 +200,34 @@ public class JSPModelProcessor
private final IFile _file;
private LifecycleListener _lifecycleListener;
private IResourceLifecycleListener _resListener;
- private boolean _isDisposed;
+ private volatile 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;
// used to avoid infinite recursion in refresh. Must never be null
private final CountingMutex _lastModificationStampMonitor = new CountingMutex();
/**
* Construct a new JSPModelProcessor for model
- *
+ *
* @param model
*/
private JSPModelProcessor(final IFile file, final LifecycleListener lifecycleListener)
{
- //_model = getModelForFile(file);
- //_modelListener = new ModelListener();
- //_model.addModelLifecycleListener(_modelListener);
_file = file;
_lifecycleListener = lifecycleListener;
_resListener = new IResourceLifecycleListener()
{
- public EventResult acceptEvent(ResourceLifecycleEvent event)
+ public EventResult acceptEvent(final ResourceLifecycleEvent event)
{
final EventResult result = EventResult.getDefaultEventResult();
// not interested
if (!_file.equals(event.getAffectedResource()))
{
- return result;
+ return result;
}
if (event.getEventType() == EventType.RESOURCE_INACCESSIBLE)
@@ -198,9 +238,10 @@ public class JSPModelProcessor
{
// if the file has changed contents on disk, then
// invoke an unforced refresh of the JSP file
- if (event.getReasonType() == ReasonType.RESOURCE_CHANGED_CONTENTS)
+ if (event.getReasonType() == ReasonType.RESOURCE_CHANGED_CONTENTS
+ && !DISABLE_WKSPACE_CHANGE_REFRESH)
{
- refresh(false);
+ refresh(! FORCE_REFRESH, NO_RUN_AFTER);
}
}
@@ -209,23 +250,19 @@ public class JSPModelProcessor
};
lifecycleListener.addListener(_resListener);
-
- // a negative value guarantees that refresh(false) will
- // force a refresh on the first run
- _lastModificationStamp = -1;
}
- private DOMStyleModelImpl getModelForFile(final IFile file)
+ private IDOMModel getModelForFile(final IFile file)
throws CoreException, IOException
{
- final IModelManager modelManager =
+ final IModelManager modelManager =
StructuredModelManager.getModelManager();
- IStructuredModel model = modelManager.getModelForRead(file);
+ final IStructuredModel model = modelManager.getModelForRead(file);
- if (model instanceof DOMStyleModelImpl)
+ if (model instanceof IDOMModel)
{
- return (DOMStyleModelImpl) model;
+ return (IDOMModel) model;
}
else if (model != null)
{
@@ -298,74 +335,145 @@ public class JSPModelProcessor
public boolean isModelDirty()
{
final long currentModificationStamp = _file.getModificationStamp();
- return _lastModificationStamp != currentModificationStamp;
+ return _lastModificationStampMonitor.hasChanged(currentModificationStamp);
}
-
+
+
+
/**
- * Updates the internal model
- * @param forceRefresh -- if true, always refreshes, if false,
- * then it only refreshes if the file's modification has changed
- * since the last refresh
- * @throws IllegalStateException if isDisposed() == true
+ * Refreshes the processor's cache of information from its associated
+ * JSP file.
+ *
+ * @param forceRefresh
+ * @param runAfter
*/
- public void refresh(final boolean forceRefresh)
+ public void refresh(final boolean forceRefresh, final Runnable runAfter)
{
if (isDisposed())
{
- throw new IllegalStateException("Processor is disposed for file: "+_file.toString()); //$NON-NLS-1$
+ throw new IllegalStateException(
+ "Processor is disposed for file: " + _file.toString()); //$NON-NLS-1$
}
- synchronized(_lastModificationStampMonitor)
+ if (runAfter == RUN_ON_CURRENT_THREAD)
{
- if (_lastModificationStampMonitor.isSignalled())
- {
- // if this calls succeeds, then this thread has obtained the
- // lock already and has called through here before.
- // return immediately to ensure that we don't recurse infinitely
- return;
- }
-
- DOMStyleModelImpl model = null;
try
{
- _lastModificationStampMonitor.setSignalled(true);
-
+ runOnCurrentThread(forceRefresh);
+ }
+ catch (final CoreException e)
+ {
+ JSFCorePlugin.log(e, "Running JSP model processor"); //$NON-NLS-1$
+ }
+ catch (final OperationCanceledException e)
+ {
+ // ignore
+ }
+ }
+ else
+ {
+ runOnWorkspaceJob(forceRefresh, runAfter);
+ }
- // only refresh if forced or if the underlying file has changed
- // since the last run
- if (forceRefresh
- || isModelDirty())
+ }
+ private void runOnWorkspaceJob(final boolean forceRefresh, final Runnable runAfter)
+ {
+ WorkspaceJob refreshJob = new WorkspaceJob(NLS.bind(Messages
+ .getString("JSPModelProcessor.0"), _file)) { //$NON-NLS-1$
+ @Override
+ public IStatus runInWorkspace(IProgressMonitor monitor)
+ throws CoreException
+ {
+ RefreshRunnable runnable = new RefreshRunnable(forceRefresh);
+ runnable.run(monitor);
+ return Status.OK_STATUS;
+ }
+ };
+ refreshJob.setSystem(true);
+ refreshJob.setRule(ResourcesPlugin.getWorkspace().getRoot());
+ if (runAfter != null)
+ {
+ refreshJob.addJobChangeListener(new JobChangeAdapter()
+ {
+ @Override
+ public void done(final IJobChangeEvent event)
{
- model = getModelForFile(_file);
- refreshInternal(model);
- _lastModificationStamp = _file.getModificationStamp();
+ runAfter.run();
}
- }
- catch (CoreException e) {
- JSFCorePlugin.log(new RuntimeException(e), "Error refreshing internal model"); //$NON-NLS-1$
- } catch (IOException e) {
- JSFCorePlugin.log(new RuntimeException(e), "Error refreshing internal model"); //$NON-NLS-1$
- }
- // make sure that we unsignal the monitor before releasing the
- // mutex
- finally
+ });
+ }
+ refreshJob.schedule();
+ }
+
+ private void runOnCurrentThread(final boolean forceRefresh) throws CoreException, OperationCanceledException
+ {
+ ResourcesPlugin.getWorkspace().run(new RefreshRunnable(forceRefresh), _file, 0, null);
+ }
+
+ private final class RefreshRunnable implements IWorkspaceRunnable
+ {
+ private final boolean _forceRefresh;
+
+ public RefreshRunnable(final boolean forceRefresh)
+ {
+ _forceRefresh = forceRefresh;
+ }
+
+ public void run(final IProgressMonitor monitor)
+ throws CoreException
+ {
+ synchronized (_lastModificationStampMonitor)
{
- if (model != null)
+ if (!_lastModificationStampMonitor.compareAndSetSignalled(false, true))
+ {
+ // if this calls succeeds, then this thread has obtained the
+ // lock already and has called through here before.
+ // return immediately to ensure that we don't recurse
+ // infinitely
+ return;
+ }
+ IDOMModel model = null;
+ try
+ {
+ // only refresh if forced or if the underlying file has
+ // changed
+ // since the last run
+ if (_forceRefresh || isModelDirty())
+ {
+ model = getModelForFile(_file);
+ refreshInternal(model);
+ _lastModificationStampMonitor.setModificationStamp(_file.getModificationStamp());
+ }
+ }
+ catch (final IOException e)
{
- model.releaseFromRead();
+ IStatus status = new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID,"Error refreshing internal model", e); //$NON-NLS-1$
+ final CoreException e2 = new CoreException(status);
+ throw e2;
+ }
+ // make sure that we unsignal the monitor before releasing the
+ // mutex
+ finally
+ {
+ _lastModificationStampMonitor.setSignalled(false);
+ if (model != null)
+ {
+ model.releaseFromRead();
+ }
}
- _lastModificationStampMonitor.setSignalled(false);
}
}
}
-
- private void refreshInternal(DOMStyleModelImpl model)
+
+
+
+ private void refreshInternal(final IDOMModel model)
{
- final IStructuredDocumentContext context =
+ final IStructuredDocumentContext context =
IStructuredDocumentContextFactory.INSTANCE.getContext(model.getStructuredDocument(), -1);
final ITaglibContextResolver taglibResolver =
IStructuredDocumentContextResolverFactory.INSTANCE.getTaglibContextResolver(context);
- IDOMDocument document = model.getDocument();
+ final IDOMDocument document = model.getDocument();
getApplicationMap().clear();
getRequestMap().clear();
getSessionMap().clear();
@@ -376,20 +484,20 @@ public class JSPModelProcessor
}
private void recurseChildNodes(final IDOMModel model,
- final NodeList nodes,
+ final NodeList nodes,
final ITaglibContextResolver taglibResolver)
{
for (int i = 0; i < nodes.getLength(); i++)
{
final Node child = nodes.item(i);
-
+
// process attributes at this node before recursing
processAttributes(model, child, taglibResolver);
recurseChildNodes(model, child.getChildNodes(), taglibResolver);
}
}
- private void processAttributes(final IDOMModel model, final Node node,
+ private void processAttributes(final IDOMModel model, final Node node,
final ITaglibContextResolver taglibResolver)
{
if (taglibResolver.hasTag(node))
@@ -397,7 +505,7 @@ public class JSPModelProcessor
final String uri =
taglibResolver.getTagURIForNodeName(node);
final String elementName = node.getLocalName();
-
+
for (int i = 0; i < node.getAttributes().getLength(); i++)
{
final Node attribute = node.getAttributes().item(i);
@@ -408,39 +516,39 @@ public class JSPModelProcessor
}
}
- private void processSymbolContrib(final IDOMModel model, final String uri, final String elementName, Node attribute)
+ private void processSymbolContrib(final IDOMModel model, final String uri, final String elementName, final Node attribute)
{
final SymbolContribAggregator aggregator =
SymbolContribAggregator.
create(_file.getProject(), uri, elementName, attribute.getLocalName());
-
+
if (aggregator != null)
- {
+ {
final AbstractContextSymbolFactory factory = aggregator.getFactory();
final String symbolName = attribute.getNodeValue();
if (factory != null)
{
// long curTime = System.currentTimeMillis();
- final IStructuredDocumentContext context =
+ final IStructuredDocumentContext context =
IStructuredDocumentContextFactory.INSTANCE.
- getContext(model.getStructuredDocument(),
+ getContext(model.getStructuredDocument(),
attribute);
if (factory.supports(context))
{
final List problems = new ArrayList();
- ISymbol symbol =
- factory.create(symbolName,
+ final ISymbol symbol =
+ factory.create(symbolName,
ISymbolConstants.SYMBOL_SCOPE_REQUEST, //TODO:
context,
problems,
// TODO: add meta-data for signature
new AdditionalContextSymbolInfo(aggregator.getStaticType(), aggregator.getValueExpressionAttr()));
-
+
// long netTime = System.currentTimeMillis() - curTime;
// System.out.println("Time to process loadBundle: "+netTime);
-
+
if (symbol != null)
{
updateMap(symbol, aggregator.getScope());
@@ -449,7 +557,7 @@ public class JSPModelProcessor
}
else
{
- IComponentSymbol componentSymbol =
+ final IComponentSymbol componentSymbol =
SymbolFactory.eINSTANCE.createIComponentSymbol();
componentSymbol.setName(symbolName);
@@ -485,10 +593,10 @@ public class JSPModelProcessor
* @return an unmodifable map containing all known symbols for
* that scope. If scopeName is not found, returns the empty map.
*/
- public Map<Object, ISymbol> getMapForScope(String scopeName)
+ public Map<Object, ISymbol> getMapForScope(final String scopeName)
{
final Map<Object, ISymbol> map = getMapForScopeInternal(scopeName);
-
+
if (map != null)
{
return Collections.unmodifiableMap(map);
@@ -497,7 +605,7 @@ public class JSPModelProcessor
return Collections.EMPTY_MAP;
}
- private void updateMap(ISymbol symbol, String scopeName)
+ private void updateMap(final ISymbol symbol, final String scopeName)
{
final Map<Object, ISymbol> map = getMapForScopeInternal(scopeName);
@@ -507,11 +615,11 @@ public class JSPModelProcessor
}
else
{
- Platform.getLog(JSFCorePlugin.getDefault().getBundle()).log(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, 0, "Scope not found: "+scopeName, new Throwable())); //$NON-NLS-1$
+ Platform.getLog(JSFCorePlugin.getDefault().getBundle()).log(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, 0, "Scope not found: "+scopeName, new Exception("Stack Trace Only"))); //$NON-NLS-1$ //$NON-NLS-2$
}
}
- private Map<Object, ISymbol> getMapForScopeInternal(String scopeName)
+ private Map<Object, ISymbol> getMapForScopeInternal(final String scopeName)
{
if (ISymbolConstants.SYMBOL_SCOPE_REQUEST_STRING.equals(scopeName))
{
@@ -529,67 +637,67 @@ public class JSPModelProcessor
{
return getNoneMap();
}
-
+
Platform.getLog(JSFCorePlugin.getDefault().getBundle()).log(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, 0, "Scope not found: "+scopeName, new Throwable())); //$NON-NLS-1$
return null;
-
+
}
-
+
private Map getRequestMap()
{
if (_requestMap == null)
{
_requestMap = new HashMap<Object, ISymbol>();
}
-
+
return _requestMap;
}
-
+
private Map<Object, ISymbol> getSessionMap()
{
if (_sessionMap == null)
{
_sessionMap = new HashMap<Object, ISymbol>();
}
-
+
return _sessionMap;
}
-
+
private Map<Object, ISymbol> getApplicationMap()
{
if (_applicationMap == null)
{
_applicationMap = new HashMap<Object, ISymbol>();
}
-
+
return _applicationMap;
}
-
+
private Map<Object, ISymbol> getNoneMap()
{
if (_noneMap == null)
{
_noneMap = new HashMap<Object, ISymbol>();
}
-
+
return _noneMap;
}
/**
* Aggregates the sets-locale meta-data
- *
+ *
* @author cbateman
*/
private static class LocaleSetAggregator
{
private final static String SETS_LOCALE = "sets-locale"; //$NON-NLS-1$
-
- static LocaleSetAggregator create(IProject project,
- final String uri,
+
+ private static LocaleSetAggregator create(final IProject project,
+ final String uri,
final String elementName, final String attributeName)
{
final ITaglibDomainMetaDataModelContext mdContext = TaglibDomainMetaDataQueryHelper.createMetaDataModelContext(project, uri);
- Trait trait = TaglibDomainMetaDataQueryHelper.getTrait(mdContext, elementName+"/"+attributeName, SETS_LOCALE); //$NON-NLS-1$
+ final Trait trait = TaglibDomainMetaDataQueryHelper.getTrait(mdContext, elementName+"/"+attributeName, SETS_LOCALE); //$NON-NLS-1$
if (TraitValueHelper.getValueAsBoolean(trait))
{
@@ -599,43 +707,43 @@ public class JSPModelProcessor
return null;
}
}
-
+
/**
* Aggregates all the symbol contributor meta-data into a single object
- *
+ *
* @author cbateman
*
*/
private static class SymbolContribAggregator
{
- private final static String CONTRIBUTES_VALUE_BINDING =
+ private final static String CONTRIBUTES_VALUE_BINDING =
"contributes-value-binding"; //$NON-NLS-1$
private final static String VALUE_BINDING_SCOPE = "value-binding-scope"; //$NON-NLS-1$
- private final static String VALUE_BINDING_SYMBOL_FACTORY =
+ private final static String VALUE_BINDING_SYMBOL_FACTORY =
"value-binding-symbol-factory"; //$NON-NLS-1$
private final static String STATIC_TYPE_KEY = "optional-value-binding-static-type"; //$NON-NLS-1$
private final static String VALUEEXPRESSION_ATTR_NAME_KEY = "optional-value-binding-valueexpr-attr"; //$NON-NLS-1$
-
+
/**
* @param attributeName
* @return a new instance only if attributeName is a symbol contributor
*/
- static SymbolContribAggregator create(final IProject project,
- final String uri,
- final String elementName,
+ private static SymbolContribAggregator create(final IProject project,
+ final String uri,
+ final String elementName,
final String attributeName)
{
final String entityKey = elementName+"/"+attributeName; //$NON-NLS-1$
final ITaglibDomainMetaDataModelContext mdContext = TaglibDomainMetaDataQueryHelper.createMetaDataModelContext(project, uri);
Trait trait = TaglibDomainMetaDataQueryHelper.getTrait(mdContext, entityKey, CONTRIBUTES_VALUE_BINDING);
- boolean contribsValueBindings = TraitValueHelper.getValueAsBoolean(trait);
+ final boolean contribsValueBindings = TraitValueHelper.getValueAsBoolean(trait);
if (contribsValueBindings)
{
String scope = null;
String symbolFactory = null;
-
+
trait = TaglibDomainMetaDataQueryHelper.getTrait(mdContext, entityKey, VALUE_BINDING_SCOPE);
scope = TraitValueHelper.getValueAsString(trait);
@@ -685,7 +793,7 @@ public class JSPModelProcessor
{
return _metadata.get("scope"); //$NON-NLS-1$
}
-
+
/**
* @return the factory
*/
@@ -693,34 +801,93 @@ public class JSPModelProcessor
{
return JSFCommonPlugin.getSymbolFactories().get(_metadata.get("factory")); //$NON-NLS-1$
}
-
+
public String getStaticType()
{
return _metadata.get("staticType"); //$NON-NLS-1$
}
-
+
public String getValueExpressionAttr()
{
return _metadata.get("valueExprAttr"); //$NON-NLS-1$
}
}
- private static class CountingMutex extends Object
+ private final static class CountingMutex extends Object
{
+ private long _lastModificationStamp = -1;
private boolean _signalled = false;
+ private final ILock _lock = Job.getJobManager().newLock();
/**
- * @return true if the state of mutex is signalled
+ * Similar to AtomicBoolean.compareAndSet. If the signalled flag
+ * is the same as expect then update is written to the flag. Otherwise,
+ * nothing happens.
+ * @param expect the value of _signalled where update occurs
+ * @param update the value written to _signalled if _signalled == expect
+ *
+ * @return true if the signalled flag was set to update
*/
- public synchronized boolean isSignalled() {
- return _signalled;
+ public boolean compareAndSetSignalled(final boolean expect, final boolean update) {
+ final boolean[] value = new boolean[1];
+ safeRun(new Runnable() {
+ public void run()
+ {
+ if (_signalled == expect)
+ {
+ _signalled = update;
+ value[0] = true;
+ }
+ else
+ {
+ value[0] = false;
+ }
+ }});
+ return value[0];
+ }
+
+ public boolean hasChanged(final long currentModificationStamp)
+ {
+ final boolean[] value = new boolean[1];
+ safeRun(new Runnable() {
+ public void run()
+ {
+ value[0] = (_lastModificationStamp != currentModificationStamp);
+ }});
+ return value[0];
}
/**
* @param signalled
*/
- public synchronized void setSignalled(boolean signalled) {
- this._signalled = signalled;
+ public void setSignalled(final boolean signalled) {
+ safeRun(new Runnable() {
+ public void run()
+ {
+ _signalled = signalled;
+ }});
+ }
+
+ public void setModificationStamp(final long newValue)
+ {
+ safeRun(new Runnable() {
+ public void run()
+ {
+ _lastModificationStamp = newValue;
+ }});
+ }
+
+ private void safeRun(final Runnable runnable)
+ {
+ _lock.acquire();
+ try
+ {
+ runnable.run();
+ }
+ finally
+ {
+ _lock.release();
+ }
}
}
}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/jsp/StartupHandler.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/jsp/StartupHandler.java
index b3b437742..40b8fc216 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/jsp/StartupHandler.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/jsp/StartupHandler.java
@@ -7,7 +7,7 @@
*
* Contributors:
* Cameron Bateman/Oracle - initial API and implementation
- *
+ *
********************************************************************************/
package org.eclipse.jst.jsf.designtime.internal.jsp;
@@ -32,58 +32,60 @@ import org.eclipse.ui.PlatformUI;
/**
* On workbench startup, registers a part listener that triggers when
* a JSP editor opens.
- *
+ *
* @author cbateman
*
*/
-public class StartupHandler implements IStartup
+public class StartupHandler implements IStartup
{
private final JSPEditorListener _partListener = new JSPEditorListener();
+ private final static boolean DISABLE_EDITOR_OPEN_REFRESH = System
+ .getProperty("org.eclipse.jst.jsf.jspmodelprocessor.disable.editor.open.refresh") != null; //$NON-NLS-1$
- public void earlyStartup()
+ public void earlyStartup()
{
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable()
{
public void run()
{
- IWorkbenchWindow windows[] =
+ final IWorkbenchWindow windows[] =
PlatformUI.getWorkbench().getWorkbenchWindows();
-
- for (int i = 0; i < windows.length; i++)
+
+ for (final IWorkbenchWindow window : windows)
{
- IWorkbenchPage pages[] = windows[i].getPages();
- for (int j = 0; j < pages.length; j++)
+ final IWorkbenchPage pages[] = window.getPages();
+ for (final IWorkbenchPage page : pages)
{
- IEditorReference[] editorReferences =
- pages[j].getEditorReferences();
-
- for (int k = 0; k < editorReferences.length; k++)
+ final IEditorReference[] editorReferences =
+ page.getEditorReferences();
+
+ for (final IEditorReference editorReference : editorReferences)
{
- if (_partListener.isValidJSPEditor(editorReferences[k]))
+ if (_partListener.isValidJSPEditor(editorReference))
{
- _partListener.setJSPModelListener(editorReferences[k]);
+ _partListener.setJSPModelListener(editorReference);
}
}
}
- windows[i].getPartService().addPartListener(_partListener);
+ window.getPartService().addPartListener(_partListener);
}
// TODO: register with all windows?
PlatformUI.getWorkbench().addWindowListener(new IWindowListener()
{
- public void windowActivated(IWorkbenchWindow window) {
+ public void windowActivated(final IWorkbenchWindow window) {
// do nothing
}
- public void windowDeactivated(IWorkbenchWindow window) {
+ public void windowDeactivated(final IWorkbenchWindow window) {
// do nothing
}
- public void windowClosed(IWorkbenchWindow window) {
+ public void windowClosed(final IWorkbenchWindow window) {
window.getPartService().removePartListener(_partListener);
}
- public void windowOpened(IWorkbenchWindow window) {
+ public void windowOpened(final IWorkbenchWindow window) {
window.getPartService().addPartListener(_partListener);
}
});
@@ -95,44 +97,44 @@ public class StartupHandler implements IStartup
{
private JSPModelProcessor _processor;
- public void partActivated(IWorkbenchPartReference partRef) {
+ public void partActivated(final IWorkbenchPartReference partRef) {
// do nothing
}
- public void partBroughtToTop(IWorkbenchPartReference partRef) {
+ public void partBroughtToTop(final IWorkbenchPartReference partRef) {
// do nothing
}
- public void partClosed(IWorkbenchPartReference partRef) {
+ public void partClosed(final IWorkbenchPartReference partRef) {
// do nothing
}
- public void partDeactivated(IWorkbenchPartReference partRef) {
+ public void partDeactivated(final IWorkbenchPartReference partRef) {
// do nothing
}
- public void partOpened(IWorkbenchPartReference partRef) {
+ public void partOpened(final IWorkbenchPartReference partRef) {
if (isValidJSPEditor(partRef))
{
setJSPModelListener((IEditorReference)partRef);
}
}
- public void partHidden(IWorkbenchPartReference partRef) {
+ public void partHidden(final IWorkbenchPartReference partRef) {
// do nothing
}
- public void partVisible(IWorkbenchPartReference partRef) {
+ public void partVisible(final IWorkbenchPartReference partRef) {
// do nothing
}
- public void partInputChanged(IWorkbenchPartReference partRef) {
+ public void partInputChanged(final IWorkbenchPartReference partRef) {
// do nothing
}
- private boolean isJSPEditor(IEditorReference editorRef)
+ private boolean isJSPEditor(final IEditorReference editorRef)
{
- IFile file = getIFile(editorRef);
+ final IFile file = getIFile(editorRef);
if (file != null)
{
@@ -147,16 +149,16 @@ public class StartupHandler implements IStartup
* @return true if the editor is editing the JSP content type and
* the owning project is a JSF project
*/
- boolean isValidJSPEditor(IEditorReference editorRef)
+ boolean isValidJSPEditor(final IEditorReference editorRef)
{
final IFile file = getIFile(editorRef);
-
- return file != null &&
+
+ return file != null &&
JSFAppConfigUtils.isValidJSFProject(file.getProject()) &&
isJSPEditor(editorRef);
}
- boolean isValidJSPEditor(IWorkbenchPartReference partRef)
+ boolean isValidJSPEditor(final IWorkbenchPartReference partRef)
{
if (partRef instanceof IEditorReference)
{
@@ -166,38 +168,43 @@ public class StartupHandler implements IStartup
return false;
}
- void setJSPModelListener(IEditorReference editorRef)
+ void setJSPModelListener(final IEditorReference editorRef)
{
- IFile file = getIFile(editorRef);
-
+ final IFile file = getIFile(editorRef);
+
if (file != null)
{
try
{
- // implicitly creates if not present
- _processor = JSPModelProcessor.get(file);
- _processor.refresh(false);
- }
- catch (Exception e)
+ if (!DISABLE_EDITOR_OPEN_REFRESH)
+ {
+ // implicitly creates if not present
+ _processor = JSPModelProcessor.get(file);
+ _processor.refresh(!JSPModelProcessor.FORCE_REFRESH,
+ JSPModelProcessor.RUN_ON_CURRENT_THREAD);
+ }
+ } catch (final Exception e)
{
- JSFCorePlugin.getDefault().getLog().log(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, 0, "Error acquiring model processor",e)); //$NON-NLS-1$
+ JSFCorePlugin.getDefault().getLog().log(
+ new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID,
+ 0, "Error acquiring model processor", e)); //$NON-NLS-1$
}
}
}
- IFile getIFile(IEditorReference editorRef)
+ IFile getIFile(final IEditorReference editorRef)
{
try
{
- IEditorInput editorInput = editorRef.getEditorInput();
- Object adapt = editorInput.getAdapter(IFile.class);
-
+ final IEditorInput editorInput = editorRef.getEditorInput();
+ final Object adapt = editorInput.getAdapter(IFile.class);
+
if (adapt instanceof IFile)
{
return (IFile) adapt;
}
}
- catch (PartInitException excp)
+ catch (final PartInitException excp)
{
JSFCorePlugin.getDefault().getLog().log(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, 0, "Error acquiring editor input",excp)); //$NON-NLS-1$
}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/symbols/JSPTagVariableSymbolSourceProvider.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/symbols/JSPTagVariableSymbolSourceProvider.java
index ca109f718..401c1be5e 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/symbols/JSPTagVariableSymbolSourceProvider.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/symbols/JSPTagVariableSymbolSourceProvider.java
@@ -56,10 +56,10 @@ public class JSPTagVariableSymbolSourceProvider extends
try
{
modelProcessor = JSPModelProcessor.get(fileContext);
-
+
// ensure internal model is sync'ed with document
// but don't force refresh
- modelProcessor.refresh(false);
+ modelProcessor.refresh(!JSPModelProcessor.FORCE_REFRESH, JSPModelProcessor.RUN_ON_CURRENT_THREAD);
final List<ISymbol> symbols = new ArrayList();
if ((symbolScopeMask & ISymbolConstants.SYMBOL_SCOPE_REQUEST) != 0)
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/messages.properties b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/messages.properties
index adccd455f..7110e26ab 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/messages.properties
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/messages.properties
@@ -11,6 +11,7 @@
AbstractDataModelVariableFactory.DataModel.Symbol.RowVariable.DetailedDescription=Row variable for dataTable
JSPDefaultSymbolFactory.Resource.bundle.map.detailedDescription=Resource bundle map for bundle <i>
JSPDefaultSymbolFactory.Problem.ErrorCreatingVariable=Error creating loadBundle variable
+JSPModelProcessor.0=Refreshing JSF information about: {0}
ResourceBundleSymbolSourceProvider.DetailedDescription=Resource bundle map for bundle <i>
DefaultBeanSymbolSourceProvider.AdditionalInformation.Name=Name:
DefaultBeanSymbolSourceProvider.AdditionalInformation.Type=Type:

Back to the top