/* * NOTE: This copyright does *not* cover user programs that use HQ * program services by normal system calls through the application * program interfaces provided as part of the Hyperic Plug-in Development * Kit or the Hyperic Client Development Kit - this is merely considered * normal use of the program, and does *not* fall under the heading of * "derived work". * * Copyright (C) [2004, 2005, 2006], Hyperic, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */ package org.hyperic.lather; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; /** * The basic value object for passing data to/from a Lather server. * * LatherValue objects have a variety of ways to interact with them. * The most simplistic way is to use simple key/value pairs. * * The object also supports keys which map onto lists of data. * * Values contained within the object can have associated primitive * types, such as int, double, byte[] and String. * * Access to LatherValue is unsynchronized, so callers must do their * own. */ public abstract class LatherValue { private Map stringVals; // Strings -> Strings private Map intVals; // Strings -> Integers private Map doubleVals; // Strings -> Doubles private Map longVals; // Strings -> Longs private Map byteaVals; // Strings -> byte[]s private Map objectVals; // Strings -> LatherValues private Map javaObjectVals; // Strings -> Object private Map stringLists; // Strings -> List of Strings private Map intLists; // Strings -> List of Integers private Map doubleLists; // Strings -> List of Doubles private Map byteaLists; // Strings -> List of byte[]s private Map objectLists; // Strings -> List of LatherValues private final Map<String, Serializable> serializableMap = new HashMap<String, Serializable>(); private boolean ensureOrder; /** * Get a map used for storing the different types of values (i.e. * setStringVals, etc.) */ private Map createStorageMap(){ if (this.ensureOrder) { return new TreeMap(); } return new HashMap(); } private void setup(boolean ensureOrder){ this.ensureOrder = ensureOrder; this.stringVals = this.createStorageMap(); this.intVals = this.createStorageMap(); this.doubleVals = this.createStorageMap(); this.longVals = this.createStorageMap(); this.byteaVals = this.createStorageMap(); this.objectVals = this.createStorageMap(); this.stringLists = this.createStorageMap(); this.intLists = this.createStorageMap(); this.doubleLists = this.createStorageMap(); this.byteaLists = this.createStorageMap(); this.objectLists = this.createStorageMap(); } public LatherValue(){ this.setup(false); } /** * Using this constructor guarantees that encoding the exact * same LatherValue 2 different times generates the same byte * order, as the maps are traversed in the same order. */ public LatherValue(boolean ensureOrder){ this.setup(ensureOrder); } private void checkArg(Object arg){ if(arg == null){ throw new IllegalArgumentException("Argument cannot be null"); } } protected String getStringValue(String key){ String res; if((res = (String)this.stringVals.get(key)) == null){ throw new LatherKeyNotFoundException(key); } return res; } protected void setStringValue(String key, String value){ this.checkArg(value); this.stringVals.put(key, value); } protected int getIntValue(String key){ Integer res; if((res = (Integer)this.intVals.get(key)) == null){ throw new LatherKeyNotFoundException(key); } return res.intValue(); } protected void setIntValue(String key, int value){ this.intVals.put(key, new Integer(value)); } protected double getDoubleValue(String key){ Double res; if((res = (Double)this.doubleVals.get(key)) == null){ throw new LatherKeyNotFoundException(key); } return res.doubleValue(); } protected void setDoubleValue(String key, double value){ this.doubleVals.put(key, new Double(value)); } protected long getLongValue(String key){ Long res; if ((res = (Long)this.longVals.get(key)) == null){ throw new LatherKeyNotFoundException(key); } return res.longValue(); } protected void setLongValue(String key, long value){ this.longVals.put(key, new Long(value)); } protected byte[] getByteAValue(String key){ byte[] res; if((res = (byte[])this.byteaVals.get(key)) == null){ throw new LatherKeyNotFoundException(key); } return res; } protected void setObjectValue(String key, LatherValue value){ this.checkArg(value); this.objectVals.put(key, value); } protected LatherValue getObjectValue(String key){ LatherValue res; if((res = (LatherValue)this.objectVals.get(key)) == null){ throw new LatherKeyNotFoundException(key); } return res; } protected void setByteAValue(String key, byte[] value){ this.checkArg(value); this.byteaVals.put(key, value); } private List getListValueForAdd(Map map, String listName){ List res = (List)map.get(listName); if(res == null){ res = new ArrayList(); map.put(listName, res); } return res; } private List getListValueForGet(Map map, String listName){ List res = (List)map.get(listName); if(res == null){ throw new LatherKeyNotFoundException(listName); } return res; } protected void addStringToList(String listName, String value){ List list = this.getListValueForAdd(this.stringLists, listName); this.checkArg(value); list.add(value); } protected String[] getStringList(String listName){ List list = this.getListValueForGet(this.stringLists, listName); return (String[])list.toArray(new String[0]); } protected void addIntToList(String listName, int value){ List list = this.getListValueForAdd(this.intLists, listName); list.add(new Integer(value)); } protected int[] getIntList(String listName){ List list = this.getListValueForGet(this.intLists, listName); int[] res; int idx; res = new int[list.size()]; idx = 0; for(Iterator i=list.iterator(); i.hasNext(); ){ Integer val = (Integer)i.next(); res[idx++] = val.intValue(); } return res; } protected void addDoubleToList(String listName, double value){ List list = this.getListValueForAdd(this.doubleLists, listName); list.add(new Double(value)); } protected double[] getDoubleList(String listName){ List list = this.getListValueForGet(this.doubleLists, listName); double[] res; int idx; res = new double[list.size()]; idx = 0; for(Iterator i=list.iterator(); i.hasNext(); ){ Double val = (Double)i.next(); res[idx++] = val.doubleValue(); } return res; } protected void addByteAToList(String listName, byte[] value){ List list = this.getListValueForAdd(this.byteaLists, listName); this.checkArg(value); list.add(value); } protected byte[][] getByteAList(String listName){ List list = this.getListValueForGet(this.byteaLists, listName); return (byte[][])list.toArray(new byte[0][]); } protected void addObjectToList(String listName, Object value){ List list = this.getListValueForAdd(this.objectLists, listName); this.checkArg(value); list.add(value); } protected Object[] getObjectList(String listName){ List list = this.getListValueForGet(this.objectLists, listName); return list.toArray(new LatherValue[0]); } protected Serializable getObject(String objectName) { return serializableMap.get(objectName); } protected void addObject(String objectName, Serializable object) { serializableMap.put(objectName, object); } public Map getStringVals(){ return this.stringVals; } public Map getIntVals(){ return this.intVals; } public Map getDoubleVals(){ return this.doubleVals; } public Map getLongVals(){ return this.longVals; } public Map getByteAVals(){ return this.byteaVals; } public Map getObjectVals(){ return this.objectVals; } public Map getStringLists(){ return this.stringLists; } public Map getIntLists(){ return this.intLists; } public Map getDoubleLists(){ return this.doubleLists; } public Map getByteALists(){ return this.byteaLists; } public Map getObjectLists(){ return this.objectLists; } public Map<String, Serializable> getSerializableMap() { return this.serializableMap; } /** * This method is called to verify that a LatherValue object * has all the appropriate contents. It is invoked after the * LatherXCoder decodes a stream and formulates a LatherValue. */ public abstract void validate() throws LatherRemoteException; }