/*******************************************************************************
* Copyright © 2005, 2013 IBM 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:
* IBM Corporation - initial API and implementation
*
*******************************************************************************/
package org.eclipse.edt.ide.ui.wizards;
import java.util.List;
import java.util.StringTokenizer;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.edt.compiler.core.IEGLConstants;
import org.eclipse.edt.compiler.core.ast.DefaultASTVisitor;
import org.eclipse.edt.compiler.core.ast.FunctionParameter;
import org.eclipse.edt.compiler.core.ast.NestedFunction;
import org.eclipse.edt.compiler.core.ast.Part;
import org.eclipse.edt.compiler.core.ast.Type;
import org.eclipse.edt.ide.core.model.EGLModelException;
import org.eclipse.edt.ide.core.model.IFunction;
import org.eclipse.edt.mof.egl.Member;
public class ExtractInterfaceOperation extends EGLFileOperation {
private ExtractInterfaceConfiguration configuration;
/**
* @param configuration
*/
public ExtractInterfaceOperation(ExtractInterfaceConfiguration configuration) {
super(configuration);
this.configuration = configuration;
}
public ExtractInterfaceOperation(ExtractInterfaceConfiguration configuration, ISchedulingRule rule) {
super(configuration, rule);
this.configuration = configuration;
}
/**
* returns the string of function's full signature, but it does NOT have "end", ";" or newLine at the end,
* caller needs to close it
* @param eglfunc
* @param currFilePkg
* @return
*/
static public String getFunctionFullSignature(NestedFunction eglfunc, String currFilePkg) {
StringBuffer strbuf = new StringBuffer();
strbuf.append(IEGLConstants.KEYWORD_FUNCTION);
strbuf.append(" "); //$NON-NLS-1$
strbuf.append(ExtractInterfaceConfiguration.getFunctionSimpleSignature(eglfunc, true, currFilePkg));
final int[] outparamCnt = new int[]{0};
if(eglfunc.hasReturnType()) {
strbuf.append(" "); //$NON-NLS-1$
strbuf.append(IEGLConstants.KEYWORD_RETURNS);
strbuf.append(" "); //$NON-NLS-1$
strbuf.append("("); //$NON-NLS-1$
//get fully qualifed return type if necessary
Type returnType = eglfunc.getReturnType();
String qualifiedReturnTypeString = ExtractInterfaceConfiguration.getQualifiedTypeString(returnType, currFilePkg, true);
strbuf.append(qualifiedReturnTypeString);
strbuf.append(")"); //$NON-NLS-1$
} else { //no return type
eglfunc.accept(new DefaultASTVisitor(){
public boolean visit(NestedFunction nestedFunction) {return true;}
public boolean visit(FunctionParameter functionParameter) {
if(functionParameter.getUseType() == FunctionParameter.UseType.OUT)
outparamCnt[0]++;
return false;
};
});
}
Member nestedFuncBinding = eglfunc.getName().resolveMember();
if(nestedFuncBinding != null) {
StringBuffer nameVal = new StringBuffer();
StringBuffer namespaceVal = new StringBuffer();
//use the function type binding, because annotation information is stored there
EGLFileConfiguration.getXMLAnnotationValueFromBinding(nestedFuncBinding, nameVal, namespaceVal);
//here is a senario, if the function has exact 1 out parameter(you could have more than one in, in/out params) and no return
//this out parameter should be at the end (validation makes sure of that)
//we need to make isLastParamReturnValue = yes
strbuf.append(getXMLAnnotationString(namespaceVal.toString(), nameVal.toString()));
} else {
if(outparamCnt[0] == 1) {
strbuf.append(getXMLAnnotationString(null, null));
}
}
return strbuf.toString();
}
static public String getFunctionFullSignature(IFunction func, String currFilePkg) throws EGLModelException {
StringBuffer strbuf = new StringBuffer();
strbuf.append(IEGLConstants.KEYWORD_FUNCTION);
strbuf.append(" "); //$NON-NLS-1$
strbuf.append(ExtractInterfaceConfiguration.getFunctionSimpleSignature(func, true, currFilePkg));
final int[] outparamCnt = new int[]{0};
if(func.getReturnTypeName() != null) {
strbuf.append(" "); //$NON-NLS-1$
strbuf.append(IEGLConstants.KEYWORD_RETURNS);
strbuf.append(" "); //$NON-NLS-1$
strbuf.append("("); //$NON-NLS-1$
//get fully qualifed return type if necessary
String returnTypeString = func.getReturnTypeName();
String returnTypePkg = func.getReturnTypePackage();
String qualifiedReturnTypeString = ExtractInterfaceConfiguration.getQualifiedTypeString(returnTypeString, returnTypePkg, currFilePkg);
strbuf.append(qualifiedReturnTypeString);
strbuf.append(")");
}
return strbuf.toString();
}
private String getAbstractFunctionDefinitionString(NestedFunction eglfunc, String currFilePkg) {
StringBuffer strbuf = new StringBuffer();
strbuf.append(getFunctionFullSignature(eglfunc, currFilePkg));
strbuf.append(";"); //$NON-NLS-1$
strbuf.append(newLine);
return strbuf.toString();
}
private StringBuffer getInterfaceString() {
StringBuffer strInterface = new StringBuffer(IEGLConstants.KEYWORD_INTERFACE);
strInterface.append(" "); //$NON-NLS-1$
strInterface.append(configuration.getInterfaceName());
Part boundServicePart = configuration.getTheBoundPart();
//need to get the annotation values
org.eclipse.edt.mof.egl.Type serviceNameBinding = boundServicePart.getName().resolveType();
if(serviceNameBinding != null) {
StringBuffer nameVal = new StringBuffer();
StringBuffer namespaceVal = new StringBuffer();
EGLFileConfiguration.getXMLAnnotationValueFromBinding(serviceNameBinding, nameVal, namespaceVal);
strInterface.append(getXMLAnnotationString(namespaceVal.toString(), nameVal.toString()));
} else {
String serviceSimpleName = configuration.getTheBoundPart().getIdentifier();
//use the service name as the element name
//senario: service => wsdl file(portType is the service name)
// service => extract to interface, the interface name is prepended with "I",
// in order to match portType in the wsdl file
// set the element name of the interface to be service name
//TODO: add SOAP feature
String servicePackage = configuration.getOriginalServicePackage();
strInterface.append(getXMLAnnotationString(createNamespace(servicePackage), serviceSimpleName));
}
strInterface.append(newLine);
strInterface.append(newLine);
//now interface functions definitions
List funcstates = configuration.getFFunctionsSelectionState();
List funcs = configuration.getFFunctions();
for(int i=0; i<funcstates.size(); i++)
{
//only generate the ones used selected
if(configuration.getFunctionSelectionState(i))
{
strInterface.append("\t"); //create indentation //$NON-NLS-1$
strInterface.append(getAbstractFunctionDefinitionString((NestedFunction)(funcs.get(i)), configuration.getFPackage()));
}
}
strInterface.append(IEGLConstants.KEYWORD_END); //end for interface definition
strInterface.append(newLine);
strInterface.append(newLine);
return strInterface;
}
@Override
protected String getFileContents() {
StringBuffer buf = new StringBuffer();
buf.append(getInterfaceString());
return buf.toString();
}
private String createNamespace(String ePackage) {
StringBuffer sbuffer;
if (ePackage == null || ePackage.length() < 1) {
sbuffer = new StringBuffer("http://default");
} else {
StringTokenizer tokenizer = new StringTokenizer(ePackage, ".", true);
sbuffer = new StringBuffer();
while (tokenizer.countTokens() > 0) {
sbuffer.insert(0, tokenizer.nextToken());
}
sbuffer.insert(0, "http://");
}
return sbuffer.toString();
}
}