/* *------------------------------------------------------------------------------ * Copyright (C) 2006-2014 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.env.data.model; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.collections.CollectionUtils; import omero.gateway.util.PojoMapper; import omero.RBool; import omero.RDouble; import omero.RFloat; import omero.RInt; import omero.RList; import omero.RLong; import omero.RMap; import omero.RObject; import omero.RString; import omero.RType; import omero.grid.Param; import omero.model.IObject; /** * Wraps up a parameter object. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * <small> * (<b>Internal version:</b> $Revision: $Date: $) * </small> * @since 3.0-Beta4 */ public class ParamData { /** The parameter to handle. */ private Param param; /** The list of possible values. */ private List<Object> values; /** The default value. */ private Object defaultValue; /** The default value. */ private Object minValue; /** The default value. */ private Object maxValue; /** The type of object to handle. */ private Class<?> type; /** The value to pass in order to run the script. */ private Object valueToPass; /** Initializes the value. */ private void initialize() { type = null; minValue = null; maxValue = null; RType t = param.prototype; Object o = convertRType(t); defaultValue = o; if (o instanceof Long) { type = Long.class; } else if (o instanceof Integer) { type = Integer.class; } else if (o instanceof String) { type = String.class; } else if (o instanceof Boolean) { type = Boolean.class; } else if (o instanceof Float) { type = Float.class; } else if (o instanceof Double) { type = Double.class; } else if (o instanceof List) { type = List.class; } else if (o instanceof Map) { type = Map.class; } else if (o instanceof omero.gateway.model.DataObject) type = omero.gateway.model.DataObject.class; Number n; boolean set = false; Object value = convertRType(param.min); if (value instanceof Number) { minValue = value; set = true; if (defaultValue == null) { defaultValue = minValue; } else { n = (Number) defaultValue; if (n.doubleValue() < ((Number) minValue).doubleValue()) defaultValue = minValue; } } value = convertRType(param.max); if (value instanceof Number) { maxValue = value; if (!set) { if (defaultValue != null) { n = (Number) defaultValue; if (n.doubleValue() > ((Number) maxValue).doubleValue()) defaultValue = maxValue; } else { defaultValue = maxValue; } } } if (defaultValue instanceof List) { List l = (List) defaultValue; if (l.size() > 0) defaultValue = l.get(0); } } /** * Converts the passed value into the corresponding RType. * * @param value The value to convert. * @return See above. */ private static RType convertBasicValue(Object value) { if (value == null) return null; if (value instanceof Boolean) return omero.rtypes.rbool((Boolean) value); if (value instanceof String) { String v = (String) value; if (v.length() == 0) return null; return omero.rtypes.rstring(v); } if (value instanceof Long) return omero.rtypes.rlong((Long) value); if (value instanceof Integer) return omero.rtypes.rint((Integer) value); if (value instanceof Float) return omero.rtypes.rfloat((Float) value); if (value instanceof Double) return omero.rtypes.rdouble((Double) value); if (value instanceof omero.gateway.model.DataObject) { IObject o = ((omero.gateway.model.DataObject) value).asIObject(); return omero.rtypes.robject(o); } return null; } /** * Converts the basic RType. * * @param value The value to convert. * @return See above. */ private static Object convertBasicRType(RType value) { if (value instanceof RBool) return ((RBool) value).getValue(); if (value instanceof RString) return ((RString) value).getValue(); if (value instanceof RLong) return ((RLong) value).getValue(); if (value instanceof RInt) return ((RInt) value).getValue(); if (value instanceof RFloat) return ((RFloat) value).getValue(); if (value instanceof RDouble) return ((RDouble) value).getValue(); if (value instanceof RObject) { IObject o = ((RObject) value).getValue(); Object r = PojoMapper.asDataObject(o); if (r != null) return r; return o; } return null; } /** * Creates a new instance. * * @param param The object to handle. */ public ParamData(Param param) { this.param = param; initialize(); } /** * Returns the grouping value if set. * * @return See above. */ public String getGrouping() { String grouping = ""; if (param.grouping != null) grouping = param.grouping.trim(); return grouping; } /** * Parses the grouping value to find if the parameter is a sub-parameter * e.g. grouping = 5.1, the returned value is 5. * * @return See above. */ public String getParent() { String v = getGrouping(); if (v.length() == 0) return ""; int index = v.lastIndexOf("."); if (index >= 0) return v.substring(0, index); return ""; } /** * Returns <code>true</code> if the parameter is optional, * <code>false</code> otherwise. * * @return See above. */ public boolean isOptional() { return param.optional; } /** * Returns the description of the parameter. * * @return See above. */ public String getDescription() { return param.description; } /** * Returns the type of value expected. * * @return See above. */ public Class<?> getPrototype() { return type; } /** * Returns the type of a key element if the prototype is a List or a Map. * * @return See above. */ public Class<?> getKeyType() { Object o; if (List.class.equals(type)) { List<RType> l = ((RList) param.prototype).getValue(); if (l.size() > 0) { o = convertBasicRType(l.get(0)); if (o instanceof Long || o instanceof Integer || o instanceof Double || o instanceof Float) return o.getClass(); } return String.class; } else if (Map.class.equals(type)) return String.class; return null; } /** * Returns the type of a value element if the prototype is a List or a Map. * * @return See above. */ public Class<?> getValueType() { if (List.class.equals(type)) return getKeyType(); else if (Map.class.equals(type)) { Map<String, RType> l = ((RMap) param.prototype).getValue(); if (l.size() > 0) { Object o; Entry<String, RType> entry; Iterator<Entry<String, RType>> i = l.entrySet().iterator(); o = null; while (i.hasNext()) { entry = i.next(); o = convertBasicRType(entry.getValue()); if (o != null) { break; } } if (o instanceof Long || o instanceof Integer || o instanceof Double || o instanceof Float) return o.getClass(); } return String.class; //TODO } return null; } /** * Returns the list of possible values or <code>null</code> if none set. * * @return See above. */ public List<Object> getValues() { if (values != null) return values; RList list = param.values; if (list == null) return null; List<RType> l = list.getValue(); if (CollectionUtils.isEmpty(l)) return null; values = new ArrayList<Object>(); Iterator<RType> i = l.iterator(); Object value; while (i.hasNext()) { value = convertRType(i.next()); if (value != null) values.add(value); } return values; } /** * Returns the maximum value or <code>null</code> if none set. * * @return See above. */ public Number getMaxValue() { if (maxValue == null) return null; return (Number) maxValue; } /** * Returns the minimum value or <code>null</code> if none set. * * @return See above. */ public Number getMinValue() { if (minValue == null) return null; return (Number) minValue; } /** * Returns the default value or <code>null</code> if none set. * * @return See above. */ public Object getDefaultValue() { if (param.useDefault) return defaultValue; return null; } /** * Sets the value to pass while running the script. * * @param valueToPass The value to pass. */ public void setValueToPass(Object valueToPass) { if (valueToPass == null) { valueToPass = getDefaultValue(); } this.valueToPass = valueToPass; } /** * Returns the value to pass while running the script. * * @return See above. */ public RType getValueToPassAsRType() { if (valueToPass instanceof Boolean || valueToPass instanceof String || valueToPass instanceof Long || valueToPass instanceof Integer || valueToPass instanceof Float || valueToPass instanceof Double) return convertBasicValue(valueToPass); if (valueToPass instanceof List) { List<RType> l = new ArrayList<RType>(); List<?> list = (List<?>) valueToPass; Iterator<?> i = list.iterator(); RType key; while (i.hasNext()) { key = convertBasicValue(i.next()); if (key != null) l.add(key); } if (l.size() == 0) return null; return omero.rtypes.rlist(l); } if (valueToPass instanceof Map) { Map<String, RType> m = new HashMap<String, RType>(); Map<String, RType> map = (Map<String, RType>) valueToPass; Entry<String, RType> entry; RType type; Iterator<Entry<String, RType>> i = map.entrySet().iterator(); while (i.hasNext()) { entry = i.next(); type = convertBasicValue(entry.getValue()); if (type != null) m.put(entry.getKey(), type); } if (m.size() == 0) return null; return omero.rtypes.rmap(m); } return null; } /** * Converts the passed value. * * @param value The value to handle. * @return The converted value. */ public static Object convertRType(RType value) { if (value instanceof RBool || value instanceof RString || value instanceof RLong || value instanceof RInt || value instanceof RFloat || value instanceof RObject || value instanceof RDouble) return convertBasicRType(value); if (value instanceof RList) { List<RType> list = ((RList) value).getValue(); List<Object> l = new ArrayList<Object>(); Iterator<RType> i = list.iterator(); Object o; while (i.hasNext()) { o = convertRType(i.next()); if (o != null) l.add(o); } return l; } if (value instanceof RMap) { Map<String, RType> map = ((RMap) value).getValue(); Map<String, Object> r = new HashMap<String, Object>(); Entry<String, RType> entry; Object v; Iterator<Entry<String, RType>> i = map.entrySet().iterator(); while (i.hasNext()) { entry = i.next(); v = convertRType(entry.getValue()); if (v != null) { r.put(entry.getKey(), v); } } return r; } return null; } }