001: /*
002:
003: Derby - Class org.apache.derby.impl.services.bytecode.GClass
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.services.bytecode;
023:
024: import org.apache.derby.iapi.services.compiler.ClassBuilder;
025: import org.apache.derby.iapi.services.loader.ClassFactory;
026: import org.apache.derby.iapi.services.loader.GeneratedClass;
027: import org.apache.derby.iapi.error.StandardException;
028: import org.apache.derby.iapi.services.sanity.SanityManager;
029: import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
030: import org.apache.derby.iapi.services.monitor.Monitor;
031:
032: import org.apache.derby.iapi.util.ByteArray;
033:
034: import java.io.File;
035: import java.io.FileOutputStream;
036: import java.io.IOException;
037:
038: /**
039: * This is a common superclass for the various impls.
040: * Saving class files is a common thing to do.
041: *
042: * @author ames
043: */
044: public abstract class GClass implements ClassBuilder {
045:
046: protected ByteArray bytecode;
047: protected final ClassFactory cf;
048: protected final String qualifiedName;
049:
050: public GClass(ClassFactory cf, String qualifiedName) {
051: this .cf = cf;
052: this .qualifiedName = qualifiedName;
053: }
054:
055: public String getFullName() {
056: return qualifiedName;
057: }
058:
059: public GeneratedClass getGeneratedClass() throws StandardException {
060: return cf.loadGeneratedClass(qualifiedName, getClassBytecode());
061: }
062:
063: protected void writeClassFile(String dir, boolean logMessage,
064: Throwable t) throws StandardException {
065:
066: if (SanityManager.DEBUG) {
067:
068: if (bytecode == null)
069: getClassBytecode(); // not recursing...
070:
071: if (dir == null)
072: dir = "";
073:
074: String filename = getName(); // leave off package
075:
076: filename = filename + ".class";
077:
078: File classFile = new File(dir, filename);
079:
080: // find the error stream
081: HeaderPrintWriter errorStream = Monitor.getStream();
082:
083: try {
084: FileOutputStream fis = new FileOutputStream(classFile);
085: fis.write(bytecode.getArray(), bytecode.getOffset(),
086: bytecode.getLength());
087: fis.flush();
088: if (logMessage) {
089: errorStream
090: .printlnWithHeader("Wrote class "
091: + getFullName()
092: + " to file "
093: + classFile.toString()
094: + ". Please provide support with the file and the following exception message: "
095: + t);
096: }
097: fis.close();
098: } catch (IOException e) {
099: if (SanityManager.DEBUG)
100: SanityManager
101: .THROWASSERT("Unable to write .class file");
102: }
103: }
104: }
105:
106: final void validateType(String typeName1) {
107: if (SanityManager.DEBUG) {
108: SanityManager.ASSERT(typeName1 != null);
109:
110: String typeName = typeName1.trim();
111:
112: if ("void".equals(typeName))
113: return;
114:
115: // first remove all array-ness
116: while (typeName.endsWith("[]"))
117: typeName = typeName.substring(0, typeName.length() - 2);
118:
119: SanityManager.ASSERT(typeName.length() > 0);
120:
121: // then check for primitive types
122: if ("boolean".equals(typeName))
123: return;
124: if ("byte".equals(typeName))
125: return;
126: if ("char".equals(typeName))
127: return;
128: if ("double".equals(typeName))
129: return;
130: if ("float".equals(typeName))
131: return;
132: if ("int".equals(typeName))
133: return;
134: if ("long".equals(typeName))
135: return;
136: if ("short".equals(typeName))
137: return;
138:
139: // then see if it can be found
140: // REVISIT: this will fail if ASSERT is on and the
141: // implementation at hand is missing the target type.
142: // We do plan to generate classes against
143: // different implementations from the compiler's implementation
144: // at some point...
145: try {
146: if (cf == null)
147: Class.forName(typeName);
148: else
149: cf.loadApplicationClass(typeName);
150: } catch (ClassNotFoundException cnfe) {
151: SanityManager.THROWASSERT("Class " + typeName
152: + " not found");
153: }
154:
155: // all the checks succeeded, it must be okay.
156: return;
157: }
158: }
159: }
|