1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.millscript.commons.vfs.mime.zip;
22
23 import org.millscript.commons.vfs.AbstractVFolder;
24 import org.millscript.commons.vfs.VEntry;
25 import org.millscript.commons.vfs.VFile;
26 import org.millscript.commons.vfs.VFolder;
27 import org.millscript.commons.vfs.alerts.VEntryNotFoundAlert;
28 import org.millscript.commons.vfs.alerts.VFSAlert;
29
30 import java.util.ArrayList;
31 import java.util.Enumeration;
32 import java.util.List;
33 import java.util.zip.ZipEntry;
34
35 /**
36 * This class implements a virtual filesystem folder for a read-only zip file
37 * folder.
38 */
39 public class ReadOnlyZipFolder extends AbstractVFolder< ReadOnlyZipVolume > {
40
41 /**
42 * Constructs a new virtual filesystem folder with the specified name,
43 * parent folder and volume.
44 *
45 * @param vol the volume this entry is held on
46 * @param parent the parent folder for this folder
47 * @param name the name of the folder
48 */
49 ReadOnlyZipFolder( final ReadOnlyZipVolume vol, final VFolder parent, final String name ) {
50 super( vol, parent, name );
51 }
52
53 /**
54 * Constructs a new virtual filesystem folder with the specified name,
55 * parent folder. This folder will belong to the same volume as the
56 * specified parent folder.
57 *
58 * @param parent the parent folder for this folder
59 * @param name the name of the folder
60 */
61 ReadOnlyZipFolder( final ReadOnlyZipFolder parent, final String name ) {
62 this( parent.getVolume(), parent, name );
63 }
64
65 /**
66 * @see org.millscript.commons.vfs.VEntry#exists()
67 */
68 public boolean exists() {
69 final String path = this.getRelativePathOnVolume();
70 if ( this.getZipEntry( path ) == null ) {
71 return false;
72 }
73 return true;
74 }
75
76 /**
77 * @see org.millscript.commons.vfs.VFolder#checkVEntry(java.lang.String)
78 */
79 public VEntry checkVEntry( final String segment ) {
80 final StringBuffer pathToFileBuffer = this.appendRelativePathOnVolume( new StringBuffer() ).append( segment );
81 final String pathToFile = pathToFileBuffer.toString();
82 if ( this.getZipEntry( pathToFileBuffer.append( '/' ).toString() ) != null ) {
83
84
85 return new ReadOnlyZipFolder( this, segment );
86 } else if ( this.getZipEntry( pathToFile ) != null ) {
87
88 return new ReadOnlyZipFile( this, segment );
89 } else {
90 throw VEntryNotFoundAlert.entryDoesNotExist( segment ).mishap();
91 }
92 }
93
94 /**
95 * @see org.millscript.commons.vfs.VFolder#checkVFile(java.lang.String)
96 */
97 public ReadOnlyZipFile checkVFile( final String segment ) {
98 final StringBuffer pathToFileBuffer = this.appendRelativePathOnVolume( new StringBuffer() ).append( segment );
99 final String pathToFile = pathToFileBuffer.toString();
100 if ( this.getZipEntry( pathToFileBuffer.append( '/' ).toString() ) != null ) {
101
102
103 throw VEntryNotFoundAlert.entryIsNotAFile( segment ).mishap();
104 } else if ( this.getZipEntry( pathToFile ) != null ) {
105
106 return new ReadOnlyZipFile( this, segment );
107 } else {
108 throw VEntryNotFoundAlert.entryDoesNotExist( segment ).mishap();
109 }
110 }
111
112 /**
113 * @see org.millscript.commons.vfs.VFolder#checkVFolder(java.lang.String)
114 */
115 public ReadOnlyZipFolder checkVFolder( final String segment ) {
116 final StringBuffer pathToFileBuffer = this.appendRelativePathOnVolume( new StringBuffer() ).append( segment );
117 final String pathToFile = pathToFileBuffer.toString();
118 if ( this.getZipEntry( pathToFileBuffer.append( '/' ).toString() ) != null ) {
119
120
121 return new ReadOnlyZipFolder( this, segment );
122 } else if ( this.getZipEntry( pathToFile ) != null ) {
123
124
125 throw VEntryNotFoundAlert.entryIsNotAFolder( segment ).mishap();
126 } else {
127 throw VEntryNotFoundAlert.entryDoesNotExist( segment ).mishap();
128 }
129 }
130
131 /**
132 * Returns an enumeration over all the entries in this ZIP file.
133 *
134 * @return an Enumeration over all the entries in this ZIP file.
135 */
136 final Enumeration getEntries() {
137 return this.getVolume().getEntries();
138 }
139
140 /**
141 * @see org.millscript.commons.vfs.VFolder#getVFile(java.lang.String)
142 */
143 public ReadOnlyZipFile getVFile( final String segment ) {
144 return new ReadOnlyZipFile( this, segment );
145 }
146
147 /**
148 * @see org.millscript.commons.vfs.VFolder#getVFolder(java.lang.String)
149 */
150 public ReadOnlyZipFolder getVFolder( final String segment ) {
151 return new ReadOnlyZipFolder( this, segment );
152 }
153
154 /**
155 * Returns the ZipEntry for the specified path.
156 *
157 * @param path the path to get a ZipEntry for
158 * @return a ZipEntry for the specified path, or <code>null</code> if the
159 * path doesn't exist
160 */
161 final ZipEntry getZipEntry( final String path ) {
162 return this.getVolume().getZipEntry( path );
163 }
164
165 /**
166 * @see org.millscript.commons.vfs.VFolder#listEntries()
167 */
168 public List< VEntry > listEntries() {
169
170 final String path = this.getRelativePathOnVolume();
171
172 final int pathLength = path.length();
173 final Enumeration e = this.getEntries();
174 final ArrayList< VEntry > list = new ArrayList< VEntry >();
175 while ( e.hasMoreElements() ) {
176 final ZipEntry ze = (ZipEntry) e.nextElement();
177 final String entryName = ze.getName();
178
179
180 if ( entryName.startsWith( path ) && entryName.length() > pathLength ) {
181
182
183 final int n = entryName.indexOf( '/', pathLength );
184
185
186
187 if ( n == -1 ) {
188
189 list.add( new ReadOnlyZipFile( this, entryName.substring( pathLength ) ) );
190 } else if ( n == entryName.length() - 1 ) {
191
192
193 list.add( new ReadOnlyZipFolder( this, entryName.substring( pathLength, n ) ) );
194 }
195 }
196 }
197 return list;
198 }
199
200 /**
201 * @see org.millscript.commons.vfs.VFolder#listFiles()
202 */
203 public List< VFile > listFiles() {
204
205 final String path = this.getRelativePathOnVolume();
206
207 final int pathLength = path.length();
208 final Enumeration e = this.getEntries();
209 final ArrayList< VFile > list = new ArrayList< VFile >();
210 while ( e.hasMoreElements() ) {
211 final ZipEntry ze = (ZipEntry) e.nextElement();
212 final String entryName = ze.getName();
213
214
215 if ( entryName.startsWith( path ) && entryName.length() > pathLength ) {
216
217
218 final int n = entryName.indexOf( '/', pathLength );
219
220 if ( n < 0 ) {
221
222 list.add( new ReadOnlyZipFile( this, entryName ) );
223 }
224 }
225 }
226 return list;
227 }
228
229 /**
230 * @see org.millscript.commons.vfs.VFolder#listFolders()
231 */
232 public List< VFolder > listFolders() {
233
234 final String path = this.getRelativePathOnVolume();
235
236 final int pathLength = path.length();
237 final Enumeration e = this.getEntries();
238 final ArrayList< VFolder > list = new ArrayList< VFolder >();
239 while ( e.hasMoreElements() ) {
240 final ZipEntry ze = (ZipEntry) e.nextElement();
241 final String entryName = ze.getName();
242
243
244 if ( entryName.startsWith( path ) && entryName.length() > pathLength ) {
245
246
247 final int n = entryName.indexOf( '/', pathLength );
248
249
250 if ( n == entryName.length() - 1 ) {
251
252 list.add( new ReadOnlyZipFolder( this, entryName.substring( 0, n ) ) );
253 }
254 }
255 }
256 return list;
257 }
258
259 /**
260 * @see org.millscript.commons.vfs.VFolder#make()
261 */
262 public VFolder make() {
263 throw(
264 new VFSAlert(
265 "Can't make a folder in a read-only ZIP volume"
266 ).decorate( this ).mishap()
267 );
268 }
269
270 }