• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2006-2017 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.android;
17 
18 import java.io.ObjectStreamClass;
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21 
22 import org.objenesis.ObjenesisException;
23 import org.objenesis.instantiator.ObjectInstantiator;
24 import org.objenesis.instantiator.annotations.Instantiator;
25 import org.objenesis.instantiator.annotations.Typology;
26 
27 /**
28  * {@link ObjectInstantiator} for Android which creates objects using the constructor from the first
29  * non-serializable parent class constructor, using internal methods on the Dalvik implementation of
30  * {@link ObjectStreamClass}.
31  *
32  * @author Ian Parkinson (Google Inc.)
33  */
34 @Instantiator(Typology.SERIALIZATION)
35 public class AndroidSerializationInstantiator<T> implements ObjectInstantiator<T> {
36    private final Class<T> type;
37    private final ObjectStreamClass objectStreamClass;
38    private final Method newInstanceMethod;
39 
AndroidSerializationInstantiator(Class<T> type)40    public AndroidSerializationInstantiator(Class<T> type) {
41       this.type = type;
42       newInstanceMethod = getNewInstanceMethod();
43       Method m = null;
44       try {
45          m = ObjectStreamClass.class.getMethod("lookupAny", Class.class);
46       } catch (NoSuchMethodException e) {
47          throw new ObjenesisException(e);
48       }
49       try {
50          objectStreamClass = (ObjectStreamClass) m.invoke(null, type);
51       } catch (IllegalAccessException e) {
52          throw new ObjenesisException(e);
53       } catch (InvocationTargetException e) {
54          throw new ObjenesisException(e);
55       }
56    }
57 
newInstance()58    public T newInstance() {
59       try {
60          return type.cast(newInstanceMethod.invoke(objectStreamClass, type));
61       }
62       catch(IllegalAccessException e) {
63          throw new ObjenesisException(e);
64       }
65       catch(IllegalArgumentException e) {
66          throw new ObjenesisException(e);
67       }
68       catch(InvocationTargetException e) {
69          throw new ObjenesisException(e);
70       }
71    }
72 
getNewInstanceMethod()73    private static Method getNewInstanceMethod() {
74       try {
75          Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod(
76             "newInstance", Class.class);
77          newInstanceMethod.setAccessible(true);
78          return newInstanceMethod;
79       }
80       catch(RuntimeException e) {
81          throw new ObjenesisException(e);
82       }
83       catch(NoSuchMethodException e) {
84          throw new ObjenesisException(e);
85       }
86    }
87 }
88