[jboss-svn-commits] JBL Code SVN: r9708 - in labs/jbossrules/trunk/drools-core/src: main/java/org/drools/base and 9 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Feb 22 14:43:07 EST 2007
Author: tirelli
Date: 2007-02-22 14:43:07 -0500 (Thu, 22 Feb 2007)
New Revision: 9708
Added:
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/Objenesis.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisBase.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisException.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisHelper.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisSerializer.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisStd.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/NullInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/ObjectInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/SerializationInstantiatorHelper.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/AccessibleInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ConstructorInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/NewInstanceInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/jrockit/
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/jrockit/JRockit131Instantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/jrockit/JRockitLegacyInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13Instantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13InstantiatorBase.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13SerializationInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/BaseInstantiatorStrategy.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/InstantiatorStrategy.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/SerializingInstantiatorStrategy.java
labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/StdInstantiatorStrategy.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/Person.java
Modified:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ClassObjectType.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ObjectTypeNodeTest.java
Log:
JBRULES-700: objenesis is integrated into the code. Unit tests added
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ClassObjectType.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ClassObjectType.java 2007-02-22 18:23:42 UTC (rev 9707)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ClassObjectType.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -16,8 +16,13 @@
* limitations under the License.
*/
+import java.lang.reflect.Field;
+
import org.drools.RuntimeDroolsException;
import org.drools.spi.ObjectType;
+import org.objenesis.Objenesis;
+import org.objenesis.ObjenesisStd;
+import org.objenesis.instantiator.ObjectInstantiator;
/**
* Java class semantics <code>ObjectType</code>.
@@ -29,10 +34,10 @@
public class ClassObjectType
implements
ObjectType {
- // ------------------------------------------------------------
- // Instance members
- // ------------------------------------------------------------
+ // Objenesis instance without cache (false)
+ private static final Objenesis OBJENESIS = new ObjenesisStd(false);
+
/**
*
*/
@@ -46,7 +51,11 @@
protected boolean shadowEnabled;
protected Class shadowClass;
+
+ protected ObjectInstantiator instantiator;
+ private Field delegate;
+
// ------------------------------------------------------------
// Constructors
// ------------------------------------------------------------
@@ -77,7 +86,14 @@
this.valueType = ValueType.determineValueType( objectTypeClass );
if ( shadowClass != null ) {
this.shadowClass = shadowClass;
+ this.instantiator = OBJENESIS.getInstantiatorOf( this.shadowClass );
this.shadowEnabled = true;
+ try {
+ delegate = this.shadowClass.getDeclaredField( ShadowProxyFactory.DELEGATE_FIELD_NAME );
+ delegate.setAccessible( true );
+ } catch ( Exception e ) {
+ throw new RuntimeDroolsException("Error retriving delegate field for shadow proxy class: "+this.shadowClass.getName(), e );
+ }
}
}
@@ -120,7 +136,8 @@
ShadowProxy proxy = null;
if ( isShadowEnabled() ) {
try {
- proxy = (ShadowProxy) this.shadowClass.getConstructor( new Class[]{this.objectTypeClass} ).newInstance( new Object[]{fact} );
+ proxy = (ShadowProxy) this.instantiator.newInstance();
+ delegate.set( proxy, fact );
} catch ( final Exception e ) {
throw new RuntimeDroolsException( "Error creating shadow fact for object: " + fact,
e );
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/Objenesis.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/Objenesis.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/Objenesis.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,29 @@
+package org.objenesis;
+
+import org.objenesis.instantiator.ObjectInstantiator;
+
+/**
+ * Common interface to all kind of Objenesis objects
+ *
+ * @author Henri Tremblay
+ */
+public interface Objenesis {
+
+ /**
+ * Will create a new object without any constructor being called
+ *
+ * @param clazz Class to instantiate
+ * @return New instance of clazz
+ */
+ Object newInstance(Class clazz);
+
+ /**
+ * Will pick the best instantiator for the provided class. If you need to create a lot of
+ * instances from the same class, it is way more efficient to create them from the same
+ * ObjectInstantiator than calling {@link #newInstance(Class)}.
+ *
+ * @param clazz Class to instantiate
+ * @return Instantiator dedicated to the class
+ */
+ ObjectInstantiator getInstantiatorOf(Class clazz);
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/Objenesis.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisBase.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisBase.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,82 @@
+package org.objenesis;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.objenesis.instantiator.ObjectInstantiator;
+import org.objenesis.strategy.InstantiatorStrategy;
+
+/**
+ * Base class to extend if you want to have a class providing your own default strategy. Can also be
+ * instantiated directly.
+ *
+ * @author Henri Tremblay
+ */
+public class ObjenesisBase implements Objenesis {
+
+ /** Strategy used by this Objenesi implementation to create classes */
+ protected final InstantiatorStrategy strategy;
+
+ /** Strategy cache. Key = Class, Value = InstantiatorStrategy */
+ protected Map cache;
+
+ /**
+ * Constructor allowing to pick a strategy and using cache
+ *
+ * @param strategy Strategy to use
+ */
+ public ObjenesisBase(InstantiatorStrategy strategy) {
+ this(strategy, true);
+ }
+
+ /**
+ * Flexible constructor allowing to pick the strategy and if caching should be used
+ *
+ * @param strategy Strategy to use
+ * @param useCache If {@link ObjectInstantiator}s should be cached
+ */
+ public ObjenesisBase(InstantiatorStrategy strategy, boolean useCache) {
+ if(strategy == null) {
+ throw new IllegalArgumentException("A strategy can't be null");
+ }
+ this.strategy = strategy;
+ this.cache = useCache ? new HashMap() : null;
+ }
+
+ public String toString() {
+ return getClass().getName() + " using " + strategy.getClass().getName()
+ + (cache == null ? " without" : " with") + " caching";
+ }
+
+ /**
+ * Will create a new object without any constructor being called
+ *
+ * @param clazz Class to instantiate
+ * @return New instance of clazz
+ */
+ public Object newInstance(Class clazz) {
+ return getInstantiatorOf(clazz).newInstance();
+ }
+
+ /**
+ * Will pick the best instantiator for the provided class. If you need to create a lot of
+ * instances from the same class, it is way more efficient to create them from the same
+ * ObjectInstantiator than calling {@link #newInstance(Class)}.
+ *
+ * @param clazz Class to instantiate
+ * @return Instantiator dedicated to the class
+ */
+ public synchronized ObjectInstantiator getInstantiatorOf(Class clazz) {
+ if(cache == null) {
+ return strategy.newInstantiatorOf(clazz);
+ }
+ ObjectInstantiator instantiator = (ObjectInstantiator) cache.get(clazz.getName());
+ if(instantiator == null) {
+ instantiator = strategy.newInstantiatorOf(clazz);
+ cache.put(clazz.getName(), instantiator);
+ }
+ return instantiator;
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisBase.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisException.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisException.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisException.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,42 @@
+package org.objenesis;
+
+/**
+ * Exception thrown by Objenesis. It wraps any instantiation exceptions. Note that this exception is
+ * runtime to prevent having to catch it. It will do normal exception wrapping for JDK 1.4 and more
+ * and basic message wrapping for JDK 1.3.
+ *
+ * @author Henri Tremblay
+ */
+public class ObjenesisException extends RuntimeException {
+
+ private static final boolean jdk14 = (Double.parseDouble(System
+ .getProperty("java.specification.version")) > 1.3);
+
+ /**
+ * @param msg Error message
+ */
+ public ObjenesisException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * @param cause Wrapped exception. The message will be the one of the cause.
+ */
+ public ObjenesisException(Throwable cause) {
+ super(cause == null ? null : cause.toString());
+ if(jdk14) {
+ initCause(cause);
+ }
+ }
+
+ /**
+ * @param msg Error message
+ * @param cause Wrapped exception
+ */
+ public ObjenesisException(String msg, Throwable cause) {
+ super(msg);
+ if(jdk14) {
+ initCause(cause);
+ }
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisException.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisHelper.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisHelper.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisHelper.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,65 @@
+package org.objenesis;
+
+import java.io.Serializable;
+
+import org.objenesis.instantiator.ObjectInstantiator;
+
+/**
+ * Use Objenesis in a static way. <strong>It is strongly not recommended to use this class.</strong>
+ *
+ * @author Henri Tremblay
+ */
+public final class ObjenesisHelper {
+
+ private static final Objenesis OBJENESIS_STD = new ObjenesisStd();
+
+ private static final Objenesis OBJENESIS_SERIALIZER = new ObjenesisSerializer();
+
+ private ObjenesisHelper() {
+ }
+
+ /**
+ * Will create a new object without any constructor being called
+ *
+ * @param clazz Class to instantiate
+ * @return New instance of clazz
+ */
+ public static final Object newInstance(Class clazz) {
+ return OBJENESIS_STD.newInstance(clazz);
+ }
+
+ /**
+ * Will create an object just like it's done by ObjectInputStream.readObject (the default
+ * constructor of the first non serializable class will be called)
+ *
+ * @param clazz Class to instantiate
+ * @return New instance of clazz
+ */
+ public static final Serializable newSerializableInstance(Class clazz) {
+ return (Serializable) OBJENESIS_SERIALIZER.newInstance(clazz);
+ }
+
+ /**
+ * Will pick the best instantiator for the provided class. If you need to create a lot of
+ * instances from the same class, it is way more efficient to create them from the same
+ * ObjectInstantiator than calling {@link #newInstance(Class)}.
+ *
+ * @param clazz Class to instantiate
+ * @return Instantiator dedicated to the class
+ */
+ public static final ObjectInstantiator getInstantiatorOf(Class clazz) {
+ return OBJENESIS_STD.getInstantiatorOf(clazz);
+ }
+
+ /**
+ * Same as {@link #getInstantiatorOf(Class)} but providing an instantiator emulating
+ * ObjectInputStream.readObject behavior.
+ *
+ * @see #newSerializableInstance(Class)
+ * @param clazz Class to instantiate
+ * @return Instantiator dedicated to the class
+ */
+ public static final ObjectInstantiator getSerializableObjectInstantiatorOf(Class clazz) {
+ return OBJENESIS_SERIALIZER.getInstantiatorOf(clazz);
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisHelper.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisSerializer.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisSerializer.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisSerializer.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,28 @@
+package org.objenesis;
+
+import org.objenesis.strategy.SerializingInstantiatorStrategy;
+
+/**
+ * Objenesis implementation using the {@link SerializingInstantiatorStrategy}.
+ *
+ * @author Henri Tremblay
+ */
+public class ObjenesisSerializer extends ObjenesisBase {
+
+ /**
+ * Default constructor using the {@link org.objenesis.strategy.SerializingInstantiatorStrategy}
+ */
+ public ObjenesisSerializer() {
+ super(new SerializingInstantiatorStrategy());
+ }
+
+ /**
+ * Instance using the {@link org.objenesis.strategy.SerializingInstantiatorStrategy} with or without caching
+ * {@link org.objenesis.instantiator.ObjectInstantiator}s
+ *
+ * @param useCache If {@link org.objenesis.instantiator.ObjectInstantiator}s should be cached
+ */
+ public ObjenesisSerializer(boolean useCache) {
+ super(new SerializingInstantiatorStrategy(), useCache);
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisSerializer.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisStd.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisStd.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisStd.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,28 @@
+package org.objenesis;
+
+import org.objenesis.strategy.StdInstantiatorStrategy;
+
+/**
+ * Objenesis implementation using the {@link org.objenesis.strategy.StdInstantiatorStrategy}.
+ *
+ * @author Henri Tremblay
+ */
+public class ObjenesisStd extends ObjenesisBase {
+
+ /**
+ * Default constructor using the {@link org.objenesis.strategy.StdInstantiatorStrategy}
+ */
+ public ObjenesisStd() {
+ super(new StdInstantiatorStrategy());
+ }
+
+ /**
+ * Instance using the {@link org.objenesis.strategy.StdInstantiatorStrategy} with or without
+ * caching {@link org.objenesis.instantiator.ObjectInstantiator}s
+ *
+ * @param useCache If {@link org.objenesis.instantiator.ObjectInstantiator}s should be cached
+ */
+ public ObjenesisStd(boolean useCache) {
+ super(new StdInstantiatorStrategy(), useCache);
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/ObjenesisStd.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/NullInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/NullInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/NullInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,16 @@
+package org.objenesis.instantiator;
+
+/**
+ * The instantiator that always return a null instance
+ *
+ * @author Henri Tremblay
+ */
+public class NullInstantiator implements ObjectInstantiator {
+
+ /**
+ * @return Always null
+ */
+ public Object newInstance() {
+ return null;
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/NullInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/ObjectInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/ObjectInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/ObjectInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,16 @@
+package org.objenesis.instantiator;
+
+/**
+ * Instantiates a new object.
+ */
+public interface ObjectInstantiator {
+
+ /**
+ * Returns a new instance of an object. The returned object's class is defined by the
+ * implementation.
+ *
+ * @return A new instance of an object.
+ */
+ Object newInstance();
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/ObjectInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/SerializationInstantiatorHelper.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/SerializationInstantiatorHelper.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/SerializationInstantiatorHelper.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,33 @@
+package org.objenesis.instantiator;
+
+import java.io.Serializable;
+
+/**
+ * Helper for common serialization-compatible instantiation functions
+ *
+ * @author Leonardo Mesquita
+ */
+public class SerializationInstantiatorHelper {
+
+ /**
+ * Returns the first non-serializable superclass of a given class. According to Java Object
+ * Serialization Specification, objects read from a stream are initialized by calling an
+ * accessible no-arg constructor from the first non-serializable superclass in the object's
+ * hierarchy, allowing the state of non-serializable fields to be correctly initialized.
+ *
+ * @param type Serializable class for which the first non-serializable superclass is to be found
+ * @return The first non-serializable superclass of 'type'.
+ * @see java.io.Serializable
+ */
+ public static Class getNonSerializableSuperClass(Class type) {
+ Class result = type;
+ while(Serializable.class.isAssignableFrom(result)) {
+ result = result.getSuperclass();
+ if(result == null) {
+ throw new Error("Bad class hierarchy: No non-serializable parents");
+ }
+ }
+ return result;
+
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/SerializationInstantiatorHelper.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/AccessibleInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/AccessibleInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/AccessibleInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,18 @@
+package org.objenesis.instantiator.basic;
+
+/**
+ * Instantiates a class by grabbing the no-args constructor, making it accessible and then calling
+ * Constructor.newInstance(). Although this still requires no-arg constructors, it can call
+ * non-public constructors (if the security manager allows it).
+ *
+ * @see org.objenesis.instantiator.ObjectInstantiator
+ */
+public class AccessibleInstantiator extends ConstructorInstantiator {
+
+ public AccessibleInstantiator(Class type) {
+ super(type);
+ if(constructor != null) {
+ constructor.setAccessible(true);
+ }
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/AccessibleInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ConstructorInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ConstructorInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ConstructorInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,36 @@
+package org.objenesis.instantiator.basic;
+
+import java.lang.reflect.Constructor;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.ObjectInstantiator;
+
+/**
+ * Instantiates a class by grabbing the no args constructor and calling Constructor.newInstance().
+ * This can deal with default public constructors, but that's about it.
+ *
+ * @see ObjectInstantiator
+ */
+public class ConstructorInstantiator implements ObjectInstantiator {
+
+ protected Constructor constructor;
+
+ public ConstructorInstantiator(Class type) {
+ try {
+ constructor = type.getDeclaredConstructor((Class[]) null);
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+
+ public Object newInstance() {
+ try {
+ return constructor.newInstance((Object[]) null);
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ConstructorInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/NewInstanceInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/NewInstanceInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/NewInstanceInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,29 @@
+package org.objenesis.instantiator.basic;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.ObjectInstantiator;
+
+/**
+ * The simplest instantiator - simply calls Class.newInstance(). This can deal with default public
+ * constructors, but that's about it.
+ *
+ * @see ObjectInstantiator
+ */
+public class NewInstanceInstantiator implements ObjectInstantiator {
+
+ private final Class type;
+
+ public NewInstanceInstantiator(Class type) {
+ this.type = type;
+ }
+
+ public Object newInstance() {
+ try {
+ return type.newInstance();
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/NewInstanceInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,164 @@
+package org.objenesis.instantiator.basic;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamConstants;
+import java.io.Serializable;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.ObjectInstantiator;
+
+/**
+ * Instantiates a class by using a dummy input stream that always feeds data for an empty object of
+ * the same kind. NOTE: This instantiator may not work properly if the class being instantiated
+ * defines a "readResolve" method, since it may return objects that have been returned previously
+ * (i.e., there's no guarantee that the returned object is a new one), or even objects from a
+ * completely different class.
+ *
+ * @author Leonardo Mesquita
+ * @see org.objenesis.instantiator.ObjectInstantiator
+ */
+public class ObjectInputStreamInstantiator implements ObjectInstantiator {
+ private static class MockStream extends InputStream {
+
+ private int pointer;
+ private byte[] data;
+ private int sequence;
+ private static final int[] NEXT = new int[] {1, 2, 2};
+ private byte[][] buffers;
+
+ private final byte[] FIRST_DATA;
+ private static byte[] HEADER;
+ private static byte[] REPEATING_DATA;
+
+ static {
+ initialize();
+ }
+
+ private static void initialize() {
+ try {
+ ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+ DataOutputStream dout = new DataOutputStream(byteOut);
+ dout.writeShort(ObjectStreamConstants.STREAM_MAGIC);
+ dout.writeShort(ObjectStreamConstants.STREAM_VERSION);
+ HEADER = byteOut.toByteArray();
+
+ byteOut = new ByteArrayOutputStream();
+ dout = new DataOutputStream(byteOut);
+
+ dout.writeByte(ObjectStreamConstants.TC_OBJECT);
+ dout.writeByte(ObjectStreamConstants.TC_REFERENCE);
+ dout.writeInt(ObjectStreamConstants.baseWireHandle);
+ REPEATING_DATA = byteOut.toByteArray();
+ }
+ catch(IOException e) {
+ throw new Error("IOException: " + e.getMessage());
+ }
+
+ }
+
+ public MockStream(Class clazz) {
+ this.pointer = 0;
+ this.sequence = 0;
+ this.data = HEADER;
+
+ // (byte) TC_OBJECT
+ // (byte) TC_CLASSDESC
+ // (short length)
+ // (byte * className.length)
+ // (long)serialVersionUID
+ // (byte) SC_SERIALIZABLE
+ // (short)0 <fields>
+ // TC_ENDBLOCKDATA
+ // TC_NULL
+ ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+ DataOutputStream dout = new DataOutputStream(byteOut);
+ try {
+ dout.writeByte(ObjectStreamConstants.TC_OBJECT);
+ dout.writeByte(ObjectStreamConstants.TC_CLASSDESC);
+ dout.writeUTF(clazz.getName());
+ dout.writeLong(ObjectStreamClass.lookup(clazz).getSerialVersionUID());
+ dout.writeByte(ObjectStreamConstants.SC_SERIALIZABLE);
+ dout.writeShort((short) 0); // Zero fields
+ dout.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA);
+ dout.writeByte(ObjectStreamConstants.TC_NULL);
+ }
+ catch(IOException e) {
+ throw new Error("IOException: " + e.getMessage());
+ }
+ this.FIRST_DATA = byteOut.toByteArray();
+ buffers = new byte[][] {HEADER, FIRST_DATA, REPEATING_DATA};
+ }
+
+ private void advanceBuffer() {
+ pointer = 0;
+ sequence = NEXT[sequence];
+ data = buffers[sequence];
+ }
+
+ public int read() throws IOException {
+ int result = data[pointer++];
+ if(pointer >= data.length) {
+ advanceBuffer();
+ }
+
+ return result;
+ }
+
+ public int available() throws IOException {
+ return Integer.MAX_VALUE;
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ int left = len;
+ int remaining = data.length - pointer;
+
+ while(remaining <= left) {
+ System.arraycopy(data, pointer, b, off, remaining);
+ off += remaining;
+ left -= remaining;
+ advanceBuffer();
+ remaining = data.length - pointer;
+ }
+ if(left > 0) {
+ System.arraycopy(data, pointer, b, off, left);
+ pointer += left;
+ }
+
+ return len;
+ }
+ }
+
+ private ObjectInputStream inputStream;
+
+ public ObjectInputStreamInstantiator(Class clazz) {
+ if(Serializable.class.isAssignableFrom(clazz)) {
+ try {
+ this.inputStream = new ObjectInputStream(new MockStream(clazz));
+ }
+ catch(IOException e) {
+ throw new Error("IOException: " + e.getMessage());
+ }
+ }
+ else {
+ throw new ObjenesisException(new NotSerializableException(clazz+" not serializable"));
+ }
+ }
+
+ public Object newInstance() {
+ try {
+ return inputStream.readObject();
+ }
+ catch(ClassNotFoundException e) {
+ throw new Error("ClassNotFoundException: " + e.getMessage());
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,54 @@
+package org.objenesis.instantiator.basic;
+
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Method;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.ObjectInstantiator;
+
+/**
+ * Instantiates a class by using reflection to make a call to private method
+ * ObjectStreamClass.newInstance, present in many JVM implementations. This instantiator will create
+ * classes in a way compatible with serialization, calling the first non-serializable superclass'
+ * no-arg constructor.
+ *
+ * @author Leonardo Mesquita
+ * @see ObjectInstantiator
+ * @see java.io.Serializable
+ */
+public class ObjectStreamClassInstantiator implements ObjectInstantiator {
+
+ private static Method newInstanceMethod;
+
+ private static void initialize() {
+ if(newInstanceMethod == null) {
+ try {
+ newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod("newInstance",
+ new Class[] {});
+ newInstanceMethod.setAccessible(true);
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+ }
+
+ private ObjectStreamClass objStreamClass;
+
+ public ObjectStreamClassInstantiator(Class type) {
+ initialize();
+ objStreamClass = ObjectStreamClass.lookup(type);
+ }
+
+ public Object newInstance() {
+
+ try {
+ return newInstanceMethod.invoke(objStreamClass, new Object[] {});
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,25 @@
+package org.objenesis.instantiator.gcj;
+
+import org.objenesis.ObjenesisException;
+
+/**
+ * Instantiates a class by making a call to internal GCJ private methods. It is only supposed to
+ * work on GCJ JVMs. This instantiator will not call any constructors.
+ *
+ * @author Leonardo Mesquita
+ * @see org.objenesis.instantiator.ObjectInstantiator
+ */
+public class GCJInstantiator extends GCJInstantiatorBase {
+ public GCJInstantiator(Class type) {
+ super(type);
+ }
+
+ public Object newInstance() {
+ try {
+ return newObjectMethod.invoke(dummyStream, new Object[] {type, Object.class});
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,49 @@
+package org.objenesis.instantiator.gcj;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Method;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.ObjectInstantiator;
+
+/**
+ * Base class for GCJ-based instantiators. It initializes reflection access to method
+ * ObjectInputStream.newObject, as well as creating a dummy ObjectInputStream to be used as the
+ * "this" argument for the method.
+ *
+ * @author Leonardo Mesquita
+ */
+public abstract class GCJInstantiatorBase implements ObjectInstantiator {
+ protected static Method newObjectMethod = null;
+ protected static ObjectInputStream dummyStream;
+
+ private static class DummyStream extends ObjectInputStream {
+ public DummyStream() throws IOException {
+ super();
+ }
+ }
+
+ private static void initialize() {
+ if(newObjectMethod == null) {
+ try {
+ newObjectMethod = ObjectInputStream.class.getDeclaredMethod("newObject", new Class[] {
+ Class.class, Class.class});
+ newObjectMethod.setAccessible(true);
+ dummyStream = new DummyStream();
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+ }
+
+ protected final Class type;
+
+ public GCJInstantiatorBase(Class type) {
+ this.type = type;
+ initialize();
+ }
+
+ public abstract Object newInstance();
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,31 @@
+package org.objenesis.instantiator.gcj;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.SerializationInstantiatorHelper;
+
+/**
+ * Instantiates a class by making a call to internal GCJ private methods. It is only supposed to
+ * work on GCJ JVMs. This instantiator will create classes in a way compatible with serialization,
+ * calling the first non-serializable superclass' no-arg constructor.
+ *
+ * @author Leonardo Mesquita
+ * @see org.objenesis.instantiator.ObjectInstantiator
+ */
+public class GCJSerializationInstantiator extends GCJInstantiatorBase {
+ private Class superType;
+
+ public GCJSerializationInstantiator(Class type) {
+ super(type);
+ this.superType = SerializationInstantiatorHelper.getNonSerializableSuperClass(type);
+ }
+
+ public Object newInstance() {
+ try {
+ return newObjectMethod.invoke(dummyStream, new Object[] {type, superType});
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/jrockit/JRockit131Instantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/jrockit/JRockit131Instantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/jrockit/JRockit131Instantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,83 @@
+/**
+ * COPYRIGHT & LICENSE
+ *
+ * This code is Copyright (c) 2006 BEA Systems, inc. It is provided free, as-is and without any warranties for the purpose of
+ * inclusion in Objenesis or any other open source project with a FSF approved license, as long as this notice is not
+ * removed. There are no limitations on modifying or repackaging the code apart from this.
+ *
+ * BEA does not guarantee that the code works, and provides no support for it. Use at your own risk.
+ *
+ * Originally developed by Leonardo Mesquita. Copyright notice added by Henrik Ståhl, BEA JRockit Product Manager.
+ *
+ */
+package org.objenesis.instantiator.jrockit;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.ObjectInstantiator;
+
+/**
+ * Instantiates a class by making a call to internal JRockit private methods. It is only supposed to
+ * work on JRockit 7.0 JVMs, which are compatible with Java API 1.3.1. This instantiator will not
+ * call any constructors.
+ *
+ * @author Leonardo Mesquita
+ * @see org.objenesis.instantiator.ObjectInstantiator
+ */
+public class JRockit131Instantiator implements ObjectInstantiator {
+
+ private Constructor mungedConstructor;
+
+ private static Method newConstructorForSerializationMethod;
+
+ private static void initialize() {
+ if(newConstructorForSerializationMethod == null) {
+ Class cl;
+ try {
+ cl = Class.forName("COM.jrockit.reflect.MemberAccess");
+ newConstructorForSerializationMethod = cl.getDeclaredMethod(
+ "newConstructorForSerialization", new Class[] {Constructor.class, Class.class});
+ newConstructorForSerializationMethod.setAccessible(true);
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+ }
+
+ public JRockit131Instantiator(Class type) {
+ initialize();
+
+ if(newConstructorForSerializationMethod != null) {
+
+ Constructor javaLangObjectConstructor;
+
+ try {
+ javaLangObjectConstructor = Object.class.getConstructor((Class[]) null);
+ }
+ catch(NoSuchMethodException e) {
+ throw new Error("Cannot find constructor for java.lang.Object!");
+ }
+
+ try {
+ mungedConstructor = (Constructor) newConstructorForSerializationMethod.invoke(null,
+ new Object[] {javaLangObjectConstructor, type});
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+
+ }
+
+ public Object newInstance() {
+ try {
+ return mungedConstructor.newInstance((Object[]) null);
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/jrockit/JRockit131Instantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/jrockit/JRockitLegacyInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/jrockit/JRockitLegacyInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/jrockit/JRockitLegacyInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,64 @@
+/**
+ * COPYRIGHT & LICENSE
+ *
+ * This code is Copyright (c) 2006 BEA Systems, inc. It is provided free, as-is and without any warranties for the purpose of
+ * inclusion in Objenesis or any other open source project with a FSF approved license, as long as this notice is not
+ * removed. There are no limitations on modifying or repackaging the code apart from this.
+ *
+ * BEA does not guarantee that the code works, and provides no support for it. Use at your own risk.
+ *
+ * Originally developed by Leonardo Mesquita. Copyright notice added by Henrik Ståhl, BEA JRockit Product Manager.
+ *
+ */
+
+package org.objenesis.instantiator.jrockit;
+
+import java.lang.reflect.Method;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.ObjectInstantiator;
+
+/**
+ * Instantiates a class by making a call to internal JRockit private methods. It is only supposed to
+ * work on JRockit 1.4.2 JVMs prior to release R25.1. From release R25.1 on, JRockit supports
+ * sun.reflect.ReflectionFactory, making this "trick" unnecessary. This instantiator will not call
+ * any constructors.
+ *
+ * @author Leonardo Mesquita
+ * @see org.objenesis.instantiator.ObjectInstantiator
+ * @see org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator
+ */
+public class JRockitLegacyInstantiator implements ObjectInstantiator {
+ private static Method safeAllocObjectMethod = null;
+
+ private static void initialize() {
+ if(safeAllocObjectMethod == null) {
+ Class memSystem;
+ try {
+ memSystem = Class.forName("jrockit.vm.MemSystem");
+ safeAllocObjectMethod = memSystem.getDeclaredMethod("safeAllocObject",
+ new Class[] {Class.class});
+ safeAllocObjectMethod.setAccessible(true);
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+ }
+
+ private Class type;
+
+ public JRockitLegacyInstantiator(Class type) {
+ initialize();
+ this.type = type;
+ }
+
+ public Object newInstance() {
+ try {
+ return safeAllocObjectMethod.invoke(null, new Object[] {type});
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/jrockit/JRockitLegacyInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13Instantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13Instantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13Instantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,26 @@
+package org.objenesis.instantiator.sun;
+
+import org.objenesis.ObjenesisException;
+
+/**
+ * Instantiates a class by making a call to internal Sun private methods. It is only supposed to
+ * work on Sun HotSpot 1.3 JVM. This instantiator will not call any constructors.
+ *
+ * @author Leonardo Mesquita
+ * @see org.objenesis.instantiator.ObjectInstantiator
+ */
+public class Sun13Instantiator extends Sun13InstantiatorBase {
+ public Sun13Instantiator(Class type) {
+ super(type);
+ }
+
+ public Object newInstance() {
+ try {
+ return allocateNewObjectMethod.invoke(null, new Object[] {type, Object.class});
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13Instantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13InstantiatorBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13InstantiatorBase.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13InstantiatorBase.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,40 @@
+package org.objenesis.instantiator.sun;
+
+import java.io.ObjectInputStream;
+import java.lang.reflect.Method;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.ObjectInstantiator;
+
+/**
+ * Base class for Sun 1.3 based instantiators. It initializes reflection access to static method
+ * ObjectInputStream.allocateNewObject.
+ *
+ * @author Leonardo Mesquita
+ */
+public abstract class Sun13InstantiatorBase implements ObjectInstantiator {
+ protected static Method allocateNewObjectMethod = null;
+
+ private static void initialize() {
+ if(allocateNewObjectMethod == null) {
+ try {
+ allocateNewObjectMethod = ObjectInputStream.class.getDeclaredMethod(
+ "allocateNewObject", new Class[] {Class.class, Class.class});
+ allocateNewObjectMethod.setAccessible(true);
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+ }
+
+ protected final Class type;
+
+ public Sun13InstantiatorBase(Class type) {
+ this.type = type;
+ initialize();
+ }
+
+ public abstract Object newInstance();
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13InstantiatorBase.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13SerializationInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13SerializationInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13SerializationInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,31 @@
+package org.objenesis.instantiator.sun;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.SerializationInstantiatorHelper;
+
+/**
+ * Instantiates a class by making a call to internal Sun private methods. It is only supposed to
+ * work on Sun HotSpot 1.3 JVM. This instantiator will create classes in a way compatible with
+ * serialization, calling the first non-serializable superclass' no-arg constructor.
+ *
+ * @author Leonardo Mesquita
+ * @see org.objenesis.instantiator.ObjectInstantiator
+ */
+public class Sun13SerializationInstantiator extends Sun13InstantiatorBase {
+ private final Class superType;
+
+ public Sun13SerializationInstantiator(Class type) {
+ super(type);
+ this.superType = SerializationInstantiatorHelper.getNonSerializableSuperClass(type);
+ }
+
+ public Object newInstance() {
+ try {
+ return allocateNewObjectMethod.invoke(null, new Object[] {type, superType});
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/Sun13SerializationInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,46 @@
+package org.objenesis.instantiator.sun;
+
+import java.lang.reflect.Constructor;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.ObjectInstantiator;
+
+import sun.reflect.ReflectionFactory;
+
+/**
+ * Instantiates an object, WITHOUT calling it's constructor, using internal
+ * sun.reflect.ReflectionFactory - a class only available on JDK's that use Sun's 1.4 (or later)
+ * Java implementation. This is the best way to instantiate an object without any side effects
+ * caused by the constructor - however it is not available on every platform.
+ *
+ * @see ObjectInstantiator
+ */
+public class SunReflectionFactoryInstantiator implements ObjectInstantiator {
+
+ private final Constructor mungedConstructor;
+
+ public SunReflectionFactoryInstantiator(Class type) {
+
+ ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
+ Constructor javaLangObjectConstructor;
+
+ try {
+ javaLangObjectConstructor = Object.class.getConstructor((Class[]) null);
+ }
+ catch(NoSuchMethodException e) {
+ throw new Error("Cannot find constructor for java.lang.Object!");
+ }
+ mungedConstructor = reflectionFactory.newConstructorForSerialization(type,
+ javaLangObjectConstructor);
+ mungedConstructor.setAccessible(true);
+ }
+
+ public Object newInstance() {
+ try {
+ return mungedConstructor.newInstance((Object[]) null);
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,57 @@
+package org.objenesis.instantiator.sun;
+
+import java.io.NotSerializableException;
+import java.lang.reflect.Constructor;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.ObjectInstantiator;
+import org.objenesis.instantiator.SerializationInstantiatorHelper;
+
+import sun.reflect.ReflectionFactory;
+
+/**
+ * Instantiates an object using internal sun.reflect.ReflectionFactory - a class only available on
+ * JDK's that use Sun's 1.4 (or later) Java implementation. This instantiator will create classes in
+ * a way compatible with serialization, calling the first non-serializable superclass' no-arg
+ * constructor. This is the best way to instantiate an object without any side effects caused by the
+ * constructor - however it is not available on every platform.
+ *
+ * @see ObjectInstantiator
+ */
+public class SunReflectionFactorySerializationInstantiator implements ObjectInstantiator {
+
+ private final Constructor mungedConstructor;
+
+ public SunReflectionFactorySerializationInstantiator(Class type) {
+
+ Class nonSerializableAncestor = SerializationInstantiatorHelper.getNonSerializableSuperClass(type);
+ ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
+ Constructor nonSerializableAncestorConstructor;
+ try {
+ nonSerializableAncestorConstructor = nonSerializableAncestor
+ .getConstructor((Class[]) null);
+ }
+ catch(NoSuchMethodException e) {
+ /**
+ * @todo (Henri) I think we should throw a NotSerializableException just to put the same
+ * message a ObjectInputStream. Otherwise, the user won't know if the null returned
+ * if a "Not serializable", a "No default constructor on ancestor" or a "Exception in
+ * constructor"
+ */
+ throw new ObjenesisException(new NotSerializableException(type+" has no suitable superclass constructor"));
+ }
+
+ mungedConstructor = reflectionFactory.newConstructorForSerialization(type,
+ nonSerializableAncestorConstructor);
+ mungedConstructor.setAccessible(true);
+ }
+
+ public Object newInstance() {
+ try {
+ return mungedConstructor.newInstance((Object[]) null);
+ }
+ catch(Exception e) {
+ throw new ObjenesisException(e);
+ }
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/BaseInstantiatorStrategy.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/BaseInstantiatorStrategy.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/BaseInstantiatorStrategy.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,33 @@
+package org.objenesis.strategy;
+
+/**
+ * Base {@link InstantiatorStrategy} class basically containing helpful constant to sort out JVMs.
+ *
+ * @author Henri Tremblay
+ */
+public abstract class BaseInstantiatorStrategy implements InstantiatorStrategy {
+
+ /** JVM_NAME prefix for JRockit */
+ protected static final String JROCKIT = "BEA";
+
+ /** JVM_NAME prefix for GCJ */
+ protected static final String GNU = "GNU libgcj";
+
+ /** JVM_NAME prefix for Sun Java HotSpot */
+ protected static final String SUN = "Java HotSpot";
+
+ /** JVM version */
+ protected static final String VM_VERSION = System.getProperty("java.runtime.version");
+
+ /** JVM version */
+ protected static final String VM_INFO = System.getProperty("java.vm.info");
+
+ /** Vendor version */
+ protected static final String VENDOR_VERSION = System.getProperty("java.vm.version");
+
+ /** Vendor name */
+ protected static final String VENDOR = System.getProperty("java.vm.vendor");
+
+ /** JVM name */
+ protected static final String JVM_NAME = System.getProperty("java.vm.name");
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/BaseInstantiatorStrategy.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/InstantiatorStrategy.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/InstantiatorStrategy.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/InstantiatorStrategy.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,17 @@
+package org.objenesis.strategy;
+
+import org.objenesis.instantiator.ObjectInstantiator;
+
+/**
+ * Defines a strategy to determine the best instantiator for a class.
+ */
+public interface InstantiatorStrategy {
+
+ /**
+ * Create a dedicated instantiator for the given class
+ *
+ * @param type Class that will be instantiate
+ * @return Dedicated instantiator
+ */
+ ObjectInstantiator newInstantiatorOf(Class type);
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/InstantiatorStrategy.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/SerializingInstantiatorStrategy.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/SerializingInstantiatorStrategy.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/SerializingInstantiatorStrategy.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,50 @@
+package org.objenesis.strategy;
+
+import java.io.NotSerializableException;
+import java.io.Serializable;
+
+import org.objenesis.ObjenesisException;
+import org.objenesis.instantiator.ObjectInstantiator;
+import org.objenesis.instantiator.basic.ObjectStreamClassInstantiator;
+import org.objenesis.instantiator.gcj.GCJSerializationInstantiator;
+import org.objenesis.instantiator.sun.Sun13SerializationInstantiator;
+
+/**
+ * Guess the best serializing instantiator for a given class. The returned instantiator will
+ * instantiate classes like the genuine java serialization framework (the constructor of the first
+ * not serializable class will be called). Currently, the selection doesn't depend on the class. It
+ * relies on the
+ * <ul>
+ * <li>JVM version</li>
+ * <li>JVM vendor</li>
+ * <li>JVM vendor version</li>
+ * </ul>
+ * However, instantiators are stateful and so dedicated to their class.
+ *
+ * @see ObjectInstantiator
+ */
+public class SerializingInstantiatorStrategy extends BaseInstantiatorStrategy {
+
+ /**
+ * Return an {@link ObjectInstantiator} allowing to create instance following the java
+ * serialization framework specifications.
+ *
+ * @param type Class to instantiate
+ * @return The ObjectInstantiator for the class
+ */
+ public ObjectInstantiator newInstantiatorOf(Class type) {
+ if(!Serializable.class.isAssignableFrom(type)) {
+ throw new ObjenesisException(new NotSerializableException(type+" not serializable"));
+ }
+ if(JVM_NAME.startsWith(SUN)) {
+ if(VM_VERSION.startsWith("1.3")) {
+ return new Sun13SerializationInstantiator(type);
+ }
+ }
+ else if(JVM_NAME.startsWith(GNU)) {
+ return new GCJSerializationInstantiator(type);
+ }
+ return new ObjectStreamClassInstantiator(type);
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/SerializingInstantiatorStrategy.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/StdInstantiatorStrategy.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/StdInstantiatorStrategy.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/StdInstantiatorStrategy.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,67 @@
+package org.objenesis.strategy;
+
+import org.objenesis.instantiator.ObjectInstantiator;
+import org.objenesis.instantiator.gcj.GCJInstantiator;
+import org.objenesis.instantiator.jrockit.JRockit131Instantiator;
+import org.objenesis.instantiator.jrockit.JRockitLegacyInstantiator;
+import org.objenesis.instantiator.sun.Sun13Instantiator;
+import org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator;
+
+/**
+ * Guess the best instantiator for a given class. The instantiator will instantiate the class
+ * without calling any constructor. Currently, the selection doesn't depend on the class. It relies
+ * on the
+ * <ul>
+ * <li>JVM version</li>
+ * <li>JVM vendor</li>
+ * <li>JVM vendor version</li>
+ * </ul>
+ * However, instantiators are stateful and so dedicated to their class.
+ *
+ * @see ObjectInstantiator
+ */
+public class StdInstantiatorStrategy extends BaseInstantiatorStrategy {
+
+ /**
+ * Return an {@link ObjectInstantiator} allowing to create instance without any constructor being
+ * called.
+ *
+ * @param type Class to instantiate
+ * @return The ObjectInstantiator for the class
+ */
+ public ObjectInstantiator newInstantiatorOf(Class type) {
+
+ if(JVM_NAME.startsWith(SUN)) {
+ if(VM_VERSION.startsWith("1.3")) {
+ return new Sun13Instantiator(type);
+ }
+ }
+ else if(JVM_NAME.startsWith(JROCKIT)) {
+ if(VM_VERSION.startsWith("1.3")) {
+ return new JRockit131Instantiator(type);
+ }
+ else if(VM_VERSION.startsWith("1.4")) {
+ // JRockit vendor version will be RXX where XX is the version
+ // Versions prior to 26 need special handling
+ // From R26 on, java.vm.version starts with R
+ if(!VENDOR_VERSION.startsWith("R")) {
+ // On R25.1 and R25.2, ReflectionFactory should work. Otherwise, we must use the
+ // Legacy instantiator.
+ if(VM_INFO == null || !VM_INFO.startsWith("R25.1") || !VM_INFO.startsWith("R25.2")) {
+ return new JRockitLegacyInstantiator(type);
+ }
+ }
+ }
+ }
+ else if(JVM_NAME.startsWith(GNU)) {
+ return new GCJInstantiator(type);
+ }
+
+ // Fallback instantiator, should work with:
+ // - Java Hotspot version 1.4 and higher
+ // - JRockit 1.4-R26 and higher
+ // - IBM and Hitachi JVMs
+ // ... might works for others so we just give it a try
+ return new SunReflectionFactoryInstantiator(type);
+ }
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/objenesis/strategy/StdInstantiatorStrategy.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/Person.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/Person.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/Person.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -0,0 +1,42 @@
+package org.drools;
+
+public class Person {
+
+ private String name;
+ private int age;
+
+ public Person( String name, int age ) {
+ this.name = name;
+ this.age = age;
+ }
+
+ /**
+ * @return the age
+ */
+ public int getAge() {
+ return age;
+ }
+
+ /**
+ * @param age the age to set
+ */
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/Person.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ObjectTypeNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ObjectTypeNodeTest.java 2007-02-22 18:23:42 UTC (rev 9707)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ObjectTypeNodeTest.java 2007-02-22 19:43:07 UTC (rev 9708)
@@ -22,6 +22,7 @@
import org.drools.Cheese;
import org.drools.DroolsTestCase;
import org.drools.FactException;
+import org.drools.Person;
import org.drools.RuleBaseFactory;
import org.drools.base.ClassObjectType;
import org.drools.base.ShadowProxy;
@@ -314,4 +315,51 @@
assertTrue( memory.contains( handle1 ) );
}
+ public void testAssertObjectWithShadowEnabledNoDefaultConstr() throws Exception {
+ final PropagationContext context = new PropagationContextImpl( 0,
+ PropagationContext.ASSERTION,
+ null,
+ null );
+
+ final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
+ final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory( 1,
+ ruleBase );
+
+ final Rete source = ruleBase.getRete();
+
+ final Class shadowClass = ShadowProxyFactory.getProxy( Person.class );
+ final ObjectTypeNode objectTypeNode = new ObjectTypeNode( 1,
+ new ClassObjectType( Person.class,
+ shadowClass ),
+ source,
+ 3);
+
+ final MockObjectSink sink = new MockObjectSink();
+ objectTypeNode.addObjectSink( sink );
+
+ final Object person = new Person( "bob",
+ 25 );
+
+ final InternalFactHandle handle1 = (InternalFactHandle) workingMemory.assertObject( person );
+
+ // should assert as ObjectType matches
+ objectTypeNode.assertObject( handle1,
+ context,
+ workingMemory );
+
+ // make sure just string1 was asserted
+ final List asserted = sink.getAsserted();
+ assertLength( 1,
+ asserted );
+ assertTrue( ((InternalFactHandle) ((Object[]) asserted.get( 0 ))[0]).getObject() instanceof ShadowProxy );
+ assertEquals( ((InternalFactHandle) ((Object[]) asserted.get( 0 ))[0]).getObject(),
+ person );
+
+ // check asserted object was added to memory
+ final FactHashTable memory = (FactHashTable) workingMemory.getNodeMemory( objectTypeNode );
+ assertEquals( 1,
+ memory.size() );
+ assertTrue( memory.contains( handle1 ) );
+ }
+
}
\ No newline at end of file
More information about the jboss-svn-commits
mailing list