View Javadoc

1   package rydeen.io;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.util.Enumeration;
6   import java.util.Iterator;
7   import java.util.jar.JarEntry;
8   import java.util.jar.JarFile;
9   import java.util.jar.Manifest;
10  
11  import rydeen.ProcessTarget;
12  import rydeen.TargetSource;
13  
14  /**
15   * <p>
16   * Jarファイル(Zipファイル)に格納された{@link ProcessTarget <code>ProcessTarget</code>}
17   * を管理する{@link TargetSource <code>TargetSource</code>}です.
18   * </p>
19   *
20   * @author Haruaki Tamada
21   */
22  public class JarFileTargetSource implements TargetSource{
23      private JarFile file;
24      private Manifest manifest;
25  
26      /**
27       * 指定されたfileが表すjarファイルに含まれるファイルを
28       * {@link ProcessTarget <code>ProcessTarget</code>}
29       * とするTargetSourceオブジェクトを構築します.
30       */
31      public JarFileTargetSource(File file) throws IOException{
32          this(new JarFile(file));
33      }
34  
35      /**
36       * 指定されたJarファイルに含まれるファイルを
37       * {@link ProcessTarget <code>ProcessTarget</code>}
38       * とするTargetSourceオブジェクトを構築します.
39       */
40      public JarFileTargetSource(JarFile file){
41          this.file = file;
42      }
43  
44      /**
45       * <p>
46       * このオブジェクトが表すjarファイルに含まれる
47       * MANIFESTファイルを返します.
48       * </p><p>
49       * マニフェストファイルが含まれない場合,nullを返します.
50       * </p>
51       */
52      public Manifest getManifest(){
53          if(manifest == null){
54              try{
55                  manifest = file.getManifest();
56              } catch(IOException e){
57              }
58          }
59          return manifest;
60      }
61  
62      /**
63       * このProcessTargetを閉じます.
64       * このメソッド呼び出し以降,他のメソッド呼び出しは正常に終了しなくなります.
65       */
66      public void close() throws IOException{
67          file.close();
68      }
69  
70      /**
71       * このTargetSourceの名前を返します.
72       */
73      @Override
74      public String getName(){
75          return file.getName();
76      }
77  
78      /**
79       * このTargetSourceが指定されたファイルを保持していればtrueを返します.
80       */
81      @Override
82      public boolean contains(String target){
83          JarEntry entry = file.getJarEntry(target);
84          return entry != null;
85      }
86  
87      /**
88       * このオブジェクトに含まれるProcessTargetの列挙を返します.
89       */
90      @Override
91      public Iterator<ProcessTarget> iterator(){
92          return new Iterator<ProcessTarget>(){
93              Enumeration<JarEntry> entries = file.entries();
94              JarEntry next = findNext();
95  
96              @Override
97              public boolean hasNext(){
98                  return next != null;
99              }
100 
101             @Override
102             public ProcessTarget next(){
103                 ProcessTarget target = null;
104                 try{
105                     String name = next.getName();
106                     target = new PlainProcessTarget(JarFileTargetSource.this, name, file.getInputStream(next));
107                     next = findNext();
108                 } catch(IOException e){
109                     e.printStackTrace();
110                 }
111                 return target;
112             }
113 
114             @Override
115             public void remove(){
116             }
117 
118             private JarEntry findNext(){
119                 JarEntry entry = null;
120                 do{
121                     if(entries.hasMoreElements()){
122                         entry = entries.nextElement();
123                     }
124                     else{
125                         break;
126                     }
127                 } while(entry.isDirectory());
128                 return entry;
129             }
130         };
131     }
132 }