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:
042: package org.netbeans.modules.compapp.projects.jbi.anttasks;
043:
044: import java.io.File;
045: import java.io.FileFilter;
046: import java.io.FileInputStream;
047: import java.io.FilenameFilter;
048: import java.util.ArrayList;
049: import java.util.HashMap;
050: import java.util.List;
051: import java.util.Map;
052: import javax.swing.text.Document;
053: import javax.swing.text.PlainDocument;
054: import javax.xml.namespace.QName;
055: import org.apache.tools.ant.BuildException;
056: import org.netbeans.modules.compapp.projects.jbi.descriptor.endpoints.model.PtConnection;
057: import org.netbeans.modules.compapp.projects.jbi.ui.customizer.JbiProjectProperties;
058: import org.netbeans.modules.xml.wsdl.model.*;
059: import org.netbeans.modules.xml.wsdl.model.extensions.bpel.PartnerLinkType;
060: import org.netbeans.modules.xml.wsdl.model.extensions.bpel.Role;
061: import org.netbeans.modules.xml.xam.ModelSource;
062: import org.netbeans.modules.xml.xam.locator.CatalogModelException;
063: import org.openide.filesystems.FileObject;
064: import org.apache.tools.ant.Project;
065: import org.apache.tools.ant.Task;
066: import org.netbeans.modules.compapp.projects.jbi.JbiProject;
067: import org.netbeans.modules.compapp.projects.jbi.api.JbiProjectConstants;
068: import org.netbeans.modules.compapp.projects.jbi.util.MyFileUtil;
069: import org.netbeans.modules.sun.manager.jbi.management.model.ComponentInformationParser;
070: import org.netbeans.modules.sun.manager.jbi.management.model.JBIComponentStatus;
071: import org.openide.util.Lookup;
072: import org.openide.util.lookup.Lookups;
073: import org.netbeans.modules.xml.retriever.catalog.Utilities;
074: import org.openide.filesystems.FileUtil;
075:
076: /**
077: * WSDL repoository of the JBI project
078: *
079: * @author tli
080: * @author jqian
081: */
082: public class wsdlRepository {
083:
084: private Project project;
085: private Task task;
086:
087: private List<WSDLModel> wsdlModels = null;
088:
089: // mapping PortType QName to PortType
090: private Map<String, PortType> portTypes = new HashMap<String, PortType>();
091:
092: // mapping Binding QName to Binding
093: private Map<String, Binding> bindings = new HashMap<String, Binding>();
094:
095: // mapping PartnerLinkType QName to PartnerLinkType
096: private Map<String, PartnerLinkType> partnerLinkTypes = new HashMap<String, PartnerLinkType>();
097:
098: // mapping Service QName to Service
099: private Map<String, Service> services = new HashMap<String, Service>();
100:
101: // mapping Port QName to Port
102: private Map<String, Port> ports = new HashMap<String, Port>();
103:
104: // mapping Port to BC name
105: private Map<Port, String> port2BC = new HashMap<Port, String>();
106:
107: // mapping PortType QName string to PtConnection
108: private Map<String, PtConnection> connections = new HashMap<String, PtConnection>();
109:
110: // mapping bc namespace to bc name
111: private Map<String, String> bcNsMap = new HashMap<String, String>();
112:
113: private static final String WSDL_FILE_EXTENSION = "wsdl";
114: //private static final WSDLFileFilter WSDL_FILE_FILTER = new WSDLFileFilter();
115:
116: private static QName SOAP_ADDRESS_QNAME = new QName(
117: "http://schemas.xmlsoap.org/wsdl/soap/", "address");
118:
119: private String DUMMY_SOAP_LOCATION = "REPLACE_WITH_ACTUAL_URL";
120:
121: public wsdlRepository(Project project, Task task) {
122:
123: this .project = project;
124: this .task = task;
125:
126: wsdlModels = getAllWsdlModels(project);
127:
128: bcNsMap = buildBindingComponentMap(project);
129:
130: initLists();
131:
132: //also look into all SE.jars
133: }
134:
135: // move me to some utility class
136: /**
137: * @param project
138: * @return a map mapping binding component namespace to binding component name.
139: */
140: public static Map<String, String> buildBindingComponentMap(
141: Project project) {
142:
143: Map<String, String> bcMap = new HashMap<String, String>();
144:
145: String projPath = project.getProperty("basedir")
146: + File.separator;
147: String cnfDir = project
148: .getProperty((JbiProjectProperties.META_INF));
149: String bcInfo = projPath + cnfDir + File.separator
150: + JbiProject.BINDING_COMPONENT_INFO_FILE_NAME;
151: File bcFile = new File(bcInfo);
152: if (bcFile.exists()) {
153: try {
154: List<JBIComponentStatus> compList = ComponentInformationParser
155: .parse(bcFile);
156: for (JBIComponentStatus comp : compList) {
157: String compName = comp.getName();
158: List<String> nsList = comp.getNamespaces();
159: for (String ns : nsList) {
160: bcMap.put(ns, compName);
161: }
162: }
163: } catch (Exception e) {
164: e.printStackTrace();
165: }
166: }
167:
168: return bcMap;
169: }
170:
171: public List<WSDLModel> getWsdlCollection() {
172: return wsdlModels;
173: }
174:
175: /**
176: * Gets all the WSDL files from both SU projects and JBI project.
177: */
178: private List<File> getAllWsdlFiles(Project project) {
179: List<File> ret = new ArrayList<File>();
180:
181: String srcPath = project.getProperty("basedir")
182: + File.separator + "src" + File.separator;
183: String serviceUnitsDirLoc = srcPath
184: + JbiProjectConstants.FOLDER_JBISERVICEUNITS;
185: String jbiAsaDirLoc = srcPath
186: + JbiProjectConstants.FOLDER_JBIASA;
187:
188: File serviceUnitsDir = new File(serviceUnitsDirLoc);
189: File jbiASADir = new File(jbiAsaDirLoc);
190: FilenameFilter filter = new FilenameFilter() {
191: public boolean accept(File dir, String name) {
192: return name.endsWith(".wsdl");
193: }
194: };
195:
196: // Note that all files under src/jbiasa/ have been copied over to
197: // src/jbiServiceUnits/ at the beginning of jbi-build.
198: // For all the WSDLs defined in JBI project, we want to use the
199: // original R/W copy under src/jbiasa/ instead of the R/O copy under
200: // src/jbiServiceUnits/.
201: List<String> jbiASAChildNames = new ArrayList<String>();
202: for (File file : jbiASADir.listFiles()) {
203: jbiASAChildNames.add(file.getName());
204: }
205:
206: // 02/12/08, add all CompApp wsdls first...
207: // Add all the WSDLs defined in JBI project (under src/jbiasa/).
208: ret.addAll(MyFileUtil.listFiles(jbiASADir, filter, true));
209:
210: // Add all WSDLs coming from SU projects
211: for (File file : serviceUnitsDir.listFiles()) {
212: String fileName = file.getName();
213: // Skip <compapp>.wsdl and other wsdl files or directories
214: // defined under src/jbiasa/.
215: if (!jbiASAChildNames.contains(fileName)) {
216: ret.addAll(MyFileUtil.listFiles(file, filter, true));
217: }
218: }
219:
220: return ret;
221: }
222:
223: private List<WSDLModel> getAllWsdlModels(Project project) {
224: List<WSDLModel> ret = new ArrayList<WSDLModel>();
225:
226: WSDLModelFactory wsdlModelFactory = WSDLModelFactory
227: .getDefault();
228:
229: for (File file : getAllWsdlFiles(project)) {
230: try {
231: ModelSource ms = null;
232: try {
233: FileObject fo = FileUtil.toFileObject(file);
234: fo.refresh();
235: ms = Utilities.createModelSource(fo, false);
236: } catch (Exception e) { // from command line
237: Lookup lookup = Lookups.fixed(new Object[] { file,
238: getDocument(file),
239: WSDLCatalogModel.getDefault() });
240: ms = new ModelSource(lookup, false);
241: }
242:
243: WSDLModel wm = wsdlModelFactory.createFreshModel(ms);
244: ret.add(wm);
245: } catch (CatalogModelException ex) {
246: ex.printStackTrace();
247: }
248: }
249:
250: return ret;
251: }
252:
253: /**
254: * Implementation of CatalogModel
255: * @param file
256: * @return
257: * @throws org.netbeans.modules.xml.xam.locator.CatalogModelException
258: */
259: protected Document getDocument(File file)
260: throws CatalogModelException {
261: Document result = null;
262:
263: try {
264: FileInputStream fis = new FileInputStream(file);
265: byte buffer[] = new byte[fis.available()];
266: result = new PlainDocument();
267: result.remove(0, result.getLength());
268: fis.read(buffer);
269: fis.close();
270: String str = new String(buffer);
271: result.insertString(0, str, null);
272: } catch (Exception ex) {
273: throw new CatalogModelException(file.getAbsolutePath()
274: + " not found.");
275: }
276:
277: return result;
278: }
279:
280: public static String getWsdlFilePath(WSDLModel doc) {
281: String wsdlFilePath = null;
282: Lookup lookup = doc.getModelSource().getLookup();
283: File wsdlFile = lookup.lookup(File.class);
284: if (wsdlFile == null) {
285: FileObject wsdlFileObject = lookup.lookup(FileObject.class);
286: wsdlFile = FileUtil.toFile(wsdlFileObject);
287: }
288: wsdlFilePath = wsdlFile.getPath();
289: return wsdlFilePath;
290: }
291:
292: public boolean isJavaEEWsdl(WSDLModel doc) {
293: String wsdlFilePath = getWsdlFilePath(doc).toUpperCase()
294: .replace('\\', '/'); // NOI18N
295:
296: // todo: 03/26/07, need to handle Catalog WSDLs..
297: int idx = wsdlFilePath.indexOf("META-INF"); // NOI18N
298: if (idx < 0) {
299: return false;
300: }
301:
302: boolean inJavaEEProject = (wsdlFilePath
303: .indexOf("META-INF/CATALOGDATA/") < 0); // NOI18N
304: return inJavaEEProject;
305: }
306:
307: public void initLists() {
308: /*
309: todo: need a flag to indicat the source wsdls is editable or not...
310: subproject wsdls should not be editable.. may be shared by other JBI projects
311: jbiproject wsdls should be editable..
312: */
313: for (WSDLModel wsdlModel : wsdlModels) {
314: String wsdlFilePath = getWsdlFilePath(wsdlModel);
315: Definitions def = wsdlModel.getDefinitions();
316: if (def == null) {
317: task.log("ERROR: Malformed WSDL file: " + wsdlFilePath);
318: }
319: String tns = def.getTargetNamespace();
320:
321: // Collect portTypes... (PortType QName -> PortType)
322: for (PortType pt : def.getPortTypes()) {
323: String key = getQName(tns, pt.getName());
324: if (portTypes.get(key) != null) {
325: System.out.println("Duplicate PortType: " + key);
326: } else {
327: portTypes.put(key, pt);
328: PtConnection con = new PtConnection(key);
329: connections.put(key, con);
330: }
331: }
332:
333: // Collect bindings... (Binding QName -> Binding)
334: for (Binding b : def.getBindings()) {
335: String key = getQName(tns, b.getName());
336: if (bindings.get(key) != null) {
337: System.out.println("Duplicate Binding: " + key);
338: } else {
339: bindings.put(key, b);
340: }
341: }
342:
343: // Collect partnerLinkTypes... (PartnerLinkType QName -> ParterLinkType)
344: for (ExtensibilityElement ee : def
345: .getExtensibilityElements()) {
346: if (ee.getQName().getLocalPart().equals(
347: "partnerLinkType")) {
348: String pltNS = ee.getQName().getNamespaceURI();
349: if (!pltNS
350: .equals("http://docs.oasis-open.org/wsbpel/2.0/plnktype")) {
351: task
352: .log(
353: "The Partnerlink namespace URI in "
354: + wsdlFilePath
355: + " is \""
356: + pltNS
357: + "\". "
358: + "It should be changed to \"http://docs.oasis-open.org/wsbpel/2.0/plnktype\".",
359: Project.MSG_ERR);
360: return;
361: }
362: PartnerLinkType plt = (PartnerLinkType) ee;
363: String key = getQName(tns, plt.getName());
364: if (partnerLinkTypes.get(key) != null) {
365: System.out.println("Duplicate ParnerLinkType: "
366: + key);
367: } else {
368: partnerLinkTypes.put(key, plt);
369: }
370: }
371: }
372: }
373:
374: for (WSDLModel wsdlModel : wsdlModels) {
375: // todo: 03/26/07, skip J2EE project concrete wsdls..
376: if (true) { // (!isJavaEEWsdl(doc)) {
377: Definitions def = wsdlModel.getDefinitions();
378: String tns = def.getTargetNamespace();
379:
380: // Collect services... (Serivce QName -> Service)
381: for (Service s : def.getServices()) {
382: String sQName = getQName(tns, s.getName());
383: if (services.get(sQName) != null) {
384: System.out.println("Duplicate Service: "
385: + sQName);
386: } else {
387: services.put(sQName, s);
388: }
389:
390: // Collect ports... (ServiceQName + Port Name -> Port)
391: for (Port p : s.getPorts()) {
392: String key = sQName + "." + p.getName();
393: if (ports.get(key) != null) {
394: System.out
395: .println("Duplicate Port: " + key);
396: } else {
397: // Mapping port to binding component ID...
398: List<ExtensibilityElement> xts = p
399: .getExtensibilityElements();
400: if (xts.size() > 0) {
401: ExtensibilityElement ee = xts.get(0);
402:
403: // Ignore dummy soap port
404: QName eeQName = ee.getQName();
405: if (SOAP_ADDRESS_QNAME.equals(eeQName)) {
406: String location = ee
407: .getAttribute("location");
408: if (DUMMY_SOAP_LOCATION
409: .equals(location)) {
410: task
411: .log("INFO: WSDL Port with dummy SOAP address \"REPLACE_WITH_ACTUAL_URL\" is ignored: "
412: + sQName
413: + ":"
414: + p.getName());
415: continue;
416: }
417: }
418:
419: String bcNs = ee.getQName()
420: .getNamespaceURI();
421: if (bcNs != null) {
422: String bcName = bcNsMap.get(bcNs);
423: if (bcName != null) {
424: port2BC.put(p, bcName);
425: } else {
426: task
427: .log(
428: "WARNING: Missing WSDL extension plug-in for \""
429: + bcNs
430: + "\" or missing binding component definition in the config file.",
431: Project.MSG_WARN);
432: }
433: }
434: }
435:
436: ports.put(key, p);
437:
438: Binding binding = p.getBinding().get();
439: if (binding == null) {
440: throw new BuildException(
441: "ERROR: Missing binding for WSDL port "
442: + key);
443: }
444: String ptQName = binding.getType()
445: .getQName().toString();
446: PtConnection ptCon = connections
447: .get(ptQName);
448: if (ptCon != null) {
449: ptCon.addPort(p);
450: }
451: }
452: }
453: }
454: }
455: }
456: }
457:
458: public String getBindingComponentName(Port p) {
459: return port2BC.get(p);
460: }
461:
462: private String getQName(String namespace, String name) {
463: if (namespace == null) {
464: return name;
465: }
466: return "{" + namespace + "}" + name;
467: }
468:
469: /**
470: * @return a map mapping PortType QName to PtConnection
471: */
472: public Map<String, PtConnection> getConnections() {
473: return connections;
474: }
475:
476: public PtConnection getPtConnection(String pt) {
477: return connections.get(pt);
478: }
479:
480: private Role[] getRoles(PartnerLinkType plt) {
481: Role r1 = plt.getRole1();
482: Role r2 = plt.getRole2();
483: List<Role> rs = new ArrayList<Role>();
484: if (r1 != null)
485: rs.add(r1);
486: if (r2 != null)
487: rs.add(r2);
488: return rs.toArray(new Role[] {});
489: }
490:
491: public PortType getPartnerLinkPortType(String pname) {
492: PartnerLinkType plt = partnerLinkTypes.get(pname);
493: if (plt == null) {
494: return null;
495: }
496:
497: Role[] rs = getRoles(plt);
498: if ((rs == null) || (rs.length < 1)) {
499: return null;
500: }
501:
502: // todo: need to handle multiple roles...
503: Role r = rs[0];
504: return r.getPortType().get();
505: }
506:
507: public PortType getPartnerLinkPortType(String pname, String rname) {
508: PartnerLinkType plt = partnerLinkTypes.get(pname);
509: if (plt == null) {
510: return null;
511: }
512:
513: Role[] rs = getRoles(plt);
514: if ((rs == null) || (rs.length < 1)) {
515: return null;
516: }
517:
518: for (int i = 0; i < rs.length; i++) {
519: Role r = rs[i];
520: if (r.getName().equalsIgnoreCase(rname)) {
521: return r.getPortType().get();
522: }
523: }
524:
525: return null;
526: }
527:
528: public Map<String, PortType> getPortTypes() {
529: return portTypes;
530: }
531:
532: public Map<String, Binding> getBindings() {
533: return bindings;
534: }
535:
536: public Map<String, PartnerLinkType> getServiceLTs() {
537: return partnerLinkTypes;
538: }
539:
540: public Map<String, Service> getServices() {
541: return services;
542: }
543:
544: public Map<String, Port> getPorts() {
545: return ports;
546: }
547:
548: static class WSDLFileFilter implements FileFilter {
549: public boolean accept(File pathname) {
550: boolean result = false;
551: if (pathname.isDirectory()) {
552: return true;
553: }
554:
555: String fileName = pathname.getName();
556: String fileExtension = null;
557: int dotIndex = fileName.lastIndexOf('.');
558: if (dotIndex != -1) {
559: fileExtension = fileName.substring(dotIndex + 1);
560: }
561:
562: if (fileExtension != null
563: && fileExtension
564: .equalsIgnoreCase(WSDL_FILE_EXTENSION)) {
565: result = true;
566: }
567:
568: return result;
569: }
570: }
571: }
|