package org.jboss.axis.wsdl.toJava;
import org.jboss.axis.encoding.DefaultTypeMappingImpl;
import org.jboss.axis.encoding.TypeMapping;
import org.jboss.axis.utils.JavaUtils;
import org.jboss.axis.utils.Messages;
import org.jboss.axis.wsdl.gen.Generator;
import org.jboss.axis.wsdl.gen.GeneratorFactory;
import org.jboss.axis.wsdl.gen.NoopGenerator;
import org.jboss.axis.wsdl.symbolTable.BaseTypeMapping;
import org.jboss.axis.wsdl.symbolTable.BindingEntry;
import org.jboss.axis.wsdl.symbolTable.Element;
import org.jboss.axis.wsdl.symbolTable.FaultInfo;
import org.jboss.axis.wsdl.symbolTable.MessageEntry;
import org.jboss.axis.wsdl.symbolTable.Parameter;
import org.jboss.axis.wsdl.symbolTable.Parameters;
import org.jboss.axis.wsdl.symbolTable.PortTypeEntry;
import org.jboss.axis.wsdl.symbolTable.SchemaUtils;
import org.jboss.axis.wsdl.symbolTable.ServiceEntry;
import org.jboss.axis.wsdl.symbolTable.SymTabEntry;
import org.jboss.axis.wsdl.symbolTable.SymbolTable;
import org.jboss.axis.wsdl.symbolTable.Type;
import org.jboss.axis.wsdl.symbolTable.TypeEntry;
import javax.wsdl.Binding;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.OperationType;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.xml.namespace.QName;
import javax.xml.rpc.holders.BooleanHolder;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
public class JavaGeneratorFactory implements GeneratorFactory
{
protected Emitter emitter;
protected SymbolTable symbolTable;
public static String COMPLEX_TYPE_FAULT = "ComplexTypeFault";
public static String EXCEPTION_CLASS_NAME = "ExceptionClassName";
public static String EXCEPTION_DATA_TYPE = "ExceptionDataType";
public JavaGeneratorFactory()
{
addGenerators();
}
public JavaGeneratorFactory(Emitter emitter)
{
this.emitter = emitter;
addGenerators();
}
public void setEmitter(Emitter emitter)
{
this.emitter = emitter;
}
private void addGenerators()
{
addMessageGenerators();
addPortTypeGenerators();
addBindingGenerators();
addServiceGenerators();
addTypeGenerators();
addDefinitionGenerators();
}
protected void addMessageGenerators()
{
}
protected void addPortTypeGenerators()
{
}
protected void addBindingGenerators()
{
}
protected void addServiceGenerators()
{
}
protected void addTypeGenerators()
{
}
protected void addDefinitionGenerators()
{
addGenerator(Definition.class, JavaDefinitionWriter.class); addGenerator(Definition.class, JavaDeployWriter.class); addGenerator(Definition.class, JavaUndeployWriter.class); }
public void generatorPass(Definition def, SymbolTable symbolTable)
{
this.symbolTable = symbolTable;
javifyNames(symbolTable);
setFaultContext(symbolTable);
resolveNameClashes(symbolTable);
determineInterfaceNames(symbolTable);
if (emitter.isAllWanted())
{
setAllReferencesToTrue();
}
else
{
ignoreNonSOAPBindings(symbolTable);
}
constructSignatures(symbolTable);
determineIfHoldersNeeded(symbolTable);
}
private Writers messageWriters = new Writers();
public Generator getGenerator(Message message, SymbolTable symbolTable)
{
MessageEntry mEntry = symbolTable.getMessageEntry(message.getQName());
messageWriters.addStuff(new NoopGenerator(), mEntry, symbolTable);
return messageWriters;
}
private Writers portTypeWriters = new Writers();
public Generator getGenerator(PortType portType, SymbolTable symbolTable)
{
PortTypeEntry ptEntry = symbolTable.getPortTypeEntry(portType.getQName());
portTypeWriters.addStuff(new NoopGenerator(), ptEntry, symbolTable);
return portTypeWriters;
}
protected Writers bindingWriters = new Writers();
public Generator getGenerator(Binding binding, SymbolTable symbolTable)
{
Generator writer = new JavaBindingWriter(emitter, binding, symbolTable);
BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName());
bindingWriters.addStuff(writer, bEntry, symbolTable);
return bindingWriters;
}
protected Writers serviceWriters = new Writers();
public Generator getGenerator(Service service, SymbolTable symbolTable)
{
Generator writer = new JavaServiceWriter(emitter, service, symbolTable);
ServiceEntry sEntry = symbolTable.getServiceEntry(service.getQName());
serviceWriters.addStuff(writer, sEntry, symbolTable);
return serviceWriters;
}
private Writers typeWriters = new Writers();
public Generator getGenerator(TypeEntry type, SymbolTable symbolTable)
{
Generator writer = new JavaTypeWriter(emitter, type, symbolTable);
typeWriters.addStuff(writer, type, symbolTable);
return typeWriters;
}
private Writers defWriters = new Writers();
public Generator getGenerator(Definition definition, SymbolTable symbolTable)
{
defWriters.addStuff(null, definition, symbolTable);
return defWriters;
}
protected class Writers implements Generator
{
Vector writers = new Vector();
SymbolTable symbolTable = null;
Generator baseWriter = null;
SymTabEntry entry = null;
Definition def = null;
public void addGenerator(Class writer)
{
writers.add(writer);
}
public void addStuff(Generator baseWriter, SymTabEntry entry, SymbolTable symbolTable)
{
this.baseWriter = baseWriter;
this.entry = entry;
this.symbolTable = symbolTable;
}
public void addStuff(Generator baseWriter, Definition def, SymbolTable symbolTable)
{
this.baseWriter = baseWriter;
this.def = def;
this.symbolTable = symbolTable;
}
public void generate() throws IOException
{
if (baseWriter != null)
{
baseWriter.generate();
}
Class[] formalArgs = null;
Object[] actualArgs = null;
if (entry != null)
{
formalArgs = new Class[]{Emitter.class, entry.getClass(), SymbolTable.class};
actualArgs = new Object[]{emitter, entry, symbolTable};
}
else
{
formalArgs = new Class[]{Emitter.class, Definition.class, SymbolTable.class};
actualArgs = new Object[]{emitter, def, symbolTable};
}
for (int i = 0; i < writers.size(); ++i)
{
Class wClass = (Class)writers.get(i);
Generator gen = null;
try
{
Constructor ctor = wClass.getConstructor(formalArgs);
gen = (Generator)ctor.newInstance(actualArgs);
}
catch (Throwable t)
{
throw new IOException(Messages.getMessage("exception01", t.getMessage()));
}
gen.generate();
}
} }
public void addGenerator(Class wsdlClass, Class generator)
{
if (Message.class.isAssignableFrom(wsdlClass))
{
messageWriters.addGenerator(generator);
}
else if (PortType.class.isAssignableFrom(wsdlClass))
{
portTypeWriters.addGenerator(generator);
}
else if (Binding.class.isAssignableFrom(wsdlClass))
{
bindingWriters.addGenerator(generator);
}
else if (Service.class.isAssignableFrom(wsdlClass))
{
serviceWriters.addGenerator(generator);
}
else if (TypeEntry.class.isAssignableFrom(wsdlClass))
{
typeWriters.addGenerator(generator);
}
else if (Definition.class.isAssignableFrom(wsdlClass))
{
defWriters.addGenerator(generator);
}
}
protected void javifyNames(SymbolTable symbolTable)
{
int uniqueNum = 0;
HashMap anonQNames = new HashMap();
Iterator it = symbolTable.getHashMap().values().iterator();
while (it.hasNext())
{
Vector v = (Vector)it.next();
for (int i = 0; i < v.size(); ++i)
{
SymTabEntry entry = (SymTabEntry)v.elementAt(i);
if (entry.getName() != null)
continue;
if (entry instanceof TypeEntry)
{
TypeEntry tEntry = (TypeEntry)entry;
String dims = tEntry.getDimensions();
TypeEntry refType = tEntry.getRefType();
while (refType != null)
{
tEntry = refType;
dims += tEntry.getDimensions();
refType = tEntry.getRefType();
}
if (tEntry.getName() == null)
{
QName typeQName = tEntry.getQName();
if ((typeQName.getLocalPart().
indexOf(SymbolTable.ANON_TOKEN) < 0))
{
tEntry.setName(emitter.getJavaName(typeQName));
}
else
{
String localName = typeQName.getLocalPart();
StringBuffer sb = new StringBuffer(localName);
int aidx = -1;
while (
(aidx = sb.toString().indexOf(SymbolTable.ANON_TOKEN)) > -1)
{
sb.replace(aidx, aidx + SymbolTable.ANON_TOKEN.length(), "_");
}
localName = sb.toString();
typeQName = new QName(typeQName.getNamespaceURI(),
localName);
symbolTable.getType(typeQName);
if (anonQNames.get(typeQName) != null)
{
localName += "Type" + uniqueNum++;
typeQName =
new QName(typeQName.getNamespaceURI(),
localName);
}
anonQNames.put(typeQName, typeQName);
tEntry.setName(emitter.getJavaName(typeQName));
}
}
entry.setName(tEntry.getName() + dims);
}
else
{
entry.setName(emitter.getJavaName(entry.getQName()));
}
}
}
}
private void setFaultContext(SymbolTable symbolTable)
{
Iterator it = symbolTable.getHashMap().values().iterator();
while (it.hasNext())
{
Vector v = (Vector)it.next();
for (int i = 0; i < v.size(); ++i)
{
SymTabEntry entry = (SymTabEntry)v.elementAt(i);
if (entry instanceof BindingEntry)
{
BindingEntry bEntry = (BindingEntry)entry;
Map allOpFaults = bEntry.getFaults();
Iterator ops = allOpFaults.values().iterator();
while (ops.hasNext())
{
ArrayList faults = (ArrayList)ops.next();
for (int j = 0; j < faults.size(); ++j)
{
FaultInfo info = (FaultInfo)faults.get(j);
setFaultContext(info, symbolTable);
}
}
}
}
}
}
private void setFaultContext(FaultInfo fault,
SymbolTable symbolTable)
{
QName faultXmlType = null;
Vector parts = new Vector();
try
{
symbolTable.getParametersFromParts(parts,
fault.getMessage().getOrderedParts(null),
false,
fault.getName(),
null);
}
catch (IOException e)
{
}
String exceptionClassName = null;
for (int j = 0; j < parts.size(); j++)
{
TypeEntry te = ((Parameter)(parts.elementAt(j))).getType();
TypeEntry elementTE = null;
if (te instanceof Element)
{
elementTE = te;
te = te.getRefType();
}
faultXmlType = te.getQName();
if (te.getBaseType() != null ||
te.isSimpleType() ||
(te.getDimensions().length() > 0 &&
te.getRefType().getBaseType() != null))
{
}
else
{
Boolean isComplexFault = (Boolean)te.getDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT);
if (isComplexFault == null ||
!isComplexFault.booleanValue())
{
te.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
new Boolean(true));
if (elementTE != null)
{
te.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
new Boolean(true));
}
HashSet derivedSet =
org.jboss.axis.wsdl.symbolTable.Utils.getDerivedTypes(te, symbolTable);
Iterator derivedI = derivedSet.iterator();
while (derivedI.hasNext())
{
TypeEntry derivedTE = (TypeEntry)
derivedI.next();
derivedTE.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
new Boolean(true));
}
TypeEntry base = SchemaUtils.getComplexElementExtensionBase(te.getNode(),
symbolTable);
while (base != null)
{
base.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
new Boolean(true));
base = SchemaUtils.getComplexElementExtensionBase(base.getNode(),
symbolTable);
}
}
exceptionClassName = te.getName();
}
}
MessageEntry me = symbolTable.getMessageEntry(fault.getMessage().getQName());
if (me != null)
{
me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_DATA_TYPE,
faultXmlType);
if (exceptionClassName != null)
{
me.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
new Boolean(true));
me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_CLASS_NAME,
exceptionClassName);
}
else
{
me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_CLASS_NAME,
emitter.getJavaName(me.getQName()));
}
}
}
protected void determineInterfaceNames(SymbolTable symbolTable)
{
Iterator it = symbolTable.getHashMap().values().iterator();
while (it.hasNext())
{
Vector v = (Vector)it.next();
for (int i = 0; i < v.size(); ++i)
{
SymTabEntry entry = (SymTabEntry)v.elementAt(i);
if (entry instanceof BindingEntry)
{
BindingEntry bEntry = (BindingEntry)entry;
String seiName = null;
PortTypeEntry ptEntry = symbolTable.getPortTypeEntry(bEntry.getBinding().getPortType().getQName());
seiName = ptEntry.getName();
bEntry.setDynamicVar(JavaBindingWriter.INTERFACE_NAME, seiName);
}
}
}
}
protected void resolveNameClashes(SymbolTable symbolTable)
{
HashSet anonTypes = new HashSet();
Iterator it = symbolTable.getHashMap().values().iterator();
while (it.hasNext())
{
Vector v = new Vector((Vector)it.next());
int index = 0;
while (index < v.size())
{
if (v.elementAt(index) instanceof MessageEntry)
{
v.removeElementAt(index);
}
else
{
index++;
}
}
if (v.size() > 1)
{
boolean resolve = true;
if (v.size() == 2 &&
((v.elementAt(0) instanceof Element &&
v.elementAt(1) instanceof Type) ||
(v.elementAt(1) instanceof Element &&
v.elementAt(0) instanceof Type)))
{
Element e = null;
if (v.elementAt(0) instanceof Element)
{
e = (Element)v.elementAt(0);
}
else
{
e = (Element)v.elementAt(1);
}
BooleanHolder forElement = new BooleanHolder();
QName eType = Utils.getTypeQName(e.getNode(), forElement, false);
if (eType != null &&
eType.equals(e.getQName()) &&
!forElement.value)
resolve = false;
}
if (resolve)
{
resolve = false; String name = null;
for (int i = 0; i < v.size() && !resolve; ++i)
{
SymTabEntry entry = (SymTabEntry)v.elementAt(i);
if (entry instanceof MessageEntry ||
entry instanceof BindingEntry)
{
; }
else if (name == null)
{
name = entry.getName();
}
else if (name.equals(entry.getName()))
{
resolve = true; }
}
}
if (resolve)
{
boolean firstType = true;
for (int i = 0; i < v.size(); ++i)
{
SymTabEntry entry = (SymTabEntry)v.elementAt(i);
if (entry instanceof Element)
{
entry.setName(mangleName(entry.getName(),
"_ElemType"));
QName anonQName = new QName(entry.getQName().getNamespaceURI(),
SymbolTable.ANON_TOKEN +
entry.getQName().getLocalPart());
TypeEntry anonType = symbolTable.getType(anonQName);
if (anonType != null)
{
anonType.setName(entry.getName());
anonTypes.add(anonType);
}
}
else if (entry instanceof TypeEntry)
{
if (firstType)
{
firstType = false;
Iterator types = symbolTable.getTypeIndex().values().iterator();
while (types.hasNext())
{
TypeEntry type = (TypeEntry)
types.next();
if (type != entry && type.getBaseType() == null &&
sameJavaClass(entry.getName(), type.getName()))
{
v.add(type);
}
}
}
if (!anonTypes.contains(entry))
{
entry.setName(mangleName(entry.getName(), "_Type"));
}
}
else if (entry instanceof PortTypeEntry)
{
entry.setName(mangleName(entry.getName(), "_Port"));
}
else if (entry instanceof ServiceEntry)
{
entry.setName(mangleName(entry.getName(),
"_Service"));
}
else if (entry instanceof BindingEntry)
{
BindingEntry bEntry = (BindingEntry)entry;
if (bEntry.hasLiteral())
{
entry.setName(mangleName(entry.getName(),
"_Binding"));
}
}
}
}
}
}
}
private String mangleName(String name, String mangle)
{
int index = name.indexOf("[");
if (index >= 0)
{
String pre = name.substring(0, index);
String post = name.substring(index);
return pre + mangle + post;
}
else
return name + mangle;
}
private boolean sameJavaClass(String one, String two)
{
int index1 = one.indexOf("[");
int index2 = two.indexOf("[");
if (index1 > 0)
one = one.substring(0, index1);
if (index2 > 0)
two = two.substring(0, index2);
return one.equals(two);
}
protected void setAllReferencesToTrue()
{
Iterator it = symbolTable.getHashMap().values().iterator();
while (it.hasNext())
{
Vector v = (Vector)it.next();
for (int i = 0; i < v.size(); ++i)
{
SymTabEntry entry = (SymTabEntry)v.elementAt(i);
if (entry instanceof BindingEntry &&
((BindingEntry)entry).getBindingType() !=
BindingEntry.TYPE_SOAP)
{
entry.setIsReferenced(false);
}
else
{
entry.setIsReferenced(true);
}
}
}
}
protected void ignoreNonSOAPBindings(SymbolTable symbolTable)
{
Vector unusedPortTypes = new Vector();
Vector usedPortTypes = new Vector();
Iterator it = symbolTable.getHashMap().values().iterator();
while (it.hasNext())
{
Vector v = (Vector)it.next();
for (int i = 0; i < v.size(); ++i)
{
SymTabEntry entry = (SymTabEntry)v.elementAt(i);
if (entry instanceof BindingEntry)
{
BindingEntry bEntry = (BindingEntry)entry;
Binding binding = bEntry.getBinding();
PortType portType = binding.getPortType();
PortTypeEntry ptEntry =
symbolTable.getPortTypeEntry(portType.getQName());
if (bEntry.getBindingType() == BindingEntry.TYPE_SOAP)
{
usedPortTypes.add(ptEntry);
if (unusedPortTypes.contains(ptEntry))
{
unusedPortTypes.remove(ptEntry);
}
}
else
{
bEntry.setIsReferenced(false);
if (!usedPortTypes.contains(ptEntry))
{
unusedPortTypes.add(ptEntry);
}
}
}
}
}
for (int i = 0; i < unusedPortTypes.size(); ++i)
{
PortTypeEntry ptEntry = (PortTypeEntry)unusedPortTypes.get(i);
ptEntry.setIsReferenced(false);
}
}
protected void constructSignatures(SymbolTable symbolTable)
{
Iterator it = symbolTable.getHashMap().values().iterator();
while (it.hasNext())
{
Vector v = (Vector)it.next();
for (int i = 0; i < v.size(); ++i)
{
SymTabEntry entry = (SymTabEntry)v.elementAt(i);
if (entry instanceof BindingEntry)
{
BindingEntry bEntry = (BindingEntry)entry;
Binding binding = bEntry.getBinding();
PortTypeEntry ptEntry =
symbolTable.getPortTypeEntry(binding.getPortType().getQName());
PortType portType = ptEntry.getPortType();
Iterator operations = portType.getOperations().iterator();
while (operations.hasNext())
{
Operation operation = (Operation)operations.next();
OperationType type = operation.getStyle();
String name = operation.getName();
Parameters parameters = bEntry.getParameters(operation);
if (type == OperationType.SOLICIT_RESPONSE)
{
parameters.signature = " // " + Messages.getMessage("invalidSolResp00", name);
System.err.println(Messages.getMessage("invalidSolResp00", name));
}
else if (type == OperationType.NOTIFICATION)
{
parameters.signature = " // " + Messages.getMessage("invalidNotif00", name);
System.err.println(Messages.getMessage("invalidNotif00", name));
}
else
{ if (parameters != null)
{
parameters.signature = constructSignature(parameters, name);
}
}
}
}
}
}
}
private String constructSignature(Parameters parms, String opName)
{
String name = Utils.xmlNameToJava(opName);
String ret = "void";
if (parms != null && parms.returnParam != null)
{
ret = Utils.getParameterTypeName(parms.returnParam);
}
String signature = " public " + ret + " " + name + "(";
boolean needComma = false;
for (int i = 0; parms != null && i < parms.list.size(); ++i)
{
Parameter p = (Parameter)parms.list.get(i);
if (needComma)
{
signature = signature + ", ";
}
else
{
needComma = true;
}
String javifiedName = Utils.xmlNameToJava(p.getName());
if (p.getMode() == Parameter.IN)
{
signature = signature + Utils.getParameterTypeName(p) + " " + javifiedName;
}
else
{
signature = signature + Utils.holder(p.getMIMEInfo(), p.getType(), emitter) + " "
+ javifiedName;
}
}
signature = signature + ") throws java.rmi.RemoteException";
if (parms != null && parms.faults != null)
{
Iterator i = parms.faults.values().iterator();
while (i.hasNext())
{
Fault fault = (Fault)i.next();
String exceptionName =
Utils.getFullExceptionName(fault.getMessage(), symbolTable);
if (exceptionName != null)
{
signature = signature + ", " + exceptionName;
}
}
}
return signature;
}
protected void determineIfHoldersNeeded(SymbolTable symbolTable)
{
Iterator it = symbolTable.getHashMap().values().iterator();
while (it.hasNext())
{
Vector v = (Vector)it.next();
for (int i = 0; i < v.size(); ++i)
{
if (v.get(i) instanceof BindingEntry)
{
BindingEntry bEntry = (BindingEntry)v.get(i);
Iterator operations =
bEntry.getParameters().values().iterator();
while (operations.hasNext())
{
Parameters parms = (Parameters)operations.next();
for (int j = 0; j < parms.list.size(); ++j)
{
Parameter p =
(Parameter)parms.list.get(j);
if (p.getMode() != Parameter.IN)
{
TypeEntry typeEntry = p.getType();
typeEntry.setDynamicVar(JavaTypeWriter.HOLDER_IS_NEEDED,
new Boolean(true));
if (!typeEntry.isSimpleType() && typeEntry.getRefType() != null)
{
typeEntry.getRefType().setDynamicVar(JavaTypeWriter.HOLDER_IS_NEEDED,
new Boolean(true));
}
QName anonQName = SchemaUtils.
getElementAnonQName(p.getType().getNode());
if (anonQName != null)
{
TypeEntry anonType =
symbolTable.getType(anonQName);
if (anonType != null)
{
anonType.setDynamicVar(JavaTypeWriter.HOLDER_IS_NEEDED,
new Boolean(true));
}
}
}
}
}
}
}
}
}
BaseTypeMapping btm = null;
public void setBaseTypeMapping(BaseTypeMapping btm)
{
this.btm = btm;
}
public BaseTypeMapping getBaseTypeMapping()
{
if (btm == null)
{
btm = new BaseTypeMapping()
{
TypeMapping defaultTM = DefaultTypeMappingImpl.getSingleton();
public String getBaseName(QName qNameIn)
{
javax.xml.namespace.QName qName =
new javax.xml.namespace.QName(qNameIn.getNamespaceURI(),
qNameIn.getLocalPart());
Class cls = defaultTM.getClassForQName(qName);
if (cls == null)
return null;
else
return JavaUtils.getTextClassName(cls.getName());
}
};
}
return btm;
}
}