1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.river.api.io;
20
21 import java.io.IOException;
22 import java.io.InvalidClassException;
23 import java.io.InvalidObjectException;
24 import java.io.ObjectInput;
25 import java.io.Externalizable;
26 import java.lang.annotation.ElementType;
27 import java.lang.annotation.Retention;
28 import java.lang.annotation.RetentionPolicy;
29 import java.lang.annotation.Target;
30 import java.lang.reflect.Constructor;
31 import java.lang.reflect.InvocationTargetException;
32 import java.lang.reflect.Modifier;
33 import java.security.AccessController;
34 import java.security.PrivilegedActionException;
35 import java.security.PrivilegedExceptionAction;
36
37
38
39
40
41
42
43
44
45
46
47
48
49 @Retention(RetentionPolicy.RUNTIME)
50 @Target(ElementType.TYPE)
51 public @interface AtomicExternal {
52
53
54
55
56 public static final class Factory {
57 private Factory(){}
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 public static <T> T instantiate(final Class<T> type, final ObjectInput arg)
86 throws IOException {
87 if (arg == null) throw new NullPointerException();
88 if (type == null) throw new NullPointerException();
89 final Class[] param = { ObjectInput.class };
90 Object[] args = { arg };
91 Constructor<T> c;
92 try {
93 c = AccessController.doPrivileged(
94 new PrivilegedExceptionAction<Constructor<T>>(){
95
96 @Override
97 public Constructor<T> run() throws Exception {
98 Constructor<T> c = type.getDeclaredConstructor(param);
99 int mods = c.getModifiers();
100 switch (mods){
101 case Modifier.PUBLIC:
102 c.setAccessible(true);
103 return c;
104 case Modifier.PROTECTED:
105 throw new InvalidClassException( type.getCanonicalName(),
106 "protected constructor cannot be called by de-serializer");
107 case Modifier.PRIVATE:
108 throw new InvalidClassException( type.getCanonicalName(),
109 "private constructor cannot be called by de-serializer");
110 default:
111 throw new InvalidClassException( type.getCanonicalName(),
112 "Package private constructor cannot be called by de-serializer");
113 }
114 }
115
116 });
117 return c.newInstance(args);
118 } catch (PrivilegedActionException ex) {
119 Exception e = ex.getException();
120 if (e instanceof NoSuchMethodException) throw new InvalidClassException(type.getCanonicalName(), "No matching AtomicSerial constructor signature found");
121 if (e instanceof SecurityException ) throw (SecurityException) e;
122 if (e instanceof InvalidClassException ) throw (InvalidClassException) e;
123 InvalidClassException ice = new InvalidClassException("Unexpected exception while attempting to access constructor");
124 ice.initCause(ex);
125 throw ice;
126 } catch (InvocationTargetException ex) {
127 Throwable e = ex.getCause();
128 if (e instanceof InvalidObjectException) throw (InvalidObjectException) e;
129 if (e instanceof IOException) throw (IOException) e;
130 if (e instanceof RuntimeException) throw (RuntimeException) e;
131 InvalidObjectException ioe = new InvalidObjectException(
132 "Construction failed: " + type);
133 ioe.initCause(ex);
134 throw ioe;
135 } catch (IllegalAccessException ex) {
136 throw new AssertionError("This shouldn't happen ", ex);
137 } catch (IllegalArgumentException ex) {
138 throw new AssertionError("This shouldn't happen ", ex);
139 } catch (InstantiationException ex) {
140 throw new InvalidClassException(type.getCanonicalName(), ex.getMessage());
141 }
142 }
143 }
144 }