[castor-dev] Re: TypeSafe Enums and Collections

2005-01-18 Thread Ram_Sarma

hey,

Just wondering if anyone had any thought on this. I had to write up a
custom handler (code borrowed from an earlier post and make changes for
handling a list). The marshalling works but the unmarshalling tries to
create an instance and fails
for the type safe enums. This is kindof urgent and wanted to find out if
anyone has gotten this to work and if so how.

public class HmsiEnumTypeFieldHandler extends AbstractFieldHandler {

/**
 * Returns the value of the field from the object. The object should
have a
 * method named codeget +
getFieldDescriptor().getFieldName()/code.
 * br
 * bExample /b: Field name =codeidentification/code, method
 * name =codegetIdentification()/code. This getter should return
the
 * itypesafe enum /i static instance.
 *
 * @param o
 *The object
 * @return The value of the field
 * @throws IllegalStateException
 * The Java object has changed and is no longer supported
by
 * this handler, or the handler is not compatible with the
Java
 * object
 */
public Object getValue(final Object o) throws IllegalStateException {
final FieldDescriptor fd = getFieldDescriptor();
final String name = fd.getFieldName();
final String methodName = get.concat(
name.substring(0, 1).toUpperCase()).concat(
name.substring(1, name.length()));

try {
final Method method = o.getClass().getMethod(methodName,
new Class[] {});

// make sure we handle arrays of enums
Object result = method.invoke(o, new Object[] {});

if (result == null) {
return result;
}

if (result.getClass().isArray()) {
int size = Array.getLength(result);
String[] values = new String[size];

for (int i = 0; i  size; i++) {
values[i] = Array.get(result, i).toString();
}

result = values;
}
return result;
} catch (NoSuchMethodException e) {
e.printStackTrace();
throw new IllegalStateException(Class  + o.getClass()
+  must have method  + methodName);
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new IllegalStateException(Method  + methodName
+  from class  + o.getClass() +  must be public);
} catch (InvocationTargetException e) {
e.printStackTrace();
throw new IllegalStateException(Method  + methodName
+  from class  + o.getClass() +  threw an
exception);
}
}

/**
 * Sets the value of the field on the object. The object should have a
field
 * name code_ + getFieldDescriptor().getFieldName()/code.br
 * bExample /b: Field name =codeidentification/code, object
 * field name =code_identification/code.
 *
 * @param o
 *The object
 * @param o1
 *The new value
 * @throws IllegalStateException
 * The Java object has changed and is no longer supported
by
 * this handler, or the handler is not compatible with the
Java
 * object
 * @throws IllegalArgumentException
 */
public void setValue(final Object o, final Object o1)
throws IllegalStateException, IllegalArgumentException {
final FieldDescriptor fd = getFieldDescriptor();
String name = fd.getFieldName();
final String methodName = set.concat(
name.substring(0, 1).toUpperCase()).concat(
name.substring(1, name.length()));
name = _.concat(name);

Class fieldClass = null;
try {
fieldClass = o.getClass().getDeclaredField(name).getType();
final Field[] fields = fieldClass.getDeclaredFields();
for (int i = 0; i  fields.length; i++) {
if (fields[i].get(null).toString().equals(o1.toString())) {
final Method method =
o.getClass().getMethod(methodName,
new Class[] { fields[i].getType() });
method.invoke(o, new Object[] { fields[i].get(null) });
break;
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
throw new IllegalStateException(Field  + name +  must exist
in 
+ o.getClass());
} catch (NoSuchMethodException e) {
e.printStackTrace();
throw new IllegalStateException(Method  + methodName
+  must exist in  + o.getClass());
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new IllegalStateException(Class  +
fieldClass.getClass()
+  must be accessible);
} 

Re: [castor-dev] Re: TypeSafe Enums and Collections

2005-01-18 Thread Keith Visco

You're on the right track, but you should probably return null from the 
newInstance methods instead of throwing exceptions. Castor will invoke 
those methods and will expect either an actual instance or null as the 
return value.

Also if you extend GeneralizedFieldHandler instead of 
AbstractFieldHandler your code will be a lot cleaner and smaller because 
you don't need to figure out the setter/getter methods as it's already 
done for you.

I know it's a limitation that the GeneralizedFieldHandler doesn't have 
built-in support to iterate automatically over collections, so everyone 
has to write their own collection support inside the convert methods. 
That's something I'm working on. In the meantime, your custom handler 
should work with a little tweaking.

--Keith
[EMAIL PROTECTED] wrote:
hey,
Just wondering if anyone had any thought on this. I had to write up a
custom handler (code borrowed from an earlier post and make changes for
handling a list). The marshalling works but the unmarshalling tries to
create an instance and fails
for the type safe enums. This is kindof urgent and wanted to find out if
anyone has gotten this to work and if so how.
public class HmsiEnumTypeFieldHandler extends AbstractFieldHandler {
/**
 * Returns the value of the field from the object. The object should
have a
 * method named codeget +
getFieldDescriptor().getFieldName()/code.
 * br
 * bExample /b: Field name =codeidentification/code, method
 * name =codegetIdentification()/code. This getter should return
the
 * itypesafe enum /i static instance.
 *
 * @param o
 *The object
 * @return The value of the field
 * @throws IllegalStateException
 * The Java object has changed and is no longer supported
by
 * this handler, or the handler is not compatible with the
Java
 * object
 */
public Object getValue(final Object o) throws IllegalStateException {
final FieldDescriptor fd = getFieldDescriptor();
final String name = fd.getFieldName();
final String methodName = get.concat(
name.substring(0, 1).toUpperCase()).concat(
name.substring(1, name.length()));
try {
final Method method = o.getClass().getMethod(methodName,
new Class[] {});
// make sure we handle arrays of enums
Object result = method.invoke(o, new Object[] {});
if (result == null) {
return result;
}
if (result.getClass().isArray()) {
int size = Array.getLength(result);
String[] values = new String[size];
for (int i = 0; i  size; i++) {
values[i] = Array.get(result, i).toString();
}
result = values;
}
return result;
} catch (NoSuchMethodException e) {
e.printStackTrace();
throw new IllegalStateException(Class  + o.getClass()
+  must have method  + methodName);
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new IllegalStateException(Method  + methodName
+  from class  + o.getClass() +  must be public);
} catch (InvocationTargetException e) {
e.printStackTrace();
throw new IllegalStateException(Method  + methodName
+  from class  + o.getClass() +  threw an
exception);
}
}
/**
 * Sets the value of the field on the object. The object should have a
field
 * name code_ + getFieldDescriptor().getFieldName()/code.br
 * bExample /b: Field name =codeidentification/code, object
 * field name =code_identification/code.
 *
 * @param o
 *The object
 * @param o1
 *The new value
 * @throws IllegalStateException
 * The Java object has changed and is no longer supported
by
 * this handler, or the handler is not compatible with the
Java
 * object
 * @throws IllegalArgumentException
 */
public void setValue(final Object o, final Object o1)
throws IllegalStateException, IllegalArgumentException {
final FieldDescriptor fd = getFieldDescriptor();
String name = fd.getFieldName();
final String methodName = set.concat(
name.substring(0, 1).toUpperCase()).concat(
name.substring(1, name.length()));
name = _.concat(name);
Class fieldClass = null;
try {
fieldClass = o.getClass().getDeclaredField(name).getType();
final Field[] fields = fieldClass.getDeclaredFields();
for (int i = 0; i  fields.length; i++) {
if (fields[i].get(null).toString().equals(o1.toString())) {
final Method method =
o.getClass().getMethod(methodName,
   

Re: [castor-dev] Re: TypeSafe Enums and Collections

2005-01-18 Thread Ram_Sarma

Keith,

Thanks for the response. I tried returning null from my newInstance
methods. This time I get an error Unable to create a new instance of type
: Subjects... Subjects is an enum type and has no constructor.
Do we need to specify anything else in my mapping?

Is there any place where I could find some documentation about writing
custom handlers, for a better understanding.

Thanks
Ram



|-+
| |   Keith Visco  |
| |   [EMAIL PROTECTED]|
| |   om  |
| ||
| |   01/18/2005 03:35 |
| |   PM   |
| |   Please respond to|
| |   castor-dev   |
| ||
|-+
  
--|
  | 
 |
  |   To:   castor-dev@exolab.org   
 |
  |   cc:   
 |
  |   Subject:  Re: [castor-dev] Re: TypeSafe Enums and Collections 
 |
  
--|






You're on the right track, but you should probably return null from the
newInstance methods instead of throwing exceptions. Castor will invoke
those methods and will expect either an actual instance or null as the
return value.

Also if you extend GeneralizedFieldHandler instead of
AbstractFieldHandler your code will be a lot cleaner and smaller because
you don't need to figure out the setter/getter methods as it's already
done for you.

I know it's a limitation that the GeneralizedFieldHandler doesn't have
built-in support to iterate automatically over collections, so everyone
has to write their own collection support inside the convert methods.
That's something I'm working on. In the meantime, your custom handler
should work with a little tweaking.

--Keith

[EMAIL PROTECTED] wrote:
 hey,

 Just wondering if anyone had any thought on this. I had to write up a
 custom handler (code borrowed from an earlier post and make changes for
 handling a list). The marshalling works but the unmarshalling tries to
 create an instance and fails
 for the type safe enums. This is kindof urgent and wanted to find out if
 anyone has gotten this to work and if so how.

 public class HmsiEnumTypeFieldHandler extends AbstractFieldHandler {

 /**
  * Returns the value of the field from the object. The object should
 have a
  * method named codeget +
 getFieldDescriptor().getFieldName()/code.
  * br
  * bExample /b: Field name =codeidentification/code, method
  * name =codegetIdentification()/code. This getter should return
 the
  * itypesafe enum /i static instance.
  *
  * @param o
  *The object
  * @return The value of the field
  * @throws IllegalStateException
  * The Java object has changed and is no longer supported
 by
  * this handler, or the handler is not compatible with
the
 Java
  * object
  */
 public Object getValue(final Object o) throws IllegalStateException {
 final FieldDescriptor fd = getFieldDescriptor();
 final String name = fd.getFieldName();
 final String methodName = get.concat(
 name.substring(0, 1).toUpperCase()).concat(
 name.substring(1, name.length()));

 try {
 final Method method = o.getClass().getMethod(methodName,
 new Class[] {});

 // make sure we handle arrays of enums
 Object result = method.invoke(o, new Object[] {});

 if (result == null) {
 return result;
 }

 if (result.getClass().isArray()) {
 int size = Array.getLength(result);
 String[] values = new String[size];

 for (int i = 0; i  size; i++) {
 values[i] = Array.get(result, i).toString();
 }

 result = values;
 }
 return result;
 } catch (NoSuchMethodException e) {
 e.printStackTrace();
 throw new IllegalStateException(Class  + o.getClass()
 +  must have method  + methodName);
 } catch (IllegalAccessException e