| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.synapse.libraries.util; |
| |
| import org.apache.axiom.om.OMAttribute; |
| import org.apache.axiom.om.OMElement; |
| import org.apache.axiom.om.OMException; |
| import org.apache.axiom.om.OMXMLBuilderFactory; |
| import org.apache.axis2.deployment.DeploymentException; |
| import org.apache.axis2.deployment.util.Utils; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.synapse.SynapseException; |
| import org.apache.synapse.deployers.SynapseArtifactDeploymentException; |
| import org.apache.synapse.libraries.imports.SynapseImport; |
| import org.apache.synapse.libraries.model.Library; |
| import org.apache.synapse.libraries.model.LibraryArtifact; |
| import org.apache.synapse.libraries.model.SynapseLibrary; |
| |
| import javax.xml.namespace.QName; |
| import java.io.*; |
| import java.util.*; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipFile; |
| |
| public class LibDeployerUtils { |
| |
| public static final String APP_UNZIP_DIR; |
| |
| static { |
| String javaTempDir = System.getProperty("java.io.tmpdir"); |
| APP_UNZIP_DIR = javaTempDir.endsWith(File.separator) ? |
| javaTempDir + LibDeployerConstants.SYNAPSE_LIBS : |
| javaTempDir + File.separator + LibDeployerConstants.SYNAPSE_LIBS; |
| createDir(APP_UNZIP_DIR); |
| } |
| |
| private static final Log log = LogFactory.getLog(LibDeployerUtils.class); |
| |
| |
| |
| public static Library createSynapseLibrary(String libPath) { |
| createDir(APP_UNZIP_DIR); |
| |
| String libFilePath = LibDeployerUtils.formatPath(libPath); |
| //extract |
| String extractPath = LibDeployerUtils.extractSynapseLib(libFilePath); |
| //create synapse lib metadata |
| SynapseLibrary synapseLib = LibDeployerUtils.populateDependencies(extractPath + |
| LibDeployerConstants.ARTIFACTS_XML); |
| |
| //create a ClassLoader for loading this synapse lib classes/resources |
| try { |
| ClassLoader libLoader = Utils.getClassLoader(LibDeployerUtils.class.getClassLoader(), |
| extractPath, false); |
| synapseLib.setLibClassLoader(libLoader); |
| } catch (DeploymentException e) { |
| throw new SynapseArtifactDeploymentException("Error setting up lib classpath for Synapse" + |
| " Library : " + libFilePath, e); |
| } |
| //resolve synapse lib artifacts |
| LibDeployerUtils.searchAndResolveDependencies(extractPath, synapseLib); |
| return synapseLib; |
| } |
| |
| /** |
| * populate Dependencies using main root artifacts.xml.. Schema for artifacts.xml is follwing |
| * |
| *<artifacts> |
| <artifact name="SampleLib" package="synapse.sample" > |
| <dependency artifact="templates1" /> + |
| <description>sample synapse library</description> ? |
| </artifact> |
| </artifacts> |
| * |
| * @param libXmlPath |
| * @return |
| */ |
| private static SynapseLibrary populateDependencies(String libXmlPath) { |
| File f = new File(libXmlPath); |
| if (!f.exists()) { |
| throw new SynapseException("artifacts.xml file not found at : " + libXmlPath); |
| } |
| InputStream xmlInputStream = null; |
| try { |
| xmlInputStream = new FileInputStream(f); |
| OMElement documentElement = OMXMLBuilderFactory.createOMBuilder(xmlInputStream).getDocumentElement(); |
| if (documentElement == null) { |
| throw new SynapseArtifactDeploymentException("Document element for artifacts.xml is " + |
| "null. Can't build " + |
| "the synapse library configuration"); |
| } |
| Iterator artifactItr = documentElement.getChildrenWithLocalName(LibDeployerConstants.ARTIFACT); |
| SynapseLibrary mainSynLibArtifact = null; |
| mainSynLibArtifact = createSynapseLibraryWithDeps(((OMElement) artifactItr.next())); |
| if (mainSynLibArtifact == null) { |
| throw new SynapseArtifactDeploymentException("artifacts.xml is invalid. <artifact> element" + |
| " Not Found "); |
| } |
| return mainSynLibArtifact; |
| } catch (FileNotFoundException e) { |
| throw new SynapseArtifactDeploymentException("artifacts.xml File cannot be loaded from " + libXmlPath, e); |
| |
| } catch (OMException e) { |
| throw new SynapseArtifactDeploymentException("Error while parsing the artifacts.xml file ", e); |
| } finally { |
| if (xmlInputStream != null) { |
| try { |
| xmlInputStream.close(); |
| } catch (IOException e) { |
| log.error("Error while closing input stream.", e); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Builds the Artifact object when an artifact element is given |
| * |
| * @param artifactEle - artifact OMElement |
| * @return created Artifact object |
| */ |
| private static SynapseLibrary createSynapseLibraryWithDeps(OMElement artifactEle) { |
| if (artifactEle == null) { |
| return null; |
| } |
| SynapseLibrary synLib = new SynapseLibrary(readAttribute(artifactEle, LibDeployerConstants.NAME), |
| readAttribute(artifactEle, LibDeployerConstants.PACKAGE_ATTR)); |
| synLib.setDescription(readChildText(artifactEle,LibDeployerConstants.DESCRIPTION_ELEMENT)); |
| // read the dependencies |
| Iterator itr = artifactEle.getChildrenWithLocalName(LibDeployerConstants.DEPENDENCY); |
| while (itr.hasNext()) { |
| OMElement depElement = (OMElement) itr.next(); |
| // create a synLib for each dependency and add to the root synLib |
| LibraryArtifact.Dependency dep = new LibraryArtifact.Dependency(readAttribute(depElement, |
| LibDeployerConstants.ARTIFACT)); |
| synLib.addDependency(dep); |
| } |
| |
| return synLib; |
| } |
| |
| |
| /** |
| * Deploys all artifacts under a root artifact.. |
| * |
| * @param rootDirPath - root dir of the extracted artifact |
| * @param library - lib instance |
| */ |
| private static void searchAndResolveDependencies(String rootDirPath, |
| SynapseLibrary library) { |
| List<LibraryArtifact> libraryArtifacts = new ArrayList<LibraryArtifact>(); |
| File extractedDir = new File(rootDirPath); |
| File[] allFiles = extractedDir.listFiles(); |
| if (allFiles == null) { |
| return; |
| } |
| |
| |
| // search for all directories under the extracted path |
| for (File artifactDirectory : allFiles) { |
| if (!artifactDirectory.isDirectory()) { |
| continue; |
| } |
| |
| String directoryPath = formatPath(artifactDirectory.getAbsolutePath()); |
| String artifactXmlPath = directoryPath + File.separator + LibDeployerConstants.ARTIFACT_XML; |
| |
| File f = new File(artifactXmlPath); |
| // if the artifact.xml not found, ignore this dir |
| if (!f.exists()) { |
| continue; |
| } |
| |
| LibraryArtifact artifact = null; |
| InputStream xmlInputStream = null; |
| try { |
| xmlInputStream = new FileInputStream(f); |
| artifact = buildArtifact(library, xmlInputStream, directoryPath); |
| } catch (FileNotFoundException e) { |
| log.warn("Error while resolving synapse lib dir :" |
| + artifactDirectory.getName() + |
| " artifacts.xml File cannot be loaded " + |
| "from " + artifactXmlPath, e); |
| } catch (Exception e) { |
| log.warn("Error ocurred while resolving synapse lib dir :" |
| + artifactDirectory.getName() + |
| " for artifacts.xml path" + artifactXmlPath, e); |
| } finally { |
| if (xmlInputStream != null) { |
| try { |
| xmlInputStream.close(); |
| } catch (IOException e) { |
| log.error("Error while closing input stream.", e); |
| } |
| } |
| } |
| |
| if (artifact == null) { |
| log.warn("Could not build lib artifact for path : " + directoryPath + " Synapse Library :" + |
| library.getQName() + ". Continue searching for other lib artifacts"); |
| continue; |
| |
| } |
| libraryArtifacts.add(artifact); |
| } |
| boolean isDepsResolved = library.resolveDependencies(libraryArtifacts); |
| if (!isDepsResolved) { |
| throw new SynapseArtifactDeploymentException("Error when resolving Dependencies for lib : " + library.toString()); |
| } |
| } |
| |
| /** |
| * Builds the artifact from the given input steam and adds it as a dependency in the provided |
| * parent Synapse library artifact |
| * |
| * @param library |
| * @param artifactXmlStream - xml input stream of the artifact.xml |
| * @param directoryPath |
| * @return - Artifact instance if successfull. otherwise null.. |
| */ |
| private static LibraryArtifact buildArtifact(SynapseLibrary library, InputStream artifactXmlStream, String directoryPath) { |
| LibraryArtifact artifact = null; |
| try { |
| OMElement artElement = OMXMLBuilderFactory.createOMBuilder(artifactXmlStream).getDocumentElement(); |
| |
| if (LibDeployerConstants.ARTIFACT.equals(artElement.getLocalName())) { |
| artifact = populateLibraryArtifact(artElement, directoryPath, null, library); |
| } else { |
| log.error("artifact.xml is invalid. Error occurred while resolving Synapse Library : " |
| + library.getQName()); |
| return null; |
| } |
| } catch (OMException e) { |
| throw new SynapseArtifactDeploymentException("Error parsing artifact.xml for path : " + |
| directoryPath ,e); |
| } |
| |
| if (artifact == null || artifact.getName() == null) { |
| log.error("Invalid artifact found in Synapse Library : " |
| + library.getQName() ); |
| return null; |
| } |
| return artifact; |
| } |
| |
| |
| /** |
| * Builds the Artifact object when an root artifact element is given . Schema for artifact.xml |
| * is as follows |
| * <artifact name="templates1" type="synapse/template" > |
| |
| <subArtifacts> |
| <artifact name="greet_func1" > |
| <file>templ1_ns1.xml</file> |
| <description>sample synapse library artifact Description</description> ? |
| </artifact> * |
| </subArtifacts> * |
| |
| <description>sample synapse library artifact Description</description> ? |
| </artifact> |
| * |
| * @param artifactEle - artifact OMElement |
| * @return created Artifact object |
| */ |
| private static LibraryArtifact populateLibraryArtifact(OMElement artifactEle, String artifactPath, |
| LibraryArtifact parent , SynapseLibrary library) { |
| if (artifactEle == null || artifactPath == null ) { |
| return null; |
| } |
| |
| LibraryArtifact artifact = new LibraryArtifact(readAttribute(artifactEle, LibDeployerConstants.NAME)); |
| artifact.setParent(parent); |
| artifact.setType(readAttribute(artifactEle, LibDeployerConstants.TYPE)); |
| artifact.setPath(artifactPath); |
| |
| artifact.setDescription(readChildText(artifactEle,LibDeployerConstants.DESCRIPTION_ELEMENT)); |
| //add a description of this artifact(if availalbe) to Synapse Library |
| library.addArtifactDescription(artifact); |
| // read the subArtifacts |
| OMElement subArtifactsElement = artifactEle |
| .getFirstChildWithName(new QName(LibDeployerConstants.SUB_ARTIFACTS)); |
| if (subArtifactsElement != null) { |
| Iterator subArtItr = subArtifactsElement.getChildrenWithLocalName(LibDeployerConstants.ARTIFACT); |
| while (subArtItr.hasNext()) { |
| // as this is also an artifact, use recursion |
| LibraryArtifact subArtifact = populateLibraryArtifact((OMElement) subArtItr.next(), artifactPath, artifact, library); |
| artifact.addSubArtifact(subArtifact); |
| } |
| } |
| |
| // read and check for files |
| Iterator fileItr = artifactEle.getChildrenWithLocalName(LibDeployerConstants.FILE); |
| while (fileItr.hasNext()) { |
| OMElement fileElement = (OMElement) fileItr.next(); |
| artifact.setupFile(fileElement.getText()); |
| } |
| return artifact; |
| } |
| |
| public static void loadLibArtifacts(SynapseImport synImport, Library library) { |
| if (synImport.getLibName().equals(library.getQName().getLocalPart()) && |
| synImport.getLibPackage().equals(library.getPackage())) { |
| library.loadLibrary(); |
| } |
| } |
| |
| public static <T> T getLibArtifact(Map<String, Library> librarySet, String key, Class<T> type) { |
| for (Library synapseLibrary : librarySet.values()) { |
| try { |
| T artifact = (T) synapseLibrary.getArtifact(key); |
| if (artifact != null) { |
| return artifact; |
| } |
| } catch (Exception e) { |
| //ignore |
| } |
| } |
| return null; |
| } |
| |
| public static String getQualifiedName(SynapseImport synImport){ |
| return new QName(synImport.getLibPackage(),synImport.getLibName()).toString(); |
| } |
| |
| |
| /////////////////////// |
| ////////////////// Start Common Utility Methods |
| /** |
| * Reads an attribute in the given element and returns the value of that attribute |
| * |
| * @param element - Element to search |
| * @param attName - attribute name |
| * @return if the attribute found, return value. else null. |
| */ |
| public static String readAttribute(OMElement element, String attName) { |
| if (element == null) { |
| return null; |
| } |
| OMAttribute temp = element.getAttribute(new QName(attName)); |
| if (temp != null) { |
| return temp.getAttributeValue(); |
| } |
| return null; |
| } |
| |
| public static String readChildText(OMElement element, String ln) { |
| return readChildText(element, ln, null); |
| } |
| |
| /** |
| * Reads a text node which is in a child element of the given element and returns the text |
| * value. |
| * |
| * @param element - Element to search |
| * @param ln - Child element name |
| * @param ns - Child element namespace |
| * @return if the child text element found, return text value. else null. |
| */ |
| public static String readChildText(OMElement element, String ln, String ns) { |
| if (element == null) { |
| return null; |
| } |
| OMElement temp = element.getFirstChildWithName(new QName(ns, ln)); |
| if (temp != null) { |
| return temp.getText(); |
| } |
| return null; |
| } |
| |
| |
| /** |
| * Extract the Synapse Library at the provided path to the java temp dir. Return the |
| * extracted location |
| * |
| * @param libPath - Absolute path of the Synapse Lib archive file |
| * @return - extracted location |
| * @throws SynapseException - error on extraction |
| */ |
| public static String extractSynapseLib(String libPath) throws SynapseException { |
| libPath = formatPath(libPath); |
| String fileName = libPath.substring(libPath.lastIndexOf('/') + 1); |
| String dest = APP_UNZIP_DIR + File.separator + System.currentTimeMillis() + |
| fileName + File.separator; |
| createDir(dest); |
| |
| try { |
| extract(libPath, dest); |
| } catch (IOException e) { |
| throw new SynapseException("Error while extracting Synapse Library : " + fileName, e); |
| } |
| return dest; |
| } |
| |
| /** |
| * Format the string paths to match any platform.. windows, linux etc.. |
| * |
| * @param path - input file path |
| * @return formatted file path |
| */ |
| public static String formatPath(String path) { |
| // removing white spaces |
| path = path.replaceAll("\\b\\s+\\b", "%20"); |
| // replacing all "\" with "/" |
| return path.replace('\\', '/'); |
| } |
| |
| private static void extract(String sourcePath, String destPath) throws IOException { |
| Enumeration entries; |
| ZipFile zipFile; |
| |
| zipFile = new ZipFile(sourcePath); |
| entries = zipFile.entries(); |
| |
| while (entries.hasMoreElements()) { |
| ZipEntry entry = (ZipEntry) entries.nextElement(); |
| // we don't need to copy the META-INF dir |
| if (entry.getName().startsWith("META-INF/")) { |
| continue; |
| } |
| // if the entry is a directory, create a new dir |
| if (entry.isDirectory()) { |
| createDir(destPath + entry.getName()); |
| continue; |
| } |
| // if the entry is a file, write the file |
| copyInputStream(zipFile.getInputStream(entry), |
| new BufferedOutputStream(new FileOutputStream(destPath + entry.getName()))); |
| } |
| zipFile.close(); |
| } |
| |
| |
| public static void createDir(String path) { |
| File temp = new File(path); |
| if (!temp.exists() && !temp.mkdir()) { |
| log.error("Error while creating directory : " + path); |
| } |
| } |
| |
| private static void copyInputStream(InputStream in, OutputStream out) |
| throws IOException { |
| byte[] buffer = new byte[40960]; |
| int len; |
| |
| while ((len = in.read(buffer)) >= 0) { |
| out.write(buffer, 0, len); |
| } |
| |
| in.close(); |
| out.close(); |
| } |
| |
| /////////////////// End Of Common Utility Methods |
| |
| |
| public static void main(String[] args) { |
| new SynapseLibrary(null, null).resolveDependencies(null); |
| } |
| } |