package nl.ipo.cds.admin.ba.controller.beans; import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; import java.sql.Date; import java.sql.Time; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import nl.ipo.cds.attributemapping.AttributeMapperUtils; import nl.ipo.cds.attributemapping.operations.OperationInputType; import nl.ipo.cds.attributemapping.operations.OperationType; import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.annotate.JsonPropertyOrder; import org.codehaus.jackson.map.annotate.JsonSerialize; import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion; import org.deegree.geometry.Geometry; @JsonSerialize (include = Inclusion.ALWAYS) @JsonPropertyOrder ({ "operationTypes", "typeDictionary" }) public class OperationTypesResponse { @JsonIgnore private final List<OperationTypeResponse> operationTypesList; @JsonIgnore private final Map<String, Map<String,Boolean>> typesMap = new HashMap<String, Map<String,Boolean>> (); @JsonIgnore private final HashSet<Type> types = new HashSet<Type> (); public OperationTypesResponse (final List<OperationTypeResponse> operationTypes) { this.operationTypesList = new ArrayList<OperationTypeResponse> (operationTypes); processTypes (operationTypes); } public List<OperationTypeResponse> getOperationTypes () { return Collections.unmodifiableList (operationTypesList); } public Map<String, Map<String, Boolean>> getTypeDictionary () { return Collections.unmodifiableMap (typesMap); } private void processTypes (final List<OperationTypeResponse> operationTypes) { types.add (Byte.TYPE); types.add (Short.TYPE); types.add (Character.TYPE); types.add (Integer.TYPE); types.add (Long.TYPE); types.add (Float.TYPE); types.add (Double.TYPE); types.add (Boolean.TYPE); types.add (BigInteger.class); types.add (BigDecimal.class); types.add (String.class); types.add (Geometry.class); types.add (Date.class); types.add (Time.class); // Create a list of all types that are used by operations: for (final OperationTypeResponse operationType: operationTypes) { listTypes (operationType.getOperationType ()); } // Calculate isAssignableFrom relations between types: for (final Type a: types) { for (final Type b: types) { processTypes (a, b); } } } private void processTypes (final Type a, final Type b) { if (a.equals (b) || Void.TYPE.equals (a) || Void.TYPE.equals (b) || !AttributeMapperUtils.areTypesAssignable (a, b)) { return; } final String aName = a.toString (); final String bName = b.toString (); if (!typesMap.containsKey (aName)) { typesMap.put (aName, new HashMap<String, Boolean> ()); } typesMap.get (aName).put (bName, true); } private void listTypes (final OperationType operationType) { listType (operationType.getReturnType ()); for (final OperationInputType input: operationType.getInputs ()) { listTypes (input); } } private void listTypes (final OperationInputType operationInputType) { listType (operationInputType.getInputType ()); } private void listType (final Type type) { types.add (type); } }