* Merged executionstate branch.
[cacao.git] / src / classes / gnu / java / lang / reflect / VMConstructor.java
1 /* java.lang.reflect.VMConstructor - VM interface for reflection of Java constructors
2    Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10  
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package java.lang.reflect;
40
41 import java.lang.annotation.Annotation;
42
43 import java.util.Arrays;
44 import java.util.Map;
45
46 final class VMConstructor
47 {
48   Class clazz;
49   int slot;
50
51   /**
52    * Unparsed annotations.
53    */
54   private byte[] annotations = null;
55
56   /**
57    * Unparsed parameter annotations.
58    */
59   private byte[] parameterAnnotations = null;
60
61   /**
62    * Annotations get parsed the first time they are
63    * accessed and are then cached it this map.
64    */
65   private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations = null;
66
67   /**
68    * Helper array for creating a new array from a java.util.Container.
69    */
70   private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
71     new Annotation[0];
72
73   /** 
74    * This field allows us to refer back to the main constructor instance.
75    *  It is set by the constructor of Constructor.
76    */
77   Constructor cons;
78
79   VMConstructor(Class clazz, int slot)
80   {
81     this.clazz = clazz;
82     this.slot = slot;
83   }
84
85   public Class getDeclaringClass()
86   {
87     return clazz;
88   }
89
90   /**
91    * Return the raw modifiers for this constructor.  In particular
92    * this will include the synthetic and varargs bits.
93    * @return the constructor's modifiers
94    */
95   native int getModifiersInternal();
96
97   /**
98    * Get the parameter list for this constructor, in declaration order. If the
99    * constructor takes no parameters, returns a 0-length array (not null).
100    *
101    * @return a list of the types of the constructor's parameters
102    */
103   native Class[] getParameterTypes();
104
105   /**
106    * Get the exception types this constructor says it throws, in no particular
107    * order. If the constructor has no throws clause, returns a 0-length array
108    * (not null).
109    *
110    * @return a list of the types in the constructor's throws clause
111    */
112   native Class[] getExceptionTypes();
113
114   native Object construct(Object[] args)
115     throws InstantiationException, IllegalAccessException,
116     InvocationTargetException;
117
118   /**
119    * Return the String in the Signature attribute for this constructor. If there
120    * is no Signature attribute, return null.
121    */
122   native String getSignature();
123   
124   /**
125    * <p>
126    * Return an array of arrays representing the annotations on each
127    * of the constructor's parameters.  The outer array is aligned against
128    * the parameters of the constructors and is thus equal in length to
129    * the number of parameters (thus having a length zero if there are none).
130    * Each array element in the outer array contains an inner array which
131    * holds the annotations.  This array has a length of zero if the parameter
132    * has no annotations.
133    * </p>
134    * <p>
135    * The returned annotations are serialized.  Changing the annotations has
136    * no affect on the return value of future calls to this method.
137    * </p>
138    * 
139    * @return an array of arrays which represents the annotations used on the
140    *         parameters of this constructor.  The order of the array elements
141    *         matches the declaration order of the parameters.
142    * @since 1.5
143    */
144   native Annotation[][] getParameterAnnotations();
145
146   /**
147    * Compare two objects to see if they are semantically equivalent.
148    * Two Constructors are semantically equivalent if they have the same
149    * declaring class and the same parameter list.  This ignores different
150    * exception clauses, but since you can't create a Method except through the
151    * VM, this is just the == relation.
152    *
153    * @param o the object to compare to
154    * @return <code>true</code> if they are equal; <code>false</code> if not.
155    */
156   public boolean equals(Object o)
157   {
158     if (!(o instanceof Constructor))
159       return false;
160     Constructor that = (Constructor)o; 
161     if (clazz != that.getDeclaringClass())
162       return false;
163     if (!Arrays.equals(getParameterTypes(), that.getParameterTypes()))
164       return false;
165     return true;
166   }
167
168   /**
169    * Returns the element's annotation for the specified annotation type,
170    * or <code>null</code> if no such annotation exists.
171    *
172    * @param annotationClass the type of annotation to look for.
173    * @return this element's annotation for the specified type, or
174    *         <code>null</code> if no such annotation exists.
175    * @throws NullPointerException if the annotation class is <code>null</code>.
176    */
177 //   native Annotation getAnnotation(Class annotationClass);
178   Annotation getAnnotation(Class annotationClass) {
179     if (annotationClass == null)
180       throw new NullPointerException();
181
182     return declaredAnnotations().get(annotationClass);
183   }
184
185   /**
186    * Returns all annotations directly defined by the element.  If there are
187    * no annotations directly associated with the element, then a zero-length
188    * array will be returned.  The returned array may be modified by the client
189    * code, but this will have no effect on the annotation content of this
190    * class, and hence no effect on the return value of this method for
191    * future callers.
192    *
193    * @return the annotations directly defined by the element.
194    * @since 1.5
195    */
196 //   native Annotation[] getDeclaredAnnotations();
197   Annotation[] getDeclaredAnnotations() {
198     return declaredAnnotations().values().toArray(EMPTY_ANNOTATIONS_ARRAY);
199   }
200
201   /**
202    * Parses the annotations if they aren't parsed yet and stores them into
203    * the declaredAnnotations map and return this map.
204    */
205   private synchronized native Map<Class<? extends Annotation>, Annotation> declaredAnnotations();
206
207 }