001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)VerifierUtils.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.ui.runtime.verifier.util;
030:
031: import java.io.FileOutputStream;
032: import java.io.InputStream;
033: import java.io.OutputStream;
034: import java.io.File;
035: import java.util.Iterator;
036: import java.util.List;
037: import java.util.zip.ZipFile;
038: import java.util.zip.ZipEntry;
039:
040: import com.sun.jbi.ui.common.I18NBundle;
041: import com.sun.jbi.ui.common.JarFactory;
042: import com.sun.jbi.ui.common.JBIArchive;
043: import com.sun.jbi.ui.common.JBIRemoteException;
044: import com.sun.jbi.ui.common.ServiceAssemblyDD;
045: import com.sun.jbi.ui.common.ToolsLogManager;
046: import com.sun.jbi.ui.runtime.verifier.LocalStringKeys;
047: import com.sun.jbi.ui.runtime.verifier.VerifierException;
048: import java.io.FileInputStream;
049: import java.util.ArrayList;
050: import java.util.HashMap;
051: import java.util.Map;
052:
053: import javax.xml.namespace.NamespaceContext;
054: import javax.xml.xpath.XPath;
055: import javax.xml.xpath.XPathConstants;
056: import javax.xml.xpath.XPathFactory;
057: import org.w3c.dom.Document;
058: import org.w3c.dom.Element;
059: import org.w3c.dom.NamedNodeMap;
060: import org.w3c.dom.Node;
061: import org.w3c.dom.NodeList;
062: import org.xml.sax.InputSource;
063:
064: /**
065: * This class has utility methods for the Verifier
066: */
067: public class VerifierUtils {
068: /** R/W buffer size for copying archive files. */
069: private static final int BUFFER_SIZE = 8 * 1024;
070:
071: /**
072: * resource bundle
073: */
074: private I18NBundle mResourceBundle;
075:
076: /** The namespaceURI represented by the prefix <code>xmlns</code>. */
077: public static final String NS_URI_XMLNS = "http://www.w3.org/2000/xmlns/";
078:
079: /** su descruptor path **/
080: private static final String SU_DESC_PATH = "META-INF"
081: + File.separator + "jbi.xml";
082:
083: /**interface name **/
084: private static final String INTERFACE_NAME = "interface-name";
085:
086: /**endpoint name **/
087: private static final String ENDPOINT_NAME = "endpoint-name";
088:
089: /**service name **/
090: private static final String SERVICE_NAME = "service-name";
091:
092: /**name attribute **/
093: private static final String NAME = "name";
094:
095: /** target ns */
096: private static final String TARGET_NS = "targetNamespace";
097:
098: /** sun-javaee-engine */
099: private static final String JAVAEE_SERVICE_ENGINE = "sun-javaee-engine";
100:
101: /** Constructor */
102: public VerifierUtils(I18NBundle resourceBundle) {
103: this .mResourceBundle = resourceBundle;
104: }
105:
106: /**
107: * This method is used to extract a SA
108: * @param vrifierTmpDir the dir where the SA has to be extracted
109: * @param archive the SA archive
110: * @returns String the dir where the SA was extracted
111: * @throws JBIRemoteException if the archive could not be extracted
112: */
113: public String extractSA(String verifierTmpDir, JBIArchive archive)
114: throws JBIRemoteException {
115:
116: ServiceAssemblyDD saDesc = null;
117: String saName = null;
118: File saDir = null;
119: try {
120: saDesc = (ServiceAssemblyDD) archive.getJbiDescriptor();
121: saName = saDesc.getName();
122: saDir = new File(verifierTmpDir, saName);
123: if (saDir.exists()) {
124: cleanDirectory(saDir);
125: }
126: saDir.mkdirs();
127:
128: ZipFile zip = new ZipFile(archive.getJarFile().getName());
129: List<ServiceAssemblyDD.ServiceUnitDD> suDescs = saDesc
130: .getServiceUnitDDList();
131:
132: for (ServiceAssemblyDD.ServiceUnitDD suDesc : suDescs) {
133: String suName = suDesc.getName();
134: String targetComponent = suDesc.getTargetName();
135: String suArtifactZip = suDesc.getArtifactZipName();
136: File suDir = new File(saDir, suName);
137: suDir.mkdir();
138: File suFile = new File(suDir, suArtifactZip);
139:
140: ZipEntry entry = zip.getEntry(suArtifactZip);
141: if (entry == null) {
142: throw new JBIRemoteException(
143: mResourceBundle
144: .getMessage(
145: LocalStringKeys.VERIFIER_SU_ARTIFACT_MISSING,
146: new Object[] { suArtifactZip }));
147: }
148:
149: transfer(zip.getInputStream(entry),
150: new FileOutputStream(suFile));
151:
152: File suComponentDir = new File(suDir, targetComponent);
153:
154: //JavaEEVerifier does not want the ear file to be extracted
155: if (!targetComponent.equals(JAVAEE_SERVICE_ENGINE)) {
156: extractArchive(suComponentDir, suFile);
157: }
158: }
159: zip.close();
160: } catch (Exception ex) {
161: throw new JBIRemoteException(ex.getMessage());
162: }
163: return saDir.getAbsolutePath();
164:
165: }
166:
167: /**
168: * Utility method that writes all data read from the input stream to
169: * the output stream. All streams are closed at the end of this method.
170: * @param input the input stream
171: * @param output the output stream
172: * @throws IOException
173: */
174: private void transfer(InputStream input, OutputStream output)
175: throws java.io.IOException {
176: byte[] buf = new byte[BUFFER_SIZE];
177:
178: for (int count = 0; count > -1; count = input.read(buf)) {
179: output.write(buf, 0, count);
180: }
181:
182: output.flush();
183: input.close();
184: output.close();
185: }
186:
187: /**
188: * Extract the archive contents.
189: *
190: * @param parentDir - the parent directory to extract tp
191: * @param archiveZip - the archive to extract
192: */
193: private void extractArchive(File parentDir, File archiveZip)
194: throws JBIRemoteException {
195: parentDir.mkdir();
196:
197: try {
198: JarFactory jarHelper = new JarFactory(parentDir
199: .getAbsolutePath());
200: jarHelper.unJar(archiveZip);
201: } catch (Exception ex) {
202: throw new JBIRemoteException(ex);
203: }
204: }
205:
206: /**
207: * This method is used to cleanup the contents of the verifier tmp dir
208: * @param tmpDir the temp dir
209: */
210: public boolean cleanup(String tmpDir) {
211: return cleanDirectory(new File(tmpDir));
212: }
213:
214: /**
215: * Removes all files and child directories in the specified directory.
216: * @return false if unable to delete the file
217: */
218: private boolean cleanDirectory(File dir) {
219: File[] tmps = dir.listFiles();
220: for (int i = 0; i < tmps.length; i++) {
221: if (tmps[i].isDirectory()) {
222: // -- Even if a single file / dir in a parent folder cannot be deleted
223: // -- break the recursion as there is no point in continuing the loop
224: if (!cleanDirectory(tmps[i])) {
225: return false;
226: }
227: }
228: if (!tmps[i].delete()) {
229: return false;
230: }
231: }
232: return true;
233: }
234:
235: /**
236: * This method is used to get a list of WSDL files in a SA
237: * @param saDir the dir where the SA is extracted
238: * @returns Map<String, List> a map of suName and list of WSDLs in the SU
239: * @throws VerifierException if the wsdl list could not be obtained
240: */
241: public Map<String, File[]> getWSDLs(String saDirPath)
242: throws VerifierException {
243: Map<String, File[]> wsdlMap = new HashMap();
244: try {
245: File saDir = new File(saDirPath);
246: if (!saDir.exists()) {
247: throw new VerifierException(
248: mResourceBundle
249: .getMessage(LocalStringKeys.VERIFIER_SA_NOT_EXTRACTED));
250: }
251: File[] sus = saDir.listFiles();
252: for (int i = 0; i < sus.length; i++) {
253: StringBuffer logInfo = new StringBuffer();
254: logInfo.append("WSDLs in " + sus[i].getName() + ": ");
255: if (sus[i].isDirectory()) {
256: List<File> wsdls = getWSDLFiles(sus[i]);
257: for (File wsdl : wsdls) {
258: logInfo.append(wsdl.getName());
259: }
260: ToolsLogManager.getRuntimeLogger().finer(
261: logInfo.toString());
262: wsdlMap.put(sus[i].getName(), (File[]) wsdls
263: .toArray(new File[wsdls.size()]));
264: }
265: }
266: return wsdlMap;
267: } catch (Exception ex) {
268: throw new VerifierException(ex);
269: }
270:
271: }
272:
273: /**
274: * This method is used to return a list of config names used in the given
275: * SU
276: * @param suDir the dir where the SU is extracted
277: * @return Map map of endpoint names against config objects
278: */
279: public Map<String, List<String>> getEndpointConfigMap(String suDir)
280: throws VerifierException {
281: Map<String, List<String>> configMap = new HashMap();
282: try {
283: File descriptor = new File(suDir, SU_DESC_PATH);
284: if (!descriptor.exists()) {
285: throw new VerifierException(
286: mResourceBundle
287: .getMessage(LocalStringKeys.VERIFIER_SA_NOT_EXTRACTED));
288: }
289: List endpointNames = new ArrayList();
290:
291: XPathFactory factory = XPathFactory.newInstance();
292: XPath xpath = factory.newXPath();
293: //inner class for namespace prefix to uri mapping
294: xpath.setNamespaceContext(new WSDL11NamespaceContext());
295:
296: InputSource inputSource = new InputSource(
297: new FileInputStream(descriptor));
298: NodeList consumes = (NodeList) xpath.evaluate(
299: "/jbi:jbi/jbi:services/jbi:consumes", inputSource,
300: XPathConstants.NODESET);
301: //create a new input stream otherwise there will be a read error
302: inputSource = new InputSource(new FileInputStream(
303: descriptor));
304: NodeList provides = (NodeList) xpath.evaluate(
305: "/jbi:jbi/jbi:services/jbi:provides", inputSource,
306: XPathConstants.NODESET);
307:
308: for (int i = 0; i < consumes.getLength(); i++) {
309: configMap
310: .putAll(getConfigsUsedInNode(consumes.item(i)));
311: }
312: for (int i = 0; i < provides.getLength(); i++) {
313: configMap
314: .putAll(getConfigsUsedInNode(provides.item(i)));
315: }
316: return configMap;
317: } catch (javax.xml.xpath.XPathExpressionException xpathEx) {
318: throw new VerifierException(xpathEx.toString());
319: } catch (java.io.IOException ioEx) {
320: throw new VerifierException(ioEx.toString());
321: } catch (Exception ex) {
322: //if the supplied document is bad, we may end up with a NPE
323: throw new VerifierException(ex.toString());
324: }
325: }
326:
327: /**
328: * This method is used to get a list of config objects used in the given node
329: * @param Node the node
330: * @return Map<String, List<String>> endpoint name mapped to config list
331: */
332: private Map<String, List<String>> getConfigsUsedInNode(Node node)
333: throws VerifierException {
334:
335: try {
336: Map<String, List<String>> configMap = new HashMap<String, List<String>>();
337: String URI = "";
338:
339: String interfaceName = getAttributeValue(node,
340: INTERFACE_NAME);
341: if (interfaceName != null) {
342: String prefix = interfaceName.substring(0,
343: interfaceName.indexOf(":"));
344: URI = node.lookupNamespaceURI(prefix);
345: }
346:
347: List configList = new ArrayList();
348:
349: XPathFactory factory = XPathFactory.newInstance();
350: XPath xpath = factory.newXPath();
351: //inner class for namespace prefix to uri mapping
352: xpath.setNamespaceContext(new WSDL11NamespaceContext());
353:
354: NodeList config = (NodeList) xpath.evaluate(
355: "config:application-config", node,
356: XPathConstants.NODESET);
357:
358: for (int j = 0; j < config.getLength(); j++) {
359: configList.add(getAttributeValue(config.item(j), NAME));
360: }
361:
362: String serviceName = null;
363: String epName = null;
364:
365: serviceName = getAttributeValue(node, SERVICE_NAME);
366: if (serviceName != null) {
367: //get rid of the prefix
368: serviceName = serviceName.substring(serviceName
369: .indexOf(":") + 1);
370: }
371:
372: epName = getAttributeValue(node, ENDPOINT_NAME);
373:
374: String endpointName = createEndpointName(URI, serviceName,
375: epName);
376: ToolsLogManager.getRuntimeLogger().finer(
377: "Adding config list to endpoint " + endpointName
378: + configList);
379: configMap.put(endpointName, configList);
380: return configMap;
381: } catch (javax.xml.xpath.XPathExpressionException xpathEx) {
382: throw new VerifierException(xpathEx.toString());
383: } catch (Exception ex) {
384: //if the supplied document is bad, we may end up with a NPE
385: throw new VerifierException(ex.toString());
386: }
387:
388: }
389:
390: /**
391: * This method is used to retrieve a list of all .wsdl files in a
392: * dir
393: * @param dir the root dir
394: * @returns List<Files> the list of files that end with .wsdl
395: */
396: private List<File> getWSDLFiles(File dir) {
397: List wsdlFiles = new ArrayList();
398: File[] files = dir.listFiles();
399: for (int i = 0; i < files.length; i++) {
400: if (files[i].isDirectory()) {
401: wsdlFiles.addAll(getWSDLFiles(files[i]));
402: } else if (files[i].getName().endsWith(".wsdl")) {
403: wsdlFiles.add(files[i]);
404: }
405: }
406: return wsdlFiles;
407:
408: }
409:
410: /**
411: * This method is used to get the list of endpoint names from a wsdl file
412: * @param File the wsdl file
413: * @returns String[] the endpoint names
414: * @throws VerifierException if the endpointName could not be obtained
415: */
416: public String[] getEndpointName(File wsdlFile)
417: throws VerifierException {
418: try {
419: List endpointNames = new ArrayList();
420: XPathFactory factory = XPathFactory.newInstance();
421: XPath xpath = factory.newXPath();
422:
423: //inner class for namespace prefix to uri mapping
424: xpath.setNamespaceContext(new WSDL11NamespaceContext());
425:
426: InputSource inputSource = new InputSource(
427: new FileInputStream(wsdlFile));
428:
429: String serviceName = getServiceName(wsdlFile);
430:
431: NodeList ports = (NodeList) xpath
432: .evaluate(
433: "/wsdl-11:definitions/wsdl-11:service/wsdl-11:port",
434: inputSource, XPathConstants.NODESET);
435:
436: String namespaceURI = null;
437: if (ports.getLength() > 0) {
438: Node port = ports.item(0);
439: Document doc = port.getOwnerDocument();
440: Element definitions = doc.getDocumentElement();
441: namespaceURI = definitions.getAttribute(TARGET_NS);
442: }
443:
444: int length = ports.getLength();
445: for (int i = 0; i < length; i++) {
446: String endpointName = createEndpointName(namespaceURI,
447: serviceName, getAttributeValue(ports.item(i),
448: "name"));
449: ToolsLogManager.getRuntimeLogger().finer(
450: "Adding endpoint " + endpointName);
451: endpointNames.add(endpointName);
452: }
453:
454: String[] endpoints = new String[endpointNames.size()];
455: endpointNames.toArray(endpoints);
456: return endpoints;
457:
458: } catch (javax.xml.xpath.XPathExpressionException xpathEx) {
459: throw new VerifierException(xpathEx.toString());
460: } catch (java.io.IOException ioEx) {
461: throw new VerifierException(ioEx.toString());
462: } catch (Exception ex) {
463: //if the supplied document is bad, we may end up with a NPE
464: throw new VerifierException(ex.toString());
465: }
466:
467: }
468:
469: /**
470: * This method is used to create the endpoint name from
471: * the namespace URI, service name and endpoint name
472: * The three items are concatenated with a comma between the,
473: * If the namespace URI is empty it is omitted
474: * @param namespace the namespace URI
475: * @param servicename the service name
476: * @param endpointName the endpoint name
477: * @returns String the endpointName
478: */
479:
480: public String createEndpointName(String namespace,
481: String serviceName, String endpointName) {
482: StringBuffer epname = new StringBuffer();
483: if (namespace != null) {
484: epname.append(namespace);
485: if (!namespace.endsWith("/")) {
486: epname.append("/");
487: }
488: epname.append(",");
489: }
490: epname.append(serviceName);
491: epname.append(",");
492: epname.append(endpointName);
493: return epname.toString();
494: }
495:
496: /**
497: * This method is used to get the service name of a wsdl file
498: * @param File wsdlFile
499: * @return String the target namespace
500: * @throws VerifierException
501: */
502: private String getServiceName(File wsdlFile)
503: throws VerifierException {
504: try {
505: XPathFactory factory = XPathFactory.newInstance();
506: XPath xpath = factory.newXPath();
507:
508: //inner class for namespace prefix to uri mapping
509: xpath.setNamespaceContext(new WSDL11NamespaceContext());
510:
511: InputSource inputSource = new InputSource(
512: new FileInputStream(wsdlFile));
513:
514: return xpath
515: .evaluate(
516: "/wsdl-11:definitions/wsdl-11:service/attribute::name",
517: inputSource);
518:
519: } catch (javax.xml.xpath.XPathExpressionException xpathEx) {
520: throw new VerifierException(xpathEx.toString());
521: } catch (Exception ex) {
522: //if the supplied document is bad, we may end up with a NPE
523: throw new VerifierException(ex.toString());
524: }
525: }
526:
527: /**
528: * This method is used to get the value of the given attribute
529: * @param node the node
530: * @param attribute the attribute name
531: * @param String the attribute value
532: */
533: public String getAttributeValue(Node node, String attribute) {
534: if (node != null) {
535: NamedNodeMap attrbs = node.getAttributes();
536: Node attrb = attrbs.getNamedItem(attribute);
537: return attrb.getNodeValue();
538: }
539: return null;
540: }
541:
542: /**
543: * This method is used to get the list of application variables
544: * used in the given endpoint in the wsdl file
545: * @param File the wsdl file
546: * @param endpointname the endpoint name
547: * @returns List list of application variables
548: * @throws VerifierException if the list could not be obtained
549: */
550: public List getApplicationVariables(File wsdlFile,
551: String endpointName) throws VerifierException {
552:
553: try {
554: String epName = null;
555: if (endpointName != null) {
556: epName = endpointName.substring(endpointName
557: .lastIndexOf(",") + 1);
558: }
559: XPathFactory factory = XPathFactory.newInstance();
560: XPath xpath = factory.newXPath();
561:
562: //inner class for namespace prefix to uri mapping
563: xpath.setNamespaceContext(new WSDL11NamespaceContext());
564:
565: InputSource inputSource = new InputSource(
566: new FileInputStream(wsdlFile));
567:
568: List appVarList = new ArrayList();
569: NodeList ports = (NodeList) xpath
570: .evaluate(
571: "/wsdl-11:definitions/wsdl-11:service/wsdl-11:port",
572: inputSource, XPathConstants.NODESET);
573:
574: int length = ports.getLength();
575: for (int i = 0; i < length; i++) {
576: if (epName.equals(getAttributeValue(ports.item(i),
577: "name"))) {
578: appVarList.addAll(getAppVars(ports.item(i)));
579: }
580: }
581:
582: ToolsLogManager.getRuntimeLogger().finer(
583: "Application Variables used in " + epName
584: + " are: " + appVarList);
585: return appVarList;
586:
587: } catch (javax.xml.xpath.XPathExpressionException xpathEx) {
588: throw new VerifierException(xpathEx.toString());
589: } catch (java.io.IOException ioEx) {
590: throw new VerifierException(ioEx.toString());
591: } catch (Exception ex) {
592: //if the supplied document is bad, we may end up with a NPE
593: throw new VerifierException(ex.toString());
594: }
595:
596: }
597:
598: /**
599: * This method is used to get a list of application variables
600: * used in a node
601: * @param Node the node
602: * @returns List the list of app vars
603: */
604: private List getAppVars(Node node) {
605: List applicationVariables = new ArrayList();
606: try {
607: //1. get the node's content
608: applicationVariables
609: .addAll(getAppVars(node.getNodeValue()));
610:
611: //2. get the attributes content
612: if (node.hasAttributes()) {
613: NamedNodeMap attrs = node.getAttributes();
614: for (int i = 0; i < attrs.getLength(); i++) {
615: applicationVariables.addAll(getAppVars(attrs
616: .item(i).getNodeValue()));
617: }
618: }
619:
620: //3.get the children's content
621: if (node.hasChildNodes()) {
622: NodeList children = node.getChildNodes();
623: for (int i = 0; i < children.getLength(); i++) {
624: applicationVariables.addAll(getAppVars(children
625: .item(i)));
626: }
627: }
628:
629: } catch (Exception ex) {
630: if (ex.getMessage() != null) {
631: ToolsLogManager.getRuntimeLogger().warning(
632: ex.getMessage());
633: }
634: }
635: return applicationVariables;
636: }
637:
638: /**
639: * This method is used to get a list of application variables
640: * present in the given String
641: * @param content the string
642: * @returns List the list of application variables
643: *
644: */
645: private List getAppVars(String content) {
646: List appVars = new ArrayList();
647: try {
648: if (content.indexOf("$") != -1) {
649: String[] tokens = content.split("[$}]");
650: for (int i = 0; i < tokens.length; i++) {
651: if (tokens[i].indexOf("{") != -1) {
652:
653: String[] variables = tokens[i].split("[{]");
654: for (int j = 0; j < variables.length; j++) {
655: if (variables[j].length() > 0) {
656: appVars.add(variables[j]);
657: }
658: }
659: }
660: }
661: }
662: } catch (Exception ex) {
663: //continue with processing
664: if (ex.getMessage() != null) {
665: ToolsLogManager.getRuntimeLogger().warning(
666: ex.getMessage());
667: }
668: }
669: return appVars;
670: }
671:
672: /**
673: * Namespace mapper class. Maps the prefix wsdl-11 to
674: * "http://schemas.xmlsoap.org/wsdl/"
675: */
676: class WSDL11NamespaceContext implements NamespaceContext {
677:
678: /**
679: * This method maps the prefix wsdl-11 to the URI
680: * "http://schemas.xmlsoap.org/wsdl/"
681: */
682: public String getNamespaceURI(String prefix) {
683: if (prefix.equals("wsdl-11")) {
684: return "http://schemas.xmlsoap.org/wsdl/";
685: } else if (prefix.equals("jbi")) {
686: return "http://java.sun.com/xml/ns/jbi";
687: } else if (prefix.equals("config")) {
688: return "http://www.sun.com/jbi/descriptor/configuration";
689: } else {
690: return NS_URI_XMLNS;
691: }
692: }
693:
694: public String getPrefix(String uri) {
695: throw new UnsupportedOperationException();
696: }
697:
698: public Iterator getPrefixes(String uri) {
699: throw new UnsupportedOperationException();
700: }
701:
702: }
703: }
|