001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.j2mews.sg;
028:
029: import java.io.*;
030: import java.util.*;
031: import java.text.*;
032:
033: import javax.xml.namespace.QName;
034: import com.sun.xml.rpc.processor.model.Model;
035: import com.sun.xml.rpc.processor.model.AbstractType;
036: import com.sun.xml.rpc.processor.model.java.*;
037: import com.sun.xml.rpc.encoding.InternalEncodingConstants;
038: import com.sun.xml.rpc.wsdl.document.soap.SOAPConstants;
039: import com.sun.xml.rpc.processor.model.soap.*;
040: import com.sun.xml.rpc.processor.model.*;
041: import com.sun.xml.rpc.processor.model.literal.*;
042: import com.sun.xml.rpc.processor.generator.*;
043: import com.sun.xml.rpc.processor.*;
044: import com.sun.xml.rpc.processor.config.Configuration;
045: import com.sun.xml.rpc.processor.model.Service;
046: import com.sun.xml.rpc.processor.ProcessorOptions;
047: import com.sun.xml.rpc.processor.util.GeneratedFileInfo;
048: import com.sun.xml.rpc.util.localization.*;
049:
050: import org.netbeans.modules.schema2beansdev.gen.*;
051:
052: /**
053: * We'll generate the Java client proxy for JSR-172.
054: *
055: */
056: public abstract class AbstractGenerator {
057: static final public String FLOAT_DOUBLE_TO_STRING = "FLOAT_DOUBLE_TO_STRING";
058: static final public String SHOW_ALL_CLDC1_0_INFO = "SHOW_ALL_CLDC1_0_INFO";
059: static final public String EXPAND_ARGUMENTS = "EXPAND_ARGUMENTS";
060: static final public String OPTIMIZE = "OPTIMIZE";
061:
062: protected com.sun.xml.rpc.processor.util.ProcessorEnvironment env;
063: protected Service service;
064: protected Port port;
065:
066: protected JavaWriter jw;
067: protected String fullClassName;
068: protected String className;
069: protected String packageName;
070: protected File sourceDir;
071:
072: /**
073: * If you're going to call getMessage, then you need to set
074: * messageFactory.
075: */
076: protected LocalizableMessageFactory messageFactory;
077: protected Localizer localizer = new Localizer();
078:
079: /**
080: * Whether or not the formal parameters on the Stub should get expanded.
081: * It will be done for each parameter and return type, if there's
082: * only 1 of them and it's a JavaStructureType.
083: */
084: protected boolean expandArguments = false;
085:
086: /**
087: * Whether to trade readable generated code for more efficient generated
088: * code.
089: */
090: protected boolean optimize = false;
091:
092: /**
093: * Whether or not to display every info message, or just 1 (similar to
094: * javac's -deprecation flag).
095: */
096: protected boolean showCldc1_0Info = false;
097:
098: /**
099: * Sets the internal state of fullClassName, className, & packageName.
100: * @param name the full class name
101: */
102: protected void setFullClassName(String name) {
103: fullClassName = name;
104: int pos = fullClassName.lastIndexOf('.');
105: if (pos >= 0) {
106: packageName = fullClassName.substring(0, pos);
107: className = fullClassName.substring(pos + 1, fullClassName
108: .length());
109: } else {
110: packageName = null;
111: className = fullClassName;
112: }
113: }
114:
115: public void setEnvironment(
116: com.sun.xml.rpc.processor.util.ProcessorEnvironment e) {
117: env = e;
118: }
119:
120: public void perform(Model model, Configuration config,
121: Properties options) {
122: //env = config.getEnvironment();
123: sourceDir = new File(
124: options
125: .getProperty(ProcessorOptions.SOURCE_DIRECTORY_PROPERTY));
126: if ("true".equals(options.getProperty(EXPAND_ARGUMENTS)))
127: expandArguments = true;
128: else
129: expandArguments = false;
130: if ("true".equals(options.getProperty(SHOW_ALL_CLDC1_0_INFO)))
131: showCldc1_0Info = true;
132: else
133: showCldc1_0Info = false;
134: if ("true".equals(options.getProperty(OPTIMIZE)))
135: optimize = true;
136: else
137: optimize = false;
138:
139: try {
140: for (Iterator it = model.getServices(); it.hasNext();) {
141: service = (Service) it.next();
142: generate(service);
143: }
144: } catch (IOException e) {
145: throw new RuntimeException(e);
146: }
147: }
148:
149: public void generate(Service service) throws IOException {
150: for (Iterator it = service.getPorts(); it.hasNext();) {
151: port = (Port) it.next();
152: setFullClassName(getFullClassName());
153: generate();
154: }
155: }
156:
157: /**
158: * The port and env variables will be set correctly before
159: * calling this method.
160: */
161: protected abstract String getFullClassName();
162:
163: /**
164: * At this point, the service and port variables are set.
165: */
166: protected void generate() throws java.io.IOException {
167: jw = new JavaWriter();
168:
169: jw.comment("This class was generated by 172 StubGenerator.");
170: jw.comment("Contents subject to change without notice.");
171: jw.comment("@generated");
172: jw.cr();
173: jw.writePackage(packageName);
174: jw.cr();
175: writeImports();
176:
177: generateClass();
178:
179: writeOutGeneratedFile();
180: }
181:
182: protected void writeOutGeneratedFile() throws IOException {
183: File srcFile = getSourceFile();
184: log("Generating Java class for: " + srcFile.getName());
185: OutputStream out = new FileOutputStream(srcFile);
186: jw.writeTo(out);
187: out.close();
188: GeneratedFileInfo fi = new GeneratedFileInfo();
189: fi.setFile(srcFile);
190: fi.setType(getSourceFileType());
191: env.addGeneratedFile(fi);
192: }
193:
194: /**
195: * The port and env variables will be set correctly before
196: * calling this method.
197: * This is the File that gets written to.
198: */
199: protected abstract File getSourceFile();
200:
201: /**
202: * @see GeneratorConstants
203: */
204: protected abstract String getSourceFileType();
205:
206: /**
207: * Here's your chance to import anything.
208: */
209: protected void writeImports() throws IOException {
210: }
211:
212: protected abstract void generateClass() throws java.io.IOException;
213:
214: /**
215: * @return the return type taking into account expandArguments.
216: */
217: protected JavaType getExpandedReturnType(JavaMethod method) {
218: JavaType returnType = method.getReturnType();
219: if (returnType == null
220: || "void".equals(javaTypeToString(returnType)))
221: return returnType;
222: boolean isNillable = false;
223: if (expandArguments && !isNillable
224: && returnType instanceof JavaStructureType) {
225: JavaStructureType jst = (JavaStructureType) returnType;
226: if (jst.getMembersCount() == 1) {
227: returnType = ((JavaStructureMember) jst.getMembers()
228: .next()).getType();
229: }
230: }
231: return returnType;
232: }
233:
234: /**
235: * @return a List of parameters to this method in the stub, taking
236: * into account expandArguments.
237: */
238: protected List getExpandedParametersList(JavaMethod method) {
239: List parameterList = method.getParametersList();
240: if (parameterList.size() == 1 && expandArguments) {
241: JavaParameter parameter = (JavaParameter) parameterList
242: .iterator().next();
243: Parameter p = parameter.getParameter();
244: JavaType parameterType = parameter.getType();
245: Block parameterBlock = p.getBlock();
246: boolean isNillable = parameterBlock.getType().isNillable();
247: if (parameterType instanceof JavaStructureType
248: && !isNillable) {
249: JavaStructureType jst = (JavaStructureType) parameterType;
250: parameterList = new ArrayList(jst.getMembersCount());
251: for (Iterator members = jst.getMembers(); members
252: .hasNext();) {
253: JavaStructureMember jsm = (JavaStructureMember) members
254: .next();
255: String memberName = jsm.getName();
256: JavaType memberType = jsm.getType();
257: parameter = new JavaParameter(memberName,
258: memberType, p);
259: parameterList.add(parameter);
260: }
261: }
262: }
263: return parameterList;
264: }
265:
266: protected String javaTypeToString(JavaType type) {
267: if (type == null)
268: return null;
269: String result;
270: if (type.isHolder())
271: result = env.getNames().holderClassName(port, type);
272: else
273: result = env.getNames().typeClassName(type);
274: return result;
275: }
276:
277: /**
278: * Is @param type valid for MIDP?
279: * This assumes CLDC 1.1 (where float and double are okay).
280: */
281: static public boolean isValidType(String type) {
282: if (type == null) // "void" type
283: return true;
284: type = type.intern();
285: if (type == "java.math.BigDecimal"
286: || type == "java.math.BigInteger")
287: return false;
288: return true;
289: }
290:
291: /**
292: * Try to get a unique and somewhat nice looking name.
293: */
294: protected String makeVarName(QName name, String prefix,
295: Map usedNames) {
296: String result = prefix + name.getLocalPart();
297: result = result.replace('.', '_');
298: result = result.replace('/', '_');
299: result = result.replace(':', '_');
300: if (usedNames != null && usedNames.containsKey(result)) {
301: String abbrevNamespace = name.getNamespaceURI();
302: if (abbrevNamespace != null) {
303: int pos = abbrevNamespace.lastIndexOf('/');
304: if (pos >= 0)
305: abbrevNamespace = abbrevNamespace.substring(
306: pos + 1, abbrevNamespace.length());
307: abbrevNamespace = abbrevNamespace.replace('.', '_');
308: abbrevNamespace = abbrevNamespace.replace(':', '_');
309: abbrevNamespace = abbrevNamespace.replace('/', '_');
310: abbrevNamespace = abbrevNamespace.replace('%', '_');
311: result = prefix + abbrevNamespace + "_"
312: + name.getLocalPart();
313: }
314: result = makeUniq(result, usedNames);
315: }
316: return result;
317: }
318:
319: protected String instanceOf(JavaType type, String suffix,
320: Map usedNames) {
321: String name = type.getName();
322: return instanceOf(name, suffix, usedNames);
323: }
324:
325: protected String instanceOf(JavaType type, Map usedNames) {
326: return instanceOf(type, null, usedNames);
327: }
328:
329: protected String instanceOf(QName name, String suffix, Map usedNames) {
330: return instanceOf(name.getLocalPart(), suffix, usedNames);
331: }
332:
333: /**
334: * Make a variable name valid and unique.
335: */
336: protected String instanceOf(String name, String suffix,
337: Map usedNames) {
338: int pos;
339: // Remove everything before the .
340: pos = name.lastIndexOf('.');
341: if (pos > 0)
342: name = name.substring(pos + 1, name.length());
343:
344: // Get rid of any trailing []
345: int arrayDimensions = 0;
346: while (name.endsWith("[]")) {
347: name = name.substring(0, name.length() - 2);
348: ++arrayDimensions;
349: }
350: for (int i = 0; i < arrayDimensions; ++i)
351: name += "Array";
352:
353: if (JavaUtil.isPrimitiveType(name))
354: name = "a_" + name;
355:
356: if (suffix != null)
357: name += suffix;
358:
359: /*
360: // make first char lowercase
361: name = java.beans.Introspector.decapitalize(name);
362: */
363: name = env.getNames().validJavaMemberName(name);
364:
365: return makeUniq(name, usedNames);
366: }
367:
368: /**
369: * Make a variable name unique.
370: * Puts the name into usedNames.
371: */
372: protected String makeUniq(String name, Map usedNames) {
373: if (usedNames.containsKey(name)
374: || env.getNames().isJavaReservedWord(name)) {
375: String baseName = name;
376:
377: for (int count = optimize ? 0 : 2; usedNames
378: .containsKey(name); ++count)
379: name = baseName
380: + (optimize ? Integer.toString(count,
381: Character.MAX_RADIX) : "" + count);
382: }
383: usedNames.put(name, null);
384: return name;
385: }
386:
387: /**
388: * This will return a name from @param fullName where everything upto
389: * and including the last '.' is removed.
390: * eg: "java.lang.String[]" -> "String[]"
391: * "java.util.ArrayList" -> "ArrayList"
392: */
393: protected static String baseName(String fullName) {
394: int pos = fullName.lastIndexOf('.');
395: if (pos == -1)
396: return fullName;
397: return fullName.substring(pos + 1, fullName.length());
398: }
399:
400: protected void onWarning(Localizable msg) {
401: //System.err.println("Warning: "+msg);
402: env.warn(msg);
403: }
404:
405: protected void onInfo(Localizable msg) {
406: //System.err.println("Info: "+msg);
407: env.info(msg);
408: }
409:
410: protected void onError(Localizable msg) {
411: //System.err.println("Error: "+msg);
412: env.error(msg);
413: }
414:
415: protected Localizable getMessage(String key) {
416: return messageFactory.getMessage(key);
417: }
418:
419: protected Localizable getMessage(String key, String arg) {
420: return messageFactory.getMessage(key, new Object[] { arg });
421: }
422:
423: protected Localizable getMessage(String key, String arg1,
424: String arg2) {
425: return messageFactory.getMessage(key,
426: new Object[] { arg1, arg2 });
427: }
428:
429: protected Localizable getMessage(String key, String arg1,
430: String arg2, String arg3) {
431: return messageFactory.getMessage(key, new Object[] { arg1,
432: arg2, arg3 });
433: }
434:
435: protected Localizable getMessage(String key, Localizable l) {
436: return messageFactory.getMessage(key, new Object[] { l });
437: }
438:
439: protected Localizable getMessage(String key, Object[] args) {
440: return messageFactory.getMessage(key, args);
441: }
442:
443: protected String localize(Localizable msg) {
444: return localizer.localize(msg);
445: }
446:
447: public void setLocalizer(Localizer l) {
448: localizer = l;
449: }
450:
451: protected void log(String msg) {
452: if (env.verbose()) {
453: System.out.println("["
454: + env.getNames().stripQualifier(
455: this .getClass().getName()) + ": " + msg
456: + "]");
457: }
458: }
459: }
|