/*************************************************************************** * Copyright 2011 (C) by Fabrizio Montesi <famontesi@gmail.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 jolie.net.ports; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import jolie.lang.parse.ast.InterfaceDefinition; import jolie.runtime.typing.OneWayTypeDescription; import jolie.runtime.typing.RequestResponseTypeDescription; import jolie.runtime.typing.Type; /** * Represents the (runtime) interface of a port, holding data about * the types of the operations defined within. * @author Fabrizio Montesi */ public class Interface { private static final class UndefinedOneWayOperationsMap implements Map< String, OneWayTypeDescription > { private static final Set< Entry< String, OneWayTypeDescription > > entrySet = Collections.unmodifiableSet( new HashSet< Entry< String, OneWayTypeDescription > >() ); private static final Collection< OneWayTypeDescription > values = Collections.unmodifiableCollection( new ArrayList< OneWayTypeDescription >( 0 ) ); private static final Set< String > keySet = Collections.unmodifiableSet( new HashSet< String >() ); private static final OneWayTypeDescription value = new OneWayTypeDescription( Type.UNDEFINED ); public Set< Entry< String, OneWayTypeDescription > > entrySet() { return entrySet; } public Collection< OneWayTypeDescription > values() { return values; } public Set< String > keySet() { return keySet; } public void clear() {} public void putAll( Map< ? extends String, ? extends OneWayTypeDescription > map ) { throw new UnsupportedOperationException(); } public OneWayTypeDescription remove( Object key ) { throw new UnsupportedOperationException(); } public OneWayTypeDescription put( String key, OneWayTypeDescription value ) { throw new UnsupportedOperationException(); } public OneWayTypeDescription get( Object key ) { return value; } public boolean containsValue( Object value ) { throw new UnsupportedOperationException(); } public boolean containsKey( Object value ) { return true; } public boolean isEmpty() { return false; } public int size() { throw new UnsupportedOperationException(); } } private static final class UndefinedRequestResponseOperationsMap implements Map< String, RequestResponseTypeDescription > { private static final Set< Entry< String, RequestResponseTypeDescription > > entrySet = Collections.unmodifiableSet( new HashSet< Entry< String, RequestResponseTypeDescription > >() ); private static final Collection< RequestResponseTypeDescription > values = Collections.unmodifiableCollection( new ArrayList< RequestResponseTypeDescription >( 0 ) ); private static final Set< String > keySet = Collections.unmodifiableSet( new HashSet< String >() ); private static final RequestResponseTypeDescription value = new RequestResponseTypeDescription( Type.UNDEFINED, Type.UNDEFINED, new HashMap< String, Type >() ); public Set< Entry< String, RequestResponseTypeDescription > > entrySet() { return entrySet; } public Collection< RequestResponseTypeDescription > values() { return values; } public Set< String > keySet() { return keySet; } public void clear() {} public void putAll( Map< ? extends String, ? extends RequestResponseTypeDescription > map ) { throw new UnsupportedOperationException(); } public RequestResponseTypeDescription remove( Object key ) { throw new UnsupportedOperationException(); } public RequestResponseTypeDescription put( String key, RequestResponseTypeDescription value ) { throw new UnsupportedOperationException(); } public RequestResponseTypeDescription get( Object key ) { return value; } public boolean containsValue( Object value ) { throw new UnsupportedOperationException(); } public boolean containsKey( Object value ) { return true; } public boolean isEmpty() { return false; } public int size() { throw new UnsupportedOperationException(); } } public static final Interface UNDEFINED; private static final Map< String, OneWayTypeDescription > UNDEFINED_ONE_WAY_MAP; private static final Map< String, RequestResponseTypeDescription > UNDEFINED_REQUEST_RESPONSE_MAP; static { UNDEFINED_ONE_WAY_MAP = new UndefinedOneWayOperationsMap(); UNDEFINED_REQUEST_RESPONSE_MAP = new UndefinedRequestResponseOperationsMap(); UNDEFINED = new Interface( UNDEFINED_ONE_WAY_MAP, UNDEFINED_REQUEST_RESPONSE_MAP ); } private final Map< String, RequestResponseTypeDescription > requestResponseOperations; private final Map< String, OneWayTypeDescription > oneWayOperations; private final Map< String, InterfaceDefinition> operationsMap; public Interface( Map< String, OneWayTypeDescription > oneWayOperations, Map< String, RequestResponseTypeDescription > requestResponseOperations ) { this.oneWayOperations = oneWayOperations; this.requestResponseOperations = requestResponseOperations; this.operationsMap = null; } public Interface( Map< String, OneWayTypeDescription > oneWayOperations, Map< String, RequestResponseTypeDescription > requestResponseOperations, List<InterfaceDefinition> interfaceNames ) { this.oneWayOperations = oneWayOperations; this.requestResponseOperations = requestResponseOperations; Map<String, InterfaceDefinition> ifaceMap = new HashMap<String, InterfaceDefinition>(); for (InterfaceDefinition i : interfaceNames) { Iterator it = i.operationsMap().entrySet().iterator(); while (it.hasNext()) { Map.Entry pairs = (Map.Entry) it.next(); if (pairs.getKey().getClass() == String.class) { ifaceMap.put((String) pairs.getKey(), i);// } it.remove(); // avoids a ConcurrentModificationException } } this.operationsMap = ifaceMap; } public Map< String, OneWayTypeDescription > oneWayOperations() { return oneWayOperations; } public Map< String, RequestResponseTypeDescription > requestResponseOperations() { return requestResponseOperations; } public void merge( Interface other ) { oneWayOperations.putAll( other.oneWayOperations ); requestResponseOperations.putAll( other.requestResponseOperations ); } public boolean containsOperation( String operationName ) { return oneWayOperations.containsKey( operationName ) || requestResponseOperations.containsKey( operationName ); } public InterfaceDefinition interfaceForOperation(String operationName) { return operationsMap.get(operationName); } }