View Javadoc

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