001: /*
002: * $Id: Folder.java 5708 2006-05-09 18:46:38 +0000 (Tue, 09 May 2006)
003: * jonathanlocke $ $Revision: 460805 $ $Date: 2006-05-09 18:46:38 +0000 (Tue, 09
004: * May 2006) $
005: *
006: * ==============================================================================
007: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
008: * use this file except in compliance with the License. You may obtain a copy of
009: * the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
015: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
016: * License for the specific language governing permissions and limitations under
017: * the License.
018: */
019: package wicket.util.file;
020:
021: import java.io.IOException;
022: import java.net.URI;
023: import java.util.ArrayList;
024: import java.util.Arrays;
025: import java.util.List;
026:
027: /**
028: * This folder subclass provides some type safety and extensibility for "files"
029: * that hold other files.
030: *
031: * @author Jonathan Locke
032: */
033: public final class Folder extends File {
034: /**
035: * Filter for files
036: *
037: * @author Jonathan Locke
038: */
039: public static interface FileFilter {
040: /**
041: * File filter that matches all files
042: */
043: public static FileFilter ALL_FILES = new FileFilter() {
044: public boolean accept(final File file) {
045: return true;
046: }
047: };
048:
049: /**
050: * @param file
051: * The file to test
052: * @return True if the file should be accepted
053: */
054: public boolean accept(File file);
055: }
056:
057: /**
058: * Filter for folders
059: *
060: * @author Jonathan Locke
061: */
062: public static interface FolderFilter {
063: /**
064: * @param folder
065: * The folder to test
066: * @return True if the file should be accepted
067: */
068: public boolean accept(Folder folder);
069: }
070:
071: private static final long serialVersionUID = 1L;
072:
073: /**
074: * Constructor.
075: *
076: * @param parent
077: * parent
078: * @param child
079: * child
080: */
081: public Folder(final Folder parent, final String child) {
082: super (parent, child);
083: }
084:
085: /**
086: * Construct.
087: *
088: * @param file
089: * File
090: */
091: public Folder(final java.io.File file) {
092: this (file.getPath());
093: }
094:
095: /**
096: * Constructor.
097: *
098: * @param pathname
099: * path name
100: */
101: public Folder(final String pathname) {
102: super (pathname);
103: }
104:
105: /**
106: * Constructor.
107: *
108: * @param parent
109: * parent
110: * @param child
111: * child
112: */
113: public Folder(final String parent, final String child) {
114: super (parent, child);
115: }
116:
117: /**
118: * Constructor.
119: *
120: * @param uri
121: * folder uri
122: */
123: public Folder(final URI uri) {
124: super (uri);
125: }
126:
127: /**
128: * Does a mkdirs() on this folder if it does not exist. If the folder cannot
129: * be created, an IOException is thrown.
130: *
131: * @throws IOException
132: * Thrown if folder cannot be created
133: */
134: public void ensureExists() throws IOException {
135: if (!exists() && !mkdirs()) {
136: throw new IOException("Unable to create folder " + this );
137: }
138: }
139:
140: /**
141: * @return Files in this folder
142: */
143: public File[] getFiles() {
144: return getFiles(FileFilter.ALL_FILES);
145: }
146:
147: /**
148: * @return All files nested within this folder
149: */
150: public File[] getNestedFiles() {
151: return getNestedFiles(FileFilter.ALL_FILES);
152: }
153:
154: /**
155: * Gets files in this folder matching a given filter recusively.
156: *
157: * @param filter
158: * The filter
159: * @return The list of files
160: */
161: public File[] getNestedFiles(final FileFilter filter) {
162: final List files = new ArrayList();
163: files.addAll(Arrays.asList(getFiles(filter)));
164: final Folder[] folders = getFolders();
165: for (int i = 0; i < folders.length; i++) {
166: files.addAll(Arrays.asList(folders[i]
167: .getNestedFiles(filter)));
168: }
169: return (File[]) files.toArray(new File[files.size()]);
170: }
171:
172: /**
173: * @param filter
174: * File filter
175: * @return Files
176: */
177: public File[] getFiles(final FileFilter filter) {
178: // Get list of java.io files
179: final java.io.File[] files = listFiles(new java.io.FileFilter() {
180: /**
181: * @see java.io.FileFilter#accept(java.io.File)
182: */
183: public boolean accept(java.io.File file) {
184: return file.isFile() && filter.accept(new File(file));
185: }
186: });
187:
188: // Convert java.io files to wicket files
189: if (files != null) {
190: final File[] wicketFiles = new File[files.length];
191: for (int i = 0; i < files.length; i++) {
192: wicketFiles[i] = new File(files[i]);
193: }
194: return wicketFiles;
195: }
196: return new File[0];
197: }
198:
199: /**
200: * Gets all folders in this folder, except "." and ".."
201: *
202: * @return Folders
203: */
204: public Folder[] getFolders() {
205: return getFolders(new FolderFilter() {
206: public boolean accept(final Folder folder) {
207: final String name = folder.getName();
208: return !name.equals(".") && !name.equals("..");
209: }
210: });
211: }
212:
213: /**
214: * @param filter
215: * Folder fiter
216: * @return Folders
217: */
218: public Folder[] getFolders(final FolderFilter filter) {
219: // Get java io files that are directories matching the filter
220: final java.io.File[] files = listFiles(new java.io.FileFilter() {
221: /**
222: * @see java.io.FileFilter#accept(java.io.File)
223: */
224: public boolean accept(java.io.File file) {
225: return file.isDirectory()
226: && filter.accept(new Folder(file.getPath()));
227: }
228: });
229:
230: // Convert
231: if (files != null) {
232: final Folder[] wicketFolders = new Folder[files.length];
233: for (int i = 0; i < files.length; i++) {
234: wicketFolders[i] = new Folder(files[i]);
235: }
236: return wicketFolders;
237: }
238: return new Folder[0];
239: }
240:
241: /**
242: * Removes this folder and everything in it, recursively. A best effort is
243: * made to remove nested folders and files in depth-first order.
244: *
245: * @return True if the folder was successfully removed
246: */
247: public boolean remove() {
248: return remove(this );
249: }
250:
251: /**
252: * Removes all the files in this folder.
253: *
254: * @return True if any files were successfully removed
255: */
256: public boolean removeFiles() {
257: final File[] files = getFiles();
258: boolean success = true;
259: for (int i = 0; i < files.length; i++) {
260: success = files[i].remove() && success;
261: }
262: return success;
263: }
264:
265: /**
266: * Removes everything in the given folder and then the folder itself.
267: *
268: * @param folder
269: * The folder
270: * @return True if the folder was successfully removed
271: */
272: private boolean remove(final Folder folder) {
273: final Folder[] folders = getFolders();
274: boolean success = true;
275: for (int i = 0; i < folders.length; i++) {
276: success = folders[i].remove() && success;
277: }
278: success = removeFiles() && success;
279: return folder.delete() && success;
280: }
281: }
|