1 | /* GPL_HEADER */
|
---|
2 | package org.greenstone.gatherer.util;
|
---|
3 |
|
---|
4 | /**************************************************************************************
|
---|
5 | * Title: Gatherer
|
---|
6 | * Description: The Gatherer: a tool for gathering and enriching a digital collection.
|
---|
7 | * Company: The University of Waikato
|
---|
8 | * Written: / /01
|
---|
9 | * Revised: 16/08/02 Improved
|
---|
10 | **************************************************************************************/
|
---|
11 | import java.awt.*;
|
---|
12 | import java.io.*;
|
---|
13 | import java.util.*;
|
---|
14 | import javax.swing.filechooser.*;
|
---|
15 | import org.w3c.dom.*;
|
---|
16 |
|
---|
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 |
|
---|
124 | /** This method efficiently appends a new node onto the end of a node array.
|
---|
125 | * @param a The initial <strong>Node[]</strong>.
|
---|
126 | * @param b The new <strong>Node</strong>.
|
---|
127 | * @return A <strong>Node[]</strong> containing a followed by b.
|
---|
128 | */
|
---|
129 | static public Node[] add(Node a[], Node b) {
|
---|
130 | Node[] c = null;
|
---|
131 | if(a != null && b != null) {
|
---|
132 | c = new Node[a.length + 1];
|
---|
133 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
134 | c[c.length - 1] = b;
|
---|
135 | }
|
---|
136 | else if(a == null && b != null) {
|
---|
137 | c = new Node[1];
|
---|
138 | c[0] = b;
|
---|
139 | }
|
---|
140 | else if(a != null && b == null) {
|
---|
141 | c = a;
|
---|
142 | }
|
---|
143 | return c;
|
---|
144 | }
|
---|
145 | /** This method efficently appends one node array onto the end of another.
|
---|
146 | * @param a The initial <strong>Node[]</strong>.
|
---|
147 | * @param b The <strong>Node[]</strong> to append.
|
---|
148 | * @return A <strong>Node[]</strong> containing a followed by b.
|
---|
149 | */
|
---|
150 | static public Node[] add(Node a[], Node b[]) {
|
---|
151 | Node[] c = null;
|
---|
152 | if(a != null && b != null) {
|
---|
153 | c = new Node[a.length + b.length];
|
---|
154 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
155 | System.arraycopy(b, 0, c, a.length, b.length);
|
---|
156 | }
|
---|
157 | else if(a == null && b != null) {
|
---|
158 | c = b;
|
---|
159 | }
|
---|
160 | else if(a != null && b == null) {
|
---|
161 | c = a;
|
---|
162 | }
|
---|
163 | return c;
|
---|
164 | }
|
---|
165 |
|
---|
166 | /** This method efficiently appends a new string onto the end of a string array.
|
---|
167 | * @param a The initial <strong>String[]</strong>.
|
---|
168 | * @param b The new <strong>String</strong>.
|
---|
169 | * @return A <strong>String[]</strong> containing a followed by b.
|
---|
170 | */
|
---|
171 | static public String[] add(String a[], String b) {
|
---|
172 | String[] c = null;
|
---|
173 | if(a != null && b != null) {
|
---|
174 | c = new String[a.length + 1];
|
---|
175 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
176 | c[c.length - 1] = b;
|
---|
177 | }
|
---|
178 | else if(a == null && b != null) {
|
---|
179 | c = new String[1];
|
---|
180 | c[0] = b;
|
---|
181 | }
|
---|
182 | else if(a != null && b == null) {
|
---|
183 | c = a;
|
---|
184 | }
|
---|
185 | return c;
|
---|
186 | }
|
---|
187 | /** This method efficently appends one string array onto the end of another.
|
---|
188 | * @param a The initial <strong>String[]</strong>.
|
---|
189 | * @param b The <strong>String[]</strong> to append.
|
---|
190 | * @return A <strong>String[]</strong> containing a followed by b.
|
---|
191 | */
|
---|
192 | static public String[] add(String a[], String b[]) {
|
---|
193 | String[] c = null;
|
---|
194 | if(a != null && b != null) {
|
---|
195 | c = new String[a.length + b.length];
|
---|
196 | System.arraycopy(a, 0, c, 0, a.length);
|
---|
197 | System.arraycopy(b, 0, c, a.length, b.length);
|
---|
198 | }
|
---|
199 | else if(a == null && b != null) {
|
---|
200 | c = b;
|
---|
201 | }
|
---|
202 | else if(a != null && b == null) {
|
---|
203 | c = a;
|
---|
204 | }
|
---|
205 | return c;
|
---|
206 | }
|
---|
207 | /** This method takes an array list and creates a string array.
|
---|
208 | * @param a An <strong>ArrayList</strong> containing hopefully <strong>String</strong> or else this will fail.
|
---|
209 | * @return A <strong>String[]</strong> or <i>null</i> if the array could not be created.
|
---|
210 | */
|
---|
211 | static public String[] arrayListToStringArray(ArrayList a) {
|
---|
212 | String array[] = new String[a.size()];
|
---|
213 | for(int i = 0; i < array.length; i++) {
|
---|
214 | array[i] = (String)a.get(i);
|
---|
215 | }
|
---|
216 | return array;
|
---|
217 | }
|
---|
218 |
|
---|
219 | static public File[] filter(File[] files, String pattern, boolean exclude) {
|
---|
220 | int write_ptr = 0;
|
---|
221 | ///ystem.err.println("Filtering by '" + pattern + "', Exclude? " + exclude + " :");
|
---|
222 | for(int read_ptr = 0; read_ptr < files.length; read_ptr++) {
|
---|
223 | File current = files[read_ptr];
|
---|
224 | files[write_ptr] = current;
|
---|
225 | ///ystem.err.print("Testing " + current.getName() + " -> ");
|
---|
226 | // Determine whether we move the write pointer or not.
|
---|
227 | if(current.getName().toLowerCase().matches(pattern)) {
|
---|
228 | if(!exclude) {
|
---|
229 | ///ystem.err.println("Match, Exclude.");
|
---|
230 | write_ptr++;
|
---|
231 | }
|
---|
232 | else {
|
---|
233 | ///ystem.err.println("Match, Include.");
|
---|
234 | }
|
---|
235 | }
|
---|
236 | else {
|
---|
237 | // You can't exclude folders with an inclusion filter!
|
---|
238 | if(exclude || current.isDirectory()) {
|
---|
239 | ///ystem.err.println("Nonmatch, Exclude.");
|
---|
240 | write_ptr++;
|
---|
241 | }
|
---|
242 | else {
|
---|
243 | ///ystem.err.println("Nonmatch, Include.");
|
---|
244 | }
|
---|
245 | }
|
---|
246 | }
|
---|
247 | File[] result = new File[write_ptr];
|
---|
248 | System.arraycopy(files, 0, result, 0, result.length);
|
---|
249 | pattern = null;
|
---|
250 | files = null;
|
---|
251 | return result;
|
---|
252 | }
|
---|
253 |
|
---|
254 | /** 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.
|
---|
255 | * @param node_list A <strong>NodeList</strong> representing the <strong>Node</strong>s we want to iterate through.
|
---|
256 | * @return A brand new <strong>Node[]</strong> with the first <strong>Node</strong> in the <strong>NodeList</strong> at the head.
|
---|
257 | * @see org.w3c.dom.Node
|
---|
258 | * @see org.w3c.dom.NodeList
|
---|
259 | */
|
---|
260 | static public Node[] nodeListToNodeArray(NodeList node_list) {
|
---|
261 | Node nodes[] = null;
|
---|
262 | for(int i = 0; i < node_list.getLength(); i++) {
|
---|
263 | nodes = add(nodes, node_list.item(i));
|
---|
264 | }
|
---|
265 | return nodes;
|
---|
266 | }
|
---|
267 | /** Transforms an Object array into a single string of the form '[o1,o2,...,on]'.
|
---|
268 | * @param objects An <strong>Object[]</strong>. Note that the objects in this array must support toString() reasonably.
|
---|
269 | * @return A <strong>String</strong> representing the given array.
|
---|
270 | */
|
---|
271 | static public String objectArrayToString(Object objects[]) {
|
---|
272 | StringBuffer result = new StringBuffer("[");
|
---|
273 | for(int i = 0; i < objects.length; i++) {
|
---|
274 | result.append(objects[i].toString());
|
---|
275 | if(i < objects.length - 1) {
|
---|
276 | result.append(",");
|
---|
277 | }
|
---|
278 | }
|
---|
279 | result.append("]");
|
---|
280 | return result.toString();
|
---|
281 | }
|
---|
282 |
|
---|
283 |
|
---|
284 | /** Sorts an array of files, putting non-files first. Case insensitive.
|
---|
285 | * @param files_to_sort The File[] to be sorted.
|
---|
286 | */
|
---|
287 | static public void sort(File[] files_to_sort)
|
---|
288 | {
|
---|
289 | // Return if there is nothing to sort
|
---|
290 | if (files_to_sort == null || files_to_sort.length <= 1) {
|
---|
291 | return;
|
---|
292 | }
|
---|
293 |
|
---|
294 | FileSystemView fileSystemView = FileSystemView.getFileSystemView();
|
---|
295 | FileComparator comparator = new FileComparator();
|
---|
296 |
|
---|
297 | // Separate the file system roots and directories from the files, and sort separately
|
---|
298 | ArrayList files_list = new ArrayList((files_to_sort.length * 3) / 4);
|
---|
299 | ArrayList non_files_list = new ArrayList((files_to_sort.length) / 4);
|
---|
300 | for (int i = 0; i < files_to_sort.length; i++) {
|
---|
301 | File file = files_to_sort[i];
|
---|
302 |
|
---|
303 | // File is a system root
|
---|
304 | if (fileSystemView.isFileSystemRoot(file)) {
|
---|
305 | non_files_list.add(file);
|
---|
306 | }
|
---|
307 | // File is a directory
|
---|
308 | else if (file.isDirectory()) {
|
---|
309 | non_files_list.add(file);
|
---|
310 | }
|
---|
311 | // File is an actual file
|
---|
312 | else {
|
---|
313 | files_list.add(file);
|
---|
314 | }
|
---|
315 | }
|
---|
316 |
|
---|
317 | // Sort files
|
---|
318 | Object[] files = files_list.toArray();
|
---|
319 | Arrays.sort(files, comparator);
|
---|
320 |
|
---|
321 | // Sort non-files
|
---|
322 | Object[] non_files = non_files_list.toArray();
|
---|
323 | Arrays.sort(non_files, comparator);
|
---|
324 |
|
---|
325 | // Merge the results, putting non-files before files
|
---|
326 | int j = 0;
|
---|
327 | for (int i = 0; i < non_files.length; i++) {
|
---|
328 | files_to_sort[j++] = (File) non_files[i];
|
---|
329 | }
|
---|
330 | for (int i = 0; i < files.length; i++) {
|
---|
331 | files_to_sort[j++] = (File) files[i];
|
---|
332 | }
|
---|
333 | }
|
---|
334 |
|
---|
335 |
|
---|
336 | /** Comparator used to order files. */
|
---|
337 | static private class FileComparator
|
---|
338 | implements Comparator {
|
---|
339 |
|
---|
340 | /** Compare two files in terms of ordering of their paths.
|
---|
341 | * @param o1 The <strong>Object</strong> that represents the first file.
|
---|
342 | * @param o2 The other <strong>Object</strong>, also a file.
|
---|
343 | * @return An <i>int</i> which is <1, 0 or >1 if o1 is <o2, =o2 or >o2 respectively.
|
---|
344 | */
|
---|
345 | public int compare(Object o1, Object o2)
|
---|
346 | {
|
---|
347 | File f1 = (File) o1;
|
---|
348 | File f2 = (File) o2;
|
---|
349 |
|
---|
350 | return f1.getName().compareToIgnoreCase(f2.getName());
|
---|
351 | }
|
---|
352 | }
|
---|
353 | }
|
---|