001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Evgueni Brevnov, Serguei S. Zapreyev
019: * @version $Revision: 1.1.2.2.4.4 $
020: */package java.lang.reflect;
021:
022: import java.lang.annotation.Annotation;
023:
024: import org.apache.harmony.lang.reflect.ReflectPermissionCollection;
025: import org.apache.harmony.lang.reflect.Reflection;
026:
027: /**
028: * @com.intel.drl.spec_ref
029: */
030: public class AccessibleObject implements AnnotatedElement {
031: /**
032: *
033: * @com.intel.drl.spec_ref
034: *
035: **/
036: public boolean isAnnotationPresent(
037: Class<? extends Annotation> annotationClass) {
038: return getAnnotation(annotationClass) == null ? false : true; // it seems to be correct for Method, Constructor, Field type object
039: }
040:
041: /**
042: *
043: * @com.intel.drl.spec_ref
044: *
045: **/
046: public Annotation[] getAnnotations() {
047: return getDeclaredAnnotations(); // it seems to be correct for Method, Constructor, Field type object
048: }
049:
050: /**
051: *
052: * @com.intel.drl.spec_ref
053: *
054: **/
055: public Annotation[] getDeclaredAnnotations() {
056: return (Annotation[]) null; // because of the method is overwritten in the Method, Constructor, Field classes
057: }
058:
059: /**
060: *
061: * @com.intel.drl.spec_ref
062: *
063: **/
064: public <T extends Annotation> T getAnnotation(
065: Class<T> annotationClass) {
066: return (T) null; // because of the method is overwritten in the Method, Constructor, Field classes
067: }
068:
069: /**
070: * one dimensional array
071: */
072: private static final String DIMENSION_1 = "[]";
073:
074: /**
075: * two dimensional array
076: */
077: private static final String DIMENSION_2 = "[][]";
078:
079: /**
080: * three dimensional array
081: */
082: private static final String DIMENSION_3 = "[][][]";
083:
084: /**
085: * used to exchange information with the java.lang package
086: */
087: static final ReflectExporter reflectExporter;
088:
089: /**
090: * indicates whether this object is accessible or not
091: */
092: boolean isAccessible = false;
093:
094: static {
095: reflectExporter = new ReflectExporter();
096: Reflection.setReflectAccessor(reflectExporter);
097: }
098:
099: /**
100: * @com.intel.drl.spec_ref
101: */
102: protected AccessibleObject() {
103: }
104:
105: /**
106: * @com.intel.drl.spec_ref
107: */
108: public static void setAccessible(AccessibleObject[] objs,
109: boolean flag) throws SecurityException {
110: SecurityManager sc = System.getSecurityManager();
111: if (sc != null) {
112: sc
113: .checkPermission(ReflectPermissionCollection.SUPPRESS_ACCESS_CHECKS_PERMISSION);
114: }
115: for (int i = 0; i < objs.length; i++) {
116: objs[i].setAccessible0(flag);
117: }
118: }
119:
120: /**
121: * @com.intel.drl.spec_ref
122: */
123: public boolean isAccessible() {
124: return isAccessible;
125: }
126:
127: /**
128: * @com.intel.drl.spec_ref
129: */
130: public void setAccessible(boolean flag) throws SecurityException {
131: SecurityManager sc = System.getSecurityManager();
132: if (sc != null) {
133: sc
134: .checkPermission(ReflectPermissionCollection.SUPPRESS_ACCESS_CHECKS_PERMISSION);
135: }
136: setAccessible0(flag);
137: }
138:
139: /*
140: * NON API SECTION
141: */
142:
143: /**
144: * Checks obj argument for correctness.
145: *
146: * @param declaringClass declaring class of the field/method member
147: * @param memberModifier field/method member modifier
148: * @param obj object to check for correctness
149: * @return null if accessing static member, otherwise obj
150: * @throws IllegalArgumentException if obj is not valid object
151: * @throws NullPointerException if obj or declaringClass argument is null
152: */
153: Object checkObject(Class declaringClass, int memberModifier,
154: Object obj) throws IllegalArgumentException {
155: if (Modifier.isStatic(memberModifier)) {
156: return null;
157: } else if (!declaringClass.isInstance(obj)) {
158: if (obj == null) {
159: throw new NullPointerException(
160: "The specified object is null but the method is not static");
161: }
162: throw new IllegalArgumentException(
163: "The specified object should be an instance of "
164: + declaringClass);
165: }
166: return obj;
167: }
168:
169: /**
170: * Appends the specified class name to the buffer. The class may represent
171: * a simple type, a reference type or an array type.
172: *
173: * @param sb buffer
174: * @param obj the class which name should be appended to the buffer
175: * @throws NullPointerException if any of the arguments is null
176: */
177: void appendArrayType(StringBuilder sb, Class<?> obj) {
178: if (!obj.isArray()) {
179: sb.append(obj.getName());
180: return;
181: }
182: int dimensions = 1;
183: Class simplified = obj.getComponentType();
184: obj = simplified;
185: while (simplified.isArray()) {
186: obj = simplified;
187: dimensions++;
188: }
189: sb.append(obj.getName());
190: switch (dimensions) {
191: case 1:
192: sb.append(DIMENSION_1);
193: break;
194: case 2:
195: sb.append(DIMENSION_2);
196: break;
197: case 3:
198: sb.append(DIMENSION_3);
199: break;
200: default:
201: for (; dimensions > 0; dimensions--) {
202: sb.append(DIMENSION_1);
203: }
204: }
205: }
206:
207: /**
208: * Appends names of the specified array classes to the buffer. The array
209: * elements may represent a simple type, a reference type or an array type.
210: * Output format: java.lang.Object[], java.io.File, void
211: *
212: * @param sb buffer
213: * @param objs array of classes to print the names
214: * @throws NullPointerException if any of the arguments is null
215: */
216: void appendArrayType(StringBuilder sb, Class[] objs) {
217: if (objs.length > 0) {
218: appendArrayType(sb, objs[0]);
219: for (int i = 1; i < objs.length; i++) {
220: sb.append(',');
221: appendArrayType(sb, objs[i]);
222: }
223: }
224: }
225:
226: /**
227: * Appends names of the specified array classes to the buffer. The array
228: * elements may represent a simple type, a reference type or an array type.
229: * Output format: java.lang.Object[], java.io.File, void
230: *
231: * @param sb buffer
232: * @param objs array of classes to print the names
233: * @throws NullPointerException if any of the arguments is null
234: */
235: void appendArrayGenericType(StringBuilder sb, Type[] objs) {
236: if (objs.length > 0) {
237: appendGenericType(sb, objs[0]);
238: for (int i = 1; i < objs.length; i++) {
239: sb.append(',');
240: appendGenericType(sb, objs[i]);
241: }
242: }
243: }
244:
245: /**
246: * Appends the generic type representation to the buffer.
247: *
248: * @param sb buffer
249: * @param obj the generic type which representation should be appended to the buffer
250: * @throws NullPointerException if any of the arguments is null
251: */
252: void appendGenericType(StringBuilder sb, Type obj) {
253: if (obj instanceof TypeVariable) {
254: sb.append(((TypeVariable) obj).getName());
255: } else if (obj instanceof ParameterizedType) {
256: sb.append(obj.toString());
257: } else if (obj instanceof GenericArrayType) { //XXX: is it a working branch?
258: Type simplified = ((GenericArrayType) obj)
259: .getGenericComponentType();
260: appendGenericType(sb, simplified);
261: sb.append("[]");
262: } else if (obj instanceof Class) {
263: Class c = ((Class<?>) obj);
264: if (c.isArray()) {
265: String as[] = c.getName().split("\\[");
266: int len = as.length - 1;
267: if (as[len].length() > 1) {
268: sb.append(as[len]
269: .substring(1, as[len].length() - 1));
270: } else {
271: char ch = as[len].charAt(0);
272: if (ch == 'I')
273: sb.append("int");
274: else if (ch == 'B')
275: sb.append("byte");
276: else if (ch == 'J')
277: sb.append("long");
278: else if (ch == 'F')
279: sb.append("float");
280: else if (ch == 'D')
281: sb.append("double");
282: else if (ch == 'S')
283: sb.append("short");
284: else if (ch == 'C')
285: sb.append("char");
286: else if (ch == 'Z')
287: sb.append("boolean");
288: else if (ch == 'V') //XXX: is it a working branch?
289: sb.append("void");
290: }
291: for (int i = 0; i < len; i++) {
292: sb.append("[]");
293: }
294: } else {
295: sb.append(c.getName());
296: }
297: }
298: }
299:
300: /**
301: * Appends names of the specified array classes to the buffer. The array
302: * elements may represent a simple type, a reference type or an array type.
303: * In case if the specified array element represents an array type its
304: * internal will be appended to the buffer.
305: * Output format: [Ljava.lang.Object;, java.io.File, void
306: *
307: * @param sb buffer
308: * @param objs array of classes to print the names
309: * @throws NullPointerException if any of the arguments is null
310: */
311: void appendSimpleType(StringBuilder sb, Class<?>[] objs) {
312: if (objs.length > 0) {
313: sb.append(objs[0].getName());
314: for (int i = 1; i < objs.length; i++) {
315: sb.append(',');
316: sb.append(objs[i].getName());
317: }
318: }
319: }
320:
321: /**
322: * Changes accessibility to the specified.
323: *
324: * @param flag accessible flag
325: * @throws SecurityException if this object represents a constructor of the
326: * Class
327: */
328: private void setAccessible0(boolean flag) throws SecurityException {
329: if (flag
330: && this instanceof Constructor
331: && ((Constructor<?>) this ).getDeclaringClass() == Class.class) {
332: throw new SecurityException(
333: "Can not make the java.lang.Class class constructor accessible");
334: }
335: isAccessible = flag;
336: }
337:
338: /**
339: * Ensures that actual parameters are compartible with types of
340: * formal parameters. For reference types, argument can be either
341: * null or assignment-compatible with formal type.
342: * For primitive types, argument must be non-null wrapper instance.
343: * @param types formal parameter' types
344: * @param args runtime arguments
345: * @throws IllegalArgumentException if arguments are incompartible
346: */
347: static void checkInvokationArguments(Class<?>[] types, Object[] args) {
348: if ((args == null) ? types.length != 0
349: : args.length != types.length) {
350: throw new IllegalArgumentException(
351: "Invalid number of actual parameters");
352: }
353: for (int i = types.length - 1; i >= 0; i--) {
354: if (types[i].isPrimitive()) {
355: if (args[i] instanceof Number
356: || args[i] instanceof Character
357: || args[i] instanceof Boolean) {
358: // more accurate conversion testing better done on VM side
359: continue;
360: }
361: } else if (args[i] == null || types[i].isInstance(args[i])) {
362: continue;
363: }
364: throw new IllegalArgumentException("Actual parameter: "
365: + (args[i] == null ? "<null>" : args[i].getClass()
366: .getName()) + " is incompatible with "
367: + types[i].getName());
368: }
369: }
370: }
|