Author: marrs
Date: Mon Mar 26 21:45:44 2012
New Revision: 1305618

URL: http://svn.apache.org/viewvc?rev=1305618&view=rev
Log:
ACE-235 added a stand-alone builder, refactored the Ant task to use it

Added:
    ace/trunk/ace-builder/
    ace/trunk/ace-builder/pom.xml
    ace/trunk/ace-builder/src/
    ace/trunk/ace-builder/src/main/
    ace/trunk/ace-builder/src/main/java/
    ace/trunk/ace-builder/src/main/java/org/
    ace/trunk/ace-builder/src/main/java/org/apache/
    ace/trunk/ace-builder/src/main/java/org/apache/ace/
    ace/trunk/ace-builder/src/main/java/org/apache/ace/builder/
    ace/trunk/ace-builder/src/main/java/org/apache/ace/builder/ArtifactData.java
    
ace/trunk/ace-builder/src/main/java/org/apache/ace/builder/DeploymentPackageBuilder.java
    ace/trunk/ace-builder/src/test/
    ace/trunk/ace-builder/src/test/java/
    ace/trunk/ace-builder/src/test/java/org/
    ace/trunk/ace-builder/src/test/java/org/apache/
    ace/trunk/ace-builder/src/test/java/org/apache/ace/
    ace/trunk/ace-builder/src/test/java/org/apache/ace/builder/
    
ace/trunk/ace-builder/src/test/java/org/apache/ace/builder/DeploymentPackageBuilderTest.java
Modified:
    ace/trunk/ace-ant-tasks/build.xml
    ace/trunk/ace-ant-tasks/pom.xml
    
ace/trunk/ace-ant-tasks/src/main/java/org/apache/ace/ant/deploymentpackage/DeploymentPackageTask.java
    ace/trunk/pom.xml

Modified: ace/trunk/ace-ant-tasks/build.xml
URL: 
http://svn.apache.org/viewvc/ace/trunk/ace-ant-tasks/build.xml?rev=1305618&r1=1305617&r2=1305618&view=diff
==============================================================================
--- ace/trunk/ace-ant-tasks/build.xml (original)
+++ ace/trunk/ace-ant-tasks/build.xml Mon Mar 26 21:45:44 2012
@@ -20,7 +20,7 @@
 <!-- be sure to run 'mvn install' to create the library before trying this -->
 <project name="sample-build" default="build">
        <!-- defines the deployment package task as 'dp' -->
-    <taskdef name="dp" 
classname="org.apache.ace.ant.deploymentpackage.DeploymentPackageTask" 
classpath="target/org.apache.ace.ant.tasks-0.8.1-SNAPSHOT.jar" />
+    <taskdef name="dp" 
classname="org.apache.ace.ant.deploymentpackage.DeploymentPackageTask" 
classpath="target/org.apache.ace.ant.tasks-0.8.1-SNAPSHOT.jar:../ace-builder/target/org.apache.ace.builder-0.8.1-SNAPSHOT.jar"
 />
 
     <!-- builds a deployment package based on some existing jar files -->
        <target name="build">
@@ -28,7 +28,7 @@
                        <!-- uses two completely arbitrary bundles -->
             <orderedinclude 
name="ace-log-listener/target/org.apache.ace.log.listener-0.8.1-SNAPSHOT.jar" />
                        <orderedinclude 
name="ace-log/target/org.apache.ace.log-0.8.1-SNAPSHOT.jar" />
-                       <include name="ace-range-api/target/*.jar" />
+                       <include 
name="ace-range-api/target/org.apache.ace.range.api-0.8.1-SNAPSHOT.jar" />
                </dp>
        </target>
 </project>

Modified: ace/trunk/ace-ant-tasks/pom.xml
URL: 
http://svn.apache.org/viewvc/ace/trunk/ace-ant-tasks/pom.xml?rev=1305618&r1=1305617&r2=1305618&view=diff
==============================================================================
--- ace/trunk/ace-ant-tasks/pom.xml (original)
+++ ace/trunk/ace-ant-tasks/pom.xml Mon Mar 26 21:45:44 2012
@@ -47,5 +47,10 @@
             <artifactId>ant</artifactId>
             <version>1.8.2</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.ace</groupId>
+            <artifactId>org.apache.ace.builder</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 </project>

Modified: 
ace/trunk/ace-ant-tasks/src/main/java/org/apache/ace/ant/deploymentpackage/DeploymentPackageTask.java
URL: 
http://svn.apache.org/viewvc/ace/trunk/ace-ant-tasks/src/main/java/org/apache/ace/ant/deploymentpackage/DeploymentPackageTask.java?rev=1305618&r1=1305617&r2=1305618&view=diff
==============================================================================
--- 
ace/trunk/ace-ant-tasks/src/main/java/org/apache/ace/ant/deploymentpackage/DeploymentPackageTask.java
 (original)
+++ 
ace/trunk/ace-ant-tasks/src/main/java/org/apache/ace/ant/deploymentpackage/DeploymentPackageTask.java
 Mon Mar 26 21:45:44 2012
@@ -19,18 +19,12 @@
 package org.apache.ace.ant.deploymentpackage;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.FilenameFilter;
-import java.io.IOException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.jar.Attributes;
-import java.util.jar.JarInputStream;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
 
+import org.apache.ace.builder.DeploymentPackageBuilder;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
 import org.apache.tools.ant.Project;
@@ -140,78 +134,16 @@ public class DeploymentPackageTask exten
         for (String file : files) {
             log("Found file: " + file);
         }
-
-        Manifest manifest = new Manifest();
-        Attributes main = manifest.getMainAttributes();
-        main.putValue("Manifest-Version", "1.0");
-        main.putValue("DeploymentPackage-SymbolicName", m_name);
-        main.putValue("DeploymentPackage-Version", m_version);
-
-        for (String file : files) {
-            try {
-                log("Parsing manifest of: " + file);
-                JarInputStream jis = new JarInputStream(new 
FileInputStream(new File(m_dir, file)));
-                Manifest bundleManifest = jis.getManifest();
-                String bsn = "INVALID";
-                String version = "INVALID";
-                if (bundleManifest == null) {
-                    throw new BuildException("Not a valid manifest in: " + 
file);
-                }
-                else {
-                    bsn = 
bundleManifest.getMainAttributes().getValue("Bundle-SymbolicName");
-                    version = 
bundleManifest.getMainAttributes().getValue("Bundle-Version");
-                    jis.close();
-                }
-                Attributes a = new Attributes();
-                a.putValue("Bundle-SymbolicName", bsn);
-                a.putValue("Bundle-Version", version);
-                manifest.getEntries().put(file, a);
-            }
-            catch (IOException e) {
-                throw new BuildException("Could not read bundle " + file + 
".", e);
-            }
-        }
-
-        JarOutputStream output = null;
-        FileInputStream fis = null;
+        
         try {
-            output = new JarOutputStream(new FileOutputStream(m_destination), 
manifest);
-            byte[] buffer = new byte[4096];
-            for (String file : files) {
-                log("Writing to deployment package: " + file);
-                output.putNextEntry(new ZipEntry(file));
-                fis = new FileInputStream(new File(m_dir, file));
-                int bytes = fis.read(buffer);
-                while (bytes != -1) {
-                    output.write(buffer, 0, bytes);
-                    bytes = fis.read(buffer);
-                }
-                output.closeEntry();
-                fis.close();
-                fis = null;
-            }
-        }
+               DeploymentPackageBuilder dp = 
DeploymentPackageBuilder.createDeploymentPackage(m_name, m_version);
+               for (String file : files) {
+                       dp.addBundle(new URL("file://" + 
m_dir.getAbsolutePath() + "/" + file));
+               }
+                       dp.generate(new FileOutputStream(m_destination));
+               }
         catch (Exception e) {
-            throw new BuildException("Could not create deployment package " + 
m_destination + ".", e);
-        }
-        finally {
-            if (output != null) {
-                try {
-                    output.close();
-                }
-                catch (IOException e) {
-                    throw new BuildException("Could not close deployment 
package " + m_destination + ".", e);
-                }
-            }
-            if (fis != null) {
-                try {
-                    fis.close();
-                }
-                catch (IOException e) {
-                    throw new BuildException("Could not close file " + fis + 
".", e);
-                }
-            }
+                       throw new BuildException("Error building deployment 
package: " + e.getMessage(), e);
         }
     }
 }
-

Added: ace/trunk/ace-builder/pom.xml
URL: 
http://svn.apache.org/viewvc/ace/trunk/ace-builder/pom.xml?rev=1305618&view=auto
==============================================================================
--- ace/trunk/ace-builder/pom.xml (added)
+++ ace/trunk/ace-builder/pom.xml Mon Mar 26 21:45:44 2012
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ace</groupId>
+        <artifactId>ace-pom</artifactId>
+        <version>0.8.1-SNAPSHOT</version>
+        <relativePath>../pom/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.ace.builder</artifactId>
+
+    <name>Apache ACE :: Builders</name>
+    <description>Collection of builders that can be used in various 
contexts.</description>
+    <packaging>jar</packaging>
+
+    <scm>
+        
<connection>scm:svn:http://svn.apache.org/repos/asf/ace/trunk/ace-builder</connection>
+        
<developerConnection>scm:svn:https://svn.apache.org/repos/asf/ace/trunk/ace-builder</developerConnection>
+        <url>http://svn.apache.org/repos/asf/ace/trunk/ace-builder</url>
+    </scm>
+    
+    <dependencies>
+       <dependency>
+         <groupId>org.apache.ace</groupId>
+         <artifactId>org.apache.ace.util</artifactId>
+       </dependency>
+     </dependencies>
+</project>

Added: 
ace/trunk/ace-builder/src/main/java/org/apache/ace/builder/ArtifactData.java
URL: 
http://svn.apache.org/viewvc/ace/trunk/ace-builder/src/main/java/org/apache/ace/builder/ArtifactData.java?rev=1305618&view=auto
==============================================================================
--- 
ace/trunk/ace-builder/src/main/java/org/apache/ace/builder/ArtifactData.java 
(added)
+++ 
ace/trunk/ace-builder/src/main/java/org/apache/ace/builder/ArtifactData.java 
Mon Mar 26 21:45:44 2012
@@ -0,0 +1,98 @@
+/*
+ * 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.ace.builder;
+
+import java.net.URL;
+
+public class ArtifactData {
+       private final URL m_url;
+       private boolean m_isBundle;
+       private String m_filename;
+       private String m_bundleSymbolicName;
+       private String m_bundleVersion;
+       private boolean m_isCustomizer;
+       private String m_processorPID;
+       
+       private ArtifactData(URL url, String filename) {
+               m_url = url;
+               m_filename = filename;
+       }
+       
+       public static ArtifactData createBundle(URL url, String filename, 
String bundleSymbolicName, String bundleVersion) {
+               ArtifactData data = new ArtifactData(url, filename);
+               data.setBundleMetadata(bundleSymbolicName, bundleVersion);
+               return data;
+       }
+       
+       public static ArtifactData createResourceProcessor(URL url, String 
filename, String bundleSymbolicName, String bundleVersion, String processorPID) 
{
+               ArtifactData data = new ArtifactData(url, filename);
+               data.setBundleMetadata(bundleSymbolicName, bundleVersion);
+               data.setResourceProcessor(processorPID);
+               return data;
+       }
+       
+       public static ArtifactData createArtifact(URL url, String filename, 
String processorPID) {
+               ArtifactData data = new ArtifactData(url, filename);
+               data.setArtifactResourceProcessor(processorPID);
+               return data;
+       }
+       
+       public URL getURL() {
+               return m_url;
+       }
+
+       public boolean isBundle() {
+               return m_isBundle;
+       }
+       
+       public String getFilename() {
+               return m_filename;
+       }
+
+       public String getSymbolicName() {
+               return m_bundleSymbolicName;
+       }
+       
+       public String getVersion() {
+               return m_bundleVersion;
+       }
+       
+       public boolean isCustomizer() {
+               return m_isCustomizer;
+       }
+       
+       public String getProcessorPid() {
+               return m_processorPID;
+       }
+
+       private void setBundleMetadata(String bundleSymbolicName, String 
bundleVersion) {
+               m_isBundle = true;
+               m_bundleSymbolicName = bundleSymbolicName;
+               m_bundleVersion = bundleVersion;
+       }
+       
+       private void setResourceProcessor(String processorPID) {
+               m_isCustomizer = true;
+               m_processorPID = processorPID;
+       }
+       
+       private void setArtifactResourceProcessor(String processorPID) {
+               m_processorPID = processorPID;
+       }
+}

Added: 
ace/trunk/ace-builder/src/main/java/org/apache/ace/builder/DeploymentPackageBuilder.java
URL: 
http://svn.apache.org/viewvc/ace/trunk/ace-builder/src/main/java/org/apache/ace/builder/DeploymentPackageBuilder.java?rev=1305618&view=auto
==============================================================================
--- 
ace/trunk/ace-builder/src/main/java/org/apache/ace/builder/DeploymentPackageBuilder.java
 (added)
+++ 
ace/trunk/ace-builder/src/main/java/org/apache/ace/builder/DeploymentPackageBuilder.java
 Mon Mar 26 21:45:44 2012
@@ -0,0 +1,242 @@
+/*
+ * 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.ace.builder;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+/**
+ * Builder for deployment packages. Can handle bundles, resource processors 
and artifacts. Uses
+ * the builder pattern:
+ * <pre>
+ * OutputStream out = new FileOutputStream("first.dp");
+ * DeploymentPackageBuilder.createDeploymentPackage("mydp", "1.0")
+ *     .addBundle(new URL("http://repository/api-1.1.0.jar";))
+ *     .addBundle(new URL("http://repository/impl-1.1.3.jar";))
+ *     .addResourceProcessor(new URL("http://repository/rp-1.0.2.jar";))
+ *     .addArtifact(new URL("http://artifacts/config/v1.jar";), "rp.pid")
+ *     .addArtifact(new URL("http://artifacts/data/v3.jar";), "rp.pid")
+ *     .generate(out);
+ * </pre>
+ * For bundles and resource processors, you can simply point to a valid URL 
and it will
+ * be queried for all required metadata. For artifacts, you need to specify 
both the URL
+ * and the PID of the resource processor. The builder will use the order you 
specify for
+ * bundles, resource processors and artifacts, but you don't have to specify 
all bundles
+ * and resource processors first and then all artifacts.
+ */
+public class DeploymentPackageBuilder {
+       private static final int BUFFER_SIZE = 32 * 1024;
+       private final String m_name;
+       private final String m_version;
+       private final List<ArtifactData> m_bundles = new 
ArrayList<ArtifactData>();
+       private final List<ArtifactData> m_processors = new 
ArrayList<ArtifactData>();
+       private final List<ArtifactData> m_artifacts = new 
ArrayList<ArtifactData>();
+       
+       private DeploymentPackageBuilder(String name, String version) {
+               m_name = name;
+               m_version = version;
+       }
+       
+       /**
+        * Creates a new deployment package.
+        * 
+        * @param name the name of the deployment package
+        * @param version the version of the deployment package
+        * @return a builder to further add data to the deployment package
+        */
+       public static DeploymentPackageBuilder createDeploymentPackage(String 
name, String version) {
+               return new DeploymentPackageBuilder(name, version);
+       }
+       
+       /**
+        * Adds a bundle to the deployment package.
+        * 
+        * @param url a url that refers to the bundle
+        * @return a builder to further add data to the deployment package
+        * @throws Exception if something goes wrong while building
+        */
+       public DeploymentPackageBuilder addBundle(URL url) throws Exception {
+               return addBundleArtifact(url, false);
+       }
+       
+       /**
+        * Adds a resource processor to the deployment package. A resource 
processor is a special
+        * type of bundle.
+        * 
+        * @param url a url that refers to the resource processor
+        * @return a builder to further add data to the deployment package
+        * @throws Exception if something goes wrong while building
+        */
+       public DeploymentPackageBuilder addResourceProcessor(URL url) throws 
Exception {
+               return addBundleArtifact(url, true);
+       }
+       
+       /**
+        * Adds an artifact to the deployment package.
+        * 
+        * @param url a url that refers to the bundle
+        * @param processorPID the PID of the processor for this artifact
+        * @return a builder to further add data to the deployment package
+        * @throws Exception if something goes wrong while building
+        */
+       public DeploymentPackageBuilder addArtifact(URL url, String 
processorPID) throws Exception {
+        File file = new File(url.toURI());
+       m_artifacts.add(ArtifactData.createArtifact(url, file.getName(), 
processorPID));
+               return this;
+       }
+
+       /**
+        * Generates a deployment package and streams it to the output stream 
you provide. Before
+        * it starts generating, it will first validate that you have actually 
specified a
+        * resource processor for each type of artifact you provided.
+        * 
+        * @param output the output stream to write to
+        * @throws Exception if something goes wrong while validating or 
generating
+        */
+       public void generate(OutputStream output) throws Exception {
+               validateArtifacts();
+               List<ArtifactData> artifacts = new ArrayList<ArtifactData>();
+               artifacts.addAll(m_bundles);
+               artifacts.addAll(m_processors);
+               artifacts.addAll(m_artifacts);
+               Manifest m = createManifest(artifacts);
+               writeStream(artifacts, m, output);
+       }
+       
+       private DeploymentPackageBuilder addBundleArtifact(URL url, boolean 
isResourceProcessor) throws Exception {
+               JarInputStream jis = null;
+               try {
+                       jis = new JarInputStream(url.openStream());
+               Manifest bundleManifest = jis.getManifest();
+               if (bundleManifest == null) {
+                       throw new Exception("Not a valid manifest in: " + url);
+               }
+               Attributes attributes = bundleManifest.getMainAttributes();
+                       String bundleSymbolicName = 
getRequiredHeader(attributes, "Bundle-SymbolicName");
+               String bundleVersion = getRequiredHeader(attributes, 
"Bundle-Version");
+               File file = new File(url.toURI());
+               if (isResourceProcessor) {
+                       if (!"true".equals(getRequiredHeader(attributes, 
"DeploymentPackage-Customizer"))) {
+                               throw new IOException("Invalid 
DeploymentPackage-Customizer header in: " + url);
+                       }
+                       String processorPID = getRequiredHeader(attributes, 
"Deployment-ProvidesResourceProcessor");
+                       
m_processors.add(ArtifactData.createResourceProcessor(url, file.getName(), 
bundleSymbolicName, bundleVersion, processorPID));
+               }
+               else {
+                       m_bundles.add(ArtifactData.createBundle(url, 
file.getName(), bundleSymbolicName, bundleVersion));
+               }
+               }
+               finally {
+                       if (jis != null) {
+                               jis.close();
+                       }
+               }
+               return this;
+       }
+
+       private void validateArtifacts() throws Exception {
+               for (ArtifactData data : m_artifacts) {
+                       String pid = data.getProcessorPid();
+                       boolean found = false;
+                       for (ArtifactData processor : m_processors) {
+                               if (pid.equals(processor.getProcessorPid())) {
+                                       found = true;
+                                       break;
+                               }
+                       }
+                       if (!found) {
+                               throw new Exception("No resource processor 
found for artifact " + data.getURL() + " with processor PID " + pid);
+                       }
+               }
+       }
+       
+       private String getRequiredHeader(Attributes mainAttributes, String 
headerName) throws Exception {
+               String value = mainAttributes.getValue(headerName);
+               if (value == null || value.equals("")) {
+                       throw new Exception("Missing or invalid " + headerName 
+ " header.");
+               }
+               return value;
+       }
+       
+       private Manifest createManifest(List<ArtifactData> files) throws 
Exception {
+               Manifest manifest = new Manifest();
+        Attributes main = manifest.getMainAttributes();
+        main.putValue("Manifest-Version", "1.0");
+        main.putValue("DeploymentPackage-SymbolicName", m_name);
+        main.putValue("DeploymentPackage-Version", m_version);
+
+        for (ArtifactData file : files) {
+               if (file.isBundle()) {
+                Attributes a = new Attributes();
+                a.putValue("Bundle-SymbolicName", file.getSymbolicName());
+                a.putValue("Bundle-Version", file.getVersion());
+                if (file.isCustomizer()) {
+                    a.putValue("DeploymentPackage-Customizer", "true");
+                    a.putValue("Deployment-ProvidesResourceProcessor", 
file.getProcessorPid());
+                }
+                manifest.getEntries().put(file.getFilename(), a);
+               }
+               else {
+                Attributes a = new Attributes();
+                a.putValue("Resource-Processor", file.getProcessorPid());
+                manifest.getEntries().put(file.getFilename(), a);
+               }
+        }
+               return manifest;
+       }
+       
+       private void writeStream(List<ArtifactData> files, Manifest manifest, 
OutputStream outputStream) throws Exception {
+        JarOutputStream output = null;
+        InputStream fis = null;
+        try {
+                       output = new JarOutputStream(outputStream, manifest);
+            byte[] buffer = new byte[BUFFER_SIZE];
+            for (ArtifactData file : files) {
+                output.putNextEntry(new ZipEntry(file.getFilename()));
+                fis = file.getURL().openStream();
+                int bytes = fis.read(buffer);
+                while (bytes != -1) {
+                    output.write(buffer, 0, bytes);
+                    bytes = fis.read(buffer);
+                }
+                output.closeEntry();
+                fis.close();
+                fis = null;
+            }
+        }
+        finally {
+            if (output != null) {
+               output.close();
+            }
+            if (fis != null) {
+                fis.close();
+            }
+        }
+    }
+}

Added: 
ace/trunk/ace-builder/src/test/java/org/apache/ace/builder/DeploymentPackageBuilderTest.java
URL: 
http://svn.apache.org/viewvc/ace/trunk/ace-builder/src/test/java/org/apache/ace/builder/DeploymentPackageBuilderTest.java?rev=1305618&view=auto
==============================================================================
--- 
ace/trunk/ace-builder/src/test/java/org/apache/ace/builder/DeploymentPackageBuilderTest.java
 (added)
+++ 
ace/trunk/ace-builder/src/test/java/org/apache/ace/builder/DeploymentPackageBuilderTest.java
 Mon Mar 26 21:45:44 2012
@@ -0,0 +1,234 @@
+/*
+ * 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.ace.builder;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import static org.apache.ace.test.utils.TestUtils.UNIT;
+
+public class DeploymentPackageBuilderTest {
+    @Test(groups = { UNIT })
+       public void testEmptyDeploymentPackage() throws Exception {
+               File tempFile = File.createTempFile("output-", ".jar");
+               System.out.println("File: " + tempFile);
+               FileOutputStream output = new FileOutputStream(tempFile);
+               String name = "test";
+               String version = "1.0.0";
+               DeploymentPackageBuilder.createDeploymentPackage(name, 
version).generate(output);
+               Manifest m = getManifest(tempFile);
+
+               // the deployment package should have just a name and a 
version, but no entries
+               Assert.assertEquals(name, 
m.getMainAttributes().getValue("DeploymentPackage-SymbolicName"));
+               Assert.assertEquals(version, 
m.getMainAttributes().getValue("DeploymentPackage-Version"));
+               Assert.assertTrue(m.getEntries().isEmpty());
+       }
+
+    @Test(groups = { UNIT })
+       public void testSingleBundleDeploymentPackage() throws Exception {
+               File tempFile = File.createTempFile("output-", ".jar");
+               FileOutputStream output = new FileOutputStream(tempFile);
+               String name = "test";
+               String version = "1.0.0";
+               
+               String bundleSymbolicName = "bundle";
+               String bundleVersion = "1.0.0";
+               File tempBundleFile = File.createTempFile(bundleSymbolicName + 
"-" + bundleVersion + "-", ".jar");
+               
+               DeploymentPackageBuilder.createDeploymentPackage(name, version)
+                       .addBundle(createBundle(bundleSymbolicName, 
bundleVersion, tempBundleFile))
+                       .generate(output);
+
+               // the deployment package should have a name and a version, and 
a single entry (our bundle)
+               Manifest m = getManifest(tempFile);
+               Assert.assertEquals(name, 
m.getMainAttributes().getValue("DeploymentPackage-SymbolicName"));
+               Assert.assertEquals(version, 
m.getMainAttributes().getValue("DeploymentPackage-Version"));
+               Assert.assertEquals(1, m.getEntries().size());
+               Attributes attributes = 
m.getEntries().get(tempBundleFile.getName());
+               Assert.assertNotNull(attributes);
+               Assert.assertEquals(bundleSymbolicName, 
attributes.getValue("Bundle-SymbolicName"));
+               Assert.assertEquals(bundleVersion, 
attributes.getValue("Bundle-Version"));
+       }
+
+    @Test(groups = { UNIT })
+       public void testTwoBundleDeploymentPackage() throws Exception {
+               File tempFile = File.createTempFile("output-", ".jar");
+               FileOutputStream output = new FileOutputStream(tempFile);
+               String name = "test";
+               String version = "1.0.0";
+               
+               String bundleSymbolicName = "bundle";
+               String bundleVersion = "1.0.0";
+               File tempBundleFile = File.createTempFile(bundleSymbolicName + 
"-" + bundleVersion + "-", ".jar");
+               
+               String bundleSymbolicName2 = "bundle-two";
+               String bundleVersion2 = "1.2.0";
+               File tempBundleFile2 = File.createTempFile(bundleSymbolicName2 
+ "-" + bundleVersion2 + "-", ".jar");
+
+               DeploymentPackageBuilder.createDeploymentPackage(name, version)
+                       .addBundle(createBundle(bundleSymbolicName, 
bundleVersion, tempBundleFile))
+                       .addBundle(createBundle(bundleSymbolicName2, 
bundleVersion2, tempBundleFile2))
+                       .generate(output);
+
+               // the deployment package should have a name and a version, and 
a single entry (our bundle)
+               Manifest m = getManifest(tempFile);
+               Assert.assertEquals(name, 
m.getMainAttributes().getValue("DeploymentPackage-SymbolicName"));
+               Assert.assertEquals(version, 
m.getMainAttributes().getValue("DeploymentPackage-Version"));
+               Assert.assertEquals(2, m.getEntries().size());
+               Attributes attributes = 
m.getEntries().get(tempBundleFile.getName());
+               Assert.assertNotNull(attributes);
+               Assert.assertEquals(bundleSymbolicName, 
attributes.getValue("Bundle-SymbolicName"));
+               Assert.assertEquals(bundleVersion, 
attributes.getValue("Bundle-Version"));
+               attributes = m.getEntries().get(tempBundleFile2.getName());
+               Assert.assertEquals(bundleSymbolicName2, 
attributes.getValue("Bundle-SymbolicName"));
+               Assert.assertEquals(bundleVersion2, 
attributes.getValue("Bundle-Version"));
+       }
+       
+    @Test(groups = { UNIT })
+       public void testProcessorAndResourceDeploymentPackage() throws 
Exception {
+               File tempFile = File.createTempFile("output-", ".jar");
+               FileOutputStream output = new FileOutputStream(tempFile);
+               String name = "test";
+               String version = "1.0.0";
+               
+               String bundleSymbolicName = "bundle";
+               String bundleVersion = "1.0.0";
+               File tempBundleFile = File.createTempFile(bundleSymbolicName + 
"-" + bundleVersion + "-", ".jar");
+               
+               String pid = "my.processor";
+
+               File tempArtifactFile = File.createTempFile("artifact-", 
".jar");
+
+               DeploymentPackageBuilder.createDeploymentPackage(name, version)
+                       
.addResourceProcessor(createResourceProcessor(bundleSymbolicName, 
bundleVersion, pid, tempBundleFile))
+                       .addArtifact(createArtifact(pid, tempArtifactFile), pid)
+                       .generate(output);
+
+               // the deployment package should have a name and a version, and 
a single entry (our bundle)
+               Manifest m = getManifest(tempFile);
+               Assert.assertEquals(name, 
m.getMainAttributes().getValue("DeploymentPackage-SymbolicName"));
+               Assert.assertEquals(version, 
m.getMainAttributes().getValue("DeploymentPackage-Version"));
+               Map<String, Attributes> entries = m.getEntries();
+               Assert.assertEquals(2, entries.size());
+               Attributes attributes = entries.get(tempBundleFile.getName());
+               Assert.assertNotNull(attributes);
+               Assert.assertEquals(bundleSymbolicName, 
attributes.getValue("Bundle-SymbolicName"));
+               Assert.assertEquals(bundleVersion, 
attributes.getValue("Bundle-Version"));
+               Assert.assertEquals("true", 
attributes.getValue("DeploymentPackage-Customizer"));
+               Assert.assertEquals(pid, 
attributes.getValue("Deployment-ProvidesResourceProcessor"));
+               attributes = entries.get(tempArtifactFile.getName());
+               Assert.assertEquals(pid, 
attributes.getValue("Resource-Processor"));
+       }
+
+    @Test(groups = { UNIT }, expectedExceptions = { Exception.class })
+       public void testResourceWithoutProcessorDeploymentPackage() throws 
Exception {
+               File tempFile = File.createTempFile("output-", ".jar");
+               FileOutputStream output = new FileOutputStream(tempFile);
+               String name = "test";
+               String version = "1.0.0";
+               
+               String pid = "my.processor";
+
+               File tempArtifactFile = File.createTempFile("artifact-", 
".jar");
+
+               DeploymentPackageBuilder.createDeploymentPackage(name, version)
+                       .addArtifact(createArtifact(pid, tempArtifactFile), pid)
+                       .generate(output);
+       }
+       
+       
+       private Manifest getManifest(File file) throws Exception {
+        JarInputStream jis = new 
JarInputStream(file.toURI().toURL().openStream());
+        Manifest bundleManifest = jis.getManifest();
+        jis.close();
+        return bundleManifest;
+       }
+       
+       private URL createBundle(String symbolicName, String version, File 
file) throws Exception {
+               Manifest manifest = new Manifest();
+        Attributes main = manifest.getMainAttributes();
+        main.putValue("Manifest-Version", "1.0");
+        main.putValue("Bundle-SymbolicName", symbolicName);
+        main.putValue("Bundle-Version", version);
+        
+        JarOutputStream output = null;
+        InputStream fis = null;
+        try {
+                       output = new JarOutputStream(new 
FileOutputStream(file), manifest);
+                       return file.toURI().toURL();
+        }
+        finally {
+            if (output != null) {
+               output.close();
+            }
+            if (fis != null) {
+                fis.close();
+            }
+        }
+       }
+       
+       private URL createResourceProcessor(String symbolicName, String 
version, String processorPID, File file) throws Exception {
+               Manifest manifest = new Manifest();
+        Attributes main = manifest.getMainAttributes();
+        main.putValue("Manifest-Version", "1.0");
+        main.putValue("Bundle-SymbolicName", symbolicName);
+        main.putValue("Bundle-Version", version);
+        main.putValue("DeploymentPackage-Customizer", "true");
+        main.putValue("Deployment-ProvidesResourceProcessor", processorPID);
+        
+        JarOutputStream output = null;
+        InputStream fis = null;
+        try {
+                       output = new JarOutputStream(new 
FileOutputStream(file), manifest);
+                       return file.toURI().toURL();
+        }
+        finally {
+            if (output != null) {
+               output.close();
+            }
+            if (fis != null) {
+                fis.close();
+            }
+        }
+       }
+
+       private URL createArtifact(String processorPID, File file) throws 
Exception {
+        FileOutputStream output = null;
+        try {
+                       output = new FileOutputStream(file);
+                       output.write(0);
+                       return file.toURI().toURL();
+        }
+        finally {
+            if (output != null) {
+               output.close();
+            }
+        }
+       }
+}

Modified: ace/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/ace/trunk/pom.xml?rev=1305618&r1=1305617&r2=1305618&view=diff
==============================================================================
--- ace/trunk/pom.xml (original)
+++ ace/trunk/pom.xml Mon Mar 26 21:45:44 2012
@@ -35,6 +35,9 @@
         <module>pom</module>
         <module>ace-util</module>
 
+        <module>ace-ant-tasks</module>
+        <module>ace-builder</module>
+
         <module>ace-range-api</module>
 
         <module>ace-repository-api</module>


Reply via email to