1 | /* |
2 | |
3 | Derby - Class org.apache.derby.impl.services.bytecode.GClass |
4 | |
5 | Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.impl.services.bytecode; |
22 | |
23 | import org.apache.derby.iapi.services.compiler.ClassBuilder; |
24 | import org.apache.derby.iapi.services.loader.ClassFactory; |
25 | import org.apache.derby.iapi.services.loader.GeneratedClass; |
26 | import org.apache.derby.iapi.error.StandardException; |
27 | import org.apache.derby.iapi.services.sanity.SanityManager; |
28 | import org.apache.derby.iapi.services.stream.HeaderPrintWriter; |
29 | import org.apache.derby.iapi.services.monitor.Monitor; |
30 | |
31 | import org.apache.derby.iapi.util.ByteArray; |
32 | |
33 | import java.io.File; |
34 | import java.io.FileOutputStream; |
35 | import java.io.IOException; |
36 | |
37 | /** |
38 | * This is a common superclass for the various impls. |
39 | * Saving class files is a common thing to do. |
40 | * |
41 | * @author ames |
42 | */ |
43 | public abstract class GClass implements ClassBuilder { |
44 | |
45 | protected ByteArray bytecode; |
46 | protected final ClassFactory cf; |
47 | protected final String qualifiedName; |
48 | |
49 | |
50 | |
51 | public GClass(ClassFactory cf, String qualifiedName) { |
52 | this.cf = cf; |
53 | this.qualifiedName = qualifiedName; |
54 | } |
55 | public String getFullName() { |
56 | return qualifiedName; |
57 | } |
58 | public GeneratedClass getGeneratedClass() throws StandardException { |
59 | return cf.loadGeneratedClass(qualifiedName, getClassBytecode()); |
60 | } |
61 | |
62 | protected void writeClassFile(String dir, boolean logMessage, Throwable t) |
63 | throws StandardException { |
64 | |
65 | if (SanityManager.DEBUG) { |
66 | |
67 | if (bytecode == null) getClassBytecode(); // not recursing... |
68 | |
69 | if (dir == null) dir=""; |
70 | |
71 | String filename = getName(); // leave off package |
72 | |
73 | filename = filename + ".class"; |
74 | |
75 | File classFile = new File(dir,filename); |
76 | |
77 | // find the error stream |
78 | HeaderPrintWriter errorStream = Monitor.getStream(); |
79 | |
80 | try { |
81 | FileOutputStream fis = new FileOutputStream(classFile); |
82 | fis.write(bytecode.getArray(), |
83 | bytecode.getOffset(), bytecode.getLength()); |
84 | fis.flush(); |
85 | if (logMessage) { |
86 | errorStream.printlnWithHeader("Wrote class "+getFullName()+" to file "+classFile.toString()+". Please provide support with the file and the following exception message: "+t); |
87 | } |
88 | fis.close(); |
89 | } catch (IOException e) { |
90 | if (SanityManager.DEBUG) |
91 | SanityManager.THROWASSERT("Unable to write .class file"); |
92 | } |
93 | } |
94 | } |
95 | |
96 | public final void validateType(String typeName1) |
97 | { |
98 | if (SanityManager.DEBUG) |
99 | { |
100 | SanityManager.ASSERT(typeName1 != null); |
101 | |
102 | String typeName = typeName1.trim(); |
103 | |
104 | // first remove all array-ness |
105 | while (typeName.endsWith("[]")) typeName = typeName.substring(0,typeName.length()-2); |
106 | |
107 | SanityManager.ASSERT(typeName.length() > 0); |
108 | |
109 | // then check for primitive types |
110 | if ("boolean".equals(typeName)) return; |
111 | if ("byte".equals(typeName)) return; |
112 | if ("char".equals(typeName)) return; |
113 | if ("double".equals(typeName)) return; |
114 | if ("float".equals(typeName)) return; |
115 | if ("int".equals(typeName)) return; |
116 | if ("long".equals(typeName)) return; |
117 | if ("short".equals(typeName)) return; |
118 | if ("void".equals(typeName)) return; |
119 | |
120 | // then see if it can be found |
121 | // REVISIT: this will fail if ASSERT is on and the |
122 | // implementation at hand is missing the target type. |
123 | // We do plan to generate classes against |
124 | // different implementations from the compiler's implementation |
125 | // at some point... |
126 | try { |
127 | if (cf == null) |
128 | Class.forName(typeName); |
129 | else |
130 | cf.loadApplicationClass(typeName); |
131 | } catch (ClassNotFoundException cnfe) { |
132 | SanityManager.THROWASSERT("Class "+typeName+" not found"); |
133 | } |
134 | |
135 | // all the checks succeeded, it must be okay. |
136 | return; |
137 | } |
138 | } |
139 | } |