/*******************************************************************************
* Copyright (c) 2002-2006 Innoopract Informationssysteme GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innoopract Informationssysteme GmbH - initial API and implementation
******************************************************************************/
package com.w4t;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/** <p>This is the superclass of all property setting classes like
* Style, WindowProperties etc.</p>
*/
public abstract class WebComponentProperties implements Cloneable {
/** <p>Returns a clone of this WebComponentProperties Object.<br>
* For all WebComponentPropertiess, cloning will result in a deep copy,
* copying all fields, and recursively deep copying Fields containing
* external references to WebComponentProperties objects in the cloned
* object.</p>
* <p>This also wraps the clone() method to make it public.</p> */
public Object clone() throws CloneNotSupportedException {
Object clone = super.clone();
try {
Field[] fields = this.getDeclaredFields(); // we use our own
// getDeclaredFields()
Class fieldType = null;
WebComponentProperties temp = null;
WebComponentProperties tempClone = null;
int length = fields.length;
for ( int i = 0; i < length; i++ ) {
if( !isStatic( fields[ i ] ) ) {
fieldType = fields[ i ].getType();
if( fieldType.isPrimitive() ) {
// it should have been copied at super.clone()
} else if ( fieldType.isAssignableFrom(
Class.forName( "java.lang.String" ) ) ) {
// it should have been copied at super.clone()
} else if ( Class.forName( "com.w4t.WebComponentProperties" ).
isAssignableFrom( fieldType ) ) {
// we clone the attribute, if it is a WebComponentProperty
// object itself
try {
fields[ i ].setAccessible( true );
temp = ( WebComponentProperties )fields[ i ].get( this );
tempClone = null;
if( temp != null ) {
tempClone = ( WebComponentProperties )temp.clone();
}
fields[ i ].set( ( WebComponentProperties )clone, tempClone );
} catch ( IllegalAccessException iace ) {
System.err.println(
"Exception occured in 'WebComponentProperties.clone()'."
+ " Cloning an attribute of WebComponentProperties type. "
+ iace.toString() );
} catch ( IllegalArgumentException iarge ) {
System.err.println(
"Exception occured in 'WebComponentProperties.clone()'."
+ " Cloning an attribute of WebComponentProperties type. "
+ iarge.toString()
+ "\nType is " + this.getClass().getName() + "." );
}
} else {
try {
// we set all references to null, for reasons of safety
fields[ i ].setAccessible( true );
fields[ i ].set( ( WebComponentProperties )clone, null );
} catch ( IllegalAccessException iace ) {
System.err.println(
"Exception occured in 'WebComponentProperties.clone()'."
+ " Nulling an attribute. "
+ iace.toString() );
} catch ( IllegalArgumentException iarge ) {
System.err.println(
"Exception occured in 'WebComponentProperties.clone()'."
+ " Nulling an attribute. "
+ iarge.toString() );
}
}
}
} // for fields
} catch ( Exception ex ) {
System.err.println(
"Exception occured in 'WebComponentProperties.clone()'. "
+ ex.toString() );
ex.printStackTrace();
}
return clone;
}
/** <p>Uses the Class.getDeclaredFields() in order to get a list of
* declared fields in this WebObject, including inherited fields
* from all classes above in the hierarchy.</p> */
protected Field[] getDeclaredFields() {
String thisClassName;
String superClassName;
Class thisClass;
Class superClass;
Field[] fields;
try {
thisClassName = this.getClass().getName();
thisClass = Class.forName( thisClassName );
superClassName = thisClass.getSuperclass().getName();
superClass = Class.forName( superClassName );
fields = thisClass.getDeclaredFields();
Field[] superFields = null;
Field[] tempFields = null;
boolean wcpReached = false;
while ( !wcpReached ) {
// get superclass
Class objClass = Class.forName( "java.lang.Object" );
if( !superClass.isAssignableFrom( objClass ) ) {
// get declared fields from the next class above in the hierarchy
superFields = superClass.getDeclaredFields();
superClassName = superClass.getSuperclass().getName();
superClass = Class.forName( superClassName );
// merge the fields arrays
tempFields = new Field[ fields.length + superFields.length ];
System.arraycopy( fields, 0, tempFields, 0, fields.length );
System.arraycopy( superFields, 0,
tempFields, fields.length, superFields.length );
fields = tempFields;
} else {
wcpReached = true;
}
} // while
} catch( final ClassNotFoundException shouldNotHappen ) {
throw new RuntimeException( shouldNotHappen );
}
return fields;
}
// helping methods
//////////////////
private boolean isStatic( final Field field ) {
int mod = field.getModifiers();
return Modifier.isStatic( mod );
}
}