Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcbateman2008-03-30 21:22:31 +0000
committercbateman2008-03-30 21:22:31 +0000
commitdca51f56166f014b0b6e8c8265466f53a99849c6 (patch)
tree76a2a5efa0db7777cdefcd2a465dc326038e53b8 /jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context
parent06afe926422dc3cd05394b1a269364a428ed35ae (diff)
downloadwebtools.jsf-dca51f56166f014b0b6e8c8265466f53a99849c6.tar.gz
webtools.jsf-dca51f56166f014b0b6e8c8265466f53a99849c6.tar.xz
webtools.jsf-dca51f56166f014b0b6e8c8265466f53a99849c6.zip
Fix for:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=211321 https://bugs.eclipse.org/bugs/show_bug.cgi?id=211321 https://bugs.eclipse.org/bugs/show_bug.cgi?id=193976 Adds forRuntimeClass and instancePerProject options to variable and property resolver along with new default decorative variable and property resolvers. Adds three new extension ids that can be used to create default context symbol factories in tag meta-data for: unknown variables (creates map variable for which all props are valid), static value variables (creates variables of meta-data specified type) and value expression variables that can receive their variable type from the EL value result of another attribute on the same tag. Also integrates code from https://bugs.eclipse.org/bugs/show_bug.cgi?id=215461 to create a new JSFSymbolFactory to make it easier to do common symbol creation tasks. The data model context factory has also been refactored into this factory. Added exemplary usage of decorative variable resolvver to the trinidad tag support in the form a decorative dt variable resolver that resolves the same symbols as the runtime trinidad equivalent. Finally, changes to tests to support changes (no new coverage yet).
Diffstat (limited to 'jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context')
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/InitializedSymbolFactory.java241
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/source/UnknownTypeContextSymbolFactory.java43
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/source/AbstractContextSymbolFactory.java96
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/source/IAdditionalContextSymbolInfo.java28
4 files changed, 399 insertions, 9 deletions
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/InitializedSymbolFactory.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/InitializedSymbolFactory.java
new file mode 100644
index 000000000..60451c389
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/InitializedSymbolFactory.java
@@ -0,0 +1,241 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Oracle Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthias Fuessel -- extracted from https://bugs.eclipse.org/bugs/show_bug.cgi?id=215461
+ * Cameron Bateman/Oracle - integrated.
+ *
+ ********************************************************************************/
+
+package org.eclipse.jst.jsf.context.symbol;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
+import org.eclipse.jst.jsf.common.internal.types.ValueType;
+import org.eclipse.jst.jsf.common.util.TypeUtil;
+
+/**
+ * Creates purpose-built symbols and descriptors fully initialized (unlike the
+ * EMF factory that simply creates empty instances.
+ *
+ * This class is for convenience only and should not do anything that clients
+ * could not do by hand (though with more work).
+ *
+ * Clients may use or subclass.
+ *
+ * @author cbateman
+ *
+ */
+public class InitializedSymbolFactory
+{
+ /**
+ * If fullyQualifiedClass can be resolved to an IType, then a bean instance
+ * symbol will be created. If the type cannot be resolved, then
+ * createUnknownInstanceSymbol is called with the type descriptor on the
+ * returned symbol forced to fullyQualifiedClass.
+ *
+ * @param project
+ * @param fullyQualifiedClass
+ * @param symbolName
+ * @param source
+ * @return a symbol
+ */
+ public final ISymbol createBeanOrUnknownInstanceSymbol(
+ final IProject project, final String fullyQualifiedClass,
+ final String symbolName, final ERuntimeSource source)
+ {
+ final IJavaProject javaProject = JavaCore.create(project);
+ try
+ {
+ final IType type = javaProject.findType(fullyQualifiedClass);
+
+ // TODO: this is a high-bred since it consists of a java instance
+ // but also has properties we can populate at designtime such as
+ // the maps. Need to add the second part
+ if (type != null)
+ {
+ final IJavaTypeDescriptor2 typeDesc = SymbolFactory.eINSTANCE
+ .createIJavaTypeDescriptor2();
+ typeDesc.setType(type);
+ final IBeanInstanceSymbol facesContextVar = SymbolFactory.eINSTANCE
+ .createIBeanInstanceSymbol();
+ facesContextVar.setTypeDescriptor(typeDesc);
+ facesContextVar.setName(symbolName);
+ facesContextVar.setRuntimeSource(source);
+ return facesContextVar;
+ }
+ }
+ catch (final JavaModelException jme)
+ {
+ // fall-through and fail with unresolved map
+ }
+
+ final ISymbol symbol = createUnknownInstanceSymbol(symbolName, source);
+ ((IInstanceSymbol) symbol)
+ .getTypeDescriptor()
+ .setTypeSignatureDelegate(
+ Signature
+ .createTypeSignature(fullyQualifiedClass, true));
+
+ return symbol;
+ }
+
+ /**
+ * @param symbolName
+ * @param source
+ * @return a symbol for a variable of unknown type
+ */
+ public final IComponentSymbol createUnknownComponentSymbol(
+ final String symbolName, final ERuntimeSource source)
+ {
+ final IComponentSymbol symbol = SymbolFactory.eINSTANCE
+ .createIComponentSymbol();
+ populateUnknownInstanceSymbol(symbol, symbolName, source);
+ return symbol;
+ }
+
+ /**
+ * @param symbolName
+ * @param source
+ * @return the unknown instance symbol as an IInstanceSymbol
+ */
+ public final IInstanceSymbol createUnknownInstanceSymbol(
+ final String symbolName, final ERuntimeSource source)
+ {
+ final IInstanceSymbol symbol = SymbolFactory.eINSTANCE
+ .createIInstanceSymbol();
+ populateUnknownInstanceSymbol(symbol, symbolName, source);
+ return symbol;
+ }
+
+ /**
+ * @param name
+ * may NOT be null.
+ * @param typeDesc
+ * may NOT be null.
+ * @param description
+ * may be null
+ * @return a component symbol using the java type descriptor
+ * @throws IllegalArgumentException
+ * if non-null argument is null
+ */
+ public final IComponentSymbol createJavaComponentSymbol(final String name,
+ final IJavaTypeDescriptor2 typeDesc, final String description)
+ {
+ if (name == null || typeDesc == null)
+ {
+ throw new IllegalArgumentException(
+ "name and typeDesc must not be null");
+ }
+
+ final IComponentSymbol symbol = SymbolFactory.eINSTANCE
+ .createIComponentSymbol();
+ symbol.setName(name);
+ symbol.setTypeDescriptor(typeDesc);
+ symbol.setRuntimeSource(ERuntimeSource.TAG_INSTANTIATED_SYMBOL_LITERAL);
+ return symbol;
+ }
+
+ /**
+ * @param name
+ * @param valueType
+ * @param description
+ * @param javaProject
+ * @return an IComponentSymbol that uses valueType to derive the type
+ * of its type descriptor
+ */
+ public final IComponentSymbol createJavaComponentSymbol(final String name,
+ final ValueType valueType, final String description,
+ final IJavaProject javaProject)
+ {
+ final IJavaTypeDescriptor2 typeDesc = createTypeDescriptorFromSignature(
+ valueType.getSignature(), javaProject);
+ return createJavaComponentSymbol(name, typeDesc, description);
+ }
+
+ private void populateUnknownInstanceSymbol(final IInstanceSymbol symbol,
+ final String symbolName, final ERuntimeSource source)
+ {
+ final IMapTypeDescriptor typeDesc = SymbolFactory.eINSTANCE
+ .createIBoundedMapTypeDescriptor();
+ // empty map source
+ typeDesc.setMapSource(Collections.emptyMap());
+ symbol.setName(symbolName);
+ symbol.setTypeDescriptor(typeDesc);
+ symbol.setRuntimeSource(source);
+ }
+
+ /**
+ * @param type
+ * @return the signature of the element type of a collection/array,
+ * <code>null</code>, if untyped Collection or no container type
+ * at all.
+ */
+ public final String getElementSignatureFromContainerType(ValueType type)
+ {
+ if (type.isArray())
+ {
+ // TODO full signature
+ String signature = type.getSignature();
+ int arrayCount = Signature.getArrayCount(signature);
+ String elementSig = Signature.getElementType(signature);
+ return Signature.createArraySignature(elementSig, arrayCount - 1);
+ }
+ if (type.isInstanceOf(TypeConstants.TYPE_COLLECTION))
+ {
+ final String[] typeArguments = type.getTypeArguments();
+ if (typeArguments.length > 0)
+ {
+ return typeArguments[0];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param signature
+ * @param javaProject
+ * @return a java type descriptor based on the fully qualified type
+ * specified by signature using javaProject as the lookup classpath.
+ * If the IType for signature cannot be found, the descriptor's
+ * typeSignatureDelegate will be used.
+ */
+ public final IJavaTypeDescriptor2 createTypeDescriptorFromSignature(
+ final String signature, final IJavaProject javaProject)
+ {
+ final String elementType = Signature.getElementType(signature);
+
+ IJavaTypeDescriptor2 desc = SymbolFactory.eINSTANCE
+ .createIJavaTypeDescriptor2();
+ final int arrayCount = Signature.getArrayCount(signature);
+ if (arrayCount > 0)
+ {
+ desc.setArrayCount(arrayCount);
+ }
+
+ IType type = TypeUtil.resolveType(javaProject, elementType);
+ if (type != null)
+ {
+ desc.setType(type);
+ }
+ else
+ {
+ desc.setTypeSignatureDelegate(Signature.getTypeErasure(signature));
+ }
+ desc.getTypeParameterSignatures().addAll(
+ Arrays.asList(Signature.getTypeArguments(signature)));
+ return desc;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/source/UnknownTypeContextSymbolFactory.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/source/UnknownTypeContextSymbolFactory.java
new file mode 100644
index 000000000..2be2d159a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/source/UnknownTypeContextSymbolFactory.java
@@ -0,0 +1,43 @@
+package org.eclipse.jst.jsf.context.symbol.internal.source;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jst.jsf.context.symbol.ERuntimeSource;
+import org.eclipse.jst.jsf.context.symbol.ISymbol;
+import org.eclipse.jst.jsf.context.symbol.InitializedSymbolFactory;
+import org.eclipse.jst.jsf.context.symbol.source.AbstractContextSymbolFactory;
+import org.eclipse.jst.jsf.context.symbol.source.IAdditionalContextSymbolInfo;
+
+/**
+ * Returns an unknown component symbol.
+ *
+ * @author cbateman
+ *
+ */
+public final class UnknownTypeContextSymbolFactory extends
+AbstractContextSymbolFactory
+{
+ private final InitializedSymbolFactory _factory = new InitializedSymbolFactory();
+
+ @Override
+ protected ISymbol internalCreate(final String symbolName, final int scope,
+ final IAdaptable context, final List problems)
+ {
+ return internalCreate(symbolName, scope, context, null);
+ }
+
+ @Override
+ protected ISymbol internalCreate(final String symbolName, final int scope,
+ final IAdaptable context, final List problems,
+ final IAdditionalContextSymbolInfo info)
+ {
+ return _factory.createUnknownComponentSymbol(symbolName,
+ ERuntimeSource.TAG_INSTANTIATED_SYMBOL_LITERAL);
+ }
+ @Override
+ public boolean supports(final IAdaptable context)
+ {
+ return true;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/source/AbstractContextSymbolFactory.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/source/AbstractContextSymbolFactory.java
index 4abd7a77f..8904e9f3b 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/source/AbstractContextSymbolFactory.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/source/AbstractContextSymbolFactory.java
@@ -7,7 +7,7 @@
*
* Contributors:
* Cameron Bateman/Oracle - initial API and implementation
- *
+ *
********************************************************************************/
package org.eclipse.jst.jsf.context.symbol.source;
@@ -15,6 +15,7 @@ package org.eclipse.jst.jsf.context.symbol.source;
import java.util.List;
import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.context.symbol.ISymbol;
/**
@@ -26,7 +27,7 @@ import org.eclipse.jst.jsf.context.symbol.ISymbol;
* @author cbateman
*
*/
-public abstract class AbstractContextSymbolFactory
+public abstract class AbstractContextSymbolFactory
{
/**
* @param symbolName -- the symbol name
@@ -34,12 +35,14 @@ public abstract class AbstractContextSymbolFactory
* @param context -- the context; must be supported (call supports(context))
* @param problems -- populated with problems found during symbol construction.
* @return a new ISymbol configured for the name, scope and context or null
- * if the arguments are valid but some other reason a symbol cannot be created.
+ * if the arguments are invalid but some other reason a symbol cannot be created.
* @throws IllegalArgumentException if this method is called with context
* for which supports(context) == false or if scope does not conform
* to exactly one of the ISymbolConstants.SYMBOL_SCOPE_* constants
+ * @deprecated Use the new create method instead.
*/
- public final ISymbol create(String symbolName, int scope, IAdaptable context, List problems)
+ @Deprecated
+ public final ISymbol create(final String symbolName, final int scope, final IAdaptable context, final List problems)
{
if (!supports(context))
{
@@ -49,19 +52,94 @@ public abstract class AbstractContextSymbolFactory
{
throw new IllegalArgumentException("Unsupported symbol constant:"+scope); //$NON-NLS-1$
}
-
- return internalCreate(symbolName, scope, context, problems);
+
+ try
+ {
+ return internalCreate(symbolName, scope, context, problems, null);
+ }
+ catch (final Exception e)
+ {
+ JSFCommonPlugin.log(e, "During execution of context symbol factory: "+this.getClass().getName());
+ return null;
+ }
+ }
+
+ /**
+ * The same as create(symbolName, scope, context, problems), except it calls
+ * the internalCreate with additionalInfo. By default this has the same
+ * effect.
+ *
+ * @param symbolName
+ * @param scope
+ * @param context
+ * @param problems
+ * @param additionalInfo
+ * @return the new Symbol
+ */
+ public final ISymbol create(final String symbolName, final int scope, final IAdaptable context, final List problems, final IAdditionalContextSymbolInfo additionalInfo)
+ {
+ if (!supports(context))
+ {
+ throw new IllegalArgumentException("Unsupported context"); //$NON-NLS-1$
+ }
+ else if (!ISymbolConstants.isValid(scope))
+ {
+ throw new IllegalArgumentException("Unsupported symbol constant:"+scope); //$NON-NLS-1$
+ }
+
+ try
+ {
+ return internalCreate(symbolName, scope, context, problems, additionalInfo);
+ }
+ catch (final Exception e)
+ {
+ JSFCommonPlugin.log(e, "During execution of context symbol factory: "+this.getClass().getName());
+ return null;
+ }
}
+
/**
+ * Use of this method is DISCOURAGED. It is preferable to move functionality
+ * to the new internalCreate method and have this one call it with null.
+ *
+ * This method will eventually be deprecated and removed
+ *
* @param symbolName
* @param scope
* @param context
* @param problems -- see problems arg on create
- * @return a new ISymbol for the name, scope and context
+ * @return a new ISymbol for the name, scope and context; may return null
+ * @deprecated Use the new internalCreate instead. Ignore the new
+ * additionalInfo parameter if you do not need it.
+ */
+ @Deprecated
+ protected ISymbol internalCreate(final String symbolName, final int scope, final IAdaptable context, final List problems)
+ {
+ // do nothing by default
+ return null;
+ }
+
+ /**
+ * NOTE: when migrating to this method, ensure that the other internalCreate
+ * method in your implementation doesn't create inconsistent behaviour.
+ *
+ * @param symbolName
+ * @param scope
+ * @param context Will conform to restrictions you set out in supports().
+ * @param problems CURRENTLY IGNORED.
+ * @param additionalInfo May be null
+ * @since 3.0
+ * @return a new ISymbol for the name, scope and context, but with the option
+ * to also consult additionalInfo passed by the framework. may return null.
*/
- protected abstract ISymbol internalCreate(String symbolName, int scope, IAdaptable context, List problems);
-
+ protected ISymbol internalCreate(final String symbolName, final int scope, final IAdaptable context, final List problems, final IAdditionalContextSymbolInfo additionalInfo)
+ {
+ // by default, call the other internalCreate for backward compatibility.
+ // implementers can override to do things with the additional info
+ return internalCreate(symbolName, scope, context, problems);
+ }
+
/**
* @param context
* @return true if this factory supports the context
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/source/IAdditionalContextSymbolInfo.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/source/IAdditionalContextSymbolInfo.java
new file mode 100644
index 000000000..4e05b84b8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/source/IAdditionalContextSymbolInfo.java
@@ -0,0 +1,28 @@
+package org.eclipse.jst.jsf.context.symbol.source;
+
+
+/**
+ * Passed to AbstractContextSymbolFactory's to provide additional information.
+ * All information is optional and need not be used if not needed.
+ *
+ * Clients may use but NOT IMPLEMENT. New methods may be added without notice.
+ *
+ * @author cbateman
+ * @since 3.0
+ *
+ */
+public interface IAdditionalContextSymbolInfo
+{
+ /**
+ * @return a suggested symbol type signature. May be null.
+ */
+ String getSymbolTypeSignature();
+
+ /**
+ * @return the name of the attribute on the current element context that
+ * contains a value expression that may be used to find type information.
+ * May be null.
+ *
+ */
+ String getValueExpressionAttributeName();
+} \ No newline at end of file

Back to the top