src.com.ibm.as400.access.PxToolboxObjectParm Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400 Show documentation
Show all versions of jt400 Show documentation
The Open Source version of the IBM Toolbox for Java
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: PxToolboxObjectParm.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2000 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.io.InputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.StringTokenizer;
import java.util.Vector;
/**
The PxToolboxObjectParm class represents a
serialized Toolbox object parameter in a proxy datastream. We can't
just serialize Toolbox objects, since they may contain proxy objects.
Otherwise, the contained proxy objects would be serialized along with
it, which is incorrect.
**/
class PxToolboxObjectParm
extends PxCompDS
implements PxParm
{
private static final String copyright = "Copyright (C) 1997-2000 International Business Machines Corporation and others.";
// Private data.
private static boolean DEBUG_ = false;
private Object value_;
public PxToolboxObjectParm ()
{
super (ProxyConstants.DS_TOOLBOX_OBJECT_PARM);
}
public PxToolboxObjectParm (Object value)
{
super (ProxyConstants.DS_TOOLBOX_OBJECT_PARM);
value_ = value;
if (DEBUG_)
System.out.println("Creating toolbox object parm: " + value + " (" + value.getClass() + ").");
// First we can just serialize this object.
addParm(new PxSerializedObjectParm(value));
// Next we will pass along a list of all contained objects
// (no matter how deep) which are proxified objects.
Vector fieldNames = new Vector();
Vector proxyImpls = new Vector();
analyze(value, "", fieldNames, proxyImpls);
// Send the number of contained proxy objects.
int proxyCount = proxyImpls.size();
addParm(new PxIntParm(proxyCount));
// Send each proxy object, name then value.
for (int i = 0; i < proxyCount; ++i) {
addParm(new PxStringParm((String)fieldNames.elementAt(i)));
addParm(new PxPxObjectParm(((ProxyImpl)proxyImpls.elementAt(i)).getPxId()));
}
}
private static void analyze(Object objectValue, String prefix, Vector fieldNames, Vector proxyImpls)
{
if (DEBUG_) {
System.out.println("Analyzing " + objectValue + " (" + objectValue.getClass() + ").");
System.out.println("Prefix=" + prefix + ".");
}
// getDeclaredFields() is not allowed in applets. If it throws // @A1A
// an exception, we will assume that there is nothing interesting // @A1A
// in the data. If there is, it will potentially be lost (i.e. // @A1A
// not everything that works for applications will work for applets. // @A1A
try { // @A1A
// First, analyze all of our declared fields, then all of
// our superclass's, etc.
for (Class clazz = objectValue.getClass();
! clazz.equals(Object.class);
clazz = clazz.getSuperclass())
{
Field[] declaredFields = clazz.getDeclaredFields();
if (declaredFields != null) {
for (int i = 0; i < declaredFields.length; ++i) {
String fieldName = declaredFields[i].getName();
if (DEBUG_)
System.out.println("Field name=" + fieldName + ".");
// If the field is transient, then do nothing.
if (! Modifier.isTransient(declaredFields[i].getModifiers())) {
// Note that this check depends on the assumption that
// contained proxy objects be declared at least package
// scope (otherwise we will catch an IllegalAccessException).
// I know this is not a great assumption, but
// it makes the implementation easier.
try {
Object fieldValue = declaredFields[i].get(objectValue);
if (fieldValue != null) {
if (DEBUG_)
System.out.println("Field value=" + fieldValue + " (" + fieldValue.getClass() + ").");
// Only be concerned with non-static Toolbox fields.
if (!Modifier.isStatic(declaredFields[i].getModifiers())
&& fieldValue.getClass().getName().startsWith("com.ibm.as400.access")) {
// If the field value is a proxy object, then add it to the list.
// Otherwise, analyze recursively.
if (fieldValue instanceof ProxyImpl) {
fieldNames.addElement(prefix + fieldName);
proxyImpls.addElement((ProxyImpl)fieldValue);
}
else if (fieldValue.getClass().getName().startsWith("com.ibm.as400.access"))
analyze(fieldValue, fieldValue + ".", fieldNames, proxyImpls);
}
}
}
catch (IllegalAccessException e) {
// Ignore.
if (DEBUG_)
System.out.println("Ignored IllegalAccessException:" + e.getMessage());
}
}
}
}
}
} // @A1A
catch (Exception e) { // @A1A
if (Trace.isTraceErrorOn()) // @A1A
Trace.log(Trace.ERROR, "Exception when analyzing Toolbox parm", e); // @A1A
} // @A1A
}
/**
Returns a new copy of this datastream.
@return A new copy of this datastream.
@exception CloneNotSupportedException If the object cannot be cloned.
**/
//
// Implementation note: This method is necessary in order to do
// a deep copy of the internal object. Otherwise,
// we run into problems with multiple threads.
public Object clone ()
throws CloneNotSupportedException
{
value_ = null;
return super.clone();
}
public Object getObjectValue ()
{
return value_;
}
public void readFrom(InputStream input, PxDSFactory factory)
throws IOException
{
super.readFrom(input, factory);
// Deserialize the object.
value_ = getParm(0).getObjectValue();
// Number of contained objects ("corrections").
int proxyCount = ((PxIntParm)getParm(1)).getIntValue();
int parmIndex = 1;
for (int i = 1; i <= proxyCount; ++i) {
String fieldName = ((PxStringParm)getParm(++parmIndex)).getStringValue();
Object impl = ((PxPxObjectParm)getParm(++parmIndex)).getObjectValue();
// Set the field.
Object fieldValue = value_;
Field field = null;
// Navigate down the containment hierarchy to
// get the right field.
StringTokenizer tokenizer = new StringTokenizer(fieldName, ".");
while (tokenizer.hasMoreTokens()) {
// Get the next field to navigate to.
String token = tokenizer.nextToken();
Class clazz = fieldValue.getClass();
try {
field = clazz.getDeclaredField(token);
if (field == null) {
// This should never happen!
if (Trace.isTraceErrorOn())
Trace.log(Trace.ERROR, "Error reading toolbox parm: field set to null");
}
}
catch(NoSuchFieldException e) {
// This should never happen!
if (Trace.isTraceErrorOn())
Trace.log(Trace.ERROR, "Error reading toolbox parm", e);
}
// Get the value of that field.
try {
if (tokenizer.hasMoreTokens())
if (field != null) fieldValue = field.get(fieldValue);
}
catch(IllegalAccessException e) {
// This should never happen!
if (Trace.isTraceErrorOn())
Trace.log(Trace.ERROR, "Error reading toolbox parm", e);
}
}
// At this point, field is set to the field that we need to set.
try {
if (field != null) field.set(fieldValue, impl);
}
catch(IllegalAccessException e) {
// This should never happen!
if (Trace.isTraceErrorOn())
Trace.log(Trace.ERROR, "Error reading toolbox parm", e);
}
}
}
public String toString ()
{
return super.toString () + " (" + value_ + ")";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy