/*******************************************************************************
* Copyright (c) 2007-2013 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
*
* Contributor:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.jsf.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.graphics.Image;
import org.jboss.tools.common.el.core.ca.AbstractELCompletionEngine;
import org.jboss.tools.common.el.core.ca.ELTextProposal;
import org.jboss.tools.common.el.core.model.ELArgumentInvocation;
import org.jboss.tools.common.el.core.model.ELExpression;
import org.jboss.tools.common.el.core.model.ELInvocationExpression;
import org.jboss.tools.common.el.core.model.ELObjectType;
import org.jboss.tools.common.el.core.model.ELPropertyInvocation;
import org.jboss.tools.common.el.core.parser.ELParser;
import org.jboss.tools.common.el.core.parser.ELParserFactory;
import org.jboss.tools.common.el.core.parser.ELParserUtil;
import org.jboss.tools.common.el.core.parser.LexicalToken;
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.ELResolutionImpl;
import org.jboss.tools.common.el.core.resolver.ELSegment;
import org.jboss.tools.common.el.core.resolver.ELSegmentImpl;
import org.jboss.tools.common.el.core.resolver.IOpenableReference;
import org.jboss.tools.common.el.core.resolver.IRelevanceCheck;
import org.jboss.tools.common.el.core.resolver.IVariable;
import org.jboss.tools.common.el.core.resolver.JavaMemberELSegmentImpl;
import org.jboss.tools.common.el.core.resolver.TypeInfoCollector;
import org.jboss.tools.common.el.core.resolver.TypeInfoCollector.MemberInfo;
import org.jboss.tools.common.model.XModelObject;
import org.jboss.tools.common.model.util.EclipseJavaUtil;
import org.jboss.tools.common.model.util.EclipseResourceUtil;
import org.jboss.tools.common.model.util.FindObjectHelper;
import org.jboss.tools.common.text.TextProposal;
import org.jboss.tools.common.text.ext.hyperlink.xpl.Messages;
import org.jboss.tools.jsf.JSFModelPlugin;
import org.jboss.tools.jsf.jsf2.model.CompositeComponentConstants;
import org.jboss.tools.jsf.model.JSFELCompletionEngine.IJSFVariable;
import org.jboss.tools.jst.web.kb.IXmlContext;
import org.jboss.tools.jst.web.kb.PageContextFactory;
/**
*
* @author V. Kabanovich
*
*/
public class JSF2CCAttrsELCompletionEngine extends AbstractELCompletionEngine<IVariable> {
private static final ImageDescriptor JSF2_EL_CC_ATTRS_PROPOSAL_IMAGE = JSFModelPlugin.getDefault().getImageDescriptorFromRegistry(JSFModelPlugin.CA_JSF_MESSAGES_IMAGE_PATH);
/*
* (non-Javadoc)
* @see org.jboss.tools.common.el.core.ca.AbstractELCompletionEngine#getELProposalImageForMember(org.jboss.tools.common.el.core.resolver.TypeInfoCollector.MemberInfo)
*/
@Override
public ImageDescriptor getELProposalImageForMember(MemberInfo memberInfo) {
return JSF2_EL_CC_ATTRS_PROPOSAL_IMAGE;
}
private static ELParserFactory factory = ELParserUtil.getDefaultFactory();
public JSF2CCAttrsELCompletionEngine() {}
/*
* (non-Javadoc)
* @see org.jboss.tools.common.el.core.resolver.ELResolver#getParserFactory()
*/
public ELParserFactory getParserFactory() {
return factory;
}
/*
* (non-Javadoc)
* @see org.jboss.tools.common.el.core.ca.AbstractELCompletionEngine#log(java.lang.Exception)
*/
protected void log(Exception e) {
JSFModelPlugin.getPluginLog().logError(e);
}
/*
* (non-Javadoc)
* @see org.jboss.tools.common.el.core.resolver.ELResolver2#getProposals(org.jboss.tools.common.el.core.resolver.ELContext, java.lang.String)
*/
public List<TextProposal> getProposals(ELContext context, String el, int offset) {
return getCompletions(el, false, 0, context);
}
public List<TextProposal> getCompletions(String elString,
boolean returnEqualedVariablesOnly, int position, ELContext context) {
IDocument document = null;
List<TextProposal> proposals = null;
try {
proposals = getCompletions(context.getResource(), context, document, elString.subSequence(0, elString.length()), position, returnEqualedVariablesOnly);
} catch (StringIndexOutOfBoundsException e) {
log(e);
} catch (BadLocationException e) {
log(e);
}
return proposals;
}
/*
* (non-Javadoc)
* @see org.jboss.tools.common.el.core.resolver.ELResolver2#resolve(org.jboss.tools.common.el.core.resolver.ELContext, org.jboss.tools.common.el.core.model.ELExpression)
*/
public ELResolution resolve(ELContext context, ELExpression operand, int offset) {
if(context instanceof IXmlContext) {
Set<String> uris = ((IXmlContext)context).getURIs();
if(uris.contains(CompositeComponentConstants.COMPOSITE_XMLNS)
|| uris.contains(CompositeComponentConstants.COMPOSITE_XMLNS_2_2)) {
ELResolutionImpl resolution = resolveELOperand(operand, context, true, offset);
if(resolution != null)
resolution.setContext(context);
return resolution;
}
}
return null;
}
public ELResolutionImpl resolveELOperand(ELExpression operand,
ELContext context, boolean returnEqualedVariablesOnly, int offset) {
try {
return resolveELOperand(context.getResource(), context, operand, returnEqualedVariablesOnly, offset);
} catch (StringIndexOutOfBoundsException e) {
log(e);
} catch (BadLocationException e) {
log(e);
}
return null;
}
public List<TextProposal> getCompletions(IFile file, ELContext context, IDocument document, CharSequence prefix,
int position, boolean returnEqualedVariablesOnly) throws BadLocationException, StringIndexOutOfBoundsException {
List<TextProposal> completions = new ArrayList<TextProposal>();
ELResolutionImpl status = resolveELOperand(file, context, parseOperand("" + prefix), returnEqualedVariablesOnly, position); //$NON-NLS-1$
if(status!=null) {
completions.addAll(status.getProposals());
}
return completions;
}
public ELResolutionImpl resolveELOperand(IFile file, ELContext context,
ELExpression operand, boolean returnEqualedVariablesOnly, int offset)
throws BadLocationException, StringIndexOutOfBoundsException {
if(!(operand instanceof ELInvocationExpression) || file == null) {
return null;
}
ELInvocationExpression expr = (ELInvocationExpression)operand;
boolean isIncomplete = expr.getType() == ELObjectType.EL_PROPERTY_INVOCATION
&& ((ELPropertyInvocation)expr).getName() == null;
boolean isArgument = expr.getType() == ELObjectType.EL_ARGUMENT_INVOCATION;
ELResolutionImpl resolution = new ELResolutionImpl(expr);
ELInvocationExpression left = expr;
List<IVariable> resolvedVariables = EMPTY_VARIABLES_LIST;
if (expr.getLeft() != null && isArgument) {
left = expr.getLeft();
resolvedVariables = resolveVariablesInternal(file, left, false,
true); // is Final and equal names are because of
// we have no more to resolve the parts of expression,
// but we have to resolve arguments of probably a message component
} else if (expr.getLeft() == null && isIncomplete) {
resolvedVariables = resolveVariablesInternal(file, expr, true,
returnEqualedVariablesOnly);
} else {
while(left != null) {
List<IVariable> resolvedVars = resolveVariablesInternal(file,
left, left == expr,
returnEqualedVariablesOnly);
if (resolvedVars != null && !resolvedVars.isEmpty()) {
resolvedVariables = resolvedVars;
resolution.setLastResolvedToken(left);
JSF2CCAttrELSegmentImpl segment = new JSF2CCAttrELSegmentImpl(combineLexicalTokensForExpression(left));
segment.setVarName(left.toString());
segment.setResource(this.currentFile);
segment.setResolved(true);
resolution.addSegment(segment);
break;
}
left = (ELInvocationExpression)left.getLeft();
}
}
if (resolution.getLastResolvedToken() == null &&
!returnEqualedVariablesOnly &&
expr != null &&
isIncomplete) {
// no vars are resolved
// the tokens are the part of var name ended with a separator (.)
resolvedVariables = resolveVariablesInternal(file, expr, true, returnEqualedVariablesOnly);
Set<TextProposal> proposals = new TreeSet<TextProposal>(TextProposal.KB_PROPOSAL_ORDER);
ELSegmentImpl segment = new ELSegmentImpl(expr.getFirstToken());
segment.setResolved(false);
resolution.addSegment(segment);
for (IVariable var : resolvedVariables) {
String varName = var.getName();
if(varName.startsWith(operand.getText())) {
ELTextProposal proposal = new ELTextProposal();
proposal.setReplacementString(varName.substring(operand.getLength()));
proposal.setImageDescriptor(getELProposalImageForMember(null));
proposals.add(proposal);
}
}
resolution.setProposals(proposals);
segment.setResolved(!proposals.isEmpty());
return resolution;
}
// Here we have a list of vars for some part of expression
// OK. we'll proceed with members of these vars
if (resolution.getLastResolvedToken() == operand) {
// First segment is the last one
Set<TextProposal> proposals = new TreeSet<TextProposal>(TextProposal.KB_PROPOSAL_ORDER);
ELSegmentImpl segment = new ELSegmentImpl(operand.getFirstToken());
segment.setResolved(true);
resolution.addSegment(segment);
for (IVariable var : resolvedVariables) {
String varName = var.getName();
if(operand.getLength()<=varName.length()) {
ELTextProposal proposal = new ELTextProposal();
proposal.setReplacementString(varName.substring(operand.getLength()));
proposal.setLabel(varName);
proposal.setImageDescriptor(getELProposalImageForMember(null));
proposals.add(proposal);
} else if(returnEqualedVariablesOnly) {
TextProposal proposal = new TextProposal();
proposal.setReplacementString(varName);
proposal.setLabel(varName);
proposal.setImageDescriptor(getELProposalImageForMember(null));
proposals.add(proposal);
}
segment.getVariables().add(var);
}
resolution.setLastResolvedToken(expr);
resolution.setProposals(proposals);
return resolution;
}
if(!resolvedVariables.isEmpty() && resolvedVariables.iterator().next() instanceof IJSFVariable) {
return buildJavaResolution(resolution, context, left, expr, operand, resolvedVariables, returnEqualedVariablesOnly, offset);
}
//process segments one by one
if(left != null) {
while(left != expr) {
left = (ELInvocationExpression)left.getParent();
if (left != expr) { // inside expression
ELSegmentImpl segment = new ELSegmentImpl(left.getLastToken());
segment.setResolved(true);
resolution.addSegment(segment);
resolution.setLastResolvedToken(left);
return resolution;
} else { // Last segment
resolveLastSegment((ELInvocationExpression)operand, resolvedVariables, resolution, returnEqualedVariablesOnly);
break;
}
}
} else {
ELSegmentImpl segment = new ELSegmentImpl(expr.getFirstToken());
resolution.addSegment(segment);
}
return resolution;
}
//Method content copies code from the end AbstractELCompletionEngine.resolveELOperand
ELResolutionImpl buildJavaResolution(ELResolutionImpl resolution, ELContext context, ELInvocationExpression left, ELInvocationExpression expr,
ELExpression operand, List<IVariable> resolvedVariables, boolean returnEqualedVariablesOnly, int offset) {
boolean varIsUsed = false;
// First segment is found - proceed with next tokens
List<TypeInfoCollector.MemberInfo> members = new ArrayList<TypeInfoCollector.MemberInfo>();
JavaMemberELSegmentImpl segment = new JavaMemberELSegmentImpl(expr.getFirstToken());
for (IVariable var : resolvedVariables) {
TypeInfoCollector.MemberInfo member = getMemberInfoByVariable(var, context, returnEqualedVariablesOnly, offset);
if (member != null && !members.contains(member)) {
members.add(member);
segment.setMemberInfo(member);
segment.getVariables().add(var);
segment.setResolved(true);
}
}
resolution.addSegment(segment);
//process segments one by one
if(left != null) {
while(left != expr) {
left = (ELInvocationExpression)left.getParent();
if (left != expr) { // inside expression
segment = new JavaMemberELSegmentImpl(left.getLastToken());
if(left instanceof ELArgumentInvocation) {
String s = "#{" + left.getLeft().toString() + collectionAdditionForCollectionDataModel + "}"; //$NON-NLS-1$ //$NON-NLS-2$
ELParser p = getParserFactory().createParser();
ELInvocationExpression expr1 = (ELInvocationExpression)p.parse(s).getInstances().get(0).getExpression();
members = resolveSegment(expr1.getLeft(), members, resolution, returnEqualedVariablesOnly, varIsUsed, segment);
members = resolveSegment(expr1, members, resolution, returnEqualedVariablesOnly, varIsUsed, segment);
if(resolution.getLastResolvedToken() == expr1) {
resolution.setLastResolvedToken(left);
}
} else {
members = resolveSegment(left, members, resolution, returnEqualedVariablesOnly, varIsUsed, segment);
}
if(!members.isEmpty()) {
segment.setResolved(true);
segment.setMemberInfo(members.get(0)); // TODO: This is a buggy way to select a member to setup in a segment
}
resolution.addSegment(segment);
} else { // Last segment
resolveLastSegment((ELInvocationExpression)operand, members, resolution, returnEqualedVariablesOnly, varIsUsed);
break;
}
}
}
if(resolution.getProposals().isEmpty() && !resolution.getSegments().isEmpty()) {
// && status.getUnpairedGettersOrSetters()!=null) {
ELSegment lastSegment = resolution.getSegments().get(resolution.getSegments().size()-1);
if(lastSegment instanceof JavaMemberELSegmentImpl) {
((JavaMemberELSegmentImpl)lastSegment).clearUnpairedGettersOrSetters();
}
}
return resolution;
}
static String[] vs = {"cc.attrs", "compositeComponent.attrs"};
private IFile currentFile;
private ELContext currentContext;
private XModelObject currentXModelObject;
public List<IVariable> resolveVariablesInternal(IFile file, ELInvocationExpression expr, boolean isFinal, boolean onlyEqualNames) {
ELContext context = null;
if(currentXModelObject==null || currentFile!=file || (context = PageContextFactory.createPageContext(file))!=currentContext) {
currentXModelObject = EclipseResourceUtil.createObjectForResource(file);
currentFile = file;
if(currentContext!=context) {
if(currentXModelObject == null) return Collections.emptyList();
String entity = currentXModelObject.getModelEntity().getName();
if(!entity.startsWith(CompositeComponentConstants.ENT_FILE_COMPONENT)) {
return Collections.emptyList();
}
}
currentContext = context;
}
List<IVariable> result = EMPTY_VARIABLES_LIST;
String varName = expr.toString();
for (int i = 0; i < vs.length; i++) {
String name = vs[i];
if(!isFinal || onlyEqualNames) {
if(!name.equals(varName)) continue;
}
if(!name.startsWith(varName)) continue;
if(varName.lastIndexOf('.') > name.length()) continue; //It is the java variable case
Variable v = new Variable(name, file);
if(result == EMPTY_VARIABLES_LIST){
result = new ArrayList<IVariable>();
}
result.add(v);
break;
}
if(currentXModelObject != null && result.isEmpty()) {
IJavaProject javaProject = EclipseResourceUtil.getJavaProject(file.getProject());
XModelObject is = currentXModelObject.getChildByPath("Interface");
if(is != null && javaProject != null) {
XModelObject[] cs = is.getChildren("JSF2ComponentAttribute");
for (int i = 0; i < cs.length; i++) {
String name = cs[i].getAttributeValue("name");
String type = cs[i].getAttributeValue("type");
if(type == null || type.length() == 0) continue;
String[] names = {vs[0] + "." + name, vs[1] + "." + name};
for (String n: names) {
boolean match = (!isFinal || onlyEqualNames) ? n.equals(varName) : false;
if(!match) continue;
IType javaType = null;
try {
javaType = EclipseJavaUtil.findType(javaProject, type);
} catch (JavaModelException e) {
}
if(javaType == null) continue;
IVariable v = new JSFELCompletionEngine.Variable(n, javaType);
if(result == EMPTY_VARIABLES_LIST){
result = new ArrayList<IVariable>();
}
result.add(v);
}
}
}
}
return result;
}
protected void resolveLastSegment(ELInvocationExpression expr,
List<IVariable> members,
ELResolutionImpl resolution,
boolean returnEqualedVariablesOnly) {
Set<TextProposal> kbProposals = new TreeSet<TextProposal>(TextProposal.KB_PROPOSAL_ORDER);
JSF2CCAttrELSegmentImpl segment = new JSF2CCAttrELSegmentImpl(expr.getFirstToken());
segment.setResource(this.currentFile);
segment.setVarName(expr.toString());
resolution.setProposals(kbProposals);
if(expr instanceof ELPropertyInvocation) {
segment.setToken(((ELPropertyInvocation)expr).getName());
}
if(segment.getToken()!=null) {
resolution.addSegment(segment);
}
if (expr.getType() == ELObjectType.EL_PROPERTY_INVOCATION && ((ELPropertyInvocation)expr).getName() == null) {
// return all the methods + properties
for (IVariable mbr : members) {
processSingularMember(mbr, kbProposals);
}
} else
if(expr.getType() != ELObjectType.EL_ARGUMENT_INVOCATION) {
Set<String> proposalsToFilter = new TreeSet<String>();
for (IVariable mbr : members) {
filterSingularMember(mbr, proposalsToFilter);
}
for (String proposal : proposalsToFilter) {
// We do expect nothing but name for method tokens (No round brackets)
String filter = expr.getMemberName();
if(filter == null) filter = ""; //$NON-NLS-1$
if(returnEqualedVariablesOnly) {
// This is used for validation.
if (proposal.equals(filter)) {
TextProposal kbProposal = new TextProposal();
kbProposal.setReplacementString(proposal);
kbProposal.setLabel(proposal);
kbProposal.setImageDescriptor(getELProposalImageForMember(null));
kbProposals.add(kbProposal);
break;
}
} else if (proposal.startsWith(filter)) {
// This is used for CA.
ELTextProposal kbProposal = new ELTextProposal();
kbProposal.setReplacementString(proposal.substring(filter.length()));
kbProposal.setLabel(proposal);
kbProposal.setImageDescriptor(getELProposalImageForMember(null));
kbProposals.add(kbProposal);
}
}
} else if(expr.getType() == ELObjectType.EL_ARGUMENT_INVOCATION) {
Set<String> proposalsToFilter = new TreeSet<String>();
boolean isMessages = false;
for (IVariable mbr : members) {
isMessages = true;
filterSingularMember(mbr, proposalsToFilter);
}
String filter = expr.getMemberName();
boolean bSurroundWithQuotes = false;
if(filter == null) {
filter = ""; //$NON-NLS-1$
bSurroundWithQuotes = true;
} else {
boolean b = filter.startsWith("'") || filter.startsWith("\""); //$NON-NLS-1$ //$NON-NLS-2$
boolean e = filter.endsWith("'") || filter.endsWith("\""); //$NON-NLS-1$ //$NON-NLS-2$
if((b) && (e)) {
filter = filter.length() == 1 ? "" : filter.substring(1, filter.length() - 1); //$NON-NLS-1$
} else if(b && !returnEqualedVariablesOnly) {
filter = filter.substring(1);
} else {
//Value is set as expression itself, we cannot compute it
if(isMessages) {
resolution.setMapOrCollectionOrBundleAmoungTheTokens(true);
}
return;
}
}
for (String proposal : proposalsToFilter) {
if(returnEqualedVariablesOnly) {
// This is used for validation.
if (proposal.equals(filter)) {
TextProposal kbProposal = new TextProposal();
kbProposal.setReplacementString(proposal);
kbProposal.setLabel(proposal);
kbProposal.setImageDescriptor(getELProposalImageForMember(null));
kbProposals.add(kbProposal);
break;
}
} else if (proposal.startsWith(filter)) {
// This is used for CA.
ELTextProposal kbProposal = new ELTextProposal();
String replacementString = proposal.substring(filter.length());
if (bSurroundWithQuotes) {
replacementString = "'" + replacementString + "']"; //$NON-NLS-1$ //$NON-NLS-2$
}
kbProposal.setReplacementString(replacementString);
kbProposal.setLabel(proposal);
kbProposal.setImageDescriptor(getELProposalImageForMember(null));
kbProposals.add(kbProposal);
}
}
}
segment.setResolved(!kbProposals.isEmpty());
if (resolution.isResolved()){
resolution.setLastResolvedToken(expr);
}
}
protected void processSingularMember(IVariable mbr, Set<TextProposal> kbProposals) {
// Surround the "long" keys containing the dots with [' ']
TreeSet<String> keys = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
keys.addAll(((Variable)mbr).getKeys());
Iterator<String> sortedKeys = keys.iterator();
while(sortedKeys.hasNext()) {
String key = sortedKeys.next();
if (key == null || key.length() == 0)
continue;
if (key.indexOf('.') != -1) {
ELTextProposal proposal = new ELTextProposal();
proposal.setReplacementString("['" + key + "']"); //$NON-NLS-1$ //$NON-NLS-2$
proposal.setLabel("['" + key + "']");
proposal.setImageDescriptor(getELProposalImageForMember(null));
kbProposals.add(proposal);
} else {
ELTextProposal proposal = new ELTextProposal();
proposal.setReplacementString(key);
proposal.setLabel(key);
proposal.setImageDescriptor(getELProposalImageForMember(null));
kbProposals.add(proposal);
}
}
}
protected void filterSingularMember(IVariable mbr, Set<String> proposalsToFilter) {
Collection<String> keys = ((Variable)mbr).getKeys();
for (String key : keys) {
proposalsToFilter.add(key);
}
}
static String[] COMMON_ATTRS = {"onclick", "ondblclick", "onkeydown", "onkeypress", "onkeyup", "onmousedown", "onmousemove", "onmouseout", "onmouseover", "onmouseup"};
static class Variable implements IVariable {
IFile f;
String name;
public Variable(String name, IFile f) {
this.name = name;
this.f = f;
}
public String getName() {
return name;
}
public Collection<String> getKeys() {
TreeSet<String> result = new TreeSet<String>();
XModelObject o = EclipseResourceUtil.createObjectForResource(f);
if(o == null || !JSF2CCAttrELSegmentImpl.isComponent(o)) return result;
for (int i = 0; i < COMMON_ATTRS.length; i++) {
result.add(COMMON_ATTRS[i]);
}
XModelObject is = o.getChildByPath("Interface");
if(is == null) return result;
XModelObject[] cs = is.getChildren("JSF2ComponentAttribute");
for (int i = 0; i < cs.length; i++) {
result.add(cs[i].getAttributeValue("name"));
}
return result;
}
}
/*
* (non-Javadoc)
* @see org.jboss.tools.common.el.core.ca.AbstractELCompletionEngine#getMemberInfoByVariable(org.jboss.tools.common.el.core.resolver.IVariable, boolean)
*/
@Override
protected MemberInfo getMemberInfoByVariable(IVariable var, ELContext context,
boolean onlyEqualNames, int offset) {
if(var instanceof IJSFVariable) {
return TypeInfoCollector.createMemberInfo(((IJSFVariable)var).getSourceMember());
}
return null;
}
/*
* (non-Javadoc)
* @see org.jboss.tools.common.el.core.ca.AbstractELCompletionEngine#resolveVariables(org.eclipse.core.resources.IFile, org.jboss.tools.common.el.core.model.ELInvocationExpression, boolean, boolean)
*/
@Override
public List<IVariable> resolveVariables(IFile file, ELContext context,
ELInvocationExpression expr, boolean isFinal, boolean onlyEqualNames, int offset) {
return resolveVariablesInternal(file, expr, isFinal, onlyEqualNames);
}
@Override
protected boolean isStaticMethodsCollectingEnabled() {
return false;
}
public IRelevanceCheck createRelevanceCheck(IJavaElement element) {
return IRRELEVANT;
}
}
class JSF2CCAttrELSegmentImpl extends ELSegmentImpl {
String varName;
IFile file;
public JSF2CCAttrELSegmentImpl(LexicalToken token) {
super(token);
}
public void setVarName(String s) {
varName = s;
}
public void setResource(IFile f) {
file = f;
super.setResource(f);
}
public IOpenableReference[] getOpenable() {
final XModelObject o = findJSF2CCAttributeXModelObject(varName, file);
if(o != null) {
IOpenableReference openable = new IOpenableReference() {
@Override
public boolean open() {
int q = FindObjectHelper.findModelObject(o, FindObjectHelper.IN_EDITOR_ONLY);
return q == 0;
}
@Override
public String getLabel() {
return Messages.OpenJsf2CCAttribute;
}
@Override
public Image getImage() {
return null;
}
};
return new IOpenableReference[]{openable};
}
return new IOpenableReference[0];
}
static String[] vs = {"cc.attrs", "compositeComponent.attrs"}; //$NON-NLS-1$ //$NON-NLS-2$
static boolean isComponent(XModelObject object) {
String entity = object.getModelEntity().getName();
return entity.startsWith(CompositeComponentConstants.ENT_FILE_COMPONENT);
}
public static XModelObject findJSF2CCAttributeXModelObject(String varName, IFile file) {
XModelObject xModelObject = EclipseResourceUtil.createObjectForResource(file);
if(xModelObject == null || !isComponent(xModelObject)) return null;
IJavaProject javaProject = EclipseResourceUtil.getJavaProject(file.getProject());
XModelObject is = xModelObject.getChildByPath("Interface");
if(is != null && javaProject != null) {
for (int i = 0; i < vs.length; i++) {
if (vs[i].equals(varName)) return is;
}
XModelObject[] cs = is.getChildren("JSF2ComponentAttribute");
for (int i = 0; i < cs.length; i++) {
String name = cs[i].getAttributeValue("name");
String[] names = {vs[0] + "." + name, vs[1] + "." + name};
for (String n: names) {
if (n.equals(varName)) return cs[i];
}
}
}
return null;
}
}