Coverage Report - org.webslinger.io.IOUtil
 
Classes in this File Line Coverage Branch Coverage Complexity
IOUtil
51%
143/280
66%
29/44
0
IOUtil$1
10%
1/10
0%
0/1
0
IOUtil$2
14%
1/7
0%
0/1
0
IOUtil$NameFilter
0%
0/35
0%
0/10
0
 
 1  
 package org.webslinger.io;
 2  
 
 3  
 import java.io.BufferedReader;
 4  
 import java.io.ByteArrayInputStream;
 5  
 import java.io.ByteArrayOutputStream;
 6  
 import java.io.CharArrayReader;
 7  
 import java.io.File;
 8  
 import java.io.FileInputStream;
 9  
 import java.io.FilenameFilter;
 10  
 import java.io.FileNotFoundException;
 11  
 import java.io.FileOutputStream;
 12  
 import java.io.InputStream;
 13  
 import java.io.InputStreamReader;
 14  
 import java.io.IOException;
 15  
 import java.io.ObjectInputStream;
 16  
 import java.io.ObjectOutputStream;
 17  
 import java.io.OutputStream;
 18  
 import java.io.OutputStreamWriter;
 19  
 import java.io.PrintWriter;
 20  
 import java.io.Reader;
 21  
 import java.io.Serializable;
 22  
 import java.io.StringReader;
 23  
 import java.io.StringWriter;
 24  
 import java.io.Writer;
 25  
 import java.nio.charset.Charset;
 26  
 import java.nio.charset.CharsetDecoder;
 27  
 import java.nio.charset.CharsetEncoder;
 28  
 import java.nio.charset.CoderResult;
 29  
 import java.nio.charset.CodingErrorAction;
 30  
 import java.nio.CharBuffer;
 31  
 import java.nio.ByteBuffer;
 32  
 import java.nio.channels.Channels;
 33  
 import java.nio.channels.ReadableByteChannel;
 34  
 import java.util.Collection;
 35  
 import java.util.HashSet;
 36  
 import java.util.Iterator;
 37  
 import java.util.LinkedList;
 38  
 import java.util.List;
 39  
 import java.util.Set;
 40  
 import java.util.regex.Matcher;
 41  
 import java.util.regex.Pattern;
 42  
 
 43  
 import org.apache.commons.collections.CollectionUtils;
 44  
 import org.apache.commons.io.IOUtils;
 45  
 import org.apache.commons.io.output.NullOutputStream;
 46  
 import org.apache.commons.lang.StringUtils;
 47  
 
 48  
 import org.webslinger.collections.CollectionUtil;
 49  
 import org.webslinger.resolver.ObjectCreator;
 50  
 import org.webslinger.resolver.ObjectLoader;
 51  
 import org.webslinger.resolver.ObjectResolver;
 52  
 import org.webslinger.resolver.ObjectWalker;
 53  
 import org.webslinger.json.JSON;
 54  
 import org.webslinger.json.JSONWriter;
 55  
 
 56  0
 public final class IOUtil {
 57  1
     public static final ObjectWalker walker = new ObjectWalker();
 58  1
     public static final ObjectLoader loader = new ObjectLoader();
 59  
 
 60  
     public static void touch(String name) {
 61  0
         touch(new File(name), System.currentTimeMillis());
 62  0
     }
 63  
 
 64  
     public static void touch(String name, long time) {
 65  0
         touch(new File(name), time);
 66  0
     }
 67  
 
 68  
     public static void touch(File file) {
 69  18
         touch(file, System.currentTimeMillis());
 70  18
     }
 71  
 
 72  
     public static void touch(File file, long time) {
 73  22
         if (!file.exists()) {
 74  
             try {
 75  18
                 file.getParentFile().mkdirs();
 76  18
                 FileOutputStream out = getOutputStream(file);
 77  18
                 out.close();
 78  0
             } catch (Exception e) {
 79  18
             }
 80  
         }
 81  22
         file.setLastModified(time);
 82  22
     }
 83  
 
 84  
     public static boolean cmp(String left, String right) throws IOException {
 85  0
         return cmp(new File(left), new File(right));
 86  
     }
 87  
 
 88  
     public static boolean cmp(File left, File right) throws IOException {
 89  0
         return cmp(new FileInputStream(left), new FileInputStream(right));
 90  
     }
 91  
 
 92  
     public static boolean cmp(InputStream left, InputStream right) throws IOException {
 93  
         try {
 94  1
             return IOUtils.contentEquals(left, right);
 95  
         } finally {
 96  1
             IOUtils.closeQuietly(right);
 97  1
             IOUtils.closeQuietly(left);
 98  
         }
 99  
 
 100  
     }
 101  
 
 102  
     public static void dump(InputStream in) throws IOException {
 103  0
         copy(in, false, new NullOutputStream(), true);
 104  0
     }
 105  
 
 106  
     public static void dump(InputStream in, boolean closeIn) throws IOException {
 107  0
         copy(in, closeIn, new NullOutputStream(), true);
 108  0
     }
 109  
 
 110  
     public static void copy(InputStream in, File file) throws IOException {
 111  0
         copy(in, false, file);
 112  0
     }
 113  
 
 114  
     public static void copy(InputStream in, boolean closeIn, File file) throws IOException {
 115  0
         copy(in, closeIn, getOutputStream(file), true);
 116  0
     }
 117  
 
 118  
     public static void copy(File file, OutputStream out) throws IOException {
 119  0
         copy(file, out, false);
 120  0
     }
 121  
 
 122  
     public static void copy(File file, OutputStream out, boolean closeOut) throws IOException {
 123  0
         copy(getInputStream(file), true, out, closeOut);
 124  0
     }
 125  
 
 126  
     public static void copy(InputStream in, OutputStream out) throws IOException {
 127  910
         copy(in, false, out, false);
 128  910
     }
 129  
 
 130  
     public static void copy(InputStream in, boolean closeIn, OutputStream out, boolean closeOut) throws IOException {
 131  
         try {
 132  
             try {
 133  1021
                 IOUtils.copy(in, out);
 134  
             } finally {
 135  1021
                 if (closeIn) in.close();
 136  
             }
 137  
         } finally {
 138  1021
             if (closeOut) out.close();
 139  
         }
 140  1021
     }
 141  
 
 142  
     public static long copy(InputStream in, boolean closeIn, OutputStream out, boolean closeOut, long count) throws IOException {
 143  
         try {
 144  0
             byte[] buf = new byte[4096];
 145  0
             long totalRead = 0;
 146  0
             while (count > 0) {
 147  0
                 int amountRead = in.read(buf);
 148  0
                 if (amountRead == -1) break;
 149  0
                 out.write(buf, 0, amountRead);
 150  0
                 totalRead += amountRead;
 151  0
                 count -= amountRead;
 152  0
             }
 153  0
             return totalRead;
 154  
         } finally {
 155  0
             if (closeIn) in.close();
 156  0
             if (closeOut) out.close();
 157  
         }
 158  
     }
 159  
 
 160  
     public static void copy(Reader reader, File file, String encoding) throws IOException {
 161  0
         copy(reader, false, file, encoding);
 162  0
     }
 163  
 
 164  
     public static void copy(Reader reader, boolean closeIn, File file, String encoding) throws IOException {
 165  0
         copy(reader, closeIn, new OutputStreamWriter(getOutputStream(file), encoding), true);
 166  0
     }
 167  
 
 168  
     public static void copy(File file, String encoding, Writer writer) throws IOException {
 169  0
          copy(file, encoding, writer, false);
 170  0
     }
 171  
 
 172  
     public static void copy(File file, String encoding, Writer writer, boolean closeOut) throws IOException {
 173  0
          copy(new InputStreamReader(getInputStream(file), encoding), true, writer, closeOut);
 174  0
     }
 175  
 
 176  
     public static void copy(Reader reader, Writer writer) throws IOException {
 177  0
         copy(reader, false, writer, false);
 178  0
     }
 179  
 
 180  
     public static void copy(Reader reader, boolean closeIn, Writer writer, boolean closeOut) throws IOException {
 181  
         try {
 182  
             try {
 183  0
                 IOUtils.copy(reader, writer);
 184  
             } finally {
 185  0
                 if (closeIn) IOUtils.closeQuietly(reader);
 186  
             }
 187  
         } finally {
 188  0
             if (closeOut) IOUtils.closeQuietly(writer);
 189  
         }
 190  0
     }
 191  
 
 192  
     public static void copy(File from, File to) throws IOException {
 193  160
         copy(from, to, null);
 194  160
     }
 195  
 
 196  
     public static void copy(File from, File to, FilenameFilter filter) throws IOException {
 197  161
         if (!from.exists()) throw new FileNotFoundException("Source(" + from + ") does not exist");
 198  161
         if (from.isDirectory()) {
 199  91
             if (to.exists()) {
 200  0
                 if (!to.isDirectory()) throw new IOException("Source(" + from + ") is directory while target(" + to + ") is not");
 201  
             } else {
 202  91
                 if (!to.mkdirs()) throw new IOException("Couldn't make target directory(" + to + ")");
 203  
             }
 204  91
             File[] files = from.listFiles(filter);
 205  91
             if (files == null) return;
 206  251
             for (File file: files) {
 207  160
                 copy(file, new File(to, file.getName()));
 208  
             }
 209  91
         } else {
 210  70
             if (to.isDirectory()) to = new File(to, from.getName());
 211  70
             copy(getInputStream(from), getOutputStream(to));
 212  
         }
 213  161
     }
 214  
 
 215  
     public static boolean rename(File from, File to) throws IOException {
 216  0
         if (from.renameTo(to)) return true;
 217  0
         copy(getInputStream(from), getOutputStream(to));
 218  0
         if (delete(from)) return true;
 219  0
         return false;
 220  
     }
 221  
 
 222  
     public static boolean delete(File file) {
 223  272
         if (!file.exists()) return true;
 224  271
         if (!file.delete() && !file.isDirectory()) return false;
 225  271
         File[] files = file.listFiles();
 226  
         // if null, then the delete above should have succeeded.
 227  271
         if (files == null) return false;
 228  333
         for (File f: files) {
 229  253
             delete(f);
 230  
         }
 231  80
         return file.delete();
 232  
     }
 233  
 
 234  
     public static String readStringFromFile(String file, String encoding) throws IOException {
 235  0
         return readStringFromFile(new File(file), encoding);
 236  
     }
 237  
 
 238  
     public static void writeStringToFile(String file, String encoding, String value) throws IOException {
 239  0
         writeStringToFile(new File(file), encoding, value);
 240  0
     }
 241  
 
 242  
     public static String readStringFromFile(String file) throws IOException {
 243  0
         return readStringFromFile(file, Charsets.UTF8);
 244  
     }
 245  
 
 246  
     public static String readStringFromFile(String file, Charset encoding) throws IOException {
 247  0
         return readStringFromFile(new File(file), encoding);
 248  
     }
 249  
 
 250  
     public static void writeStringToFile(String file, String value) throws IOException {
 251  0
         writeStringToFile(file, Charsets.UTF8, value);
 252  0
     }
 253  
 
 254  
     public static void writeStringToFile(String file, Charset charset, String value) throws IOException {
 255  0
         writeStringToFile(new File(file), charset, value);
 256  0
     }
 257  
 
 258  
     public static String readString(File file, String encoding) throws IOException {
 259  0
         return readStringFromFile(file, encoding);
 260  
     }
 261  
 
 262  
     public static String readStringFromFile(File file, String encoding) throws IOException {
 263  0
         return readString(getInputStream(file), encoding);
 264  
     }
 265  
 
 266  
     public static void writeString(File file, String encoding, String value) throws IOException {
 267  0
         writeStringToFile(file, encoding, value);
 268  0
     }
 269  
 
 270  
     public static void writeStringToFile(File file, String encoding, String value) throws IOException {
 271  0
         file.getParentFile().mkdirs();
 272  0
         writeString(getOutputStream(file), encoding, value);
 273  0
     }
 274  
 
 275  
     public static String readString(File file) throws IOException {
 276  0
         return readStringFromFile(file);
 277  
     }
 278  
 
 279  
     public static String readStringFromFile(File file) throws IOException {
 280  14
         return readStringFromFile(file, Charsets.UTF8);
 281  
     }
 282  
 
 283  
     public static String readString(File file, Charset encoding) throws IOException {
 284  0
         return readStringFromFile(file, encoding);
 285  
     }
 286  
 
 287  
     public static String readStringFromFile(File file, Charset encoding) throws IOException {
 288  14
         return readString(getInputStream(file), encoding);
 289  
     }
 290  
 
 291  
     public static void writeString(File file, String value) throws IOException {
 292  53
         writeStringToFile(file, value);
 293  53
     }
 294  
 
 295  
     public static void writeStringToFile(File file, String value) throws IOException {
 296  75
         writeStringToFile(file, Charsets.UTF8, value);
 297  75
     }
 298  
 
 299  
     public static void writeString(File file, Charset charset, String value) throws IOException {
 300  0
         writeStringToFile(file, charset, value);
 301  0
     }
 302  
 
 303  
     public static void writeStringToFile(File file, Charset charset, String value) throws IOException {
 304  75
         file.getParentFile().mkdirs();
 305  75
         writeString(getOutputStream(file), charset, value);
 306  75
     }
 307  
 
 308  
     public static String readString(InputStream in) throws IOException {
 309  138
         return readString(in, Charsets.UTF8);
 310  
     }
 311  
 
 312  
     public static String readString(InputStream in, String encoding) throws IOException {
 313  11
         return readString(in, Charset.forName(encoding));
 314  
     }
 315  
 
 316  
     public static void writeString(OutputStream out, String encoding, String value) throws IOException {
 317  0
         writeString(out, Charset.forName(encoding), value);
 318  0
     }
 319  
 
 320  
     public static String readString(InputStream in, Charset encoding) throws IOException {
 321  
         try {
 322  521
             ByteBuffer buf = ByteBuffer.allocate(4096);
 323  521
             CharBuffer cbuf = CharBuffer.allocate(4096);
 324  521
             ReadableByteChannel channel = Channels.newChannel(in);
 325  521
             StringBuilder sb = new StringBuilder();
 326  521
             CharsetDecoder decoder = encoding.newDecoder().onMalformedInput(CodingErrorAction.REPORT);
 327  
             int r;
 328  1056
             while ((r = channel.read(buf)) != -1) {
 329  535
                 buf.flip();
 330  535
                 CoderResult result = decoder.decode(buf, cbuf, false);
 331  535
                 if (result.isError()) result.throwException();
 332  535
                 cbuf.flip();
 333  535
                 sb.append(cbuf);
 334  535
                 buf.clear();
 335  535
                 cbuf.clear();
 336  535
             }
 337  521
             CoderResult result = decoder.decode(buf, cbuf, true);
 338  521
             if (result.isError()) result.throwException();
 339  520
             sb.append(cbuf);
 340  520
             return sb.toString();
 341  
         } finally {
 342  520
             IOUtils.closeQuietly(in);
 343  
         }
 344  
     }
 345  
 
 346  
     public static void writeString(OutputStream out, String value) throws IOException {
 347  42
         writeString(out, Charsets.UTF8, value);
 348  42
     }
 349  
 
 350  
     public static void writeString(OutputStream out, Charset charset, String value) throws IOException {
 351  
         try {
 352  151
             ByteBuffer buf = charset.encode(CharBuffer.wrap(value));
 353  151
             Channels.newChannel(out).write(buf);
 354  
         } finally {
 355  151
             IOUtils.closeQuietly(out);
 356  151
         }
 357  151
     }
 358  
 
 359  
     public static String readString(byte[] bytes) throws IOException {
 360  840
         return readString(bytes, Charsets.UTF8);
 361  
     }
 362  
 
 363  
     public static String readString(byte[] bytes, String encoding) throws IOException {
 364  0
         return readString(bytes, Charset.forName(encoding));
 365  
     }
 366  
 
 367  
     public static String readString(byte[] bytes, int offset, int length) throws IOException {
 368  0
         return readString(bytes, offset, length, Charsets.UTF8);
 369  
     }
 370  
 
 371  
     public static String readString(byte[] bytes, int offset, int length, String encoding) throws IOException {
 372  0
         return readString(bytes, offset, length, Charset.forName(encoding));
 373  
     }
 374  
 
 375  
     public static String readString(byte[] bytes, Charset charset) throws IOException {
 376  840
         return readString(bytes, 0, bytes.length, charset);
 377  
     }
 378  
 
 379  
     public static String readString(byte[] bytes, int offset, int length, Charset charset) throws IOException {
 380  840
         ByteBuffer buf = ByteBuffer.allocate(length);
 381  840
         buf.put(bytes, offset, length);
 382  840
         buf.flip();
 383  840
         CharBuffer cbuf = charset.decode(buf);
 384  840
         return cbuf.toString();
 385  
     }
 386  
 
 387  
     public static byte[] getBytes(String value) throws IOException {
 388  5
         return getBytes(value, Charsets.UTF8);
 389  
     }
 390  
 
 391  
     public static byte[] getBytes(String value, String encoding) throws IOException {
 392  0
         return getBytes(value, Charset.forName(encoding));
 393  
     }
 394  
 
 395  
     public static byte[] getBytes(String value, Charset charset) throws IOException {
 396  5
         ByteBuffer bb = charset.encode(value);
 397  5
         byte[] bytes = new byte[bb.limit()];
 398  5
         bb.get(bytes);
 399  5
         return bytes;
 400  
     }
 401  
 
 402  
     public static Object readObjectFromFile(String file) throws ClassNotFoundException, IOException {
 403  0
         return readObjectFromFile(new File(file));
 404  
     }
 405  
 
 406  
     public static Object readObjectFromFile(File file) throws ClassNotFoundException, IOException {
 407  0
         return readObject(getInputStream(file));
 408  
     }
 409  
 
 410  
     public static void writeObjectToFile(String file, Object value) throws IOException {
 411  0
         writeObjectToFile(new File(file), value);
 412  0
     }
 413  
 
 414  
     public static void writeObjectToFile(File file, Object value) throws IOException {
 415  0
         file.getParentFile().mkdirs();
 416  0
         writeObject(getOutputStream(file), value);
 417  0
     }
 418  
 
 419  
     private static ClassLoader getClassLoader() {
 420  839
         ClassLoader loader = Thread.currentThread().getContextClassLoader();
 421  839
         if (loader != null) return loader;
 422  0
         return IOUtil.class.getClassLoader();
 423  
     }
 424  
 
 425  
     public static Object readObject(InputStream in) throws ClassNotFoundException, IOException {
 426  839
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 427  839
         copy(in, baos);
 428  839
         in.close();
 429  839
         byte[] bytes = baos.toByteArray();
 430  
         try {
 431  839
             char[] buffer = StringUtils.chomp(readString(bytes)).toCharArray();
 432  
             int i;
 433  839
             for (i = 0; i < buffer.length && buffer[i] != ':'; i++);
 434  839
             if (i > 0 && i < buffer.length) {
 435  839
                 String className = new String(buffer, 0, i);
 436  839
                 Class type = getClassLoader().loadClass(className);
 437  838
                 return walker.getObject(type, buffer, i + 1, buffer.length - i - 1);
 438  
             }
 439  1
         } catch (Exception e) {
 440  0
         }
 441  
         try {
 442  1
             return new JSON(new ByteArrayInputStream(bytes)).JSONValue();
 443  0
         } catch (Exception e) {
 444  
         }
 445  0
         ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(bytes));
 446  0
         Serializable value = (Serializable) oin.readObject();
 447  0
         oin.close();
 448  0
         return value;
 449  
     }
 450  
 
 451  
     public static Object readObject(String name, InputStream in) throws IOException {
 452  1
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 453  1
         copy(in, baos);
 454  1
         in.close();
 455  1
         byte[] bytes = baos.toByteArray();
 456  1
         char[] buffer = StringUtils.chomp(readString(bytes)).toCharArray();
 457  
         try {
 458  1
             ObjectCreator<?> creator = loader.getCreator(name);
 459  1
             if (creator != null) return creator.newObject(null, buffer, 0, buffer.length);
 460  1
             return walker.getObject(name, buffer, 0, buffer.length);
 461  0
         } catch (IOException e) {
 462  0
             throw e;
 463  0
         } catch (RuntimeException e) {
 464  0
             throw e;
 465  0
         } catch (Exception e) {
 466  0
             throw (IOException) new IOException(e.getMessage()).initCause(e);
 467  
         }
 468  
     }
 469  
 
 470  
     public static void writeObject(OutputStream out, Object value) throws IOException {
 471  
         try {
 472  58
             ObjectResolver resolver = walker.getResolver(value.getClass());
 473  58
             if (resolver != null) {
 474  58
                 Class clz = resolver.primaryClass();
 475  58
                 char[] chars = resolver.getChars(value);
 476  58
                 if (chars != null) {
 477  57
                     if (clz == null) clz = value.getClass();
 478  57
                     PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, Charsets.UTF8));
 479  57
                     writer.write(clz.getName());
 480  57
                     writer.write(':');
 481  57
                     writer.write(chars);
 482  57
                     writer.println();
 483  57
                     writer.close();
 484  57
                     return;
 485  
                 }
 486  
             }
 487  1
             StringWriter writer = new StringWriter();
 488  1
             IndentingWriter indenting = new IndentingWriter(writer, true, false);
 489  1
             new JSONWriter(indenting).write(value);
 490  1
             writer.write('\n');
 491  1
             out.write(writer.toString().getBytes("UTF-8"));
 492  1
             return;
 493  0
         } catch (Exception e) {
 494  
         }
 495  0
         ObjectOutputStream oout = new ObjectOutputStream(out);
 496  0
         oout.writeObject(value);
 497  0
         oout.close();
 498  0
         out.close();
 499  0
     }
 500  
 
 501  
     public static void writeObject(OutputStream out, String name, Object value) throws IOException {
 502  0
         writeObject(out, Charsets.UTF8, name, value);
 503  0
     }
 504  
 
 505  
     public static void writeObject(OutputStream out, Charset charset, String name, Object value) throws IOException {
 506  
         try {
 507  0
             writeString(out, charset, new String(loader.getChars(name, value)));
 508  0
         } catch (IOException e) {
 509  0
             throw e;
 510  0
         } catch (RuntimeException e) {
 511  0
             throw e;
 512  0
         } catch (Exception e) {
 513  0
             throw (IOException) new IOException(e.getMessage()).initCause(e);
 514  0
         }
 515  0
     }
 516  
 
 517  
     public static InputStream getInputStream(String value) throws IOException {
 518  1
         return new ByteArrayInputStream(getBytes(value));
 519  
     }
 520  
 
 521  
     public static InputStream getInputStream(String value, String encoding) throws IOException {
 522  0
         return new ByteArrayInputStream(getBytes(value, encoding));
 523  
     }
 524  
 
 525  
     public static InputStream getInputStream(String value, Charset charset) throws IOException {
 526  0
         return new ByteArrayInputStream(getBytes(value, charset));
 527  
     }
 528  
 
 529  
     public static FileInputStream getInputStream(File file) throws IOException {
 530  84
         if (file == null) return null;
 531  84
         return new FileInputStream(file);
 532  
     }
 533  
 
 534  
     public static FileOutputStream getOutputStream(File file) throws IOException {
 535  163
         if (file == null) return null;
 536  163
         if (!file.exists()) file.getParentFile().mkdirs();
 537  163
         return new FileOutputStream(file);
 538  
     }
 539  
 
 540  
     public static File getFile(File base, List names) {
 541  0
         if (names.isEmpty()) return base;
 542  0
         return new File(base, StringUtils.join(names, File.separator));
 543  
     }
 544  
 
 545  
     public static final String quoteName(String name) {
 546  0
         return QuoteConvertor.convertString(name);
 547  
     }
 548  
 
 549  
     public static final Collection quoteNames(Collection names) {
 550  0
         return CollectionUtils.collect(names, QuoteConvertor);
 551  
     }
 552  
 
 553  
     public static final Collection quoteNames(Iterator names) {
 554  0
         return CollectionUtils.collect(names, QuoteConvertor);
 555  
     }
 556  
 
 557  
     public static final <T> T checkException(Throwable t) throws IOException {
 558  5
         if (t instanceof IOException) throw (IOException) t;
 559  1
         if (t instanceof RuntimeException) throw (RuntimeException) t;
 560  0
         if (t instanceof Error) throw (Error) t;
 561  0
         throw (IOException) new IOException(t.getMessage()).initCause(t);
 562  
     }
 563  
 
 564  
     public static final String unquoteName(String name) {
 565  0
         return UnquoteConvertor.convertString(name);
 566  
     }
 567  
 
 568  
     public static final String slashToNative(String name) {
 569  0
         String[] parts = name.split("/");
 570  0
         StringBuilder sb = new StringBuilder(name.length() + parts.length * (File.separator.length() - 1));
 571  0
         for (int i = 0; i < parts.length; i++) {
 572  0
             if (i != 0) sb.append(File.separator);
 573  0
             sb.append(parts[i]);
 574  
         }
 575  0
         return sb.toString();
 576  
     }
 577  
 
 578  
     public static final String nativeToSlash(String name) {
 579  0
         String[] parts = name.split(File.separator);
 580  0
         StringBuilder sb = new StringBuilder(name.length() - parts.length * (File.separator.length() - 1));
 581  0
         for (int i = 0; i < parts.length; i++) {
 582  0
             if (i != 0) sb.append('/');
 583  0
             sb.append(parts[i]);
 584  
         }
 585  0
         return sb.toString();
 586  
     }
 587  
 
 588  
     // FIXME: get list from Robert's email
 589  1
     public static final Pattern nameBadChars = Pattern.compile("[/\"\\\\:]");
 590  1
     public static final CollectionUtil.StringConvertor QuoteConvertor = new CollectionUtil.StringConvertor() {
 591  
         public String convertString(String string) {
 592  0
             StringBuffer sb = new StringBuffer(string.length());
 593  0
             Matcher matcher = nameBadChars.matcher(string);
 594  0
             while (matcher.find()) {
 595  0
                 int c = matcher.group(0).charAt(0);
 596  0
                 matcher.appendReplacement(sb, "");
 597  0
                 sb.append("%{").append((int) c).append('}');
 598  0
             }
 599  0
             matcher.appendTail(sb);
 600  0
             return sb.toString();
 601  
         }
 602  
     };
 603  
 
 604  1
     public static final Pattern nameQuoted = Pattern.compile("%\\{(\\d+)\\}");
 605  1
     public static final CollectionUtil.StringConvertor UnquoteConvertor = new CollectionUtil.StringConvertor() {
 606  
         public String convertString(String string) {
 607  0
             StringBuffer sb = new StringBuffer(string.length());
 608  0
             Matcher matcher = nameQuoted.matcher(string);
 609  0
             while (matcher.find()) {
 610  0
                 matcher.appendReplacement(sb, Character.toString((char) Integer.parseInt(matcher.group(1))));
 611  
             }
 612  0
             matcher.appendTail(sb);
 613  0
             return sb.toString();
 614  
         }
 615  
     };
 616  
 
 617  0
     public static class NameFilter implements FilenameFilter {
 618  0
         protected Set<Pattern> includePatterns = new HashSet<Pattern>();
 619  0
         protected Set<Pattern> excludePatterns = new HashSet<Pattern>();
 620  
         protected Pattern includePattern;
 621  
         protected Pattern excludePattern;
 622  
         protected boolean def;
 623  
 
 624  0
         public NameFilter(boolean def) {
 625  0
             this.def = def;
 626  0
         }
 627  
 
 628  
         public void addName(String name, boolean mode) {
 629  0
             addPattern(Pattern.compile("^\\Q" + name + "\\E$"), mode);
 630  0
         }
 631  
 
 632  
         public void addPattern(Pattern pattern, boolean mode) {
 633  0
             if (mode) {
 634  0
                 includePatterns.add(pattern);
 635  0
                 includePattern = null;
 636  
             } else {
 637  0
                 excludePatterns.add(pattern);
 638  0
                 excludePattern = null;
 639  
             }
 640  0
         }
 641  
 
 642  
         public Pattern getIncludePattern() {
 643  0
             if (includePattern != null) return includePattern;
 644  0
             includePattern = makePattern(includePatterns);
 645  
 //System.err.println("include:" + includePattern.pattern());
 646  0
             return includePattern;
 647  
         }
 648  
 
 649  
         public Pattern getExcludePattern() {
 650  0
             if (excludePattern != null) return excludePattern;
 651  0
             excludePattern = makePattern(excludePatterns);
 652  
 //System.err.println("exclude:" + excludePattern.pattern());
 653  0
             return excludePattern;
 654  
         }
 655  
 
 656  
         protected Pattern makePattern(Set patterns) {
 657  0
             StringBuilder sb = new StringBuilder();
 658  0
             Iterator it = patterns.iterator();
 659  0
             while (it.hasNext()) {
 660  0
                 Pattern pattern = (Pattern) it.next();
 661  0
                 sb.append(pattern.pattern());
 662  0
                 if (it.hasNext()) sb.append('|');
 663  0
             }
 664  0
             return Pattern.compile(sb.toString());
 665  
         }
 666  
 
 667  
         public boolean accept(File dir, String name) {
 668  0
             Pattern includePattern = getIncludePattern();
 669  0
             Pattern excludePattern = getExcludePattern();
 670  0
             if (def) {
 671  0
                 if (includePattern.matcher(name).matches()) return true;
 672  0
                 if (excludePattern.matcher(name).matches()) return false;
 673  
             } else {
 674  0
                 if (excludePattern.matcher(name).matches()) return true;
 675  0
                 if (includePattern.matcher(name).matches()) return false;
 676  
             }
 677  0
             return true;
 678  
         }
 679  
     }
 680  
 }
 681