blob: 8f74b9550157fd2908f280ad1f5a51818119a317 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2012 Oracle Corporation and others.
* 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:
* Oracle Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.bpel.ui.contentassist;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.eclipse.bpel.fnmeta.model.Argument;
import org.eclipse.bpel.fnmeta.model.Function;
import org.eclipse.bpel.model.util.BPELConstants;
import org.eclipse.bpel.model.util.BPELUtils;
import org.eclipse.bpel.ui.BPELUIPlugin;
import org.eclipse.bpel.ui.IBPELUIConstants;
import org.eclipse.bpel.ui.expressions.Functions;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateCompletionProcessor;
import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.swt.graphics.Image;
/**
*
* @author Michal Chmielewski (michal.chmielewski@oracle.com)
* @date Oct 27, 2006
*
*/
@SuppressWarnings("nls")
public class FunctionTemplatesContentAssistProcessor extends TemplateCompletionProcessor {
static final String XPATH_FUNCTIONS = "xpath.functions";
/** Template context type */
TemplateContextType fTemplateContextType;
/** Build the templates */
Template[] fTemplates = {};
/** The context model object */
EObject fModel;
/**
* @param model
*/
public void setModel (Object model) {
assert model instanceof EObject : "argument is not an EObject";
fModel = (EObject) model;
}
/**
* @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getContextType(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
*/
@Override
protected TemplateContextType getContextType (ITextViewer viewer, IRegion region) {
if (fTemplateContextType == null) {
fTemplateContextType = new TemplateContextType (XPATH_FUNCTIONS,"XPath functions"); //$NON-NLS-1$
}
return fTemplateContextType;
}
/**
*
* @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getImage(org.eclipse.jface.text.templates.Template)
*/
@Override
protected Image getImage(Template template) {
return BPELUIPlugin.INSTANCE.getImage(IBPELUIConstants.ICON_EXPR_FUNCTION);
}
/**
* Compute the templates that we use as the completion proposals for our
* functions.
*
* @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getTemplates(java.lang.String)
*/
@Override
protected Template[] getTemplates (String contextTypeId) {
if ( XPATH_FUNCTIONS.equals ( contextTypeId )) {
if (fTemplates.length == 0) {
Map<String,Function> fnMap = Functions.getInstance(BPELConstants.XMLNS_XPATH_EXPRESSION_LANGUAGE).getFunctions();
List<Template> list = new ArrayList<Template>( fnMap.size() );
for(Function fn : fnMap.values() ) {
String ns = fn.getNamespace();
if (BPELUtils.isEmptyOrWhitespace(ns) || BPELConstants.XMLNS_XPATH_EXPRESSION_LANGUAGE.equals(ns) ) {
list.add(new Template (fn.getName(),fn.getHelp(),contextTypeId,getPattern(fn),true)) ;
} else {
String pfx = getPrefix ( ns , fn.getPrefix() );
if (pfx == null) {
continue ;
}
list.add(new Template (pfx + ":" + fn.getName(),fn.getHelp(),contextTypeId,getPattern(fn),true)) ;
}
}
fTemplates = list.toArray(fTemplates);
if (fTemplates.length > 1) {
Arrays.sort(fTemplates,new Comparator<Template> () {
public int compare(Template o1, Template o2) {
return o1.getName().compareTo(o2.getName() );
}
});
}
}
}
return fTemplates;
}
String getPrefix ( String ns , String preferredPrefix ) {
/**
* Namespaces must be mapped to a prefix as the template proposal is going
* to generate a proposal where the prefix is used.
*/
String pfx = BPELUtils.getNamespacePrefix (fModel, ns);
/** Valid, already mapped prefix */
if (BPELUtils.isEmptyOrWhitespace(pfx) == false) {
return pfx;
}
/** Not yet mapped */
pfx = preferredPrefix;
if (BPELUtils.isValidPrefixName(pfx) ) {
// problem
return null;
}
return pfx;
}
/** This has to be someplace else, as this really just XPath formatting */
@SuppressWarnings("boxing")
String getPattern( Function fn ) {
StringBuilder builder = new StringBuilder(128);
String ns = fn.getNamespace();
if (BPELUtils.isEmptyOrWhitespace(ns) == false && BPELConstants.XMLNS_XPATH_EXPRESSION_LANGUAGE.equals(ns) == false) {
// map the namespace prefix.
String pfx = getPrefix( ns, fn.getPrefix() );
// This must not be null here
assert (pfx != null) : "Prefix for ns=" + ns + " cannot be null here" ;
builder.append(pfx).append(":");
}
builder.append(fn.getName()).append("(");
int argCount = fn.getArguments().size();
for(Argument a : fn.getArguments()) {
builder.append("${").append(a.getName()).append("}");
switch (a.getOptionality()) {
case OPTIONAL :
builder.append("?");
break;
case OPTIONAL_MANY :
builder.append("*");
break;
case REQUIRED :
break;
}
builder.append(", ");
}
if (argCount > 0) {
// delete the last ", "
builder.setLength( builder.length() - 2);
}
builder.append(")");
return builder.toString();
}
}