blob: 29b1518532a0c34361abe3475a7c94b99201c5d0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2007 Oracle Corporation and others.
* 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:
* Oracle Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.jsf.core.internal.contentassist.el;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jst.jsf.common.internal.types.CompositeType;
import org.eclipse.jst.jsf.common.internal.types.IAssignable;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IDOMContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.ITaglibContextResolver;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.symbol.IInstanceSymbol;
import org.eclipse.jst.jsf.context.symbol.IObjectSymbol;
import org.eclipse.jst.jsf.context.symbol.ISymbol;
import org.eclipse.jst.jsf.designtime.resolver.ISymbolContextResolver;
import org.eclipse.jst.jsf.designtime.resolver.StructuredDocumentSymbolResolverFactory;
import org.eclipse.jst.jsf.metadataprocessors.MetaDataEnabledProcessingFactory;
import org.eclipse.jst.jsf.metadataprocessors.features.ELIsNotValidException;
import org.eclipse.jst.jsf.metadataprocessors.features.IValidELValues;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* Utility class for resolving symbols for a IStructuredDocumentContext.
*/
public class SymbolResolveUtil {
private SymbolResolveUtil() {
// utility class; not instantiable
}
/**
* Get symbol for a variable (managed bean name, bundle name)
*
* @param context
* @param name
* @return ISymbol
*/
public static ISymbol getSymbolForVariable(
final IStructuredDocumentContext context, final String name) {
final ISymbolContextResolver symbolResolver = StructuredDocumentSymbolResolverFactory
.getInstance().getSymbolContextResolver(context);
return symbolResolver.getVariable(name);
}
/**
* Get symbol for a variable suffix (e. g. bean property/method, bundle
* property). Takes into account whether method bindings are expected for
* the given context.
*
* @param context -
* the IStructuredDocumentContext
* @param fullName -
* full name of the suffix (e. g. bean.property1.property2)
* @param isLastSuffix -
* set true if there follows no other suffix. Method names will
* only be considered if true
* @return ISymbol. May be null.
*/
public static ISymbol getSymbolForVariableSuffixExpr(
final IStructuredDocumentContext context, final String fullName,
final boolean isLastSuffix) {
String[] ids = fullName.split("\\."); //$NON-NLS-1$
// if no suffixes, only one id
if (ids.length < 1) {
ids = new String[] { fullName };
}
final ISymbolContextResolver symbolResolver = StructuredDocumentSymbolResolverFactory
.getInstance().getSymbolContextResolver(context);
if (symbolResolver != null) {
ISymbol symbol = symbolResolver.getVariable(ids[0]);
if (symbol instanceof IInstanceSymbol
&& ((IInstanceSymbol) symbol).isTypeResolved()) {
for (int curSuffixIdx = 1; curSuffixIdx < ids.length; curSuffixIdx++) {
if (isLastSuffix && curSuffixIdx == ids.length - 1
&& isMethodBindingExpected(context)) {
/*
* TODO Take into acount required method signature,
* since there may be different methods with the same
* name
*/
return symbolResolver.getMethod((IObjectSymbol) symbol,
ids[curSuffixIdx]);
}
final ISymbol property = symbolResolver.getProperty(symbol,
ids[curSuffixIdx]);
if (property == null) {
return null;
}
symbol = property;
}
return symbol;
}
}
return null;
}
/**
* Tells whether method bindings are expected for the given context.
*
* @param context -
* the IStructuredDocumentContext
* @return true, if method bindings expected
*/
public static boolean isMethodBindingExpected(
final IStructuredDocumentContext context) {
return isMethodBindingExpected(context, null);
}
/**
* Tells whether method bindings are expected for the given context. Will
* add signatures of expected method bindings to a given list.
*
* @param context -
* the IStructuredDocumentContext
* @param expectedBindings -
* a list. If not null, signatures of expected method bindings
* will be appended to this list.
* @return true, if method bindings expected
*/
public static boolean isMethodBindingExpected(
final IStructuredDocumentContext context,
final List expectedBindings) {
final IDOMContextResolver domResolver = IStructuredDocumentContextResolverFactory.INSTANCE
.getDOMContextResolver(context);
final Node curNode = domResolver.getNode();
if (curNode instanceof Attr) {
final Attr attr = (Attr) curNode;
final Element element = attr.getOwnerElement();
final ITaglibContextResolver taglibResolver = IStructuredDocumentContextResolverFactory.INSTANCE
.getTaglibContextResolver(context);
final String uri = taglibResolver.getTagURIForNodeName(element);
final List elVals = MetaDataEnabledProcessingFactory.getInstance()
.getAttributeValueRuntimeTypeFeatureProcessors(
IValidELValues.class, context, uri,
element.getLocalName(), attr.getLocalName());
boolean methodBindingExpected = false;
for (final Iterator it = elVals.iterator(); it.hasNext();) {
final IValidELValues validValues = (IValidELValues) it.next();
try {
final CompositeType type = validValues
.getExpectedRuntimeType();
if (type != null
&& type.getAssignmentTypeMask() == IAssignable.ASSIGNMENT_TYPE_NONE) {
methodBindingExpected = true;
if (expectedBindings != null) {
expectedBindings.addAll(Arrays.asList(validValues
.getExpectedRuntimeType().getSignatures()));
} else {
// if we don't need the method signatures, *one*
// expected method binding is sufficient.
return true;
}
}
} catch (final ELIsNotValidException e) {
// do nothing
}
}
return methodBindingExpected;
}
// default condition is no method binding
return false;
}
}