1 | /* GPL_HEADER */
|
---|
2 | package org.greenstone.gatherer.util;
|
---|
3 | /**************************************************************************************
|
---|
4 | * Title: Gatherer
|
---|
5 | * Description: The Gatherer: a tool for gathering and enriching a digital collection.
|
---|
6 | * Company: The University of Waikato
|
---|
7 | * Written: / /01
|
---|
8 | * Revised: 16/08/02 Improved
|
---|
9 | **************************************************************************************/
|
---|
10 | import java.awt.*;
|
---|
11 | import java.io.*;
|
---|
12 | import java.util.*;
|
---|
13 | import javax.swing.filechooser.*;
|
---|
14 | import org.greenstone.gatherer.file.FileNode;
|
---|
15 | import org.greenstone.gatherer.msm.Metadata;
|
---|
16 | import org.w3c.dom.*;
|
---|
17 | /** This utility class contains a series of static methods for common array type manipulations including appending, casting and changing between containers.
|
---|
18 | * @author John Thompson
|
---|
19 | * @version 2.3
|
---|
20 | */
|
---|
21 | public class ArrayTools {
|
---|
22 |
|
---|
23 | /** Append a Component onto an array of Components. */
|
---|
24 | static public Component[] add(Component[] a, Component b) {
|
---|
25 | Component[] c = null;
|
---|
26 | if(a != null && b != null) {
|
---|
27 | c = new Component[a.length + 1];
|
---|
28 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
29 | c[c.length - 1] = b;
|
---|
30 | }
|
---|
31 | else if(a == null && b != null) {
|
---|
32 | c = new Component[1];
|
---|
33 | c[0] = b;
|
---|
34 | }
|
---|
35 | else if(a != null && b == null) {
|
---|
36 | c = a;
|
---|
37 | }
|
---|
38 | return c;
|
---|
39 | }
|
---|
40 | /** This method efficiently appends a new element onto the end of a element array.
|
---|
41 | * @param a The initial <strong>Element[]</strong>.
|
---|
42 | * @param b The new <strong>Element</strong>.
|
---|
43 | * @return An <strong>Element[]</strong> containing a followed by b.
|
---|
44 | */
|
---|
45 | static public Element[] add(Element a[], Element b) {
|
---|
46 | Element[] c = null;
|
---|
47 | if(a != null && b != null) {
|
---|
48 | c = new Element[a.length + 1];
|
---|
49 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
50 | c[c.length - 1] = b;
|
---|
51 | }
|
---|
52 | else if(a == null && b != null) {
|
---|
53 | c = new Element[1];
|
---|
54 | c[0] = b;
|
---|
55 | }
|
---|
56 | else if(a != null && b == null) {
|
---|
57 | c = a;
|
---|
58 | }
|
---|
59 | return c;
|
---|
60 | }
|
---|
61 | /** This method efficently appends one element array onto the end of another.
|
---|
62 | * @param a The initial <strong>Element[]</strong>.
|
---|
63 | * @param b The <strong>Element[]</strong> to append.
|
---|
64 | * @return An <strong>Element[]</strong> containing a followed by b.
|
---|
65 | */
|
---|
66 | static public Element[] add(Element a[], Element b[]) {
|
---|
67 | Element[] c = null;
|
---|
68 | if(a != null && b != null) {
|
---|
69 | c = new Element[a.length + b.length];
|
---|
70 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
71 | System.arraycopy(b, 0, c, a.length, b.length);
|
---|
72 | }
|
---|
73 | else if(a == null && b != null) {
|
---|
74 | c = b;
|
---|
75 | }
|
---|
76 | else if(a != null && b == null) {
|
---|
77 | c = a;
|
---|
78 | }
|
---|
79 | return c;
|
---|
80 | }
|
---|
81 | /** This method efficiently appends a new file onto the end of a file array.
|
---|
82 | * @param a The initial <strong>File[]</strong>.
|
---|
83 | * @param b The new <strong>File</strong>.
|
---|
84 | * @return A <strong>File[]</strong> containing a followed by b.
|
---|
85 | */
|
---|
86 | static public File[] add(File a[], File b) {
|
---|
87 | File[] c = null;
|
---|
88 | if(a != null && b != null) {
|
---|
89 | c = new File[a.length + 1];
|
---|
90 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
91 | c[c.length - 1] = b;
|
---|
92 | }
|
---|
93 | else if(a == null && b != null) {
|
---|
94 | c = new File[1];
|
---|
95 | c[0] = b;
|
---|
96 | }
|
---|
97 | else if(a != null && b == null) {
|
---|
98 | c = a;
|
---|
99 | }
|
---|
100 | return c;
|
---|
101 | }
|
---|
102 | /** This method efficently appends one file array onto the end of another.
|
---|
103 | * @param a The initial <strong>File[]</strong>.
|
---|
104 | * @param b The <strong>File[]</strong> to append.
|
---|
105 | * @return A <strong>File[]</strong> containing a followed by b.
|
---|
106 | */
|
---|
107 | static public File[] add(File a[], File b[]) {
|
---|
108 | File[] c = null;
|
---|
109 | if(a != null && b != null) {
|
---|
110 | c = new File[a.length + b.length];
|
---|
111 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
112 | System.arraycopy(b, 0, c, a.length, b.length);
|
---|
113 | }
|
---|
114 | else if(a == null && b != null) {
|
---|
115 | c = b;
|
---|
116 | }
|
---|
117 | else if(a != null && b == null) {
|
---|
118 | c = a;
|
---|
119 | }
|
---|
120 | return c;
|
---|
121 | }
|
---|
122 |
|
---|
123 | /** This method efficiently appends a new FileNode onto the end of a FileNode array.
|
---|
124 | * @param a The initial <strong>FileNode[]</strong>.
|
---|
125 | * @param b The new <strong>FileNode</strong>.
|
---|
126 | * @return An <strong>FileNode[]</strong> containing a followed by b.
|
---|
127 | */
|
---|
128 | static public FileNode[] add(FileNode a[], FileNode b) {
|
---|
129 | FileNode[] c = null;
|
---|
130 | if(a != null && b != null) {
|
---|
131 | c = new FileNode[a.length + 1];
|
---|
132 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
133 | c[c.length - 1] = b;
|
---|
134 | }
|
---|
135 | else if(a == null && b != null) {
|
---|
136 | c = new FileNode[1];
|
---|
137 | c[0] = b;
|
---|
138 | }
|
---|
139 | else if(a != null && b == null) {
|
---|
140 | c = a;
|
---|
141 | }
|
---|
142 | return c;
|
---|
143 | }
|
---|
144 | /** This method efficently appends one FileNode array onto the end of another FileNode array.
|
---|
145 | * @param a The initial <strong>FileNode[]</strong>.
|
---|
146 | * @param b The <strong>FileNode[]</strong> to append.
|
---|
147 | * @return An <strong>FileNode[]</strong> containing a followed by b.
|
---|
148 | */
|
---|
149 | static final public FileNode[] add(FileNode a[], FileNode b[]) {
|
---|
150 | FileNode[] c = null;
|
---|
151 | if(a != null && b != null) {
|
---|
152 | c = new FileNode[a.length + b.length];
|
---|
153 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
154 | System.arraycopy(b, 0, c, a.length, b.length);
|
---|
155 | }
|
---|
156 | else if(a == null && b != null) {
|
---|
157 | c = b;
|
---|
158 | }
|
---|
159 | else if(a != null && b == null) {
|
---|
160 | c = a;
|
---|
161 | }
|
---|
162 | return c;
|
---|
163 | }
|
---|
164 | /** Determine if a certain FileNode is present in an array of FileNodes.
|
---|
165 | * @param array The <strong>FileNode[]</strong>.
|
---|
166 | * @param a The <strong>FileNode</strong> we are searching for.
|
---|
167 | * @return <i>true</i> if the FileNode is in the array, <i>false</i> otherwise.
|
---|
168 | */
|
---|
169 | static final public boolean contains(FileNode array[], FileNode a) {
|
---|
170 | for(int i = 0; i < array.length; i++) {
|
---|
171 | if(array[i].equals(a)) {
|
---|
172 | return true;
|
---|
173 | }
|
---|
174 | }
|
---|
175 | return false;
|
---|
176 | }
|
---|
177 | /** Remove the first element from an array, and return the remaining 'tail'.
|
---|
178 | * @param a A <strong>FileNode[]</strong>.
|
---|
179 | * @return The same <strong>FileNode[]</strong> sans its head element.
|
---|
180 | */
|
---|
181 | static final public FileNode[] tail(FileNode a[]) {
|
---|
182 | if(a.length == 1) {
|
---|
183 | return null;
|
---|
184 | }
|
---|
185 | FileNode b[] = new FileNode[a.length - 1];
|
---|
186 | System.arraycopy(a, 1, b, 0, b.length);
|
---|
187 | return b;
|
---|
188 | }
|
---|
189 |
|
---|
190 | /** Append a Metadata object onto an array of Metadata objects. */
|
---|
191 | static public Metadata[] add(Metadata[] a, Metadata b) {
|
---|
192 | Metadata[] c = null;
|
---|
193 | if(a != null && b != null) {
|
---|
194 | c = new Metadata[a.length + 1];
|
---|
195 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
196 | c[c.length - 1] = b;
|
---|
197 | }
|
---|
198 | else if(a == null && b != null) {
|
---|
199 | c = new Metadata[1];
|
---|
200 | c[0] = b;
|
---|
201 | }
|
---|
202 | else if(a != null && b == null) {
|
---|
203 | c = a;
|
---|
204 | }
|
---|
205 | return c;
|
---|
206 | }
|
---|
207 | /** Append a Metadata object array onto an array of Metadata objects. */
|
---|
208 | static public Metadata[] add(Metadata[] a, Metadata[] b) {
|
---|
209 | Metadata[] c = null;
|
---|
210 | if(a != null && b != null) {
|
---|
211 | c = new Metadata[a.length + b.length];
|
---|
212 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
213 | System.arraycopy(b, 0, c, a.length, b.length);
|
---|
214 | }
|
---|
215 | else if(a == null && b != null) {
|
---|
216 | c = b;
|
---|
217 | }
|
---|
218 | else if(a != null && b == null) {
|
---|
219 | c = a;
|
---|
220 | }
|
---|
221 | return c;
|
---|
222 | }
|
---|
223 | /** Remove the Metadata object at the given index form the specified Metadata object array. */
|
---|
224 | static public Metadata[] remove(Metadata[] a, int index) {
|
---|
225 | Metadata[] c = null;
|
---|
226 | if(a != null) {
|
---|
227 | c = new Metadata[a.length - 1];
|
---|
228 | System.arraycopy(a, 0, c, 0, index);
|
---|
229 | System.arraycopy(a, index + 1, c, index, c.length - index);
|
---|
230 | }
|
---|
231 | return c;
|
---|
232 | }
|
---|
233 |
|
---|
234 | /** This method efficiently appends a new node onto the end of a node array.
|
---|
235 | * @param a The initial <strong>Node[]</strong>.
|
---|
236 | * @param b The new <strong>Node</strong>.
|
---|
237 | * @return A <strong>Node[]</strong> containing a followed by b.
|
---|
238 | */
|
---|
239 | static public Node[] add(Node a[], Node b) {
|
---|
240 | Node[] c = null;
|
---|
241 | if(a != null && b != null) {
|
---|
242 | c = new Node[a.length + 1];
|
---|
243 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
244 | c[c.length - 1] = b;
|
---|
245 | }
|
---|
246 | else if(a == null && b != null) {
|
---|
247 | c = new Node[1];
|
---|
248 | c[0] = b;
|
---|
249 | }
|
---|
250 | else if(a != null && b == null) {
|
---|
251 | c = a;
|
---|
252 | }
|
---|
253 | return c;
|
---|
254 | }
|
---|
255 | /** This method efficently appends one node array onto the end of another.
|
---|
256 | * @param a The initial <strong>Node[]</strong>.
|
---|
257 | * @param b The <strong>Node[]</strong> to append.
|
---|
258 | * @return A <strong>Node[]</strong> containing a followed by b.
|
---|
259 | */
|
---|
260 | static public Node[] add(Node a[], Node b[]) {
|
---|
261 | Node[] c = null;
|
---|
262 | if(a != null && b != null) {
|
---|
263 | c = new Node[a.length + b.length];
|
---|
264 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
265 | System.arraycopy(b, 0, c, a.length, b.length);
|
---|
266 | }
|
---|
267 | else if(a == null && b != null) {
|
---|
268 | c = b;
|
---|
269 | }
|
---|
270 | else if(a != null && b == null) {
|
---|
271 | c = a;
|
---|
272 | }
|
---|
273 | return c;
|
---|
274 | }
|
---|
275 |
|
---|
276 | /** This method efficiently appends a new string onto the end of a string array.
|
---|
277 | * @param a The initial <strong>String[]</strong>.
|
---|
278 | * @param b The new <strong>String</strong>.
|
---|
279 | * @return A <strong>String[]</strong> containing a followed by b.
|
---|
280 | */
|
---|
281 | static public String[] add(String a[], String b) {
|
---|
282 | String[] c = null;
|
---|
283 | if(a != null && b != null) {
|
---|
284 | c = new String[a.length + 1];
|
---|
285 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
286 | c[c.length - 1] = b;
|
---|
287 | }
|
---|
288 | else if(a == null && b != null) {
|
---|
289 | c = new String[1];
|
---|
290 | c[0] = b;
|
---|
291 | }
|
---|
292 | else if(a != null && b == null) {
|
---|
293 | c = a;
|
---|
294 | }
|
---|
295 | return c;
|
---|
296 | }
|
---|
297 | /** This method efficently appends one string array onto the end of another.
|
---|
298 | * @param a The initial <strong>String[]</strong>.
|
---|
299 | * @param b The <strong>String[]</strong> to append.
|
---|
300 | * @return A <strong>String[]</strong> containing a followed by b.
|
---|
301 | */
|
---|
302 | static public String[] add(String a[], String b[]) {
|
---|
303 | String[] c = null;
|
---|
304 | if(a != null && b != null) {
|
---|
305 | c = new String[a.length + b.length];
|
---|
306 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
307 | System.arraycopy(b, 0, c, a.length, b.length);
|
---|
308 | }
|
---|
309 | else if(a == null && b != null) {
|
---|
310 | c = b;
|
---|
311 | }
|
---|
312 | else if(a != null && b == null) {
|
---|
313 | c = a;
|
---|
314 | }
|
---|
315 | return c;
|
---|
316 | }
|
---|
317 | /** This method takes an array list and creates a string array.
|
---|
318 | * @param a An <strong>ArrayList</strong> containing hopefully <strong>String</strong> or else this will fail.
|
---|
319 | * @return A <strong>String[]</strong> or <i>null</i> if the array could not be created.
|
---|
320 | */
|
---|
321 | static public String[] arrayListToStringArray(ArrayList a) {
|
---|
322 | String array[] = new String[a.size()];
|
---|
323 | for(int i = 0; i < array.length; i++) {
|
---|
324 | array[i] = (String)a.get(i);
|
---|
325 | }
|
---|
326 | return array;
|
---|
327 | }
|
---|
328 |
|
---|
329 | static public File[] filter(File[] files, String pattern, boolean exclude) {
|
---|
330 | int write_ptr = 0;
|
---|
331 | ///ystem.err.println("Filtering by '" + pattern + "', Exclude? " + exclude + " :");
|
---|
332 | for(int read_ptr = 0; read_ptr < files.length; read_ptr++) {
|
---|
333 | File current = files[read_ptr];
|
---|
334 | files[write_ptr] = current;
|
---|
335 | ///ystem.err.print("Testing " + current.getName() + " -> ");
|
---|
336 | // Determine whether we move the write pointer or not.
|
---|
337 | if(current.getName().toLowerCase().matches(pattern)) {
|
---|
338 | if(!exclude) {
|
---|
339 | ///ystem.err.println("Match, Exclude.");
|
---|
340 | write_ptr++;
|
---|
341 | }
|
---|
342 | else {
|
---|
343 | ///ystem.err.println("Match, Include.");
|
---|
344 | }
|
---|
345 | }
|
---|
346 | else {
|
---|
347 | // You can't exclude folders with an inclusion filter!
|
---|
348 | if(exclude || current.isDirectory()) {
|
---|
349 | ///ystem.err.println("Nonmatch, Exclude.");
|
---|
350 | write_ptr++;
|
---|
351 | }
|
---|
352 | else {
|
---|
353 | ///ystem.err.println("Nonmatch, Include.");
|
---|
354 | }
|
---|
355 | }
|
---|
356 | }
|
---|
357 | File[] result = new File[write_ptr];
|
---|
358 | System.arraycopy(files, 0, result, 0, result.length);
|
---|
359 | pattern = null;
|
---|
360 | files = null;
|
---|
361 | return result;
|
---|
362 | }
|
---|
363 |
|
---|
364 | /** Method to convert a list of nodes from the DOM model into a node array. This is quite useful as using a <strong>NodeList</strong> is problematic if you wish to traverse the tree while editing. Because they are 'live' representations of the model you are editing, it is easy to drop out of for loops early or run off the ends of arrays.
|
---|
365 | * @param node_list A <strong>NodeList</strong> representing the <strong>Node</strong>s we want to iterate through.
|
---|
366 | * @return A brand new <strong>Node[]</strong> with the first <strong>Node</strong> in the <strong>NodeList</strong> at the head.
|
---|
367 | * @see org.w3c.dom.Node
|
---|
368 | * @see org.w3c.dom.NodeList
|
---|
369 | */
|
---|
370 | static public Node[] nodeListToNodeArray(NodeList node_list) {
|
---|
371 | Node nodes[] = null;
|
---|
372 | for(int i = 0; i < node_list.getLength(); i++) {
|
---|
373 | nodes = add(nodes, node_list.item(i));
|
---|
374 | }
|
---|
375 | return nodes;
|
---|
376 | }
|
---|
377 | /** Transforms an Object array into a single string of the form '[o1,o2,...,on]'.
|
---|
378 | * @param objects An <strong>Object[]</strong>. Note that the objects in this array must support toString() reasonably.
|
---|
379 | * @return A <strong>String</strong> representing the given array.
|
---|
380 | */
|
---|
381 | static public String objectArrayToString(Object objects[]) {
|
---|
382 | StringBuffer result = new StringBuffer("[");
|
---|
383 | for(int i = 0; i < objects.length; i++) {
|
---|
384 | result.append(objects[i].toString());
|
---|
385 | if(i < objects.length - 1) {
|
---|
386 | result.append(",");
|
---|
387 | }
|
---|
388 | }
|
---|
389 | result.append("]");
|
---|
390 | return result.toString();
|
---|
391 | }
|
---|
392 |
|
---|
393 | /** Sorts an array of files. */
|
---|
394 | static public void sort(File[] files) {
|
---|
395 | sort(files, false);
|
---|
396 | }
|
---|
397 |
|
---|
398 | /** Sorts an array of files. Can also to instructed to list directories first. Case insensitive.
|
---|
399 | * @param files The File[] to be sorted.
|
---|
400 | * @param directories_first true if you want to directories to be listed first.
|
---|
401 | */
|
---|
402 | static public void sort(File[] files, boolean directories_first) {
|
---|
403 | if(files != null && files.length > 1) {
|
---|
404 | FileComparator comparator = new FileComparator(directories_first);
|
---|
405 | Arrays.sort(files, comparator);
|
---|
406 | }
|
---|
407 | }
|
---|
408 |
|
---|
409 | /** Comparator used to order files. */
|
---|
410 | static private class FileComparator
|
---|
411 | implements Comparator {
|
---|
412 | private boolean directories_first = false;
|
---|
413 |
|
---|
414 | public FileComparator(boolean directories_first) {
|
---|
415 | this.directories_first = directories_first;
|
---|
416 | }
|
---|
417 | /** Compare two files in terms of ordering of their paths.
|
---|
418 | * @param o1 The <strong>Object</strong> that represents the first file.
|
---|
419 | * @param o2 The other <strong>Object</strong>, also a file.
|
---|
420 | * @return An <i>int</i> which is <1, 0 or >1 if o1 is < o2, = o2 or > o2 respectively.
|
---|
421 | */
|
---|
422 | public int compare(Object o1, Object o2) {
|
---|
423 | int result = 0;
|
---|
424 | File f1 = (File) o1;
|
---|
425 | String n1 = f1.getName().toLowerCase();
|
---|
426 | File f2 = (File) o2;
|
---|
427 | String n2 = f2.getName().toLowerCase();
|
---|
428 | // Special checks for system roots as these include removable media drives and thus we should never attempt to call isDirectory until the user explicitly attempts to map drive.
|
---|
429 | boolean f1_system_root = FileSystemView.getFileSystemView().isFileSystemRoot(f1);
|
---|
430 | boolean f2_system_root = FileSystemView.getFileSystemView().isFileSystemRoot(f2);
|
---|
431 | if((f1_system_root && f2_system_root) || (!f2_system_root && f1_system_root && f2.isDirectory()) || (!f1_system_root && f1.isDirectory() && f2_system_root) || (f1.isDirectory() && f2.isDirectory()) || (f1.isFile() && f2.isFile())) {
|
---|
432 | result = n1.compareTo(n2);
|
---|
433 | }
|
---|
434 | else if(f1_system_root || f1.isDirectory()) {
|
---|
435 | result = -1;
|
---|
436 | }
|
---|
437 | else {
|
---|
438 | result = 1;
|
---|
439 | }
|
---|
440 | return result;
|
---|
441 | }
|
---|
442 | /** Compare two files for equality, in terms of their file paths.
|
---|
443 | * @param object The <strong>Object</strong> representing the file we are about to compare ourselves to.
|
---|
444 | * @return <i>true</i> if we equal the given file, <i>false</i> otherwise.
|
---|
445 | */
|
---|
446 | public boolean equals(Object obj) {
|
---|
447 | return (compare(this, obj) == 0);
|
---|
448 | }
|
---|
449 | }
|
---|
450 | }
|
---|
451 |
|
---|
452 |
|
---|
453 |
|
---|
454 |
|
---|