View Javadoc
1   package org.codehaus.mojo.webstart.util;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.plugin.MojoExecutionException;
23  import org.codehaus.plexus.component.annotations.Component;
24  import org.codehaus.plexus.component.annotations.Requirement;
25  
26  import java.io.File;
27  import java.io.FileOutputStream;
28  import java.io.IOException;
29  import java.io.InputStream;
30  import java.util.Enumeration;
31  import java.util.Map;
32  import java.util.Map.Entry;
33  import java.util.Set;
34  import java.util.jar.Attributes.Name;
35  import java.util.jar.JarFile;
36  import java.util.jar.JarOutputStream;
37  import java.util.jar.Manifest;
38  import java.util.zip.ZipEntry;
39  import java.util.zip.ZipFile;
40  
41  /**
42   * Created on 10/26/13.
43   *
44   * @author Tony Chemit <chemit@codelutin.com>
45   * @since 1.0-beta-4
46   */
47  @Component( role = JarUtil.class, hint = "default" )
48  public class DefaultJarUtil
49      implements JarUtil
50  {
51  
52      /**
53       * io helper.
54       */
55      @Requirement
56      protected IOUtil ioUtil;
57  
58      /**
59       * {@inheritDoc}
60       */
61      public void updateManifestEntries( File jar, Map<String, String> manifestentries )
62          throws MojoExecutionException
63      {
64  
65          Manifest manifest = createManifest( jar, manifestentries );
66  
67          File updatedUnprocessedJarFile = new File( jar.getParent(), jar.getName() + "_updateManifestEntriesJar" );
68  
69          ZipFile originalJar = null;
70          JarOutputStream targetJar = null;
71  
72          try
73          {
74              originalJar = new ZipFile( jar );
75              targetJar = new JarOutputStream( new FileOutputStream( updatedUnprocessedJarFile ), manifest );
76  
77              // add all other entries from the original jar file
78              Enumeration<? extends ZipEntry> entries = originalJar.entries();
79              while ( entries.hasMoreElements() )
80              {
81                  ZipEntry entry = entries.nextElement();
82  
83                  // skip the original manifest
84                  if ( JarFile.MANIFEST_NAME.equals( entry.getName() ) )
85                  {
86                      continue;
87                  }
88  
89                  ZipEntry newEntry = new ZipEntry( entry.getName() );
90                  targetJar.putNextEntry( newEntry );
91  
92                  // write content to stream if it is a file
93                  if ( !entry.isDirectory() )
94                  {
95                      InputStream inputStream = null;
96                      try
97                      {
98                          inputStream = originalJar.getInputStream( entry );
99                          org.codehaus.plexus.util.IOUtil.copy( inputStream, targetJar );
100                         inputStream.close();
101                     }
102                     finally
103                     {
104                         org.apache.maven.shared.utils.io.IOUtil.close( inputStream );
105                     }
106                 }
107                 targetJar.closeEntry();
108             }
109             targetJar.close();
110             originalJar.close();
111         }
112         catch ( IOException e )
113         {
114             throw new MojoExecutionException( "Error while updating manifest of " + jar.getName(), e );
115         }
116         finally
117         {
118             org.apache.maven.shared.utils.io.IOUtil.close( targetJar );
119             ioUtil.close( originalJar );
120         }
121 
122         // delete incoming jar file
123         ioUtil.deleteFile( jar );
124 
125         // rename patched jar to incoming jar file
126         ioUtil.renameTo( updatedUnprocessedJarFile, jar );
127     }
128 
129     /**
130      * Create the new manifest from the existing jar file and the new entries
131      *
132      * @param jar
133      * @param manifestentries
134      * @return Manifest
135      * @throws MojoExecutionException
136      */
137     protected Manifest createManifest( File jar, Map<String, String> manifestentries )
138         throws MojoExecutionException
139     {
140         JarFile jarFile = null;
141         try
142         {
143             jarFile = new JarFile( jar );
144 
145             // read manifest from jar
146             Manifest manifest = jarFile.getManifest();
147 
148             if ( manifest == null || manifest.getMainAttributes().isEmpty() )
149             {
150                 manifest = new Manifest();
151                 manifest.getMainAttributes().putValue( Name.MANIFEST_VERSION.toString(), "1.0" );
152             }
153 
154             // add or overwrite entries
155             Set<Entry<String, String>> entrySet = manifestentries.entrySet();
156             for ( Entry<String, String> entry : entrySet )
157             {
158                 manifest.getMainAttributes().putValue( entry.getKey(), entry.getValue() );
159             }
160 
161             return manifest;
162         }
163         catch ( IOException e )
164         {
165             throw new MojoExecutionException( "Error while reading manifest from " + jar.getAbsolutePath(), e );
166         }
167         finally
168         {
169             ioUtil.close( jarFile );
170         }
171     }
172 }