001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: *
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: /**
020: * @author Vasily Zakharov
021: * @version $Revision: 1.1.2.1 $
022: */package org.apache.harmony.rmi.compiler;
023:
024: import java.io.File;
025:
026: import org.apache.harmony.rmi.common.RMIUtil;
027: import org.apache.harmony.rmi.internal.nls.Messages;
028:
029: /**
030: * Utility functions for RMI compiler.
031: *
032: * This class cannot be instantiated.
033: *
034: * @author Vasily Zakharov
035: * @version $Revision: 1.1.2.1 $
036: */
037: final class RmicUtil implements RmicConstants {
038:
039: /**
040: * This class cannot be instantiated.
041: */
042: private RmicUtil() {
043: }
044:
045: /**
046: * Returns suitable name for a parameter based on its class name and number.
047: *
048: * @param cls
049: * Parameter class.
050: *
051: * @param number
052: * Parameter number.
053: *
054: * @return Suitable name for a parameter.
055: */
056: static String getParameterName(Class cls, int number) {
057: StringBuffer buffer = new StringBuffer(paramPrefix);
058:
059: while (cls.isArray()) {
060: buffer.append(arrayPrefix);
061: cls = cls.getComponentType();
062: }
063:
064: buffer.append(RMIUtil.getShortName(cls) + '_' + number);
065:
066: return buffer.toString();
067: }
068:
069: /**
070: * Creates source code fragment for method parameter,
071: * wrapping primitive types into respective Object types.
072: *
073: * @param cls
074: * Parameter class.
075: *
076: * @param varName
077: * Parameter variable name.
078: *
079: * @return Source code fragment for method parameter,
080: * for Object types it's just <code>varName</code>,
081: * for primitive types (e. g. <code>int</code>)
082: * it's a string like this:
083: * <code>"new java.lang.Integer(varName)"</code>.
084: */
085: static String getObjectParameterString(Class cls, String varName) {
086: return (cls.isPrimitive() ? ("new " + RMIUtil.getWrappingClass(cls).getName() //$NON-NLS-1$
087: + '(' + varName + ')')
088: : varName);
089: }
090:
091: /**
092: * Returns string with capitalized first letter.
093: *
094: * @param str
095: * String.
096: *
097: * @return String with capitalized first letter,
098: * or string itself if the string is empty.
099: */
100: static String firstLetterToUpperCase(String str) {
101: int length = str.length();
102:
103: if (length < 1) {
104: return str;
105: }
106:
107: char[] array = new char[length];
108: str.getChars(0, length, array, 0);
109: array[0] = Character.toUpperCase(array[0]);
110: return String.copyValueOf(array);
111: }
112:
113: /**
114: * Returns name of the class with capitalized first letter
115: * for primitive classes and <code>Object</code> for non-primitive classes.
116: *
117: * @param cls
118: * Class.
119: *
120: * @return Returns name of the class with capitalized first letter
121: * for primitive classes and <code>Object</code> for non-primitive
122: * classes.
123: */
124: static String getHandlingType(Class cls) {
125: return (cls.isPrimitive() ? firstLetterToUpperCase(cls
126: .getName()) : "Object"); //$NON-NLS-1$
127: }
128:
129: /**
130: * Creates source code fragment for reading object from a stream,
131: * correctly handling primitive types.
132: *
133: * @param cls
134: * Class of object being read.
135: *
136: * @param streamName
137: * Name of stream to read variable from.
138: *
139: * @return Source code fragment for reading object,
140: * for Object class it's like
141: * <code>"streamName.readObject()"</code>,
142: * for other Object types (e. g. <code>Vector</code>)
143: * it's a string like this:
144: * <code>"(java.util.Vector) streamName.readObject()"</code>,
145: * for primitive types (e. g. <code>int</code>)
146: * it's a string like this:
147: * <code>"streamName.readInt()"</code>.
148: */
149: static String getReadObjectString(Class cls, String streamName) {
150: // For primitive types, use respective special read method.
151: // For non-primitive types, use readObject() and cast (if not Object).
152: return (((!cls.isPrimitive() && (cls != Object.class)) ? ('(' + RMIUtil
153: .getCanonicalName(cls) + ") ") : "") //$NON-NLS-1$ //$NON-NLS-2$
154: + streamName + ".read" + getHandlingType(cls) + "()"); //$NON-NLS-1$ //$NON-NLS-2$
155: }
156:
157: /**
158: * Creates source code fragment for writing object to a stream,
159: * correctly handling primitive types.
160: *
161: * @param cls
162: * Class of object to write.
163: *
164: * @param varName
165: * Name of the variable to write.
166: *
167: * @param streamName
168: * Name of stream to write variable to.
169: *
170: * @return Source code fragment for writing object,
171: * for object types it's like
172: * <code>"streamName.writeObject(varName)"</code>,
173: * for primitive types (e. g. <code>int</code>)
174: * it's a string like this:
175: * <code>"streamName.writeInt(varName)"</code>.
176: */
177: static String getWriteObjectString(Class cls, String varName,
178: String streamName) {
179: // For primitive types, use respective special write method.
180: // For non-primitive types, use writeObject().
181: return (streamName + ".write" + getHandlingType(cls) //$NON-NLS-1$
182: + '(' + varName + ')');
183: }
184:
185: /**
186: * Creates source code fragment for return object,
187: * correctly de-wrapping primitive types.
188: *
189: * @param cls
190: * Return class.
191: *
192: * @param varName
193: * Return variable name.
194: *
195: * @return Source code fragment for return object,
196: * for {@link Object} class it's just <code>varName</code>,
197: * for other Object types (e. g. <code>Vector</code>)
198: * it's a string like this:
199: * <code>"((java.util.Vector) varName)"</code>,
200: * for primitive types (e. g. <code>int</code>)
201: * it's a string like this:
202: * <code>"((java.lang.Integer) varName).intValue()"</code>.
203: */
204: static String getReturnObjectString(Class cls, String varName) {
205: // For Object return type, do nothing.
206: if (cls == Object.class) {
207: return varName;
208: }
209:
210: // For all other types, create the respective cast statement.
211: StringBuffer buffer = new StringBuffer("(("); //$NON-NLS-1$
212: buffer.append(RMIUtil.getCanonicalName(RMIUtil
213: .getWrappingClass(cls)));
214: buffer.append(") " + varName + ')'); //$NON-NLS-1$
215:
216: // For primitive types, include case to primitive type.
217: if (cls.isPrimitive()) {
218: buffer.append('.' + cls.getName() + "Value()"); //$NON-NLS-1$
219: }
220:
221: return buffer.toString();
222: }
223:
224: /**
225: * Creates a file object for a directory created basing on the specified
226: * base directory and the package name for subdirectory.
227: *
228: * @param base
229: * Base directory.
230: *
231: * @param packageName
232: * Package name (for subdirectory).
233: *
234: * @return File object for a directory like this:
235: * <code>baseDir/my/java/package</code>.
236: *
237: * @throws RMICompilerException
238: * If directory cannot be created.
239: */
240: static File getPackageDir(String base, String packageName)
241: throws RMICompilerException {
242: File dir = new File(base, (packageName != null) ? packageName
243: : ""); //$NON-NLS-1$
244:
245: if (dir.exists() ? !dir.isDirectory() : !dir.mkdirs()) {
246: // rmi.4E=Can't create target directory: {0}
247: throw new RMICompilerException(Messages.getString(
248: "rmi.4E", dir)); //$NON-NLS-1$
249: }
250:
251: return dir;
252: }
253:
254: /**
255: * Creates a file object for a file created basing on the specified
256: * directory and the name of file itself.
257: *
258: * @param dir
259: * Directory to create the file in.
260: *
261: * @param fileName
262: * Name of file itself.
263: *
264: * @return File object for a file name like this:
265: * <code>dir/fileName</code>.
266: *
267: * @throws RMICompilerException
268: * If file cannot be created.
269: */
270: static File getPackageFile(File dir, String fileName)
271: throws RMICompilerException {
272: File file = new File(dir, fileName);
273:
274: if (file.exists() ? !(file.isFile() && file.canWrite()) : !dir
275: .canWrite()) {
276: // rmi.4F=Can't create file: {0}
277: throw new RMICompilerException(Messages.getString(
278: "rmi.4F", file)); //$NON-NLS-1$
279: }
280:
281: return file;
282: }
283: }
|