/** * Copyright 2008-2016 Qualogy Solutions B.V. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.qualogy.qafe.bind.commons.type; import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.commons.lang.builder.ToStringBuilder; import com.qualogy.qafe.bind.core.messages.PlaceHolder; /** * A parameter represents any form of data used in a call. * * A parameter typically has a name and ref (to a piece of data) or static value. * A parameter also could have a type supplied through its value property, if * not supplied its assumable the type for this parameter is the instanceof the data * the parameter represents. * * The ref is what the calling party has called it for the using party. * The name is what the using party needs for further processing. * * If you would take a look at a possible implementation than an inbound parameter * to f.i. a service could have a name supplied which points to the name used * in the actual service. The ref will be used to retrieve data from the datastore * to be used in that service (or if not supplied the name is assumed to be the ref). * Outbound, the ref points to the name the actual service uses for the piece of data * and the ref tells where it'll be stored in the datastore. * * <code> * <in ref="servicein" name="actualservicein"/><!-- ref is how its stored in the datastore, name is how this service calls it --> * <out ref="actualserviceout" name="serviceout"/><!-- in ref from actualservice, out name to the world --> * </code> * * @author * */ public class Parameter implements Serializable, Inputable, Comparable<Parameter>, Cloneable { private static final long serialVersionUID = 73634993433835489L; public final static char ATTRIBUTE_DELIMITER ='@'; /** * key to delimit objects */ public final static char OBJECT_DELIMITER = '.'; /** * identifier to identify the start of a reference call to one of a lists objects */ public final static String LIST_IDENTIFIER_START = "["; /** * identifier to identify the end of a reference call to one of a lists objects */ public final static String LIST_IDENTIFIER_END = "]"; public static final String ATTRIBUTE_SIZE = "size"; /** * name for this parameter */ protected String name; /** * reference property holder to the data for this parameter */ protected Reference ref; /** * object that holds the defaultvalue and type for this object */ protected Value value; /** * adapter holds variables for the posibility of adapting a value for this parameter * to the actual type of this parameter */ protected AdapterMapping adapter; /** * list of placeholder objects intended for replacement of placeholder data * within a value that concludes from getting this parameter from any system resource */ protected List<PlaceHolder> placeHolders = null; /** * parameter that can hold an executable script expression */ protected String expression; /** * boolean indicating if this parameter allows the value for this parameter may be null */ protected boolean nullable; /** * variable which can be set (some paramaters don't take this attr by binding) to specify * if this parameter should be set inbound on a resource even when null. */ protected Boolean useWhenNotSet; private Object data; public Object getData() { return data; } public void setData(Object data) { this.data = data; } public Boolean getUseWhenNotSet() { return useWhenNotSet; } public void setUseWhenNotSet(Boolean useWhenNotSet) { this.useWhenNotSet = useWhenNotSet; } public boolean isNullable() { return nullable; } public Parameter() { super(); } public Parameter(String staticValue) { super(); this.value = new Value(staticValue); } public Parameter(Parameter otherParam) { this.adapter = otherParam.adapter; this.expression = otherParam.expression; this.name = otherParam.name; this.nullable = otherParam.nullable; this.placeHolders = otherParam.placeHolders; if (otherParam.ref != null) { this.ref = new Reference(otherParam.ref); } if (otherParam.value != null) { this.value = new Value(otherParam.value.getStaticValue()); } } public Parameter(String name, Reference ref, Value value, AdapterMapping adapter) { super(); this.name = name; this.ref = ref; this.value = value; this.adapter = adapter; } public Parameter(final String name, final Value value) { super(); this.name = name; this.value = value; } public Parameter(final String name, final Reference ref) { super(); this.name = name; this.ref = ref; } public Parameter(final Reference ref) { this(null, ref); } public Parameter(Reference reference, Value value) { this(null, reference, value, null); } public String getName() { return name; } /** * Method to get the root for this name. Examples: * - root.key1.key2 = root * - key1.key2 = key1 * - key2 = key2 * @return */ public final String getNameRoot(){ String key = this.name; int dotMark = key.indexOf(Parameter.OBJECT_DELIMITER); return (dotMark>-1)?key.substring(0, dotMark):key; } //TODO: if one of the values is not a number public int compareTo(Parameter otherParameter) { int value1 = 0; int value2 = 0; try { value1 = Integer.parseInt(getName()); }catch (NumberFormatException e) { // counted for, ordering is only for numbered parameters } try { value2 = Integer.parseInt(otherParameter.getName()); }catch (NumberFormatException e) { // counted for, ordering is only for numbered parameters } return value1 - value2; } public Reference getRef() { return ref; } public AdapterMapping getAdapter() { return adapter; } public String toString() { return ToStringBuilder.reflectionToString(this); } public Value getValue() { return value; } public void setValue(Value value) { this.value = value; } public void setName(String name) { this.name = name; } public void setRef(Reference ref) { this.ref = ref; } public TypeDefinition getType() { return value != null ? value.getType() : null; } public String getOutputClass() { return value != null ? value.getOutputClass() : null; } public void setType(String type) { TypeDefinition def = new TypeDefinition(type); if(value == null) value = new Value(); value.setType(def); } /** * shallow clone */ public Object clone() throws CloneNotSupportedException { Parameter clone = (Parameter)super.clone(); if (this.adapter != null) { clone.adapter = this.adapter; } if (this.name != null) { clone.name = new String(this.name); } if (this.ref != null) { clone.ref = new Reference(this.ref); } if (this.value != null) { clone.value = new Value(this.value.getStaticValue()); } if (this.expression != null) { clone.expression = new String(this.expression); } clone.nullable = this.nullable; if (placeHolders != null) { clone.placeHolders = new ArrayList<PlaceHolder>(); Iterator<PlaceHolder> itr = placeHolders.iterator(); while (itr.hasNext()){ Object o = itr.next(); if (o instanceof PlaceHolder){ PlaceHolder origPlaceHolder = (PlaceHolder)o; PlaceHolder clonePlaceHolder = (PlaceHolder)origPlaceHolder.clone(); clone.placeHolders.add(clonePlaceHolder); } } } return clone; } public boolean hasPlaceHolders() { return placeHolders!=null && placeHolders.size()>0; } public List<PlaceHolder> getPlaceHolders() { return placeHolders; } /** * method to add a placeHolder to a placeHolder list. The list will be * created when null * @param placeHolder * @throws IllegalArgumentException - when object param passed is null or reference within the item is null */ public void add(PlaceHolder placeHolder) { if(placeHolder==null) throw new IllegalArgumentException("placeHolder cannot be null"); if(placeHolders==null) placeHolders = new ArrayList<PlaceHolder>(); placeHolders.add(placeHolder); } public String getExpression() { return expression; } public void setExpression(String expression) { this.expression = expression; } public void addAll(List<PlaceHolder> placeHolders) { if(placeHolders!=null){ if(this.placeHolders==null) this.placeHolders = new ArrayList<PlaceHolder>(); this.placeHolders.addAll(placeHolders); } } }