View Javadoc

1   /*
2    * Copyright 2005 The Apache Software Foundation.
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  
17  package org.apache.jdo.impl.enhancer.meta.model;
18  
19  import java.io.InputStream;
20  
21  import org.apache.jdo.impl.enhancer.util.ResourceLocator;
22  import org.apache.jdo.impl.model.java.reflection.ReflectionJavaModel;
23  import org.apache.jdo.model.java.JavaType;
24  import org.apache.jdo.model.jdo.JDOModel;
25  
26  /***
27   * Provides some basic Java type information based on JVM descriptors.
28   * 
29   * @author Michael Bouschen
30   * @author Martin Zaun
31   */
32  public class EnhancerJavaModel
33      extends ReflectionJavaModel
34  {
35      /***
36       * The "package" jdo file.
37       */
38      final private ResourceLocator locator;
39  
40      /***
41       * Creates an instance.
42       */
43      public EnhancerJavaModel(ClassLoader classLoader,
44                               ResourceLocator locator)
45      {
46          super(classLoader, null);
47          this.locator = locator;
48      }
49      
50      /***
51       * Finds a resource with a given name.  This method returns
52       * <code>null</code> if no resource with this name is found.
53       * The name of a resource is a "/"-separated path name.
54       */
55      public InputStream getInputStreamForResource(String resourceName)
56      {
57          // first try the locator
58          InputStream stream = locator.getInputStreamForResource(resourceName);
59          if (stream == null)
60              // if the locator cannot find the resource try the class loader
61              stream = super.getInputStreamForResource(resourceName);
62          return stream;
63      }
64  
65      // ===== Methods not defined in JavaModel =====
66  
67      /*** 
68       * Creates a new JavaType instance for the specified Class object.
69       * <p>
70       * This implementation returns a EnhancerJavaType instance.
71       * @param clazz the Class instance representing the type
72       * @return a new JavaType instance
73       */
74      protected JavaType newJavaTypeInstance(Class clazz)
75      {
76          return new EnhancerJavaType(clazz, this);
77      }
78  
79      /*** 
80       * Returns the fully qualified name of the specified type representation.
81       */
82      public String getTypeName(String sig)
83      {
84          // translates a VM type field signature into Java-format signature
85          final int n = sig.length();
86          affirm(n > 0, "invalid field signature: \"\"");
87  
88          // handle arrays
89          if (sig.startsWith("["))
90              return sig.replace('/','.');
91  
92          // parse rest of signature
93          final String name;
94          final char c = sig.charAt(0);
95          switch (c) {
96          case 'Z':
97              name = "boolean";
98              break;
99          case 'C':
100             name = "char";
101             break;
102         case 'B':
103             name = "byte";
104             break;
105         case 'S':
106             name = "short";
107             break;
108         case 'I':
109             name = "int";
110             break;
111         case 'F':
112             name = "float";
113             break;
114         case 'J':
115             name = "long";
116             break;
117         case 'D':
118             name = "double";
119             break;
120         case 'L':
121             // return reference type with array dimensions
122             affirm(sig.indexOf(';') == n - 1,
123                    "invalid field signature: " + sig);
124             name = sig.substring(1, n - 1);
125             affirm(isValidName(name, '/'),
126                    "invalid field signature: " + sig);
127             return name.replace('/','.');
128         default:
129             name = "";
130             affirm(false, "invalid field signature: " + sig);
131         }
132         return name;
133     }
134 
135     static private boolean isValidName(String name, char separator) 
136     {
137         final int n = name.length();
138         if (n == 0) {
139             return false;
140         }
141         if (!Character.isJavaIdentifierStart(name.charAt(0))) {
142             return false;
143         }
144         for (int i = 1; i < n; i++) {
145             final char c = name.charAt(i);
146             if (!Character.isJavaIdentifierPart(c) && c != separator) {
147                 return false;
148             }
149         }
150         return true;
151     }
152 
153     static protected final void affirm(boolean condition, String msg) {
154         if (!condition)
155             throw new InternalError("assertion failed: " + msg);
156     }
157 
158 }