/******************************************************************************* * Copyright (c) 2007 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.seam.ui.views.properties; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.jface.fieldassist.ContentProposalAdapter; import org.eclipse.jface.fieldassist.IContentProposal; import org.eclipse.jface.fieldassist.IContentProposalProvider; import org.eclipse.jface.viewers.LabelProvider; import org.jboss.tools.common.el.core.ca.AbstractELCompletionEngine; 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.model.ELUtil; import org.jboss.tools.common.el.core.resolver.SimpleELContext; import org.jboss.tools.common.meta.XAttribute; import org.jboss.tools.common.meta.action.XEntityData; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.filesystems.FileSystemsHelper; import org.jboss.tools.common.model.ui.attribute.AttributeContentProposalProviderFactory; import org.jboss.tools.common.model.ui.attribute.IAttributeContentProposalProvider; import org.jboss.tools.common.text.TextProposal; import org.jboss.tools.seam.core.ISeamProject; import org.jboss.tools.seam.core.SeamCorePlugin; import org.jboss.tools.seam.internal.core.el.SeamELCompletionEngine; /** * @author Viacheslav Kabanovich */ public class SeamELAttributeContentProposalProvider implements IAttributeContentProposalProvider { XModelObject object; XAttribute attribute; IFile file; SeamELCompletionEngine engine; public boolean isRelevant(XModelObject object, XAttribute attribute) { if(attribute == null) { return false; } String module = attribute.getModelEntity().getModule(); if(module == null || !module.startsWith("Seam")) { return false; } String entity = attribute.getModelEntity().getName(); if(entity.startsWith("File")) { return false; } return true; } public IContentProposalProvider getContentProposalProvider() { if(file == null || engine == null) return null; return new ContentProposalProvider(); } public int getProposalAcceptanceStyle() { return ContentProposalAdapter.PROPOSAL_INSERT; } public void init(XModelObject object, XEntityData data, XAttribute attribute) { this.object = object; this.attribute = attribute; object = FileSystemsHelper.getFile(object); if(object != null) { IResource r = (IResource)object.getAdapter(IResource.class); if(r instanceof IFile) { file = (IFile)r; } } if(file != null) { IProject project = file.getProject(); ISeamProject seamProject = SeamCorePlugin.getSeamProject(project, true); if(seamProject != null) { engine = new SeamELCompletionEngine(); } } } static IContentProposal[] EMPTY = new IContentProposal[0]; class ContentProposalProvider implements IContentProposalProvider { public IContentProposal[] getProposals(String contents, int position) { ELModel model = engine.getParserFactory().createParser().parse(contents); ELInstance is = ELUtil.findInstance(model, position); if(is == null) { return EMPTY; } boolean addClosingToken = is.getOpenInstanceToken() != null && is.getCloseInstanceToken() == null; String prefix = getPrefix(contents, position, 0, contents.length()); if(prefix == null || prefix.length() == 0) { if(!isExpressionAllowed(contents, position)) { return EMPTY; } } if(prefix == null) prefix = ""; List<TextProposal> suggestions = null; SimpleELContext context = new SimpleELContext(); context.setResource(file); suggestions = engine.getProposals(context, prefix, -1); if(suggestions == null) { return EMPTY; } List<TextProposal> uniqueSuggestions = AbstractELCompletionEngine.makeProposalsUnique(suggestions); List<IContentProposal> list = new ArrayList<IContentProposal>(); for (TextProposal p: uniqueSuggestions) { String label = prefix + p.getReplacementString(); IContentProposal cp = AttributeContentProposalProviderFactory.makeContentProposal(p.getReplacementString() + (addClosingToken ? "}" : ""), label, null); list.add(cp); } return list.toArray(new IContentProposal[0]); } } public String getPrefix(String content, int offset, int start, int end) throws StringIndexOutOfBoundsException { if (content == null || offset > content.length()) return null; ELInvocationExpression expr = engine.findExpressionAtOffset(content, offset, start, end); if (expr == null) return null; return content.substring(expr.getStartPosition(), offset); } private boolean isExpressionAllowed(String contents, int position) { String el = contents.substring(0, position) + "a"; ELModel model1 = engine.getParserFactory().createParser().parse(el); ELInvocationExpression expr = ELUtil.findExpression(model1, el.length()); return (expr != null); } public void dispose() { object = null; attribute = null; file = null; engine = null; } public LabelProvider getCustomLabelProbider() { return null; } }