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-2007 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: package org.netbeans.modules.etl.project.anttasks;
042:
043: import java.io.File;
044: import java.io.FileWriter;
045: import java.io.IOException;
046: import java.io.Writer;
047: import java.net.URL;
048: import java.util.Iterator;
049: import java.util.List;
050: import java.util.Map;
051: import net.java.hulp.i18n.Logger;
052:
053: import javax.wsdl.Binding;
054: import javax.wsdl.BindingOperation;
055: import javax.wsdl.Definition;
056: import javax.wsdl.Operation;
057: import javax.wsdl.Port;
058: import javax.wsdl.PortType;
059: import javax.wsdl.Service;
060: import javax.wsdl.Types;
061: import javax.wsdl.WSDLException;
062: import javax.wsdl.extensions.UnknownExtensibilityElement;
063: import javax.wsdl.extensions.schema.Schema;
064: import javax.wsdl.extensions.soap.SOAPAddress;
065: import javax.wsdl.factory.WSDLFactory;
066: import javax.wsdl.xml.WSDLReader;
067: import javax.wsdl.xml.WSDLWriter;
068: import javax.xml.namespace.QName;
069: import javax.xml.parsers.DocumentBuilderFactory;
070: import javax.xml.parsers.ParserConfigurationException;
071:
072: import org.w3c.dom.Document;
073: import org.w3c.dom.Element;
074: import org.w3c.dom.Node;
075: import org.w3c.dom.NodeList;
076: import org.xml.sax.SAXException;
077:
078: import com.sun.etl.engine.impl.ETLEngineImpl;
079: import com.sun.sql.framework.exception.BaseException;
080: import com.sun.sql.framework.utils.RuntimeAttribute;
081: import java.util.HashMap;
082: import javax.wsdl.Message;
083: import javax.wsdl.Part;
084: import org.netbeans.modules.etl.logger.Localizer;
085: import org.netbeans.modules.etl.logger.LogUtil;
086:
087: /**
088: * This class generates an ETL WSDL file given an ETL engine file name
089: *
090: */
091: public class WsdlGenerator {
092:
093: private static Logger logger = Logger.getLogger(WsdlGenerator.class
094: .getName());
095: private static WSDLFactory factory;
096: private String engineFileName;
097: private String wsdlLocation;
098: private Definition def;
099: private File engineFile;
100: private static transient final Logger mLogger = LogUtil
101: .getLogger(WsdlGenerator.class.getName());
102: private static transient final Localizer mLoc = Localizer.get();
103:
104: static {
105: initFactory();
106: }
107:
108: /**
109: * @param engineFileName
110: * @param wsdlLocation
111: */
112: public WsdlGenerator(String engineFileName, String wsdlLocation) {
113: this .engineFileName = engineFileName;
114: this .wsdlLocation = wsdlLocation;
115:
116: }
117:
118: public WsdlGenerator(File f, String wsdlLocation) {
119: engineFile = f;
120: this .engineFileName = f.getName().substring(0,
121: f.getName().indexOf(".xml"));
122: this .wsdlLocation = wsdlLocation;
123:
124: }
125:
126: /**
127: *
128: * @param f,
129: * represents the engine file
130: * @param engineFileName,
131: * the name used for generation wsdl artifacts, should be
132: * combination of project + engine file
133: * @param wsdlLocation,
134: * location of the wsdl file generated
135: */
136: public WsdlGenerator(File f, String engineFileName,
137: String wsdlLocation) {
138: engineFile = f;
139: this .engineFileName = engineFileName;
140: this .wsdlLocation = wsdlLocation;
141: }
142:
143: /**
144: * generates the etl wsdl file and writes to disk
145: *
146: * @return Definition
147: *
148: * @throws WsdlGenerateException
149: */
150: public Definition generateWsdl() throws WsdlGenerateException {
151: this .def = getWsdlTemplate();
152:
153: if (engineFileName == null) {
154: throw new WsdlGenerateException(
155: "cannot generate wsdl file as engineFileName is null ");
156: }
157: if (wsdlLocation == null) {
158: throw new WsdlGenerateException(
159: "cannot generate wsdl file as wsdlLocation is null ");
160: }
161: modifyWsdl();
162: writeWsdl();
163: return def;
164: }
165:
166: /**
167: * @return
168: * @throws SAXException
169: * @throws IOException
170: * @throws ParserConfigurationException
171: * @throws BaseException
172: */
173: private Map getEngineInputParams() {
174: ETLEngineImpl engine = null;
175: try {
176: DocumentBuilderFactory df = DocumentBuilderFactory
177: .newInstance();
178: Element element = df.newDocumentBuilder().parse(engineFile)
179: .getDocumentElement();
180: engine = new ETLEngineImpl();
181: engine.parseXML(element);
182: } catch (SAXException e) {
183: // TODO Auto-generated catch block
184: e.printStackTrace();
185: } catch (IOException e) {
186: // TODO Auto-generated catch block
187: e.printStackTrace();
188: } catch (ParserConfigurationException e) {
189: // TODO Auto-generated catch block
190: e.printStackTrace();
191: } catch (BaseException e) {
192: // TODO Auto-generated catch block
193: e.printStackTrace();
194: }
195: return engine.getInputAttrMap();
196: }
197:
198: /**
199: * persist the wsdl file to disk
200: *
201: * @throws WsdlGenerateException
202: */
203: private void writeWsdl() throws WsdlGenerateException {
204: try {
205:
206: WSDLWriter writer = factory.newWSDLWriter();
207: Writer sink = new FileWriter(wsdlLocation + "/"
208: + engineFileName + ".wsdl");
209:
210: writer.writeWSDL(def, sink);
211: sink.flush();
212: sink.close();
213: } catch (Exception e) {
214: mLogger.infoNoloc(mLoc.t("PRSR015: Exception{0}", e
215: .getMessage()));
216: throw new WsdlGenerateException(e);
217: }
218:
219: }
220:
221: /**
222: * modify the wsdl template
223: */
224: private void modifyWsdl() {
225: try {
226: modifyName();
227: modifyMessages();
228: modifyMessageTypes();
229: modifyPortTypes();
230: modifyBinding();
231: modifyServices();
232: modifyPartnerLink();
233: } catch (Exception ex) {
234: ex.printStackTrace();
235: }
236: }
237:
238: private void modifyBinding() {
239: //Binding b = def.getBinding(new QName(def.getTargetNamespace(), "Binding"));
240:
241: HashMap bMap = (HashMap) def.getBindings();
242: java.util.Iterator keysIter = bMap.keySet().iterator();
243: while (keysIter.hasNext()) {
244: Binding b = (Binding) bMap.get(keysIter.next());
245: if (b != null) {
246: BindingOperation bo = b.getBindingOperation("execute",
247: null, null);
248: if (getEngineInputParams().isEmpty()) {
249: bo.setBindingInput(null);
250: }
251: }
252: }
253: }
254:
255: private void modifyMessages() {
256: Map msgs = def.getMessages();
257: java.util.Iterator keysIter = msgs.keySet().iterator();
258: while (keysIter.hasNext()) {
259: Message msg = (Message) msgs.get(keysIter.next());
260: if (msg != null) {
261: modifyMessageElementName((Message) msg);
262: }
263: }
264: }
265:
266: private void modifyMessageElementName(Message message) {
267: String msgLocalName = message.getQName().getLocalPart();
268: if (message != null) {
269: QName qname = new QName("http://com.sun.jbi/etl/etlengine",
270: engineFileName + "_" + msgLocalName);
271: message.setQName(qname);
272: }
273: Part p = message.getPart("part");
274: QName pqname = new QName("http://com.sun.jbi/etl/etlengine",
275: engineFileName + "_"
276: + p.getElementName().getLocalPart());
277: p.setElementName(pqname);
278: }
279:
280: private void modifyMessageTypes() {
281: Types types = def.getTypes();
282: types.getDocumentationElement();
283: List schemaList = types.getExtensibilityElements();
284:
285: for (int i = 0; i < schemaList.size(); i++) {
286: Object o = schemaList.get(i);
287: if (o instanceof Schema) {
288: Schema s = (Schema) o;
289: modifySchema(s);
290: }
291:
292: }
293:
294: }
295:
296: private void modifySchema(Schema s) {
297: Element root = s.getElement();
298: Document doc = (Document) root.getParentNode().getParentNode()
299: .getParentNode();
300: Element inputItem = getElementByName(root, "inputItem");
301:
302: inputItem.setAttribute("name", engineFileName + "_"
303: + "inputItem");
304:
305: Element outputItem = getElementByName(root, "outputItem");
306: outputItem.setAttribute("name", engineFileName + "_"
307: + "outputItem");
308: Node sequence = inputItem.getElementsByTagName("xsd:sequence")
309: .item(0);
310:
311: Map inputParams = getEngineInputParams();
312: Iterator iterator = inputParams.keySet().iterator();
313: while (iterator.hasNext()) {
314: Object key = iterator.next();
315: RuntimeAttribute ra = (RuntimeAttribute) inputParams
316: .get(key);
317:
318: Element child = doc.createElementNS(
319: "http://www.w3.org/2001/XMLSchema", "xsd:element");
320: child.setAttribute("name", ra.getAttributeName());
321: child.setAttribute("type", getAttributeType(ra));
322: sequence.appendChild(child);
323: }
324:
325: }
326:
327: private String getAttributeType(RuntimeAttribute ra) {
328:
329: String type = null;
330:
331: switch (ra.getJdbcType()) {
332:
333: case java.sql.Types.BOOLEAN:
334: type = "xsd:boolean";
335: break;
336: case java.sql.Types.INTEGER:
337: type = "xsd:integer";
338: break;
339: case java.sql.Types.DECIMAL:
340: type = "xsd:decimal";
341: break;
342: case java.sql.Types.DOUBLE:
343: type = "xsd:double";
344: break;
345: case java.sql.Types.FLOAT:
346: type = "xsd:float";
347: break;
348: case java.sql.Types.DATE:
349: type = "xsd:date";
350: break;
351: case java.sql.Types.TIME:
352: type = "xsd:time";
353: break;
354: case java.sql.Types.TIMESTAMP:
355: type = "xsd:datetime";
356: break;
357: case java.sql.Types.VARCHAR:
358: case java.sql.Types.CHAR:
359: default:
360: type = "xsd:string";
361: }
362: return type;
363: }
364:
365: private Element getElementByName(Element e, String elementName) {
366: if (e.getAttribute("name").equalsIgnoreCase(elementName)) {
367: return e;
368: }
369: NodeList list = e.getChildNodes();
370: Element el = null;
371: Element e2 = null;
372: for (int i = 0; i < list.getLength(); i++) {
373: if (e2 == null) {
374: Node n = list.item(i);
375: if (n.getNodeType() == Node.ELEMENT_NODE) {
376: el = (Element) n;
377: if (el.getAttribute("name").equalsIgnoreCase(
378: elementName)) {
379: e2 = el;
380: break;
381: } else {
382: e2 = getElementByName(el, elementName);
383: if ((e2 != null)
384: && (e2.getAttribute("name")
385: .equalsIgnoreCase(elementName))) {
386: return e2;
387: }
388: }
389: }
390: } else {
391: break;
392: }
393: }
394: return e2;
395: }
396:
397: private void modifyPartnerLink() {
398: List<UnknownExtensibilityElement> l = def
399: .getExtensibilityElements();
400: UnknownExtensibilityElement plinkType = l.get(0);
401:
402: // set plinkType name
403: plinkType.getElement();
404: String plinkName = plinkType.getElement().getAttribute("name");
405: plinkType.getElement().setAttribute("name",
406: engineFileName + "_" + plinkName);
407:
408: // set plink:role name and portType
409: NodeList nl = plinkType.getElement().getChildNodes();
410: Element plinkRole = (Element) nl.item(1);
411: plinkRole.setAttribute("name", engineFileName + "_"
412: + plinkRole.getAttribute("name"));
413:
414: String temp = plinkRole.getAttribute("portType").substring(
415: "tns:".length());
416: plinkRole.setAttribute("portType", "tns:" + engineFileName
417: + "_" + temp);
418:
419: }
420:
421: private void modifyName() {
422: QName q = def.getQName();
423: q = new QName(q.getNamespaceURI(), engineFileName);
424: def.setQName(q);
425: }
426:
427: /**
428: * sets the service name and SOAP address
429: */
430: @SuppressWarnings("unchecked")
431: private void modifyServices() {
432: Map<QName, Service> m = def.getServices();
433: Iterator<QName> iterator = m.keySet().iterator();
434: while (iterator.hasNext()) {
435: QName key = iterator.next();
436: Service s = m.get(key);
437:
438: QName qn = new QName(key.getNamespaceURI(), engineFileName
439: + "_" + key.getLocalPart());
440:
441: s.setQName(qn);
442: Port p = s.getPort("etlPort");
443: p.setName(engineFileName + "_" + p.getName());
444: List<SOAPAddress> l = p.getExtensibilityElements();
445: Iterator iterator2 = l.iterator();
446: while (iterator2.hasNext()) {
447: SOAPAddress element = (SOAPAddress) iterator2.next();
448: String loc = element.getLocationURI() + "/"
449: + engineFileName;
450: element.setLocationURI(loc);
451:
452: }
453: }
454:
455: }
456:
457: /**
458: * this sets the portType name according to the given etl engine file
459: */
460: @SuppressWarnings("unchecked")
461: private void modifyPortTypes() {
462:
463: ;
464:
465: Map<QName, PortType> m = def.getPortTypes();
466: Iterator<QName> iterator = m.keySet().iterator();
467: while (iterator.hasNext()) {
468: QName key = iterator.next();
469: PortType pt = m.get(key);
470:
471: //if engine input params is empty, then operation has no inputMsg
472: if (getEngineInputParams().isEmpty()) {
473: List ops = pt.getOperations();
474: for (int i = 0; i < ops.size(); i++) {
475: Operation op = (Operation) ops.get(i);
476: op.setName("execute");
477: op.setInput(null);
478: }
479: }
480:
481: QName qn = new QName(key.getNamespaceURI(), engineFileName
482: + "_" + key.getLocalPart());
483:
484: pt.setQName(qn);
485: }
486:
487: }
488:
489: /**
490: * reads an etl wsdl template file and genarates the javax.wsdl.Definition
491: *
492: * @return Definition
493: * @throws WsdlGenerateException
494: */
495: private Definition getWsdlTemplate() throws WsdlGenerateException {
496:
497: Definition def = null;
498: WSDLReader reader = factory.newWSDLReader();
499:
500: try {
501: URL u = WsdlGenerator.class
502: .getResource("etl.wsdl.template");
503: String wsdlURI = u.getFile().indexOf(".jar") > 0 ? "jar:"
504: + u.getFile() : u.getFile();
505: def = reader.readWSDL(wsdlURI);
506: } catch (WSDLException e) {
507: mLogger.infoNoloc(mLoc.t("PRSR016: Exception{0}", e
508: .getMessage()));
509: throw new WsdlGenerateException(e);
510: }
511: return def;
512: }
513:
514: /**
515: * initialize the WSDLFactory
516: *
517: * @throws WsdlGenerateException
518: */
519: private static void initFactory() {
520: if (factory == null) {
521: try {
522: factory = WSDLFactory.newInstance();
523: } catch (WSDLException e) {
524: mLogger.infoNoloc(mLoc.t("PRSR017: Exception{0}", e
525: .getMessage()));
526: }
527: }
528: }
529:
530: public static void main(String[] args) {
531: File f = new File("test/xxx_engine.xml");
532:
533: WsdlGenerator wg = new WsdlGenerator(f, "xxx_engine", "test");
534: try {
535: wg.generateWsdl();
536: } catch (WsdlGenerateException e) {
537: e.printStackTrace();
538: }
539:
540: }
541: }
|