View Javadoc

1   package com.atlassian.plugin;
2   
3   import org.apache.commons.lang.Validate;
4   import org.apache.commons.io.IOUtils;
5   
6   import java.util.jar.JarFile;
7   import java.util.zip.ZipEntry;
8   import java.io.*;
9   
10  /**
11   * The implementation of PluginArtifact that is backed by a jar file.
12   *
13   * @see PluginArtifact
14   * @since 2.0.0
15   */
16  public class JarPluginArtifact implements PluginArtifact
17  {
18      private final File jarFile;
19  
20      public JarPluginArtifact(File jarFile)
21      {
22          Validate.notNull(jarFile);
23          this.jarFile = jarFile;
24      }
25  
26      public boolean doesResourceExist(String name)
27      {
28          InputStream in = null;
29          try
30          {
31              in = getResourceAsStream(name);
32              return (in != null);
33          }
34          finally
35          {
36              IOUtils.closeQuietly(in);
37          }
38      }
39  
40      /**
41       * @return an input stream for the this file in the jar. Closing this stream also closes the jar file this stream comes from.
42       */
43      public InputStream getResourceAsStream(String fileName) throws PluginParseException
44      {
45          Validate.notNull(fileName, "The file name must not be null");
46          final JarFile jar;
47          try
48          {
49              jar = new JarFile(jarFile);
50          }
51          catch (IOException e)
52          {
53              throw new PluginParseException("Cannot open JAR file for reading: " + jarFile, e);
54          }
55  
56          ZipEntry entry = jar.getEntry(fileName);
57          if (entry == null)
58          {
59              return null;
60          }
61  
62          InputStream descriptorStream;
63          try
64          {
65              descriptorStream = new BufferedInputStream(jar.getInputStream(entry)) {
66  
67                  // because we do not expose a handle to the jar file this stream is associated with, we need to make sure
68                  // we explicitly close the jar file when we're done with the stream (else we'll have a file handle leak)
69                  public void close() throws IOException
70                  {
71                      super.close();
72                      jar.close();
73                  }
74              };
75          }
76          catch (IOException e)
77          {
78              throw new PluginParseException("Cannot retrieve " + fileName + " from plugin JAR [" + jarFile + "]", e);
79          }
80          return descriptorStream;
81      }
82  
83      public String getName()
84      {
85          return jarFile.getName();
86      }
87  
88      @Override
89      public String toString()
90      {
91          return getName();
92      }
93  
94      /**
95       * @return a buffered file input stream of the file on disk. This input stream
96       * is not resettable.
97       */
98      public InputStream getInputStream()
99      {
100         try
101         {
102             return new BufferedInputStream(new FileInputStream(jarFile));
103         }
104         catch (FileNotFoundException e)
105         {
106             throw new RuntimeException("Could not open JAR file for reading: " + jarFile, e);
107         }
108     }
109 
110     public File toFile()
111     {
112         return jarFile;
113     }
114 }