Home | History | Annotate | Download | only in perc
      1 /**
      2  * Copyright 2006-2013 the original author or authors.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package org.objenesis.instantiator.perc;
     17 
     18 import java.io.ObjectInputStream;
     19 import java.io.Serializable;
     20 import java.lang.reflect.InvocationTargetException;
     21 import java.lang.reflect.Method;
     22 
     23 import org.objenesis.ObjenesisException;
     24 import org.objenesis.instantiator.ObjectInstantiator;
     25 
     26 /**
     27  * Instantiates a class by making a call to internal Perc private methods. It is only supposed to
     28  * work on Perc JVMs. This instantiator will create classes in a way compatible with serialization,
     29  * calling the first non-serializable superclass' no-arg constructor. <p/> Based on code provided by
     30  * Aonix but <b>doesn't work right now</b>
     31  *
     32  * @author Henri Tremblay
     33  * @see org.objenesis.instantiator.ObjectInstantiator
     34  */
     35 public class PercSerializationInstantiator implements ObjectInstantiator {
     36 
     37    private Object[] typeArgs;
     38 
     39    private final java.lang.reflect.Method newInstanceMethod;
     40 
     41    public PercSerializationInstantiator(Class type) {
     42 
     43       // Find the first unserializable parent class
     44       Class unserializableType = type;
     45 
     46       while(Serializable.class.isAssignableFrom(unserializableType)) {
     47          unserializableType = unserializableType.getSuperclass();
     48       }
     49 
     50       try {
     51          // Get the special Perc method to call
     52          Class percMethodClass = Class.forName("COM.newmonics.PercClassLoader.Method");
     53 
     54          newInstanceMethod = ObjectInputStream.class.getDeclaredMethod("noArgConstruct",
     55             new Class[] {Class.class, Object.class, percMethodClass});
     56          newInstanceMethod.setAccessible(true);
     57 
     58          // Create invoke params
     59          Class percClassClass = Class.forName("COM.newmonics.PercClassLoader.PercClass");
     60          Method getPercClassMethod = percClassClass.getDeclaredMethod("getPercClass",
     61             new Class[] {Class.class});
     62          Object someObject = getPercClassMethod.invoke(null, new Object[] {unserializableType});
     63          Method findMethodMethod = someObject.getClass().getDeclaredMethod("findMethod",
     64             new Class[] {String.class});
     65          Object percMethod = findMethodMethod.invoke(someObject, new Object[] {"<init>()V"});
     66 
     67          typeArgs = new Object[] {unserializableType, type, percMethod};
     68 
     69       }
     70       catch(ClassNotFoundException e) {
     71          throw new ObjenesisException(e);
     72       }
     73       catch(NoSuchMethodException e) {
     74          throw new ObjenesisException(e);
     75       }
     76       catch(InvocationTargetException e) {
     77          throw new ObjenesisException(e);
     78       }
     79       catch(IllegalAccessException e) {
     80          throw new ObjenesisException(e);
     81       }
     82    }
     83 
     84    public Object newInstance() {
     85       try {
     86          return newInstanceMethod.invoke(null, typeArgs);
     87       }
     88       catch(IllegalAccessException e) {
     89          throw new ObjenesisException(e);
     90       }
     91       catch(InvocationTargetException e) {
     92          throw new ObjenesisException(e);
     93       }
     94    }
     95 
     96 }
     97