Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/libraries/util/LibDeployerUtils.java URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/libraries/util/LibDeployerUtils.java?rev=1237557&view=auto ============================================================================== --- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/libraries/util/LibDeployerUtils.java (added) +++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/libraries/util/LibDeployerUtils.java Mon Jan 30 07:48:16 2012 @@ -0,0 +1,460 @@ +/* +* Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. 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.impl.builder.StAXOMBuilder; +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 javax.xml.stream.XMLStreamException; +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) { + String libFilePath = LibDeployerUtils.formatPath(libPath); + //extract + String extractPath = LibDeployerUtils.extractSynapseLib(libFilePath); + //create synapse lib metadata + SynapseLibrary synapseLib = LibDeployerUtils.populateDependencies(extractPath + LibDeployerConstants.ARTIFACTS_XML); + //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 = new StAXOMBuilder(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 (XMLStreamException 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 = new StAXOMBuilder(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 (XMLStreamException 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); + } +}
Modified: synapse/trunk/java/repository/conf/axis2.xml URL: http://svn.apache.org/viewvc/synapse/trunk/java/repository/conf/axis2.xml?rev=1237557&r1=1237556&r2=1237557&view=diff ============================================================================== --- synapse/trunk/java/repository/conf/axis2.xml (original) +++ synapse/trunk/java/repository/conf/axis2.xml Mon Jan 30 07:48:16 2012 @@ -93,6 +93,8 @@ <deployer extension="xml" directory="conf/synapse-config/message-stores" class="org.apache.synapse.deployers.MessageStoreDeployer"/> <deployer extension="xml" directory="conf/synapse-config/message-processors" class="org.apache.synapse.deployers.MessageProcessorDeployer"/> <deployer extension="xml" directory="conf/synapse-config/api" class="org.apache.synapse.deployers.APIDeployer"/> + <deployer extension="xml" directory="conf/synapse-config/imports" class="org.apache.synapse.deployers.ImportDeployer"/> + <deployer extension="zip" directory="conf/synapse-libs" class="org.apache.synapse.deployers.LibraryArtifactDeployer"/> <!-- Following parameter will set the host name for the epr--> <!--<parameter name="hostname" locked="true">myhost.com</parameter>-->
