/******************************************************************************* * Copyright (c) 2007 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: * Cameron Bateman/Oracle - initial API and implementation * ********************************************************************************/ package org.eclipse.jst.jsf.designtime.symbols; import org.eclipse.core.resources.IFile; import org.eclipse.jdt.core.IJavaProject; 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.context.structureddocument.IStructuredDocumentContext; import org.eclipse.jst.jsf.context.symbol.ERuntimeSource; import org.eclipse.jst.jsf.context.symbol.ISymbol; import org.eclipse.jst.jsf.core.internal.JSFCorePlugin; import org.eclipse.jst.jsf.core.internal.tld.IJSFConstants; import org.eclipse.jst.jsf.validation.internal.appconfig.AppConfigValidationUtil; import org.w3c.dom.Element; /** * A framework provided variable factory for EL model objects that are * constructed based on DataModel's dervied from an EL expression. * * @author cbateman * */ public abstract class AbstractDataModelVariableFactory { private final JSFSymbolFactory _symbolFactory = new JSFSymbolFactory(); /** * @param elText * The EL expression text. Must not be null * @param elContext * The document context pointing to elText in the source * document. Must not be null * @param file * The workspace resource that contains elText. Must not be null. * @return the value expression resolved from elText or null if it cannot be * resolved or elText doesn't resolve to value expression (i.e. is a * method expression) * @deprecated use JSFSymbolFactory.getValueTypeFromEL instead. */ public final ValueType createValueExpression(final String elText, final IStructuredDocumentContext elContext, final IFile file) { return getSymbolFactory().getValueTypeFromEL(elText, elContext, file); } /** * @return the symbol factory used by this variable factory */ public final JSFSymbolFactory getSymbolFactory() { return _symbolFactory; } /** * @param symbolName * The name of the symbol to be created. Must not be null * @param signature * The type signature of the array type. Must not be null * @param javaProject * must not be null * @return a symbol based approximating an implicit DataModel wrapper for an * array * @deprecated use JSFSymbolFactory.createArraySymbol instead */ protected final ISymbol createArraySymbol(final String symbolName, final String signature, final IJavaProject javaProject) { return getSymbolFactory().createArraySymbol(symbolName, signature, ERuntimeSource.TAG_INSTANTIATED_SYMBOL_LITERAL, javaProject); } /** * Implements default rules for taking an non-array value expression and * resolving it to a ISymbol modelling a JSF DataModel * * @param symbolName * @param valueType * @param javaProject * @return a symbol where valueType is considered to be the base type upon * which a data model would be created. This combines the * possibility that the value expression is either an explicit * DataModel implementation or a non-DataModel type for which JSF be * default provides an implicit wrapper model. * * List is treated as a special case here, since their are two subcases: 1) * the list is a raw type, in which case it must be treated as implicit and * opaque (as to the type of the variable created) 2) the list has Java 5 * type argument information that can be used to infer the type of the row * variable */ public ISymbol createFromType(String symbolName, ValueType valueType, IJavaProject javaProject) { return internalCreateFromBaseType(symbolName, valueType, javaProject); } private ISymbol internalCreateFromBaseType(String symbolName, ValueType valueType, IJavaProject javaProject) { // based on JSF 1.1 spec section 4.2.1.4 the data model // value binding can be one of a number of object that will // get an implicit DataModel wrapper at runtime // could be an array if (Signature.getArrayCount(valueType.getSignature()) > 0) { return getSymbolFactory() .createArraySymbol(symbolName, valueType.getSignature(), ERuntimeSource.TAG_INSTANTIATED_SYMBOL_LITERAL, javaProject); } // if is a list, then we have extra work to do if it // is generic and has info about its contents if (valueType.isInstanceOf(TypeConstants.TYPE_LIST)) { return getSymbolFactory().createFromList(symbolName, valueType, ERuntimeSource.TAG_INSTANTIATED_SYMBOL_LITERAL, null, javaProject); } // if is JSTL ResultSet, java ResultSet or DataModel // return the default symbol -- in the absence of definite // template info, these row containers are opaque to us else if (valueType .isInstanceOf(TypeConstants.TYPE_JAVAX_SERVLET_JSP_JSTL_SQL_RESULT) || valueType.isInstanceOf(TypeConstants.TYPE_RESULT_SET) || valueType.isInstanceOf(TypeConstants.TYPE_DATA_MODEL)) { return getSymbolFactory().createDefaultSymbol(symbolName, ERuntimeSource.TAG_INSTANTIATED_SYMBOL_LITERAL, Messages .getString("AbstractDataModelVariableFactory.DataModel.Symbol.RowVariable.DetailedDescription")); //$NON-NLS-1$ } // in other cases, we assume that the value is an explicit single row // scalar object return getSymbolFactory().createScalarSymbol(symbolName, valueType.getSignature(), ERuntimeSource.TAG_INSTANTIATED_SYMBOL_LITERAL, javaProject); } /** * @param symbolName * The name of the symbol to create. Must not be null. * @param valueType * The value expression representing the implicit list. The * signature on the valueType must be a list. Must not be null. * @param javaProject * The JavaProject whose classpath will be used to resolve types. * Must not be null. * * @return a symbol that approximates as best as possible an implicit * DataModel for java.util.List value expressions. If the List has * resolvable Java 5 type arguments, then a scalar symbol will be * created using this type information. If it is a raw type, then * createDefaultSymbol() is called * @deprecated use JSFSymbolFactory.createFromList */ protected final ISymbol createFromList(String symbolName, ValueType valueType, IJavaProject javaProject) { return getSymbolFactory().createFromList(symbolName, valueType, ERuntimeSource.TAG_INSTANTIATED_SYMBOL_LITERAL, null, javaProject); } /** * @param symbolName * The name of the symbol to create. Must not be null. * @param signature * The fully resolved type signature of the scalar. Must not be * null. * @param javaProject * The JavaProject whose classpath is to be used to resolve type * information for signture. Must not be null. * @return a symbol approximating a scalar object DataModel wrapper. The row * variable for the data model becomes of type signature * @deprecated use JSFSymbolFactory.createScalarSymbol instead. */ protected final ISymbol createScalarSymbol(final String symbolName, final String signature, final IJavaProject javaProject) { return getSymbolFactory().createScalarSymbol(symbolName, signature, ERuntimeSource.TAG_INSTANTIATED_SYMBOL_LITERAL, javaProject); } /** * @param symbolName * The name of the symbol to create. Must not be null * @return a default symbol that eliminates bogus warnings for this * dataTable's row variable in cases where something better is * resolvable. Note that this is not ideal, since will result in any * property being accepted on the variable with this name. * @deprecated use JSFSymbolFactory.createDefaultSymbol instead. */ public final ISymbol createDefaultSymbol(final String symbolName) { return getSymbolFactory() .createDefaultSymbol( symbolName, ERuntimeSource.TAG_INSTANTIATED_SYMBOL_LITERAL, Messages .getString("AbstractDataModelVariableFactory.DataModel.Symbol.RowVariable.DetailedDescription")); //$NON-NLS-1$ } /** * @param dataTableElement * the DOM element that has a "value" attribute. Must not be * null. * @return the el text from the 'value attribute of a dataTable element or * null if not found */ protected static String getELText(final Element dataTableElement) { assert dataTableElement != null; String attrVal = dataTableElement .getAttribute(IJSFConstants.ATTR_VALUE); if (attrVal != null) { return AppConfigValidationUtil.extractELExpression(attrVal) .getElText(); } return null; } /** * @return the variable source name. Protects against null in the abstract * method */ protected final String internalGetVariableSourceName() { String variableSourceName = getVariableSourceName(); if (variableSourceName == null) { JSFCorePlugin.log("Missing variableSourceName", new Throwable()); //$NON-NLS-1$ return "**missing variable source name**"; //$NON-NLS-1$ } return variableSourceName; } /** * @return a user displayable name for the source of variables created by * this factory Must not return null. */ protected abstract String getVariableSourceName(); }