/******************************************************************************* * 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; } }