/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.xml.ws.typeprovider; import gw.internal.xml.xsd.typeprovider.XmlSchemaIndex; import gw.lang.reflect.java.IJavaClassInfo; import gw.lang.reflect.java.JavaTypes; import gw.internal.xml.ws.StaticallyTypedWsdlFaultImpl; import gw.xml.XmlElement; import gw.internal.xml.xsd.typeprovider.XmlTypeData; import gw.internal.xml.xsd.typeprovider.IWsdlFaultTypeData; import gw.internal.xml.xsd.typeprovider.schema.WsdlPart; import gw.lang.reflect.ConstructorInfoBuilder; import gw.lang.reflect.IConstructorHandler; import gw.lang.reflect.IConstructorInfo; import gw.lang.reflect.IMethodInfo; import gw.lang.reflect.IPropertyAccessor; import gw.lang.reflect.IPropertyInfo; import gw.lang.reflect.IType; import gw.lang.reflect.ParameterInfoBuilder; import gw.lang.reflect.PropertyInfoBuilder; import gw.lang.reflect.TypeSystem; import gw.util.ILogger; import gw.util.concurrent.LockingLazyVar; import gw.xml.ws.WsdlFault; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class WsdlFaultTypeData extends XmlTypeData implements IWsdlFaultTypeData { private final Wsdl _wsdl; private final String _typeName; private boolean _initialized; private List<IPropertyInfo> _props; private List<IMethodInfo> _methods; private List<IConstructorInfo> _constructors; private final WsdlPart _part; private final LockingLazyVar<IType> _detailElementType = new LockingLazyVar<IType>( TypeSystem.getGlobalLock() ) { @Override protected IType init() { return _part.getSchemaIndex().getGosuTypeByXmlSchemaElementQName( _part.getElementName() ); } }; /** * Create a new port definition * * @param wsdl the wsdl that this port is defined in * @param part */ public WsdlFaultTypeData( final Wsdl wsdl, String typeName, WsdlPart part ) { _wsdl = wsdl; _typeName = typeName; _part = part; if ( getLogger().isDebugEnabled() ) { getLogger().debug( "WsdlFaultTypeInfo created for " + typeName ); } } public ILogger getLogger() { return _wsdl.getLogger(); } public void maybeInit() { if ( !_initialized ) { _methods = new ArrayList<IMethodInfo>(); _props = new ArrayList<IPropertyInfo>(); _constructors = new ArrayList<IConstructorInfo>(); addPropertiesAndMethods( _props, _constructors ); if ( getLogger().isDebugEnabled() ) { getLogger().debug( "WsdlFaultTypeInfo for " + _typeName + " properties=" + _props ); getLogger().debug( "WsdlFaultTypeInfo for " + _typeName + " methods=" + _methods ); } _initialized = true; } } public void addPropertiesAndMethods( List<IPropertyInfo> props, List<IConstructorInfo> constructors ) { constructors.add( new ConstructorInfoBuilder() .withConstructorHandler( new IConstructorHandler() { @Override public Object newInstance( Object... args ) { return createWsdlFault( null, null ); } } ) .build( this ) ); constructors.add( new ConstructorInfoBuilder() .withParameters( new ParameterInfoBuilder().withName( "message" ).withType( String.class ) ) .withConstructorHandler( new IConstructorHandler() { @Override public Object newInstance( Object... args ) { return createWsdlFault( null, (String) args[ 0 ] ); } } ) .build( this ) ); constructors.add( new ConstructorInfoBuilder() .withParameters( new ParameterInfoBuilder().withName( "cause" ).withType( Throwable.class ) ) .withConstructorHandler( new IConstructorHandler() { @Override public Object newInstance( Object... args ) { return createWsdlFault( (Throwable) args[ 0 ], null ); } } ) .build( this ) ); constructors.add( new ConstructorInfoBuilder() .withParameters( new ParameterInfoBuilder().withName( "message" ).withType( String.class ), new ParameterInfoBuilder().withName( "cause" ).withType( Throwable.class ) ) .withConstructorHandler( new IConstructorHandler() { @Override public Object newInstance( Object... args ) { return createWsdlFault( (Throwable) args[ 1 ], (String) args[ 0 ] ); } } ) .build( this ) ); props.add( new PropertyInfoBuilder().withName( "Detail" ) .withType( _detailElementType.get() ) .withWritable( false ) .withAccessor( new IPropertyAccessor() { @Override public Object getValue( Object ctx ) { WsdlFault castFault = (WsdlFault) ctx; return castFault.getDetail(); } @Override public void setValue( Object ctx, Object value ) { throw new UnsupportedOperationException(); } } ).build( this ) ); } @Override public String getName() { return _typeName; } @Override public List<IPropertyInfo> getDeclaredProperties() { maybeInit(); return _props; } @Override public List<IMethodInfo> getDeclaredMethods() { maybeInit(); return _methods; } public List<IConstructorInfo> getDeclaredConstructors() { maybeInit(); return _constructors; } @Override public boolean isFinal() { return true; } @Override public boolean isEnum() { return false; } @Override public IType getSuperType() { return TypeSystem.get( WsdlFault.class ); } @Override public boolean prefixSuperProperties() { return false; } @Override public long getFingerprint() { return 0; // TODO } @Override public Class getBackingClass() { return WsdlFault.class; } @Override public IJavaClassInfo getBackingClassInfo() { return JavaTypes.getSystemType(WsdlFault.class).getBackingClassInfo(); } @Override public XmlSchemaIndex<?> getSchemaIndex() { return _part.getSchemaIndex(); } @Override public List<Class<?>> getAdditionalInterfaces() { return Collections.<Class<?>>singletonList( IWsdlFaultTypeData.class ); } private WsdlFault createWsdlFault( Throwable cause, String message ) { final XmlElement detailElement = (XmlElement) _detailElementType.get().getTypeInfo().getConstructor().getConstructor().newInstance(); StaticallyTypedWsdlFaultImpl fault = new StaticallyTypedWsdlFaultImpl( message, cause, getType() ); fault.setCode( WsdlFault.FaultCode.Sender ); fault.setDetail( detailElement ); return fault; } }