/******************************************************************************* * Copyright (c) 2009-2011 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.jsf.model; import java.util.ArrayList; 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.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jface.text.BadLocationException; import org.jboss.tools.common.el.core.model.ELExpression; import org.jboss.tools.common.el.core.model.ELInstance; import org.jboss.tools.common.el.core.model.ELInvocationExpression; import org.jboss.tools.common.el.core.model.ELModel; import org.jboss.tools.common.el.core.parser.ELParser; import org.jboss.tools.common.el.core.parser.ELParserUtil; import org.jboss.tools.common.el.core.resolver.ELContext; import org.jboss.tools.common.el.core.resolver.ELResolution; import org.jboss.tools.common.el.core.resolver.ELSegment; import org.jboss.tools.common.el.core.resolver.JavaMemberELSegment; import org.jboss.tools.common.el.core.resolver.TypeInfoCollector; import org.jboss.tools.common.model.project.IModelNature; import org.jboss.tools.common.model.util.EclipseResourceUtil; /** * @author Alexey Kazakov */ public class JSFImplicitObjectELResolver extends JSFELCompletionEngine { private static final String FACES_CONTEXT = "facesContext"; //$NON-NLS-1$ private static final Map<String, ELExpression> IMPLICT_OBJECTS_ELS = new HashMap<String, ELExpression>(); static { IMPLICT_OBJECTS_ELS.put("application", parseEl("#{facesContext.externalContext.context}")); //$NON-NLS-1$ //$NON-NLS-2$ IMPLICT_OBJECTS_ELS.put("applicationScope", parseEl("#{facesContext.externalContext.applicationMap}")); //$NON-NLS-1$ //$NON-NLS-2$ IMPLICT_OBJECTS_ELS.put("cookie", parseEl("#{facesContext.externalContext.requestCookieMap}")); //$NON-NLS-1$ //$NON-NLS-2$ IMPLICT_OBJECTS_ELS.put("header", parseEl("#{facesContext.externalContext.requestHeaderMap}")); //$NON-NLS-1$ //$NON-NLS-2$ IMPLICT_OBJECTS_ELS.put("headerValues", parseEl("#{facesContext.externalContext.requestHeaderValuesMap}")); //$NON-NLS-1$ //$NON-NLS-2$ IMPLICT_OBJECTS_ELS.put("initParam", parseEl("#{facesContext.externalContext.initParameterMap}")); //$NON-NLS-1$ //$NON-NLS-2$ IMPLICT_OBJECTS_ELS.put("param", parseEl("#{facesContext.externalContext.requestParameterMap}")); //$NON-NLS-1$ //$NON-NLS-2$ IMPLICT_OBJECTS_ELS.put("paramValues", parseEl("#{facesContext.externalContext.requestParameterValuesMap}")); //$NON-NLS-1$ //$NON-NLS-2$ IMPLICT_OBJECTS_ELS.put("request", parseEl("#{facesContext.externalContext.request}")); //$NON-NLS-1$ //$NON-NLS-2$ IMPLICT_OBJECTS_ELS.put("requestScope", parseEl("#{facesContext.externalContext.requestMap}")); //$NON-NLS-1$ //$NON-NLS-2$ // IMPLICT_OBJECTS_ELS.put("session", parseEl("#{facesContext.externalContext.getSession()}")); IMPLICT_OBJECTS_ELS.put("session", parseEl("#{facesContext.externalContext.request}")); // FIXME we should fix EL resolving for methods with arguments (e.g. #{facesContext.externalContext.getSession(true)}) See https://jira.jboss.org/jira/browse/JBIDE-4580 //$NON-NLS-1$ //$NON-NLS-2$ IMPLICT_OBJECTS_ELS.put("sessionScope", parseEl("#{facesContext.externalContext.sessionMap}")); //$NON-NLS-1$ //$NON-NLS-2$ IMPLICT_OBJECTS_ELS.put("view", parseEl("#{facesContext.viewRoot}")); //$NON-NLS-1$ //$NON-NLS-2$ } private IFile file; /* * (non-Javadoc) * @see org.jboss.tools.jst.web.kb.el.AbstractELCompletionEngine#resolveVariables(org.eclipse.core.resources.IFile, org.jboss.tools.common.el.core.model.ELInvocationExpression, boolean, boolean) */ @Override public List<IJSFVariable> resolveVariables(IFile file, ELContext context, ELInvocationExpression expr, boolean isFinal, boolean onlyEqualNames, int offset) { this.file = file; return super.resolveVariables(file, context, expr, isFinal, onlyEqualNames, offset); } /* * (non-Javadoc) * @see org.jboss.tools.jsf.model.JSFELCompletionEngine#resolveVariables(org.jboss.tools.common.model.project.IModelNature, java.lang.String, boolean, int) */ @Override protected List<IJSFVariable> resolveVariables(IModelNature project, ELContext context, String varName, boolean onlyEqualNames, int offset) { if(file.getProject() == null) { return null; } List<IJSFVariable> resolvedVariables = new ArrayList<IJSFVariable>(); if(onlyEqualNames) { if(FACES_CONTEXT.equals(varName)) { return getFacesContextVariable(); } } else { if(FACES_CONTEXT.startsWith(varName)) { resolvedVariables.addAll(getFacesContextVariable()); } } Set<String> vars = IMPLICT_OBJECTS_ELS.keySet(); List<String> elVars = new ArrayList<String>(); for (String var : vars) { if(onlyEqualNames) { if(var.equals(varName)) { elVars.add(var); } } else if(var.startsWith(varName)) { elVars.add(var); } } for (String var : elVars) { try { ELResolution resolution = resolveEL(file, context, IMPLICT_OBJECTS_ELS.get(var), false, offset); if(resolution!=null && resolution.isResolved()) { ELSegment segment = resolution.getLastSegment(); if(segment instanceof JavaMemberELSegment) { TypeInfoCollector.MemberInfo info = ((JavaMemberELSegment)segment).getMemberInfo(); if(info!=null) { IType type = info.getMemberType(); if(type!=null) { resolvedVariables.add(new Variable(var, type)); } } } } } catch (StringIndexOutOfBoundsException e) { log(e); } catch (BadLocationException e) { log(e); } } return resolvedVariables; } private static ELExpression parseEl(String el) { if(el.length()>3 && el.startsWith("#{") && el.endsWith("}")) { //$NON-NLS-1$ //$NON-NLS-2$ ELParser parser = ELParserUtil.getDefaultFactory().createParser(); ELModel model = parser.parse(el); if(model == null || model.getSyntaxErrors().size() > 0) { return null; } List<ELInstance> is = model.getInstances(); if(is.size() == 0) { return null; } return is.get(0).getExpression(); } return null; } private List<IJSFVariable> getFacesContextVariable() { IJavaProject jp = EclipseResourceUtil.getJavaProject(file.getProject()); List<IJSFVariable> list = new ArrayList<IJSFVariable>(); try { IType type = jp.findType("javax.faces.context.FacesContext"); //$NON-NLS-1$ list.add(new Variable(FACES_CONTEXT, type)); } catch (JavaModelException e) { log(e); } return list; } }