com.ibm.staf.STAFMarshallingContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jstaf Show documentation
Show all versions of jstaf Show documentation
The Software Testing Automation Framework (STAF) is an open source,
multi-platform, multi-language framework designed around the idea of reusable
components, called services (such as process invocation, resource management,
logging, and monitoring). STAF removes the tedium of building an automation
infrastructure, thus enabling you to focus on building your automation solution.
The STAF framework provides the foundation upon which to build higher level
solutions, and provides a pluggable approach supported across a large variety
of platforms and languages.
This component contains the STAF Java API
(http://staf.sourceforge.net/current/STAFJava.htm ) only.
For more information see http://staf.sourceforge.net/ .
The newest version!
/*****************************************************************************/
/* Software Testing Automation Framework (STAF) */
/* (C) Copyright IBM Corp. 2004 */
/* */
/* This software is licensed under the Eclipse Public License (EPL) V1.0. */
/*****************************************************************************/
package com.ibm.staf;
import java.util.*;
public class STAFMarshallingContext
{
public static final int UNMARSHALLING_DEFAULTS = 0;
public static final int IGNORE_INDIRECT_OBJECTS = 1;
public static boolean isMarshalledData(String someData)
{
return someData.startsWith("@SDT/");
}
public STAFMarshallingContext()
{ /* Do nothing */ }
public STAFMarshallingContext(Object obj)
{
rootObject = obj;
}
STAFMarshallingContext(Object obj, Map mapClassMap)
{
rootObject = obj;
this.mapClassMap = mapClassMap;
}
public void setMapClassDefinition(STAFMapClassDefinition mapClassDef)
{
mapClassMap.put(mapClassDef.name(),
mapClassDef.getMapClassDefinitionObject());
}
public STAFMapClassDefinition getMapClassDefinition(String mapClassName)
{
return new STAFMapClassDefinition((Map)mapClassMap.get(mapClassName));
}
public boolean hasMapClassDefinition(String mapClassName)
{
return mapClassMap.containsKey(mapClassName);
}
Map getMapClassMap()
{
return Collections.unmodifiableMap(mapClassMap);
}
public Iterator mapClassDefinitionIterator()
{
return mapClassMap.keySet().iterator();
}
public void setRootObject(Object rootObject)
{
this.rootObject = rootObject;
}
public Object getRootObject()
{
return rootObject;
}
public Object getPrimaryObject()
{
if (mapClassMap.size() == 0) return rootObject;
return this;
}
public String marshall()
{
return marshall(this, this);
}
public static String marshall(Object object, STAFMarshallingContext context)
{
if (object == null)
{
return NONE_MARKER;
}
if (object instanceof List)
{
List list = (List)object;
Iterator iter = list.iterator();
StringBuffer listData = new StringBuffer();
while (iter.hasNext())
listData.append(marshall(iter.next(), context));
return LIST_MARKER + list.size() + ":" + listData.length() + ":" +
listData.toString();
}
else if (object instanceof Map)
{
Map map = (Map)object;
// If a staf-map-class-name key exists in the map, make sure that
// it's map class definition is provided in the marshalling context.
// If it's not, then treat the map as a plain map object.
boolean isMapClass = false;
String mapClassName = "";
if ((context != null) &&
(context instanceof STAFMarshallingContext) &&
(map.containsKey(MAP_CLASS_NAME_KEY)))
{
mapClassName = (String)map.get(MAP_CLASS_NAME_KEY);
if (context.hasMapClassDefinition(mapClassName))
{
isMapClass = true;
}
}
if (isMapClass)
{
STAFMapClassDefinition mapClass =
context.getMapClassDefinition(mapClassName);
Iterator iter = mapClass.keyIterator();
StringBuffer result = new StringBuffer(
":" + mapClassName.length() + ":" + mapClassName);
while (iter.hasNext())
{
Map key = (Map)iter.next();
result.append(marshall(map.get(key.get("key")), context));
}
return MC_INSTANCE_MARKER + ":" + result.length() + ":" +
result.toString();
}
else
{
Iterator iter = map.keySet().iterator();
StringBuffer mapData = new StringBuffer();
while (iter.hasNext())
{
Object key = iter.next();
mapData.append(":" + key.toString().length() + ":" +
key.toString() + marshall(map.get(key), context));
}
return MAP_MARKER + ":" + mapData.length() + ":" +
mapData.toString();
}
}
else if (object instanceof STAFMarshallingContext)
{
STAFMarshallingContext mc = (STAFMarshallingContext)object;
Map classMap = (Map)mc.getMapClassMap();
if (classMap.size() == 0)
{
return marshall(mc.getRootObject(), context);
}
else
{
Map contextMap = new HashMap();
contextMap.put(MAP_CLASS_MAP_KEY, classMap);
// Note: We can't simply put the root object as a map key like
// "root-object" and then marshall the whole map, as in
// the unmarshalling routines, we need to be able to
// unmarshall the root object in the context of the
// map-class-map.
String data = marshall(contextMap, context) +
marshall(mc.getRootObject(),
(STAFMarshallingContext)object);
return CONTEXT_MARKER + ":" + data.length() + ":" + data;
}
}
// else if (object has method "stafMarshall")
String objString = object.toString();
return "@SDT/$S:" + objString.length() + ":" + objString;
}
public static STAFMarshallingContext unmarshall(String marshalledObject)
{
return unmarshall(marshalledObject, new STAFMarshallingContext(),
UNMARSHALLING_DEFAULTS);
}
public static STAFMarshallingContext unmarshall(String marshalledObject,
int flags)
{
return unmarshall(marshalledObject, new STAFMarshallingContext(), flags);
}
public static STAFMarshallingContext unmarshall(
String data, STAFMarshallingContext context)
{
return unmarshall(data, context, UNMARSHALLING_DEFAULTS);
}
public static STAFMarshallingContext unmarshall(
String data, STAFMarshallingContext context, int flags)
{
try
{
if (data.startsWith(NONE_MARKER))
{
return new STAFMarshallingContext();
}
else if (data.startsWith(SCALAR_MARKER))
{
// @SDT/$S::
int colonIndex = data.indexOf(':', SCALAR_MARKER.length());
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int dataIndex = colonIndex + 1;
colonIndex = data.indexOf(':', dataIndex);
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int stringLength = Integer.parseInt(
data.substring(dataIndex, colonIndex));
dataIndex = colonIndex + 1;
if (stringLength != (data.length() - dataIndex))
return new STAFMarshallingContext(data);
String theString = data.substring(dataIndex);
if (theString.startsWith(MARSHALLED_DATA_MARKER) &&
((flags & IGNORE_INDIRECT_OBJECTS) !=
IGNORE_INDIRECT_OBJECTS))
{
return unmarshall(theString, context, flags);
}
else
{
return new STAFMarshallingContext(theString);
}
}
else if (data.startsWith(LIST_MARKER))
{
// @SDT/[::...
//
// Get number-of-items in the list
int colonIndex = data.indexOf(':', LIST_MARKER.length());
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int numItems = Integer.parseInt(
data.substring(LIST_MARKER.length(), colonIndex));
// Get array-length
int dataIndex = colonIndex + 1;
colonIndex = data.indexOf(':', dataIndex);
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int arrayLength = Integer.parseInt(
data.substring(dataIndex, colonIndex));
dataIndex = colonIndex + 1;
if (arrayLength != (data.length() - dataIndex))
return new STAFMarshallingContext(data);
// Create a list of the data
List list = new LinkedList();
for (int i = 0; i < numItems; ++i)
{
// Get the next item in the list and unmarshall it and add
// it to the list
int colonIndex1 = data.indexOf(':', dataIndex);
if (colonIndex1 == -1)
return new STAFMarshallingContext(data);
int colonIndex2 = data.indexOf(':', colonIndex1 + 1);
if (colonIndex2 == -1)
return new STAFMarshallingContext(data);
int itemLength = Integer.parseInt(
data.substring(colonIndex1 + 1, colonIndex2));
list.add(unmarshall(
data.substring(
dataIndex, colonIndex2 + itemLength + 1),
context, flags).getPrimaryObject());
dataIndex = colonIndex2 + itemLength + 1;
}
return new STAFMarshallingContext(list);
}
else if (data.startsWith(MAP_MARKER))
{
// @SDT/{::::
// ...
// ::
// Get map-length
int colonIndex = data.indexOf(':', MAP_MARKER.length());
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int dataIndex = colonIndex + 1;
colonIndex = data.indexOf(':', dataIndex);
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int mapLength = Integer.parseInt(
data.substring(dataIndex, colonIndex));
dataIndex = colonIndex + 1;
if (mapLength != (data.length() - dataIndex))
{
return new STAFMarshallingContext(data);
}
// Create the map of data
Map map = new HashMap();
while (dataIndex < data.length())
{
// Get key first
int keyColonIndex1 = data.indexOf(':', dataIndex);
if (keyColonIndex1 == -1)
return new STAFMarshallingContext(data);
int keyColonIndex2 = data.indexOf(':', keyColonIndex1 + 1);
if (keyColonIndex2 == -1)
return new STAFMarshallingContext(data);
int keyLength = Integer.parseInt(
data.substring(keyColonIndex1 + 1, keyColonIndex2));
String key = data.substring(keyColonIndex2 + 1,
keyColonIndex2 + 1 + keyLength);
dataIndex = keyColonIndex2 + 1 + keyLength;
// Now, get the object
int colonIndex1 = data.indexOf(':', dataIndex);
if (colonIndex1 == -1)
return new STAFMarshallingContext(data);
int colonIndex2 = data.indexOf(':', colonIndex1 + 1);
if (colonIndex2 == -1)
return new STAFMarshallingContext(data);
int itemLength = Integer.parseInt(
data.substring(colonIndex1 + 1, colonIndex2));
map.put(key, unmarshall(
data.substring(
dataIndex, colonIndex2 + itemLength + 1),
context, flags).getPrimaryObject());
dataIndex = colonIndex2 + itemLength + 1;
}
return new STAFMarshallingContext(map);
}
else if (data.startsWith(MC_INSTANCE_MARKER))
{
// @SDT/%::::
// ...
// Get the map-class-instance-length
int colonIndex = data.indexOf(
':', MC_INSTANCE_MARKER.length());
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int dataIndex = colonIndex + 1;
colonIndex = data.indexOf(':', dataIndex);
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int mapClassInstanceLength = Integer.parseInt(
data.substring(dataIndex, colonIndex));
dataIndex = colonIndex + 1;
if (mapClassInstanceLength != (data.length() - dataIndex))
return new STAFMarshallingContext(data);
// Get map-class-name-length
colonIndex = data.indexOf(':', dataIndex);
if (colonIndex == -1)
return new STAFMarshallingContext(data);
dataIndex = colonIndex + 1;
colonIndex = data.indexOf(':', dataIndex);
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int mapClassNameLength = Integer.parseInt(
data.substring(dataIndex, colonIndex));
// Get map-class-name
dataIndex = colonIndex + 1;
String mapClassName = data.substring(
dataIndex, dataIndex + mapClassNameLength);
dataIndex = dataIndex + mapClassNameLength;
// Create a map and add the the staf-map-class-name key and
// value to the map
Map map = new HashMap();
map.put(MAP_CLASS_NAME_KEY, mapClassName);
// Unmarshall all of the actual keys and add to the map
STAFMapClassDefinition mapClass =
context.getMapClassDefinition(mapClassName);
Iterator iter = mapClass.keyIterator();
while (dataIndex < data.length())
{
colonIndex = data.indexOf(':', dataIndex);
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int colonIndex2 = data.indexOf(':', colonIndex + 1);
if (colonIndex2 == -1)
return new STAFMarshallingContext(data);
int itemLength = Integer.parseInt(
data.substring(colonIndex + 1, colonIndex2));
map.put(((Map)iter.next()).get("key"),
unmarshall(data.substring(
dataIndex, colonIndex2 + itemLength + 1),
context, flags).getPrimaryObject());
dataIndex = colonIndex2 + itemLength + 1;
}
return new STAFMarshallingContext(map);
}
else if (data.startsWith(CONTEXT_MARKER))
{
// @SDT/*::
// @SDT/{::
// Get context-length
int colonIndex = data.indexOf(':', CONTEXT_MARKER.length());
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int contextIndex = data.indexOf(':', colonIndex + 1);
if (contextIndex == -1)
return new STAFMarshallingContext(data);
int contextLength = Integer.parseInt(
data.substring(colonIndex + 1, contextIndex));
contextIndex = contextIndex + 1;
if (contextLength != (data.length() - contextIndex))
return new STAFMarshallingContext(data);
// Get mapClassLength
colonIndex = data.indexOf(':', contextIndex);
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int mapIndex = contextIndex;
int mapDataIndex = data.indexOf(':', colonIndex + 1);
if (mapDataIndex == -1)
return new STAFMarshallingContext(data);
int mapLength = Integer.parseInt(
data.substring(colonIndex + 1, mapDataIndex));
mapDataIndex++;
if (mapLength > (data.length() - mapDataIndex))
return new STAFMarshallingContext(data);
// Create a new marshalling context with the map classes and
// root object
Map contextMap = (Map)unmarshall(
data.substring(mapIndex, mapDataIndex + mapLength),
context, flags).getPrimaryObject();
Map mapClassMap = (Map)contextMap.get(MAP_CLASS_MAP_KEY);
STAFMarshallingContext newContext = new STAFMarshallingContext(
null, mapClassMap);
colonIndex = data.indexOf(':', mapDataIndex + mapLength);
if (colonIndex == -1)
return new STAFMarshallingContext(data);
int rootObjIndex = mapDataIndex + mapLength;
int rootObjDataIndex = data.indexOf(':', colonIndex + 1);
if (rootObjDataIndex == -1)
return new STAFMarshallingContext(data);
int rootObjLength = Integer.parseInt(data.substring(
colonIndex + 1, rootObjDataIndex));
rootObjDataIndex++;
if (rootObjLength > (data.length() - rootObjDataIndex))
return new STAFMarshallingContext(data);
newContext.setRootObject(
unmarshall(data.substring(
rootObjIndex, rootObjDataIndex + rootObjLength),
newContext, flags).getPrimaryObject());
return newContext;
}
else if (data.startsWith(MARSHALLED_DATA_MARKER))
{
// Here, we don't know what the type is
return new STAFMarshallingContext(data);
}
else
{
return new STAFMarshallingContext(data);
}
}
catch (Exception e)
{
// An exception occurred processing the marshalling data.
// This means its probably invalid marshalled data, so just fall
// through to return a marshalling context of the string
// containing the invalid marshalled data.
}
return new STAFMarshallingContext(data);
}
private static String quoteString(String input)
{
if (input.indexOf("'") == -1)
return "'" + input + "'";
if (input.indexOf("\"") == -1)
return "\"" + input + "\"";
StringTokenizer tokens = new StringTokenizer(input, "'");
String output = "'" + tokens.nextToken();
while (tokens.hasMoreTokens())
output = output + "\'" + tokens.nextToken();
return output + "'";
}
public String toString()
{
return formatObject(rootObject, this, 0, 0);
}
public String toString(int flags)
{
return formatObject(rootObject, this, 0, flags);
}
public static String formatObject(Object obj)
{
return formatObject(obj, null, 0, 0);
}
public static String formatObject(Object obj, int flags)
{
return formatObject(obj, null, 0, flags);
}
static String formatObject(Object obj, STAFMarshallingContext context,
int indentLevel, int flags)
{
String lineSep = System.getProperty("line.separator");
StringBuffer output = new StringBuffer();
if (obj instanceof List)
{
List list = (List)obj;
output.append("[");
++indentLevel;
if (list.size() > 0) output.append(lineSep);
// Format each object
for (Iterator iter = list.iterator(); iter.hasNext();)
{
Object thisObj = iter.next();
if ((thisObj instanceof List) ||
(thisObj instanceof Map) ||
(thisObj instanceof STAFMarshallingContext))
{
output.append(
SPACES.substring(0, indentLevel * INDENT_DELTA));
output.append(formatObject(thisObj, context, indentLevel,
flags));
}
else
{
output.append(
SPACES.substring(0, indentLevel * INDENT_DELTA));
if (thisObj == null)
output.append(NONE_STRING);
else
output.append(thisObj.toString());
}
if (iter.hasNext()) output.append(ENTRY_SEPARATOR);
output.append(lineSep);
}
--indentLevel;
if (list.size() > 0)
output.append(SPACES.substring(0, indentLevel * INDENT_DELTA));
output.append("]");
}
else if (obj instanceof Map)
{
Map map = (Map)obj;
output.append("{");
++indentLevel;
if (map.size() > 0) output.append(lineSep);
// Check if the map object has a map class key and if the context
// is valid and contains a map class definition for this map class.
// If not, treat as a plain map class.
if (map.containsKey(MAP_CLASS_NAME_KEY) &&
(context != null) &&
(context instanceof STAFMarshallingContext) &&
(context.hasMapClassDefinition(
(String)map.get(MAP_CLASS_NAME_KEY))))
{
STAFMapClassDefinition mapClass =
context.getMapClassDefinition(
(String)map.get(MAP_CLASS_NAME_KEY));
// Determine maximum key length
int maxKeyLength = 0;
for (Iterator iter = mapClass.keyIterator(); iter.hasNext();)
{
Map theKey = (Map)iter.next();
String theKeyString = (String)theKey.get("key");
if (theKey.containsKey(DISPLAY_NAME_KEY))
theKeyString = (String)theKey.get(DISPLAY_NAME_KEY);
if (theKeyString.length() > maxKeyLength)
maxKeyLength = theKeyString.length();
}
// Now print each object in the map
for (Iterator iter = mapClass.keyIterator(); iter.hasNext();)
{
Map theKey = (Map)iter.next();
String theKeyString = (String)theKey.get("key");
if (theKey.containsKey(DISPLAY_NAME_KEY))
theKeyString = (String)theKey.get(DISPLAY_NAME_KEY);
output.append(SPACES.substring(0,
indentLevel * INDENT_DELTA))
.append(theKeyString)
.append(SPACES.substring(0, maxKeyLength -
theKeyString.length()))
.append(": ");
Object thisObj = map.get(theKey.get("key"));
if ((thisObj instanceof List) ||
(thisObj instanceof Map) ||
(thisObj instanceof STAFMarshallingContext))
{
output.append(
formatObject(thisObj, context, indentLevel, flags));
}
else if (thisObj == null)
{
output.append(NONE_STRING);
}
else
{
output.append(thisObj.toString());
}
if (iter.hasNext()) output.append(ENTRY_SEPARATOR);
output.append(lineSep);
}
}
else
{
// Determine maximum key length
int maxKeyLength = 0;
for (Iterator iter = map.keySet().iterator(); iter.hasNext();)
{
String theKeyString = (String)iter.next();
if (theKeyString.length() > maxKeyLength)
maxKeyLength = theKeyString.length();
}
// Now print each object in the map
for (Iterator iter = map.keySet().iterator(); iter.hasNext();)
{
String theKeyString = (String)iter.next();
output.append(SPACES.substring(0,
indentLevel * INDENT_DELTA))
.append(theKeyString)
.append(SPACES.substring(0, maxKeyLength -
theKeyString.length()))
.append(": ");
Object thisObj = map.get(theKeyString);
if ((thisObj instanceof List) ||
(thisObj instanceof Map) ||
(thisObj instanceof STAFMarshallingContext))
{
output.append(
formatObject(thisObj, context, indentLevel, flags));
}
else if (thisObj == null)
{
output.append(NONE_STRING);
}
else
{
output.append(thisObj.toString());
}
if (iter.hasNext()) output.append(ENTRY_SEPARATOR);
output.append(lineSep);
}
}
--indentLevel;
if (map.size() > 0)
output.append(SPACES.substring(0, indentLevel * INDENT_DELTA));
output.append("}");
}
else if (obj instanceof STAFMarshallingContext)
{
STAFMarshallingContext inputContext = (STAFMarshallingContext)obj;
return formatObject(inputContext.getRootObject(), inputContext,
indentLevel, flags);
}
else if (obj == null) return NONE_STRING;
else return obj.toString();
return output.toString();
}
// Class data
private static final String MARSHALLED_DATA_MARKER = new String("@SDT/");
private static final String NONE_MARKER = new String("@SDT/$0:0:");
private static final String SCALAR_MARKER = new String("@SDT/$");
private static final String LIST_MARKER = new String("@SDT/[");
private static final String MAP_MARKER = new String("@SDT/{");
private static final String MC_INSTANCE_MARKER = new String("@SDT/%");
private static final String CONTEXT_MARKER = new String("@SDT/*");
private static final String NONE_STRING = new String("");
private static final String DISPLAY_NAME_KEY = new String("display-name");
private static final String MAP_CLASS_MAP_KEY = new String("map-class-map");
private static final String MAP_CLASS_NAME_KEY =
new String("staf-map-class-name");
private static final String ENTRY_SEPARATOR = new String("");
// 80 spaces
private static final String SPACES = new String(
" " +
" ");
private static final int INDENT_DELTA = 2;
private Map mapClassMap = new HashMap();
private Object rootObject = null;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy