001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.websvc.jaxrpc.dev.wizard;
043:
044: import java.io.BufferedInputStream;
045: import java.io.BufferedOutputStream;
046: import java.io.ByteArrayInputStream;
047: import java.io.ByteArrayOutputStream;
048: import java.io.IOException;
049: import java.io.InputStream;
050: import java.io.OutputStream;
051: import java.io.OutputStreamWriter;
052: import java.io.StringReader;
053: import java.io.StringWriter;
054: import java.io.Writer;
055: import java.text.DateFormat;
056: import java.util.*;
057: import javax.swing.text.BadLocationException;
058: import javax.swing.text.Document;
059: import javax.xml.parsers.ParserConfigurationException;
060: import javax.xml.parsers.SAXParser;
061: import javax.xml.parsers.SAXParserFactory;
062: import javax.xml.transform.Source;
063: import javax.xml.transform.Templates;
064: import javax.xml.transform.Transformer;
065: import javax.xml.transform.TransformerConfigurationException;
066: import javax.xml.transform.TransformerException;
067: import javax.xml.transform.TransformerFactory;
068: import javax.xml.transform.URIResolver;
069: import javax.xml.transform.stream.StreamResult;
070: import javax.xml.transform.stream.StreamSource;
071: import org.netbeans.api.java.project.JavaProjectConstants;
072: import org.netbeans.api.project.Project;
073: import org.netbeans.api.project.ProjectUtils;
074: import org.netbeans.api.project.SourceGroup;
075: import org.netbeans.api.project.Sources;
076: import org.netbeans.modules.websvc.jaxrpc.dev.dd.gen.wscreation.Bean;
077: import org.openide.ErrorManager;
078: import org.openide.cookies.EditorCookie;
079: import org.openide.filesystems.FileLock;
080: import org.openide.filesystems.FileObject;
081: import org.openide.filesystems.FileUtil;
082: import org.openide.loaders.DataObject;
083: import org.openide.text.IndentEngine;
084: import org.openide.util.RequestProcessor;
085: import org.xml.sax.Attributes;
086: import org.xml.sax.InputSource;
087: import org.xml.sax.SAXException;
088: import org.xml.sax.helpers.DefaultHandler;
089:
090: public class WSGenerationUtil {
091: public static final String TEMPLATE_BASE = "/org/netbeans/modules/websvc/jaxrpc/dev/wizard/xsl/"; //NOI18N
092: private String genDate;
093: private String genAuthor;
094: private Map templateCache = new HashMap();
095:
096: public static String getSelectedPackageName(
097: FileObject targetFolder, Project p) {
098: Sources sources = ProjectUtils.getSources(p);
099: SourceGroup[] groups = sources
100: .getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
101: String packageName = null;
102: for (int i = 0; i < groups.length && packageName == null; i++) {
103: packageName = FileUtil.getRelativePath(groups[i]
104: .getRootFolder(), targetFolder);
105: }
106: if (packageName != null) {
107: packageName = packageName.replaceAll("/", ".");
108: }
109: return packageName + "";
110: }
111:
112: public String getBeanClassName(String wsName) {
113: //TO-DO: We should get this from the module
114: //Naming convention for web module is: servicename + Impl
115: //Naming convention for ejb module is: servicename + Bean
116: return wsName + "Impl"; //NOI18N
117: }
118:
119: public String getSEIName(String wsName) {
120: return wsName + "SEI"; //NOI18N
121: }
122:
123: public Bean getDefaultBean() {
124: Bean b = new Bean();
125: b.setCommentData(true);
126: if (genDate == null) {
127: genDate = DateFormat.getDateTimeInstance().format(
128: new Date());
129: genAuthor = System.getProperty("user.name");
130: }
131: b.setCommentDataAuthor(genAuthor); //NOI18N
132: b.setCommentDataDate(genDate);
133: return b;
134: }
135:
136: public String getFullClassName(String pkg, String className) {
137: return (pkg == null || pkg.length() == 0) ? className : pkg
138: + "." + className; //NOI18N
139: }
140:
141: public String generateClass(String template, Bean genData,
142: FileObject pkg, boolean open) throws IOException {
143: String clsName = genData.getClassnameName();
144: clsName = FileUtil.findFreeFileName(pkg, clsName, "java"); //NOI18N
145: genData.setClassnameName(clsName);
146: generateClass(template, pkg, clsName, getStreamSource(genData),
147: open);
148: return clsName;
149: }
150:
151: public String generateClass(String template, FileObject pkg,
152: String clsName, String inputXml, boolean open)
153: throws IOException {
154: clsName = FileUtil.findFreeFileName(pkg, clsName, "java"); //NOI18N
155: generateClass(template, pkg, clsName,
156: getStreamSource(inputXml), open);
157: return clsName;
158: }
159:
160: public FileObject generateWSDL(String template, String wsName,
161: String soapBinding, String portTypeName, FileObject folder,
162: String wsdlName, StreamSource source) throws IOException {
163: return generateWSDL(template, wsName, soapBinding,
164: portTypeName, folder, null, wsdlName, source);
165: }
166:
167: public FileObject generateWSDL(String template, String wsName,
168: String soapBinding, String portTypeName, FileObject folder,
169: FileObject originalFolder, String wsdlName,
170: StreamSource source) throws IOException {
171: FileObject wsdlFile = folder.createData(FileUtil
172: .findFreeFileName(folder, wsdlName, "wsdl"), "wsdl"); //NOI18N
173: FileLock fl = null;
174: OutputStream os = null;
175: try {
176: fl = wsdlFile.lock();
177: os = new BufferedOutputStream(wsdlFile.getOutputStream(fl));
178: Transformer transformer = getTransformer(template);
179: transformer.setParameter("WSNAME", wsName);
180: transformer.setParameter("SOAPBINDING", soapBinding);
181: if (portTypeName != null) {
182: transformer.setParameter("PORTTYPENAME", portTypeName);
183: } else {
184: return wsdlFile;
185: }
186: transformer.transform(source, new StreamResult(os));
187: os.close();
188: } catch (TransformerConfigurationException tce) {
189: IOException ioe = new IOException();
190: ioe.initCause(tce);
191: throw ioe;
192: } catch (TransformerException te) {
193: IOException ioe = new IOException();
194: ioe.initCause(te);
195: throw ioe;
196: } finally {
197: if (os != null) {
198: os.close();
199: }
200: if (fl != null) {
201: fl.releaseLock();
202: }
203: }
204: // Also copy the importing wsdl/schema files
205: copyImportedSchemas(originalFolder, folder, wsdlFile);
206: return wsdlFile;
207: }
208:
209: public void generateClass(String template, FileObject pkg,
210: String clsName, StreamSource source, boolean open)
211: throws IOException {
212: FileObject cFile = pkg.createData(clsName, "java"); //NOI18N
213: FileLock fl = null;
214: OutputStream os = null;
215: Writer w = null;
216: try {
217: fl = cFile.lock();
218: os = new BufferedOutputStream(cFile.getOutputStream(fl));
219: getTransformer(template)
220: .transform(
221: source,
222: new StreamResult(new OutputStreamWriter(os,
223: "UTF8")));
224: os.close();
225: fl.releaseLock();
226: DataObject dobj = DataObject.find(cFile);
227: final EditorCookie ec = (EditorCookie) dobj
228: .getCookie(EditorCookie.class);
229: Document d = ec.openDocument();
230: try {
231: String fullText = d.getText(0, d.getLength());
232: IndentEngine javaIndent = IndentEngine.find(d);
233: StringWriter writer = new StringWriter(d.getLength());
234: w = javaIndent.createWriter(d, 0, writer);
235: w.write(fullText);
236: w.close();
237: d.remove(0, d.getLength());
238: d.insertString(0, writer.getBuffer().toString(), null);
239: ec.saveDocument();
240: } catch (BadLocationException ble) {
241: ErrorManager.getDefault().notify(ble);
242: }
243: if (open) {
244: RequestProcessor.getDefault().post(new Runnable() {
245: public void run() {
246: ec.open();
247: }
248: }, 1000);
249: }
250: } catch (TransformerConfigurationException tce) {
251: IOException ioe = new IOException();
252: ioe.initCause(tce);
253: throw ioe;
254: } catch (TransformerException te) {
255: IOException ioe = new IOException();
256: ioe.initCause(te);
257: throw ioe;
258: } finally {
259: if (os != null) {
260: os.close();
261: }
262: if (w != null) {
263: w.close();
264: }
265: if (fl != null) {
266: fl.releaseLock();
267: }
268: }
269: }
270:
271: public String getBaseName(String fullClassName) {
272: return fullClassName
273: .substring(fullClassName.lastIndexOf('.') + 1); //NOI18N
274: }
275:
276: private Transformer getTransformer(String template)
277: throws TransformerConfigurationException {
278: Templates t = (Templates) templateCache.get(template);
279: if (t != null) {
280: return t.newTransformer();
281: }
282: InputStream is = new BufferedInputStream(getClass()
283: .getResourceAsStream(template));
284: TransformerFactory transFactory = TransformerFactory
285: .newInstance();
286: transFactory.setURIResolver(new URIResolver() {
287: public Source resolve(String href, String base)
288: throws TransformerException {
289: InputStream is = getClass().getResourceAsStream(
290: TEMPLATE_BASE
291: + href
292: .substring(href
293: .lastIndexOf('/') + 1));
294: if (is == null) {
295: return null;
296: }
297:
298: return new StreamSource(is);
299: }
300: });
301: t = transFactory.newTemplates(new StreamSource(is));
302: templateCache.put(template, t);
303: return t.newTransformer();
304: }
305:
306: private StreamSource getStreamSource(Bean genData)
307: throws IOException {
308: ByteArrayOutputStream bos = new ByteArrayOutputStream();
309: try {
310: genData.write(bos);
311: } finally {
312: bos.close();
313: }
314: return new StreamSource(new ByteArrayInputStream(bos
315: .toByteArray()));
316: }
317:
318: private StreamSource getStreamSource(String xml) throws IOException {
319: StringReader sr = new StringReader(xml);
320: return new StreamSource(sr);
321: }
322:
323: /** Static method to identify wsdl/schema files to import
324: */
325: static List /*String*/getSchemaNames(FileObject fo,
326: boolean fromWsdl) {
327: List result = null;
328: try {
329: SAXParserFactory factory = SAXParserFactory.newInstance();
330: factory.setNamespaceAware(true);
331: SAXParser saxParser = factory.newSAXParser();
332: ImportsHandler handler = (fromWsdl ? (ImportsHandler) new WsdlImportsHandler()
333: : (ImportsHandler) new SchemaImportsHandler());
334: saxParser.parse(new InputSource(fo.getInputStream()),
335: (DefaultHandler) handler);
336: result = handler.getSchemaNames();
337: } catch (ParserConfigurationException ex) {
338: // Bogus WSDL, return null.
339: } catch (SAXException ex) {
340: // Bogus WSDL, return null.
341: } catch (IOException ex) {
342: // Bogus WSDL, return null.
343: }
344:
345: return result;
346: }
347:
348: private static interface ImportsHandler {
349: public List getSchemaNames();
350: }
351:
352: private static class WsdlImportsHandler extends DefaultHandler
353: implements ImportsHandler {
354:
355: private static final String W3C_WSDL_SCHEMA = "http://schemas.xmlsoap.org/wsdl"; // NOI18N
356: private static final String W3C_WSDL_SCHEMA_SLASH = "http://schemas.xmlsoap.org/wsdl/"; // NOI18N
357:
358: private List schemaNames;
359:
360: private boolean insideSchema;
361:
362: WsdlImportsHandler() {
363: schemaNames = new ArrayList();
364: }
365:
366: public void startElement(String uri, String localname,
367: String qname, Attributes attributes)
368: throws SAXException {
369: if (W3C_WSDL_SCHEMA.equals(uri)
370: || W3C_WSDL_SCHEMA_SLASH.equals(uri)) {
371: if ("types".equals(localname)) { // NOI18N
372: insideSchema = true;
373: }
374: if ("import".equals(localname)) { // NOI18N
375: String wsdlLocation = attributes
376: .getValue("location"); //NOI18N
377: if (wsdlLocation != null
378: && wsdlLocation.indexOf("/") < 0
379: && wsdlLocation.endsWith(".wsdl")) { //NOI18N
380: schemaNames.add(wsdlLocation);
381: }
382: }
383: }
384: if (insideSchema && "import".equals(localname)) { // NOI18N
385: String schemaLocation = attributes
386: .getValue("schemaLocation"); //NOI18N
387: if (schemaLocation != null
388: && schemaLocation.indexOf("/") < 0
389: && schemaLocation.endsWith(".xsd")) { //NOI18N
390: schemaNames.add(schemaLocation);
391: }
392: }
393: }
394:
395: public void endElement(String uri, String localname,
396: String qname) throws SAXException {
397: if (W3C_WSDL_SCHEMA.equals(uri)
398: || W3C_WSDL_SCHEMA_SLASH.equals(uri)) {
399: if ("types".equals(localname)) { // NOI18N
400: insideSchema = false;
401: }
402: }
403: }
404:
405: public List/*String*/getSchemaNames() {
406: return schemaNames;
407: }
408: }
409:
410: private static class SchemaImportsHandler extends DefaultHandler
411: implements ImportsHandler {
412:
413: private List schemaNames;
414:
415: SchemaImportsHandler() {
416: schemaNames = new ArrayList();
417: }
418:
419: public void startElement(String uri, String localname,
420: String qname, Attributes attributes)
421: throws SAXException {
422: if ("import".equals(localname)) { // NOI18N
423: String schemaLocation = attributes
424: .getValue("schemaLocation"); //NOI18N
425: if (schemaLocation != null
426: && schemaLocation.indexOf("/") < 0
427: && schemaLocation.endsWith(".xsd")) { //NOI18N
428: schemaNames.add(schemaLocation);
429: }
430: }
431: }
432:
433: public List/*String*/getSchemaNames() {
434: return schemaNames;
435: }
436: }
437:
438: /* Recursive method that copies all necessary wsdl/schema files imported by FileObject to target folder
439: */
440: private synchronized void copyImportedSchemas(
441: FileObject resourceFolder, FileObject targetFolder,
442: FileObject fo) throws IOException {
443: List schemaNames = getSchemaNames(fo, "wsdl"
444: .equals(fo.getExt())); //NOI18N
445: Iterator it = schemaNames.iterator();
446: while (it.hasNext()) {
447: String schemaName = (String) it.next();
448: FileObject schemaFile = resourceFolder
449: .getFileObject(schemaName);
450: if (schemaFile != null) {
451: FileObject target = targetFolder.getFileObject(
452: schemaFile.getName(), schemaFile.getExt());
453: if (target != null) {
454: target.delete();
455: }
456: //copy the schema file
457: FileObject copy = schemaFile.copy(targetFolder,
458: schemaFile.getName(), schemaFile.getExt());
459: copyImportedSchemas(resourceFolder, targetFolder, copy);
460: }
461: }
462: }
463:
464: }
|