blob: 8edcf893e2e64cf41c47c507ce3ea7d05c757b51 [file] [log] [blame]
/*
* Copyright 2003-2004 The Apache Software Foundation.
// (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Srinath Perera(hemapani@openource.lk)
* @author Susantha Kumara(susantha@opensource.lk, skumara@virtusa.com)
* @author Samisa Abeysinghe (sabeysinghe@virtusa.com)
*/
package org.apache.axis.wsdl.wsdl2ws.cpp;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;
import javax.xml.namespace.QName;
import org.apache.axis.wsdl.symbolTable.TypeEntry;
import org.apache.axis.wsdl.wsdl2ws.CUtils;
import org.apache.axis.wsdl.wsdl2ws.ParamWriter;
import org.apache.axis.wsdl.wsdl2ws.WSDL2Ws;
import org.apache.axis.wsdl.wsdl2ws.WrapperFault;
import org.apache.axis.wsdl.wsdl2ws.info.Type;
import org.apache.axis.wsdl.wsdl2ws.info.WebServiceContext;
public class ParmHeaderFileWriter extends ParamWriter
{
public ParmHeaderFileWriter(WebServiceContext wscontext, Type type)
throws WrapperFault
{
super(wscontext, type, CUtils.getHeaderFileExtension());
}
public void writeSource() throws WrapperFault
{
try
{
c_writer = new BufferedWriter(new FileWriter(getFilePath(false), false));
writeClassComment();
// if this headerfile not defined define it
c_writer.write("#if !defined(__" + c_classname.toUpperCase() + "_"
+ getFileType().toUpperCase() + "_H__INCLUDED_)\n");
c_writer.write("#define __" + c_classname.toUpperCase() + "_"
+ getFileType().toUpperCase() + "_H__INCLUDED_\n\n");
if (type.isSimpleType())
writeSimpleTypeWithRestrictions();
else
{
writePreprocessorStatements();
c_writer.write("\n");
c_writer.write("/* ********************************************************************* */\n");
c_writer.write("/* --- Custom type --- */\n");
c_writer.write("/* ********************************************************************* */\n");
c_writer.write("\n");
c_classname = CUtils.sanitizeString( c_classname);
c_writer.write("class STORAGE_CLASS_INFO " + c_classname);
if (this.type.isFault())
c_writer.write(" : public SoapFaultException");
c_writer.write("\n{\n");
writeAttributes();
writeGetSetMethods();
writeConstructors();
writeDestructors();
writeDeepCopyFlags();
c_writer.write("};\n\n");
writeFunctionPrototypes();
}
c_writer.write("\n");
c_writer.write("#endif /* !defined(__" + c_classname.toUpperCase()
+ "_" + getFileType().toUpperCase() + "_H__INCLUDED_)*/\n");
c_writer.flush();
c_writer.close();
if (WSDL2Ws.c_veryVerbose)
System.out.println(getFilePath(false).getAbsolutePath() + " created.....");
}
catch (IOException e)
{
throw new WrapperFault(e);
}
}
/**
*
*/
private void writeDeepCopyFlags() throws WrapperFault
{
if (type.isArray())
return;
if (attribs.length == 0)
return;
try
{
boolean foundDeepCopyType = false;
for (int i = 0 ; i < attribs.length ; i++)
{
Type type = attribs[i].getType();
boolean isPointerType = false;
if (type.isSimpleType())
isPointerType = CUtils.isPointerType(CUtils.getSimpleType(type.getBaseType()));
else
isPointerType = CUtils.isPointerType(getCorrectParmNameConsideringArraysAndComplexTypes(attribs[i]));
if ((attribs[i].isSimpleType() || attribs[i].getType().isSimpleType())
&& !attribs[i].isArray()
&& (isElementNillable(i)
|| isElementOptional(i)
|| isPointerType
|| attribs[i].getChoiceElement()
|| attribs[i].getAllElement()))
{
if (!foundDeepCopyType)
{
c_writer.write("\nprivate:\n");
foundDeepCopyType = true;
}
c_writer.write("\tbool __axis_deepcopy_" + attribs[i].getParamNameAsMember() + ";\n");
}
}
}
catch (IOException e)
{
throw new WrapperFault(e);
}
}
protected void writeSimpleTypeWithRestrictions() throws WrapperFault
{
try
{
c_writer.write("#include <axis/AxisUserAPI.hpp>\n");
c_writer.write("#include <axis/AxisUserAPIArrays.hpp>\n");
Vector restrictionData = type.getEnumerationdata();
if (restrictionData == null)
return;
TypeEntry baseEType = (TypeEntry) restrictionData.firstElement();
QName baseType = baseEType.getQName();
if (!CUtils.isSimpleType(baseType))
return;
String baseTypeName = CUtils.getSimpleType(baseType);
String langTypeName;
// User defined simple type based on another user-defined simple type
String restrictionBaseType = type.getRestrictionBaseType();
if (null != restrictionBaseType )
{
langTypeName = CUtils.sanitizeString(restrictionBaseType);
c_writer.write( "#include \"" + langTypeName + ".hpp\"\n\n");
}
else
langTypeName = baseTypeName;
c_writer.write("AXIS_CPP_NAMESPACE_USE \n\n");
c_writer.write("\n");
c_writer.write("/* ********************************************************************* */\n");
c_writer.write("/* --- Simple types and restrictions --- */\n");
c_writer.write("/* ********************************************************************* */\n");
c_writer.write("\n");
// Need to determine what to use for enumeration identifiers. That is, if a string
// enumeration value is "foobar", then we can generate an enumerator identifer of
// [type]_foobar. However, if the value is "foo bar", then we are forced to generate
// identifiers in the following format: [type]_ENUM[#], where [#] is a number starting
// at 1. We need to go through all the enumerators to determine what to do.
boolean validEnumIdentifier = true;
for (int i = 1; i < restrictionData.size(); i++)
{
QName value = (QName) restrictionData.elementAt(i);
if ("enumeration".equals(value.getLocalPart()))
validEnumIdentifier = CUtils.isValidCIdentifier(value.getNamespaceURI(), false);
if (!validEnumIdentifier)
break;
}
c_writer.write("typedef " + langTypeName + " " + c_classname + ";\n");
c_writer.write("typedef "
+ CUtils.getArrayNameForType(langTypeName) + " "
+ CUtils.getArrayNameForType(c_classname) + ";\n");
if (CUtils.isPointerType(baseTypeName)
|| "xsd__base64Binary".equals(baseTypeName)
|| "xsd__hexBinary".equals(baseTypeName))
{
c_writer.write("\n");
for (int i = 1; i < restrictionData.size(); i++)
{
QName value = (QName) restrictionData.elementAt(i);
if ("enumeration".equals(value.getLocalPart()))
{
c_writer.write("static const " + c_classname + " " + c_classname + "_");
if (validEnumIdentifier)
c_writer.write(value.getNamespaceURI());
else
c_writer.write("ENUM" + i);
c_writer.write(" = \"" + value.getNamespaceURI() + "\";\n");
}
else if ("maxLength".equals(value.getLocalPart()))
{
c_writer.write("static const int " + c_classname
+ "_MaxLength = " + value.getNamespaceURI() + ";\n");
}
else if ("minLength".equals(value.getLocalPart()))
{
c_writer.write("static const int " + c_classname
+ "_MinLength = " + value.getNamespaceURI() + ";\n");
}
}
}
else if ("int".equals(baseType.getLocalPart()))
{
if (restrictionData.size() > 1)
{
//there are enumerations or min/maxInclusive
boolean isEnum = false;
for (int i = 1; i < restrictionData.size(); i++)
{
QName value = (QName) restrictionData.elementAt(i);
if ("enumeration".equals(value.getLocalPart()))
{
isEnum = true;
if (i > 1)
c_writer.write(", ");
else
c_writer.write("typedef enum { ");
c_writer.write("ENUM" + c_classname.toUpperCase() + "_"
+ value.getNamespaceURI() + "="
+ value.getNamespaceURI());
}
else if ("minInclusive".equals(value.getLocalPart()))
{
c_writer.write("static const int " + c_classname
+ "_MinInclusive = " + value.getNamespaceURI() + ";\n");
}
else if ("maxInclusive".equals(value.getLocalPart()))
{
c_writer.write("static const int " + c_classname
+ "_MaxInclusive = " + value.getNamespaceURI() + ";\n");
}
}
if (isEnum)
c_writer.write("} " + c_classname + "_Enum;\n");
}
}
else
{
for (int i = 1; i < restrictionData.size(); i++)
{
QName value = (QName) restrictionData.elementAt(i);
if ("enumeration".equals(value.getLocalPart()))
{
c_writer.write("static const " + c_classname + " " + c_classname + "_");
if (validEnumIdentifier)
c_writer.write(value.getNamespaceURI());
else
c_writer.write("ENUM" + i);
c_writer.write(" = \"" + value.getNamespaceURI() + "\";\n");
}
}
}
}
catch (IOException e)
{
throw new WrapperFault(e);
}
}
protected void writeAttributes() throws WrapperFault
{
int anyCounter = 0;
if (type.isArray())
return;
try
{
c_writer.write("public:\n");
for (int i = 0; i < attribs.length; i++)
{
// Following will set the correct type
String paramType = getCorrectParmNameConsideringArraysAndComplexTypes(attribs[i]);
// Following will set param name - if xsd:any element, we index param name
String paramName = attribs[i].getParamNameAsMember();
if (attribs[i].getType().isAnyElement())
{
anyCounter += 1;
paramName += Integer.toString(anyCounter);
}
// we pass arrays as pointers - ensure this
if (attribs[i].isArray())
{
// TODO - work on removing the following if-check, should not be needed if we
// let getCorrectParmNameConsideringArraysAndComplexTypes() perform check.
if (!paramType.endsWith("*"))
paramType += "*";
if ((!attribs[i].isSimpleType() && attribs[i].getType().isSimpleType())
|| attribs[i].getType().isRestriction())
c_writer.write("\t");
else
c_writer.write("\tclass ");
}
else
c_writer.write("\t");
// Print out field.
c_writer.write(CUtils.resolveWSDL2LanguageNameClashes(paramType) + " " + paramName + ";\n");
}
// Handle extension
if (extensionBaseAttrib != null &&
getCorrectParmNameConsideringArraysAndComplexTypes(extensionBaseAttrib) != null)
{
c_writer.write("\t"
+ CUtils.sanitizeString(getCorrectParmNameConsideringArraysAndComplexTypes(extensionBaseAttrib))
+ " "
+ extensionBaseAttrib.getParamNameAsMember() + ";\n");
}
}
catch (IOException e)
{
throw new WrapperFault(e);
}
}
/**
* Dushshantha: This method writes getters and setters of the attributes.
*/
protected void writeGetSetMethods() throws WrapperFault
{
int anyCounter = 0;
if (type.isArray())
return;
try
{
for (int i = 0; i < attribs.length; i++)
{
// Following will set the correct type
String paramType = getCorrectParmNameConsideringArraysAndComplexTypes(attribs[i]);
// Set method name to use
String methodName = attribs[i].getMethodName();
// If xsd:any element, we index method name
if(attribs[i].getType().isAnyElement())
{
anyCounter += 1;
methodName += Integer.toString(anyCounter);
}
// we pass arrays as pointers - ensure this
if (attribs[i].isArray() && !paramType.endsWith("*"))
paramType += "* ";
c_writer.write("\n");
// Generate getter prototype
c_writer.write("\t" + CUtils.resolveWSDL2LanguageNameClashes(paramType) + " get" + methodName + "();\n");
// Generate setter prototype - need to consider deep copies
c_writer.write("\t" + "void set" + methodName + "(" + CUtils.resolveWSDL2LanguageNameClashes(paramType) + " InValue");
Type type = attribs[i].getType();
boolean isPointerType;
if (type.isSimpleType())
isPointerType = CUtils.isPointerType(CUtils.getSimpleType(type.getBaseType()));
else
isPointerType = CUtils.isPointerType(paramType);
if ((attribs[i].isSimpleType() || attribs[i].getType().isSimpleType())
&& !attribs[i].isArray()
&& (isElementNillable(i)
|| isElementOptional(i)
|| isPointerType
|| attribs[i].getChoiceElement()
|| attribs[i].getAllElement()))
c_writer.write(", bool deep=true, bool makeCopy=true");
c_writer.write(");\n");
}
}
catch (IOException e)
{
throw new WrapperFault(e);
}
}
protected void writeConstructors() throws WrapperFault
{
try
{
c_writer.write("\n\t" + c_classname + "();\n");
c_writer.write("\t" + c_classname + "(const " + c_classname + " & original);\n");
writeReset();
}
catch (IOException e)
{
throw new WrapperFault(e);
}
}
protected void writeReset() throws WrapperFault
{
try
{
c_writer.write("\n\tvoid reset();\n");
}
catch (IOException e)
{
throw new WrapperFault(e);
}
}
protected void writeDestructors() throws WrapperFault
{
try
{
if (this.type.isFault())
c_writer.write("\tvirtual ~" + c_classname + "() throw();\n");
else
c_writer.write("\tvirtual ~" + c_classname + "();\n");
}
catch (IOException e)
{
throw new WrapperFault(e);
}
}
protected void writeMethods() throws WrapperFault
{
}
protected void writeFunctionPrototypes() throws WrapperFault
{
try
{
if (type.isSimpleType() || type.isArray() || type.isAnyType() || type.isAnyElement()
|| (type.isAnonymous() && !type.isExternalized()))
return;
String typeName = c_classname;
c_writer.write("\n");
c_writer.write("/* ********************************************************************* */\n");
c_writer.write("/* --- Functions to create/delete, serialize/deserialize custom type --- */\n");
c_writer.write("/* ********************************************************************* */\n");
c_writer.write("\n");
c_writer.write("extern int Axis_DeSerialize_" + typeName
+ "(" + typeName + "* param, IWrapperSoapDeSerializer* pDZ);\n");
c_writer.write("extern void* Axis_Create_" + typeName + "(int nSize=0);\n");
c_writer.write("extern void Axis_Delete_" + typeName + "("
+ typeName + "* param, int nSize=0);\n");
c_writer.write("extern int Axis_Serialize_" + typeName + "("
+ typeName + "* param, IWrapperSoapSerializer* pSZ, bool bArray = false);\n\n");
}
catch (IOException e)
{
throw new WrapperFault(e);
}
}
/*
* (non-Javadoc)
*
* @see org.apache.axis.wsdl.wsdl2ws.cpp.BasicFileWriter#writePreprocssorStatements()
*/
protected void writePreprocessorStatements() throws WrapperFault
{
try
{
c_writer.write("#include <axis/AxisUserAPI.hpp>\n");
c_writer.write("#include <axis/AxisUserAPIArrays.hpp>\n");
c_writer.write("#include <axis/IWrapperSoapDeSerializer.hpp>\n");
c_writer.write("#include <axis/IWrapperSoapSerializer.hpp>\n");
if (this.type.isFault())
{
c_writer.write("#include <axis/SoapFaultException.hpp>\n");
c_writer.write("\n");
c_writer.write("using namespace std;\n");
}
c_writer.write("AXIS_CPP_NAMESPACE_USE \n\n");
HashSet typeSet = new HashSet();
for (int i = 0; i < attribs.length; i++)
{
String basicType = attribs[i].getTypeName();
Type theType = attribs[i].getType();
if (theType.isRestriction() && !CUtils.isPrimitiveType(basicType))
typeSet.add(basicType);
else if (!attribs[i].isSimpleType() && !attribs[i].isAnyElement())
{
if ((attribs[i].isArray()) && !theType.isSimpleType())
typeSet.add(CUtils.getArrayNameForType(basicType));
typeSet.add(basicType);
}
}
// TODO we really do not support xsd:extension correctly or completely!
if (extensionBaseAttrib != null
&& getCorrectParmNameConsideringArraysAndComplexTypes(extensionBaseAttrib) != null)
{
String extBaseType = getCorrectParmNameConsideringArraysAndComplexTypes(extensionBaseAttrib);
// TODO following is hack till we really support xsd:extension correctly
if (extBaseType.lastIndexOf("*") > -1)
extBaseType = extBaseType.substring(0, extBaseType.lastIndexOf("*"));
if (!CUtils.isPrimitiveType(extBaseType))
typeSet.add(CUtils.sanitizeString(extBaseType));
}
Iterator itr = typeSet.iterator();
if (itr.hasNext())
c_writer.write("\n");
while (itr.hasNext())
{
// Do not want to include the header file we are generating!
String includeFile = itr.next().toString();
if (!includeFile.equals(c_classname))
c_writer.write("#include \"" + CUtils.resolveWSDL2LanguageNameClashes(includeFile) + CUtils.getHeaderFileExtension() + "\"\n");
}
c_writer.write("\n");
//Local name and the URI for the type
c_writer.write("/*Local name and the URI for the type*/\n");
c_writer.write("static const char Axis_URI_" + c_classname + "[] = \""
+ type.getName().getNamespaceURI() + "\";\n");
c_writer.write("static const char Axis_TypeName_" + c_classname
+ "[] = \"" + type.getName().getLocalPart() + "\";\n\n");
// Define class to avoid compilation issues (cycle in includes).
// This is a must for complex wsdl files.
typeSet = new HashSet();
for (int i = 0; i < attribs.length; i++)
{
if (!attribs[i].isArray() &&
!(attribs[i].isSimpleType() || attribs[i].getType().isSimpleType())
&& !attribs[i].isAnyElement())
{
typeSet.add(attribs[i].getTypeName());
}
}
itr = typeSet.iterator();
while (itr.hasNext())
{
c_writer.write("class " + itr.next().toString() + ";\n");
}
}
catch (IOException e)
{
throw new WrapperFault(e);
}
}
protected String getFileType()
{
return "Param";
}
}