| /******************************************************************************* |
| * Copyright (c) 2006 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 java.util.AbstractMap; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.jst.jsf.context.symbol.ERuntimeSource; |
| import org.eclipse.jst.jsf.context.symbol.IInstanceSymbol; |
| import org.eclipse.jst.jsf.context.symbol.IMapTypeDescriptor; |
| import org.eclipse.jst.jsf.context.symbol.ISymbol; |
| import org.eclipse.jst.jsf.context.symbol.SymbolFactory; |
| import org.eclipse.jst.jsf.context.symbol.source.ISymbolConstants; |
| import org.eclipse.jst.jsf.designtime.DesignTimeApplicationManager; |
| import org.eclipse.jst.jsf.designtime.context.IDTExternalContext; |
| |
| /** |
| * Provides the default built-in JSF symbols |
| * |
| * Clients may sub-class |
| * |
| * @author cbateman |
| * |
| */ |
| public class DefaultBuiltInSymbolProvider |
| { |
| private static DefaultBuiltInSymbolProvider INSTANCE; |
| private static final JSFSymbolFactory _symbolFactory; |
| |
| /** |
| * @return the singleton instance |
| */ |
| public synchronized static DefaultBuiltInSymbolProvider getInstance() |
| { |
| if (INSTANCE == null) |
| { |
| INSTANCE = new DefaultBuiltInSymbolProvider(); |
| } |
| |
| return INSTANCE; |
| } |
| |
| private static final String APPLICATION_SCOPE = "applicationScope"; //$NON-NLS-1$ |
| private static final String SESSION_SCOPE = "sessionScope"; //$NON-NLS-1$ |
| private static final String REQUEST_SCOPE = "requestScope"; //$NON-NLS-1$ |
| private static final String COOKIE_IMPLICIT_OBJ = "cookie"; //$NON-NLS-1$ |
| private static final String FACES_CONTEXT_IMPLICIT_OBJ = "facesContext"; //$NON-NLS-1$ |
| private static final String HEADER_IMPLICIT_OBJ = "header"; //$NON-NLS-1$ |
| private static final String HEADER_VALUES_IMPLICIT_OBJ = "headerValues"; //$NON-NLS-1$ |
| private static final String INIT_PARAM_IMPLICIT_OBJ = "initParam"; //$NON-NLS-1$ |
| private static final String PARAM_IMPLICIT_OBJ = "param"; //$NON-NLS-1$ |
| private static final String PARAM_VALUES_IMPLICIT_OBJ = "paramValues"; //$NON-NLS-1$ |
| private static final String VIEW_IMPLICIT_OBJ = "view"; //$NON-NLS-1$ |
| |
| private static final String FACES_CONTEXT_FULLY_QUALIFIED_CLASS = "javax.faces.context.FacesContext"; //$NON-NLS-1$ |
| private static final String VIEW_FULLY_QUALIFIED_CLASS = "javax.faces.component.UIViewRoot"; //$NON-NLS-1$ |
| |
| private static final ISymbol SYMBOL_COOKIE_IMPLICIT_OBJ; |
| private static final ISymbol SYMBOL_HEADER_IMPLICIT_OBJ; |
| private static final ISymbol SYMBOL_HEADER_VALUES_IMPLICIT_OBJ; |
| private static final ISymbol SYMBOL_PARAM_IMPLICIT_OBJ; |
| private static final ISymbol SYMBOL_PARAM_VALUES_IMPLICIT_OBJ; |
| private static final ISymbol SYMBOL_INIT_PARAM_IMPLICIT_OBJ; |
| |
| static |
| { |
| _symbolFactory = new JSFSymbolFactory(); |
| // invariant request scope variables |
| SYMBOL_COOKIE_IMPLICIT_OBJ = _symbolFactory.createUnknownInstanceSymbol(COOKIE_IMPLICIT_OBJ, ERuntimeSource.BUILT_IN_SYMBOL_LITERAL); |
| SYMBOL_HEADER_IMPLICIT_OBJ = _symbolFactory.createUnknownInstanceSymbol(HEADER_IMPLICIT_OBJ, ERuntimeSource.BUILT_IN_SYMBOL_LITERAL); |
| SYMBOL_HEADER_VALUES_IMPLICIT_OBJ = _symbolFactory.createUnknownInstanceSymbol(HEADER_VALUES_IMPLICIT_OBJ, ERuntimeSource.BUILT_IN_SYMBOL_LITERAL); |
| SYMBOL_PARAM_IMPLICIT_OBJ = _symbolFactory.createUnknownInstanceSymbol(PARAM_IMPLICIT_OBJ, ERuntimeSource.BUILT_IN_SYMBOL_LITERAL); |
| SYMBOL_PARAM_VALUES_IMPLICIT_OBJ = _symbolFactory.createUnknownInstanceSymbol(PARAM_VALUES_IMPLICIT_OBJ, ERuntimeSource.BUILT_IN_SYMBOL_LITERAL); |
| |
| // invariant application scope variables |
| SYMBOL_INIT_PARAM_IMPLICIT_OBJ = _symbolFactory.createUnknownInstanceSymbol(INIT_PARAM_IMPLICIT_OBJ, ERuntimeSource.BUILT_IN_SYMBOL_LITERAL); |
| } |
| |
| |
| /** |
| * No direct instantiation -- use getInstance |
| * |
| * Made protected to allow sub-classing |
| */ |
| protected DefaultBuiltInSymbolProvider() |
| { |
| // nothing to do. |
| } |
| |
| /** |
| * @param context |
| * @param symbolScopeMask |
| * @return all symbols for context in scopes matching symbolScopeMask |
| */ |
| public ISymbol[] getSymbols(final IAdaptable context, |
| final int symbolScopeMask) |
| { |
| final IFile fileContext = FileContextUtil |
| .deriveIFileFromContext(context); |
| return (ISymbol[]) getSymbolsForScope(fileContext, symbolScopeMask) |
| .toArray(ISymbol.EMPTY_SYMBOL_ARRAY); |
| } |
| |
| /** |
| * @param name |
| * @param context |
| * @param symbolScopeMask |
| * @return the symbol in context matching name or null if not found |
| */ |
| public ISymbol getSymbol(final String name, final IAdaptable context, |
| final int symbolScopeMask) |
| { |
| final IFile file = FileContextUtil.deriveIFileFromContext(context); |
| |
| ISymbol symbol = null; |
| if ((symbolScopeMask & ISymbolConstants.SYMBOL_SCOPE_REQUEST) != 0) |
| { |
| symbol = getRequestScopeSymbols(file).get(name); |
| } |
| if ((symbolScopeMask & ISymbolConstants.SYMBOL_SCOPE_SESSION) != 0 |
| && symbol == null) |
| { |
| symbol = getSessionScopeSymbols(file).get(name); |
| } |
| if ((symbolScopeMask & ISymbolConstants.SYMBOL_SCOPE_APPLICATION) != 0 |
| && symbol == null) |
| { |
| symbol = getApplicationScopeSymbols(file).get(name); |
| } |
| |
| return symbol; |
| } |
| |
| /** |
| * @param prefix |
| * @param context |
| * @param symbolScopeMask |
| * @return all implicit symbols for context starting with prefix in scopes |
| * matching symbolScopeMask |
| */ |
| public ISymbol[] getSymbols(final String prefix, final IAdaptable context, |
| final int symbolScopeMask) |
| { |
| final IFile file = FileContextUtil.deriveIFileFromContext(context); |
| |
| final List<ISymbol> symbols = new ArrayList<ISymbol>(); |
| if ((symbolScopeMask & ISymbolConstants.SYMBOL_SCOPE_REQUEST) != 0) |
| { |
| symbols.addAll(getRequestScopeSymbols(file).values()); |
| } |
| if ((symbolScopeMask & ISymbolConstants.SYMBOL_SCOPE_SESSION) != 0) |
| { |
| symbols.addAll(getSessionScopeSymbols(file).values()); |
| } |
| if ((symbolScopeMask & ISymbolConstants.SYMBOL_SCOPE_APPLICATION) != 0) |
| { |
| symbols.addAll(getApplicationScopeSymbols(file).values()); |
| } |
| return symbols.toArray(ISymbol.EMPTY_SYMBOL_ARRAY); |
| } |
| |
| private List getSymbolsForScope(final IFile file, final int symbolScopeMask) |
| { |
| final List symbols = new ArrayList(); |
| if ((symbolScopeMask & ISymbolConstants.SYMBOL_SCOPE_REQUEST) != 0) |
| { |
| symbols.addAll(getRequestScopeSymbols(file).values()); |
| } |
| if ((symbolScopeMask & ISymbolConstants.SYMBOL_SCOPE_SESSION) != 0) |
| { |
| symbols.addAll(getSessionScopeSymbols(file).values()); |
| } |
| if ((symbolScopeMask & ISymbolConstants.SYMBOL_SCOPE_APPLICATION) != 0) |
| { |
| symbols.addAll(getApplicationScopeSymbols(file).values()); |
| } |
| |
| return symbols; |
| } |
| |
| private Map<String, ISymbol> getRequestScopeSymbols(final IFile file) |
| { |
| final Map<String, ISymbol> requestSymbols = new HashMap<String, ISymbol>(); |
| |
| ISymbol symbol = createScopeSymbol(file, |
| ISymbolConstants.SYMBOL_SCOPE_REQUEST, REQUEST_SCOPE); |
| requestSymbols.put(symbol.getName(), symbol); |
| |
| requestSymbols.put(SYMBOL_COOKIE_IMPLICIT_OBJ.getName(), SYMBOL_COOKIE_IMPLICIT_OBJ); |
| requestSymbols.put(SYMBOL_HEADER_IMPLICIT_OBJ.getName(), SYMBOL_HEADER_IMPLICIT_OBJ); |
| requestSymbols.put(SYMBOL_HEADER_VALUES_IMPLICIT_OBJ.getName(), SYMBOL_HEADER_VALUES_IMPLICIT_OBJ); |
| requestSymbols.put(SYMBOL_PARAM_IMPLICIT_OBJ.getName(), SYMBOL_PARAM_IMPLICIT_OBJ); |
| requestSymbols.put(SYMBOL_PARAM_VALUES_IMPLICIT_OBJ.getName(), SYMBOL_PARAM_VALUES_IMPLICIT_OBJ); |
| |
| // TODO: these aren't maps; need to find way to handle |
| symbol = _symbolFactory.createBeanOrUnknownInstanceSymbol(file |
| .getProject(), FACES_CONTEXT_FULLY_QUALIFIED_CLASS, |
| FACES_CONTEXT_IMPLICIT_OBJ, |
| ERuntimeSource.BUILT_IN_SYMBOL_LITERAL); |
| requestSymbols.put(symbol.getName(), symbol); |
| |
| symbol = _symbolFactory.createBeanOrUnknownInstanceSymbol(file |
| .getProject(), VIEW_FULLY_QUALIFIED_CLASS, VIEW_IMPLICIT_OBJ, |
| ERuntimeSource.BUILT_IN_SYMBOL_LITERAL); |
| requestSymbols.put(symbol.getName(), symbol); |
| |
| return Collections.unmodifiableMap(requestSymbols); |
| } |
| |
| private Map<String,ISymbol> getSessionScopeSymbols(final IFile file) |
| { |
| ISymbol symbol = createScopeSymbol(file, |
| ISymbolConstants.SYMBOL_SCOPE_SESSION, SESSION_SCOPE); |
| |
| return Collections.unmodifiableMap |
| (Collections.singletonMap(symbol.getName(), symbol)); |
| } |
| |
| private Map<String,ISymbol> getApplicationScopeSymbols(final IFile file) |
| { |
| final Map<String,ISymbol> symbols = new HashMap<String, ISymbol>(); |
| |
| // TODO: may be able to resolve this one based on web.xml |
| symbols.put(SYMBOL_INIT_PARAM_IMPLICIT_OBJ.getName(), SYMBOL_INIT_PARAM_IMPLICIT_OBJ); |
| |
| ISymbol symbol = createScopeSymbol(file, |
| ISymbolConstants.SYMBOL_SCOPE_APPLICATION, APPLICATION_SCOPE); |
| symbols.put(symbol.getName(), symbol); |
| |
| return Collections.unmodifiableMap(symbols); |
| } |
| |
| private ISymbol createScopeSymbol(final IFile file, final int scopeMask, |
| final String name) |
| { |
| final Map mapSource = new ScopeMap(file, scopeMask); |
| final IMapTypeDescriptor typeDesc = SymbolFactory.eINSTANCE |
| .createIBoundedMapTypeDescriptor(); |
| typeDesc.setMapSource(mapSource); |
| typeDesc.setImmutable(false); // scope maps are mutable |
| final IInstanceSymbol symbol = SymbolFactory.eINSTANCE |
| .createIInstanceSymbol(); |
| symbol.setName(name); |
| symbol.setRuntimeSource(ERuntimeSource.BUILT_IN_SYMBOL_LITERAL); |
| symbol.setTypeDescriptor(typeDesc); |
| // TODO:symbol.setDetailedDescription("A Map of the application scope |
| // attribute values, keyed by attribute name"); |
| |
| return symbol; |
| } |
| |
| private static class ScopeMap extends AbstractMap |
| { |
| private final IFile _externalContextKey; |
| private final int _scopeMask; |
| |
| ScopeMap(final IFile externalContextKey, final int scopeMask) |
| { |
| _externalContextKey = externalContextKey; |
| _scopeMask = scopeMask; |
| } |
| |
| @Override |
| public Set entrySet() |
| { |
| final Map scopeMap = new HashMap(); |
| // do beans first so in case of name collision, beans are hidden |
| final DefaultBeanSymbolSourceProvider beanProvider = DefaultBeanSymbolSourceProvider |
| .getInstance(); |
| |
| final ISymbol beanSymbols[] = beanProvider.getSymbols( |
| _externalContextKey, _scopeMask); |
| |
| for (final ISymbol beanSymbol : beanSymbols) |
| { |
| scopeMap.put(beanSymbol.getName(), beanSymbol); |
| } |
| |
| final DesignTimeApplicationManager manager = DesignTimeApplicationManager |
| .getInstance(_externalContextKey.getProject()); |
| |
| if (manager != null) |
| { |
| |
| final IDTExternalContext externalContext = manager |
| .getFacesContext(_externalContextKey) |
| .getDTExternalContext(_externalContextKey); |
| |
| scopeMap.putAll(externalContext.getMapForScope(_scopeMask)); |
| } |
| |
| return scopeMap.entrySet(); |
| |
| } |
| } |
| } |