/***************************************************************************
* 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);
}
}