/*************************************************************************** * Copyright (C) 2011 by Claudio Guidi <cguidi@italianasoftware.com> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * * For details about the authors of this software, see the AUTHORS file. * ***************************************************************************/ package joliex.surface; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import jolie.lang.NativeType; import jolie.lang.parse.ast.InputPortInfo; import jolie.lang.parse.ast.InterfaceDefinition; import jolie.lang.parse.ast.InterfaceExtenderDefinition; import jolie.lang.parse.ast.OneWayOperationDeclaration; import jolie.lang.parse.ast.OperationDeclaration; import jolie.lang.parse.ast.OutputPortInfo; import jolie.lang.parse.ast.RequestResponseOperationDeclaration; import jolie.lang.parse.ast.types.TypeDefinition; import jolie.lang.parse.ast.types.TypeDefinitionLink; import jolie.lang.parse.ast.types.TypeInlineDefinition; import jolie.lang.parse.util.Interfaces; import jolie.lang.parse.util.ProgramInspector; import jolie.runtime.typing.OneWayTypeDescription; import jolie.runtime.typing.RequestResponseTypeDescription; import jolie.util.Range; /** * * @author Claudio Guidi * * Modified by Francesco Bullini, 05/07/2012 */ public class SurfaceCreator { private ProgramInspector inspector; private URI originalFile; private ArrayList<RequestResponseOperationDeclaration> rr_vector; private ArrayList<OneWayOperationDeclaration> ow_vector; private ArrayList<String> types_vector; private ArrayList<TypeDefinition> aux_types_vector; private int MAX_CARD = 2147483647; public SurfaceCreator( ProgramInspector inspector, URI originalFile ) { this.inspector = inspector; this.originalFile = originalFile; } public void ConvertDocument( String inputPortToCreate ) throws Exception { ArrayList<InterfaceDefinition> interface_vector = new ArrayList<InterfaceDefinition>(); rr_vector = new ArrayList<RequestResponseOperationDeclaration>(); ow_vector = new ArrayList<OneWayOperationDeclaration>(); types_vector = new ArrayList<String>(); aux_types_vector = new ArrayList<TypeDefinition>(); // find inputPort InputPortInfo[] inputPortList = inspector.getInputPorts( originalFile ); InputPortInfo inputPort = null; for( InputPortInfo iP : inputPortList ) { if ( iP.id().equals( inputPortToCreate ) ) { inputPort = iP; } } if ( inputPort == null ) { throw (new Exception( "Error! inputPort not found!" )); } // extracts the list of all the interfaces to be parsed // extracts interfaces declared into Interfaces for( InterfaceDefinition interfaceDefinition : inputPort.getInterfaceList() ) { interface_vector.add( interfaceDefinition ); } OutputPortInfo[] outputPortList = inspector.getOutputPorts( originalFile ); // extracts interfaces from aggregated outputPorts for( int x = 0; x < inputPort.aggregationList().length; x++ ) { int i = 0; while( !inputPort.aggregationList()[x].outputPortList()[0].equals( outputPortList[i].id() ) ) { i++; } for( InterfaceDefinition interfaceDefinition : outputPortList[i].getInterfaceList() ) { interface_vector.add( Interfaces.extend( interfaceDefinition, inputPort.aggregationList()[x].interfaceExtender(), inputPort.id() ) ); } } // for each interface extract the list of all the available operations and types for( InterfaceDefinition interfaceDefinition : interface_vector ) { addOperation( interfaceDefinition ); } // create oputput createOutput( inputPort ); } private void addOperation( InterfaceDefinition interfaceDefinition ) { for( OperationDeclaration op : interfaceDefinition.operationsMap().values() ) { if ( op instanceof RequestResponseOperationDeclaration ) { rr_vector.add( (RequestResponseOperationDeclaration) op ); } else { ow_vector.add( (OneWayOperationDeclaration) op ); } } } private String getOWString( OneWayOperationDeclaration ow ) { String ret = ow.id() + "( " + ow.requestType().id() + " )"; return ret; } private String getRRString( RequestResponseOperationDeclaration rr ) { String ret = rr.id() + "( " + rr.requestType().id() + " )( " + rr.responseType().id() + " )"; if ( rr.faults().size() > 0 ) { ret = ret + " throws "; boolean flag = false; for( Entry<String, TypeDefinition> fault : rr.faults().entrySet() ) { if ( flag == false ) { flag = true; } else { ret = ret + " "; } ret = ret + fault.getKey(); if ( fault.getValue() != null ) { ret = ret + "( " + fault.getValue().id() + " )"; } } } return ret; } private String getMax( int max ) { if ( max == MAX_CARD ) { return "*"; } else { return new Integer( max ).toString(); } } private String getCardinality( Range card ) { return "[" + card.min() + "," + getMax( card.max() ) + "]"; } private String getSubType( TypeDefinition type, int indent ) { String ret = ""; for( int y = 0; y < indent; y++ ) { ret = ret + "\t"; } ret = ret + "." + type.id() + getCardinality( type.cardinality() ) + ":"; if ( type instanceof TypeDefinitionLink ) { ret = ret + ((TypeDefinitionLink) type).linkedTypeName(); if ( !aux_types_vector.contains( ((TypeDefinitionLink) type).linkedType() ) ) { aux_types_vector.add( ((TypeDefinitionLink) type).linkedType() ); } } else { ret = ret + type.nativeType().id(); if ( ((TypeInlineDefinition) type).hasSubTypes() ) { ret = ret + "{ \n"; for( Entry<String, TypeDefinition> entry : ((TypeInlineDefinition) type).subTypes() ) { ret = ret + getSubType( entry.getValue(), indent + 1 ) + "\n"; } for( int y = 0; y < indent; y++ ) { ret = ret + "\t"; } ret = ret + "}"; } else if (type.untypedSubTypes()){ ret = ret+ "{ ? }"; } } ; return ret; } private String getType( TypeDefinition type ) { String ret = ""; if ( !types_vector.contains( type.id() ) && !NativeType.isNativeTypeKeyword( type.id() ) && !type.id().equals("undefined")) { System.out.print( "type " + type.id() + ":" ); if ( type instanceof TypeDefinitionLink ) { System.out.println( ((TypeDefinitionLink) type).linkedTypeName() ); if ( !aux_types_vector.contains( ((TypeDefinitionLink) type).linkedType() ) ) { aux_types_vector.add( ((TypeDefinitionLink) type).linkedType() ); } } else { System.out.print( type.nativeType().id() ); if ( ((TypeInlineDefinition) type).hasSubTypes() ) { System.out.println( "{" ); for( Entry<String, TypeDefinition> entry : ((TypeInlineDefinition) type).subTypes() ) { System.out.println( getSubType( entry.getValue(), 1 ) ); } System.out.println( "}" ); } else { if (type.untypedSubTypes()) { System.out.println( " { ? }" );} else { System.out.println( "" ); } } } types_vector.add( type.id() ); } return ret; } private void printType( String type ) { if ( !type.equals( "" ) ) { System.out.println( type ); } } private void createOutput( InputPortInfo inputPort ) { // types creation if ( ow_vector.size() > 0 ) { for( int x = 0; x < ow_vector.size(); x++ ) { //System.out.println("// types for operation " + ow_vector.get(x).id() ); printType( getType( ow_vector.get( x ).requestType() ) ); } System.out.println(); } if ( rr_vector.size() > 0 ) { for( int x = 0; x < rr_vector.size(); x++ ) { //System.out.println("// types for operation " + rr_vector.get(x).id() ); printType( getType( rr_vector.get( x ).requestType() ) ); printType( getType( rr_vector.get( x ).responseType() ) ); for( Entry<String, TypeDefinition> fault : rr_vector.get( x ).faults().entrySet() ) { if ( !fault.getValue().id().equals( "undefined" ) ) { System.out.println( getType( fault.getValue() ) ); } } } System.out.println(); } // add auxiliary types while( !aux_types_vector.isEmpty() ) { ArrayList<TypeDefinition> aux_types_temp_vector = new ArrayList<TypeDefinition>(); aux_types_temp_vector.addAll( aux_types_vector ); aux_types_vector.clear(); Iterator it = aux_types_temp_vector.iterator(); while( it.hasNext() ) { printType( getType( (TypeDefinition) it.next() ) ); } } System.out.println(); // interface creation System.out.println( "interface " + inputPort.id() + "Surface {" ); // oneway declaration if ( ow_vector.size() > 0 ) { System.out.println( "OneWay:" ); for( int x = 0; x < ow_vector.size(); x++ ) { if ( x != 0 ) { System.out.println( "," ); } System.out.print( "\t" + getOWString( ow_vector.get( x ) ) ); } System.out.println(); } // request response declaration if ( rr_vector.size() > 0 ) { System.out.println( "RequestResponse:" ); for( int x = 0; x < rr_vector.size(); x++ ) { if ( x != 0 ) { System.out.println( "," ); } System.out.print( "\t" + getRRString( rr_vector.get( x ) ) ); } System.out.println(); } System.out.println( "}" ); System.out.println(); // outputPort definition System.out.println( "outputPort " + inputPort.id() + "{" ); System.out.println( "\tLocation:\"" + inputPort.location() + "\"" ); System.out.println( "\tProtocol:" + inputPort.protocolId() ); System.out.println( "\tInterfaces:" + inputPort.id() + "Surface" ); System.out.println( "}" ); } }