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      /**
89       * @return a buffered file input stream of the file on disk. This input stream
90       * is not resettable.
91       */
92      public InputStream getInputStream()
93      {
94          try
95          {
96              return new BufferedInputStream(new FileInputStream(jarFile));
97          }
98          catch (FileNotFoundException e)
99          {
100             throw new RuntimeException("Could not open JAR file for reading: " + jarFile, e);
101         }
102     }
103 
104     public File toFile()
105     {
106         return jarFile;
107     }
108 }