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