1 10 package org.mmbase.util; 11 12 import java.io.*; 14 import java.util.*; 15 import java.util.regex.Pattern ; 16 import java.net.*; 17 18 import javax.servlet.ServletContext ; 20 import javax.servlet.http.HttpServletRequest ; 21 22 23 import org.mmbase.bridge.*; 25 import org.mmbase.bridge.util.Queries; 26 import org.mmbase.storage.search.implementation.*; 27 import org.mmbase.storage.search.*; 28 29 import org.w3c.dom.Document ; 31 import org.w3c.dom.DocumentType ; 32 import org.xml.sax.InputSource ; 33 import javax.xml.transform.*; 34 import javax.xml.transform.Transformer ; 35 import javax.xml.parsers.DocumentBuilder ; 36 import javax.xml.transform.stream.StreamResult ; 37 import javax.xml.transform.dom.DOMSource ; 38 39 import org.mmbase.util.transformers.*; 41 42 import org.mmbase.util.logging.Logger; 43 import org.mmbase.util.logging.Logging; 44 45 46 102 public class ResourceLoader extends ClassLoader { 103 104 private static final Logger log = Logging.getLoggerInstance(ResourceLoader.class); 105 106 109 protected static final String PROTOCOL = "mm"; 110 111 114 protected static final String RESOURCE_ROOT = "/WEB-INF/config"; 115 116 119 protected static final String CLASSLOADER_ROOT = "/org/mmbase/config"; 120 121 124 public static final URL NODE_URL_CONTEXT; 125 126 static { 127 URL temp = null; 128 try { 129 temp = new URL("http", "localhost", "/node/"); 130 } catch (MalformedURLException mfue) { 131 assert false : mfue; 132 } 133 NODE_URL_CONTEXT = temp; 134 } 135 136 137 140 protected static final String INDEX = "INDEX"; 141 142 private static ResourceLoader configRoot = null; 143 private static ResourceLoader webRoot = null; 144 private static ResourceLoader systemRoot = null; 145 private static ServletContext servletContext = null; 146 147 148 149 public static final String RESOURCENAME_FIELD = "name"; 151 public static final String TYPE_FIELD = "type"; 152 public static final String FILENAME_FIELD = "filename"; 153 public static final String HANDLE_FIELD = "handle"; 154 public static final String LASTMODIFIED_FIELD = "lastmodified"; 155 public static final String DEFAULT_CONTEXT = "admin"; 156 157 public static final int TYPE_CONFIG = 0; 158 public static final int TYPE_WEB = 1; 159 160 161 162 static NodeManager resourceBuilder = null; 164 165 166 169 170 private final MMURLStreamHandler mmStreamHandler = new MMURLStreamHandler(); 171 172 181 protected URL newURL(final String url) throws MalformedURLException { 182 try { 184 return new URL (url); 185 } catch (MalformedURLException ignore) { 186 } 188 189 final int firstColon = url.indexOf (':'); 190 if (firstColon <= 0) { 191 if (new File(url).exists()) return new URL("file:" + url); throw new MalformedURLException ("No protocol specified: " + url); 193 } else { 194 195 final String protocol = url.substring (0, firstColon); 196 if (protocol.equals(PROTOCOL)) { 197 return new URL (null, url, mmStreamHandler); 198 } else { 199 if (new File(url).exists()) return new URL("file:" + url); 200 throw new MalformedURLException ("Unknown protocol: " + protocol); 201 } 202 } 203 } 204 205 206 private List roots; 207 208 209 static { 210 init(null); 212 } 213 214 215 216 220 public static synchronized void init(ServletContext sc) { 221 servletContext = sc; 222 configRoot = null; 224 webRoot = null; 225 } 226 227 234 public static void setResourceBuilder(NodeManager b) { 235 if (ResourceWatcher.resourceWatchers == null) { 236 throw new RuntimeException ("A resource builder was set already: " + resourceBuilder); 237 } 238 resourceBuilder = b; 239 ResourceWatcher.setResourceBuilder(); log.info("The resources builder '" + b.getName() + "' is available. (user: " + b.getCloud().getUser() + ")"); 242 } 243 244 245 249 public static String getName(String path) { 250 if (path == null){ 252 return null; 253 } 254 int i = path.lastIndexOf('/'); 255 path = path.substring(i + 1); 256 257 i = path.lastIndexOf('.'); 258 if (i > 0) { 259 path = path.substring(0, i); 260 } 261 return path; 262 } 263 264 268 public static String getDirectory(String path) { 269 if (path == null){ 271 return null; 272 } 273 int i = path.lastIndexOf('/'); 274 if (i > 0) { 275 path = path.substring(0, i); 276 } else { 277 path = ""; 278 } 279 return path; 280 } 281 282 287 public static String getDirectoryName(String path) { 288 if (path == null){ 289 return null; 290 } 291 if (path.length() > 0 && path.charAt(path.length() - 1) == '/') path = path.substring(0, path.length() - 1); 292 String dir = getDirectory(path); 293 int i = path.lastIndexOf('/'); 294 path = path.substring(i + 1); 295 if (path.length() > 0 && path.charAt(0) == '/') path = path.substring(1); 296 return path; 297 } 298 299 302 public static synchronized ResourceLoader getConfigurationRoot() { 303 if (configRoot == null) { 304 305 configRoot = new ResourceLoader(); 306 307 configRoot.roots.add(configRoot.new NodeURLStreamHandler(TYPE_CONFIG)); 309 310 String configPath = null; 312 if (servletContext != null) { 313 configPath = servletContext.getInitParameter("mmbase.config"); 314 log.debug("found the mmbase config path parameter using the mmbase.config servlet context parameter"); 315 } 316 if (configPath == null) { 317 configPath = System.getProperty("mmbase.config"); 318 if (configPath != null) { 319 log.debug("found the mmbase.config path parameter using the mmbase.config system property"); 320 } 321 } else if (System.getProperty("mmbase.config") != null){ 322 log.warn("mmbase.config system property is masked by mmbase.config servlet context parameter"); 325 } 326 327 if (configPath != null) { 328 if (servletContext != null) { 329 if (configPath.startsWith("$WEBROOT")) { 331 configPath = servletContext.getRealPath(configPath.substring(8)); 332 } 333 } 334 log.debug("Adding " + configPath); 335 configRoot.roots.add(configRoot.new FileURLStreamHandler(new File(configPath), true)); 336 } 337 338 if (servletContext != null) { 339 String s = servletContext.getRealPath(RESOURCE_ROOT); 340 if (s != null) { 341 configRoot.roots.add(configRoot.new FileURLStreamHandler(new File(s), true)); 342 } else { 343 configRoot.roots.add(configRoot.new ServletResourceURLStreamHandler(RESOURCE_ROOT)); 344 } 345 } 346 347 if (servletContext != null) { 348 String s = servletContext.getRealPath("/WEB-INF/classes" + CLASSLOADER_ROOT); if (s != null) { 350 configRoot.roots.add(configRoot.new FileURLStreamHandler(new File(s), false)); 351 } 352 } 353 354 configRoot.roots.add(configRoot.new ClassLoaderURLStreamHandler(CLASSLOADER_ROOT)); 355 356 configRoot.roots.add(configRoot.new ClassLoaderURLStreamHandler("/")); 358 359 } 360 return configRoot; 361 } 362 363 364 370 public static synchronized ResourceLoader getSystemRoot() { 371 if (systemRoot == null) { 372 systemRoot = new ResourceLoader(); 373 systemRoot.roots.add(systemRoot.new FileURLStreamHandler(new File(System.getProperty("user.dir")), true)); 374 File[] roots = File.listRoots(); 375 for (int i = 0; i <roots.length; i++) { 376 systemRoot.roots.add(systemRoot.new FileURLStreamHandler(roots[i], true)); 377 } 378 379 } 380 return systemRoot; 381 } 382 383 386 public static synchronized ResourceLoader getWebRoot() { 387 if (webRoot == null) { 388 webRoot = new ResourceLoader(); 389 390 392 393 String htmlRoot = null; 394 if (servletContext != null) { 395 htmlRoot = servletContext.getInitParameter("mmbase.htmlroot"); 396 } 397 398 if (htmlRoot == null) { 399 htmlRoot = System.getProperty("mmbase.htmlroot"); 400 } 401 if (htmlRoot != null) { 402 webRoot.roots.add(webRoot.new FileURLStreamHandler(new File(htmlRoot), true)); 403 } 404 405 if (servletContext != null) { 406 String s = servletContext.getRealPath("/"); 407 if (s != null) { 408 webRoot.roots.add(webRoot.new FileURLStreamHandler(new File(s), true)); 409 } 410 webRoot.roots.add(webRoot.new ServletResourceURLStreamHandler("/")); 411 } 412 } 413 414 return webRoot; 415 } 416 417 420 public static synchronized ResourceLoader getWebDirectory(HttpServletRequest request) { 421 return ResourceLoader.getWebRoot().getChildResourceLoader(request.getServletPath()).getParentResourceLoader(); 422 } 423 424 425 428 private URL context; 429 430 431 434 private ResourceLoader parent = null; 435 436 440 protected ResourceLoader() { 441 super(); 442 roots = new ArrayList(); 443 try { 444 context = newURL(PROTOCOL + ":/"); 445 } catch (MalformedURLException mue) { 446 throw new RuntimeException (mue); 447 } 448 } 449 450 451 452 455 protected ResourceLoader(final ResourceLoader cl, final String context) { 456 super(ResourceLoader.class.getClassLoader()); 457 this.context = cl.findResource(context + "/"); 458 roots = new ArrayList(); 459 Iterator i = cl.roots.iterator(); 460 while (i.hasNext()) { 462 Object o = i.next(); 463 if (o instanceof FileURLStreamHandler) { 464 roots.add(new FileURLStreamHandler((FileURLStreamHandler) o)); 465 } else if (o instanceof NodeURLStreamHandler) { 466 roots.add(new NodeURLStreamHandler((NodeURLStreamHandler) o)); 467 } else if (o instanceof ServletResourceURLStreamHandler) { 468 roots.add(new ServletResourceURLStreamHandler((ServletResourceURLStreamHandler) o)); 469 } else if (o instanceof ClassLoaderURLStreamHandler) { 470 roots.add(new ClassLoaderURLStreamHandler((ClassLoaderURLStreamHandler) o)); 471 } else { 472 assert false; 473 } 474 } 475 parent = cl; 476 } 477 478 479 480 487 protected URL findResource(final String name) { 488 try { 489 if (name.startsWith("/")) { 490 return newURL(PROTOCOL + ":" + name); 491 } else if (name.startsWith(PROTOCOL + ":")) { 492 return newURL(name); 493 } else { 494 return new URL(context, name); 495 } 496 } catch (MalformedURLException mfue) { 497 log.info(mfue + Logging.stackTrace(mfue)); 498 return null; 499 } 500 } 501 502 503 507 protected Enumeration findResources(final String name) throws IOException { 508 final Iterator i = roots.iterator(); 509 return new Enumeration() { 510 private Enumeration current = null; 511 private Enumeration next; 512 { 513 current = getNext(); 514 next = getNext(); 515 } 516 517 protected Enumeration getNext() { 518 if (i.hasNext()) { 519 try { 520 PathURLStreamHandler ush = (PathURLStreamHandler) i.next(); 521 Enumeration e = ush.getResources(name); 522 return e; 523 } catch (IOException io) { 524 log.warn(io); 525 return current; 526 } 527 } else { 528 return current; 529 } 530 } 531 532 public boolean hasMoreElements() { 533 return current.hasMoreElements() || next.hasMoreElements(); 534 } 535 public Object nextElement() { 536 if (! current.hasMoreElements()) { 537 current = next; 538 next = getNext(); 539 } 540 return current.nextElement(); 541 } 542 543 }; 544 } 545 546 551 public List getResourceList(final String name) { 552 try { 553 return Collections.list(getResources(name)); 554 } catch (IOException io) { 555 log.warn(io); 556 return Collections.EMPTY_LIST; 557 } 558 } 559 560 561 565 public static final Pattern XML_PATTERN = Pattern.compile(".*\\.xml$"); 566 567 570 public URL getContext() { 571 return context; 572 } 573 574 575 580 public ResourceLoader getParentResourceLoader() { 581 return parent; 582 } 583 584 591 public ResourceLoader getChildResourceLoader(final String context) { 592 if (context.equals("..")) { return getParentResourceLoader(); 594 } 595 String [] dirs = context.split("/"); 596 ResourceLoader rl = this; 597 for (int i = 0; i < dirs.length; i++) { 598 rl = new ResourceLoader(rl, dirs[i]); 599 } 600 return rl; 601 602 } 603 604 605 612 public Set getResourcePaths(final Pattern pattern, final boolean recursive) { 613 return getResourcePaths(pattern, recursive, false); 614 } 615 616 622 public Set getChildContexts(final Pattern pattern, final boolean recursive) { 623 return getResourcePaths(pattern, recursive, true); 624 } 625 626 632 protected Set getResourcePaths(final Pattern pattern, final boolean recursive, final boolean directories) { 633 Set results = new TreeSet(); Iterator i = roots.iterator(); 635 while (i.hasNext()) { 636 PathURLStreamHandler cf = (PathURLStreamHandler) i.next(); 637 cf.getPaths(results, pattern, recursive, directories); 638 } 639 return results; 640 } 641 642 643 644 655 public OutputStream createResourceAsStream(String name) throws IOException { 656 if (name == null || name.equals("")) { 657 throw new IOException("You cannot create a resource with an empty name"); 658 } 659 URL resource = findResource(name); 660 URLConnection connection = resource.openConnection(); 661 return connection.getOutputStream(); 662 } 663 664 671 public InputSource getInputSource(final String name) throws IOException { 672 return getInputSource(findResource(name)); 673 } 674 675 678 public static InputSource getInputSource(final URL url) throws IOException { 679 try { 680 InputStream stream = url.openStream(); 681 if (stream == null) return null; 682 InputSource is = new InputSource (stream); 683 is.setSystemId(url.toExternalForm()); 685 return is; 686 } catch (MalformedURLException mfue) { 687 log.info(mfue); 688 return null; 689 } 690 } 691 692 701 public Document getDocument(String name) throws org.xml.sax.SAXException , IOException { 702 return getDocument(name, true, null); 703 } 704 705 716 public Document getDocument(String name, boolean validation, Class baseClass) throws org.xml.sax.SAXException , IOException { 717 return getDocument(getResource(name), validation, baseClass); 718 } 719 720 721 724 public static Document getDocument(URL url, boolean validation, Class baseClass) throws org.xml.sax.SAXException , IOException { 725 boolean xsd = validation; 726 if (validation) { 727 Reader r = new InputStreamReader(url.openStream()); 729 if (r == null) return null; 730 BufferedReader reader = new BufferedReader(r); 731 String line = reader.readLine(); 732 int lineNumber = 0; 733 while (lineNumber < 2 && line != null) { 734 if (line.startsWith("<!DOCTYPE")) { 735 log.debug("Using DTD to validate '" + url + "'"); 736 xsd = false; 737 } 738 line = reader.readLine(); 739 lineNumber++; 740 } 741 reader.close(); 742 } 743 744 InputSource source = getInputSource(url); 745 if (source == null) return null; 746 XMLEntityResolver resolver = new XMLEntityResolver(validation, baseClass); 747 DocumentBuilder dbuilder = org.mmbase.util.xml.DocumentReader.getDocumentBuilder(validation, xsd, 748 null, resolver); 749 if(dbuilder == null) throw new RuntimeException ("failure retrieving document builder"); 750 if (log.isDebugEnabled()) log.debug("Reading " + source.getSystemId()); 751 try { 752 Document doc = dbuilder.parse(source); 753 return doc; 754 } catch (IOException ioe) { if (validation) { 756 log.error(ioe); 757 return getDocument(url, false, baseClass); 759 } else { 760 throw ioe; 761 } 762 } 763 764 } 765 766 772 public void storeSource(String name, Source source, DocumentType docType) throws IOException { 773 try { 774 log.service("Storing source " + name + " for " + this); 775 OutputStream stream = createResourceAsStream(name); 776 StreamResult streamResult = new StreamResult (stream); 777 TransformerFactory tf = TransformerFactory.newInstance(); 778 Transformer serializer = tf.newTransformer(); 779 serializer.setOutputProperty(OutputKeys.INDENT, "yes"); 780 if (docType != null) { 781 serializer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, docType.getPublicId()); 782 serializer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, docType.getSystemId()); 783 } 784 serializer.transform(source, streamResult); 787 stream.close(); 788 } catch (final TransformerException te) { 789 IOException io = new IOException(te.getMessage()); 790 io.initCause(te); 791 throw io; 792 } 793 } 794 795 801 public void storeDocument(String name, Document doc) throws IOException { 802 storeSource(name, new DOMSource (doc), doc.getDoctype()); 803 } 804 805 813 public Reader getReader(String name) throws IOException { 814 try { 815 InputStream is = getResourceAsStream(name); 816 if (is == null) return null; 817 if (name.endsWith(".properties")) { 818 return new TransformingReader(new InputStreamReader(is, "UTF-8"), new InverseCharTransformer(new UnicodeEscaper())); 820 } 821 byte b[] = new byte[100]; 822 if (is.markSupported()) { 823 is.mark(101); 824 } 825 try { 826 is.read(b, 0, 100); 827 if (is.markSupported()) { 828 is.reset(); 829 } else { 830 is = getResourceAsStream(name); 831 } 832 } catch (IOException ioe) { 833 is = getResourceAsStream(name); 834 } 835 836 837 String encoding = GenericResponseWrapper.getXMLEncoding(b); 838 if (encoding != null) { 839 return new InputStreamReader(is, encoding); 840 } 841 842 return new InputStreamReader(is, "UTF-8"); 844 } catch (UnsupportedEncodingException uee) { 845 return null; 847 } 848 } 849 850 857 public Writer getWriter(String name) throws IOException { 858 OutputStream os = createResourceAsStream(name); 859 try { 860 if (os == null) return null; 861 if (name.endsWith(".properties")) { 862 return new TransformingWriter(new OutputStreamWriter(os, "UTF-8"), new UnicodeEscaper()); 864 } 865 } catch (UnsupportedEncodingException uee) { 866 log.error("uee " + uee); 867 } 868 return new EncodingDetectingOutputStreamWriter(os); 869 } 870 871 874 public String toInternalForm(String name) { 875 return toInternalForm(findResource(name)); 876 877 } 878 879 public static String toInternalForm(URL u) { 880 return u.getProtocol() + ":" + u.getPath(); 881 } 882 883 887 public List getFiles(String name) { 888 889 890 List result = new ArrayList(); 891 Iterator i = roots.iterator(); 892 while (i.hasNext()) { 893 Object o = i.next(); 894 if (o instanceof FileURLStreamHandler) { 895 result.add(((FileURLStreamHandler) o).getFile(name)); 896 } 897 } 898 return result; 899 900 } 901 902 903 907 Node getResourceNode(String name) { 908 Iterator i = roots.iterator(); 909 while (i.hasNext()) { 910 Object o = i.next(); 911 if (o instanceof NodeURLStreamHandler) { 912 return ((NodeConnection) (((PathURLStreamHandler) o).openConnection(name))).getResourceNode(); 913 } 914 } 915 return null; 916 } 917 918 921 void checkShadowedNewerResources(String name) { 922 long lastModified = -1; 923 URL usedUrl = null; 924 925 Iterator i = roots.iterator(); 926 while (i.hasNext()) { 927 PathURLStreamHandler cf = (PathURLStreamHandler) i.next(); 928 URLConnection con = cf.openConnection(name); 929 if (con.getDoInput()) { 930 long lm = con.getLastModified(); 931 if (lm > 0 && usedUrl != null && lastModified > 0 && lm > lastModified) { 932 log.warn("File " + con.getURL() + " is newer (" + new Date(lm) + ") then " + usedUrl + "(" + new Date(lastModified) + ") but shadowed by it"); 933 log.debug("Checked because " + Logging.stackTrace(15)); 934 } 935 if (usedUrl == null && lm > 0) { 936 usedUrl = con.getURL(); 937 lastModified = lm; 938 } 939 } 940 } 941 } 942 943 950 URL shadowed(File f, String name) { 951 Iterator i = roots.iterator(); 952 while (i.hasNext()) { 953 PathURLStreamHandler cf = (PathURLStreamHandler) i.next(); 954 if (cf instanceof NodeURLStreamHandler) { 955 URLConnection con = cf.openConnection(name); 956 if (con.getDoInput()) { 957 return con.getURL(); 958 } 959 } else if (cf instanceof FileURLStreamHandler) { 960 FileConnection con = (FileConnection) cf.openConnection(name); 961 File file = con.getFile(); 962 if (file.equals(f)) { 963 return null; } else { 965 if (file.exists()) { 966 try { 967 return file.toURL(); } catch (MalformedURLException mfue) { 969 assert false : mfue; 970 } 971 } 972 } 973 } 974 } 975 throw new IllegalArgumentException ("File " + f + " is not a file for resource " + name); 977 } 978 979 980 981 984 public String toString() { 985 return "" + context.getPath() + " resolving in " + roots; 986 } 987 988 991 public boolean equals(Object o) { 992 if(this == o) return true; 993 if (parent == null) return false; 995 if (o instanceof ResourceLoader) { 996 ResourceLoader rl = (ResourceLoader) o; 997 return rl.parent == parent && rl.context.sameFile(context); 998 } else { 999 return false; 1000 } 1001 } 1002 1003 1006 public int hashCode() { 1007 int result = 0; 1008 result = HashCodeUtil.hashCode(result, parent); 1009 result = HashCodeUtil.hashCode(result, context); 1010 return result; 1011 } 1012 1013 1018 1019 1020 1023 protected abstract class PathURLStreamHandler extends URLStreamHandler { 1024 1027 abstract public URLConnection openConnection(String name); 1028 1029 1032 abstract protected String getName(URL u); 1033 1034 1037 Enumeration getResources(final String name) throws IOException { 1038 return new Enumeration() { 1039 private boolean hasMore = true; 1040 public boolean hasMoreElements() { return hasMore; }; 1041 public Object nextElement() { 1042 hasMore = false; 1043 return openConnection(name).getURL(); 1044 } 1045 1046 }; 1047 } 1048 1049 protected URLConnection openConnection(URL u) throws IOException { 1050 return openConnection(getName(u)); 1051 } 1052 1053 abstract Set getPaths(Set results, Pattern pattern, boolean recursive, boolean directories); 1054 } 1055 1056 1057 protected class FileURLStreamHandler extends PathURLStreamHandler { 1058 private File fileRoot; 1059 private boolean writeable; 1060 FileURLStreamHandler(File root, boolean w) { 1061 fileRoot = root; 1062 writeable = w; 1063 1064 } 1065 FileURLStreamHandler(FileURLStreamHandler f) { 1066 fileRoot = f.fileRoot; 1067 writeable = f.writeable; 1068 } 1069 1070 public File getFile(String name) { 1071 if (name != null && name.startsWith("file:")) { 1072 try { 1073 return new File(new URI(name)); } catch (URISyntaxException use) { 1075 log.warn(use); 1076 } 1077 } 1078 String fileName = fileRoot + ResourceLoader.this.context.getPath() + (name == null ? "" : name); 1079 if (! File.separator.equals("/")) { fileName = fileName.replace('/', File.separator.charAt(0)); } 1082 return new File(fileName); 1083 } 1084 public String getName(URL u) { 1085 int l = (fileRoot + ResourceLoader.this.context.getPath()).length(); 1086 String path = u.getPath(); 1087 return l < path.length() ? path.substring(l) : path; 1088 } 1089 public URLConnection openConnection(String name) { 1090 URL u; 1091 try { 1092 if (name.startsWith("file:")) { 1093 u = new URL(null, name, this); 1094 } else { 1095 u = new URL(null, "file:" + getFile(name), this); 1096 } 1097 } catch (MalformedURLException mfue) { 1098 throw new AssertionError (mfue.getMessage()); 1099 } 1100 return new FileConnection(u, getFile(name), writeable); 1101 } 1102 public Set getPaths(final Set results, final Pattern pattern, final boolean recursive, final boolean directories) { 1103 return getPaths(results, pattern, recursive ? "" : null, directories); 1104 } 1105 private Set getPaths(final Set results, final Pattern pattern, final String recursive, final boolean directories) { 1106 FilenameFilter filter = new FilenameFilter() { 1107 public boolean accept(File dir, String name) { 1108 File f = new File(dir, name); 1109 return pattern == null || (f.isDirectory() && recursive != null) || pattern.matcher(f.toString()).matches(); 1110 } 1111 }; 1112 File f = getFile(recursive); 1113 1114 if (f.isDirectory()) { File [] files = f.listFiles(filter); 1116 if (files == null) return results; 1117 for (int j = 0; j < files.length; j++) { 1118 if (files[j].getName().equals("")) continue; 1119 if (recursive != null && files[j].isDirectory()) { 1120 getPaths(results, pattern, recursive + files[j].getName() + "/", directories); 1121 } 1122 if (files[j].canRead() && (directories == files[j].isDirectory())) { 1123 results.add((recursive == null ? "" : recursive) + files[j].getName()); 1124 } 1125 1126 } 1127 } 1128 1129 return results; 1130 } 1131 public String toString() { 1132 return fileRoot.toString(); 1133 } 1134 1135 1136 } 1137 1138 1139 1146 private class FileConnection extends URLConnection { 1147 private File file; 1148 private boolean writeable; 1149 FileConnection(URL u, File f, boolean w) { 1150 super(u); 1151 this.file = f; 1152 this.writeable = w; 1153 } 1154 public void connect() throws IOException { 1155 connected = true; 1156 } 1157 1158 public File getFile() { 1159 return file; 1160 } 1161 1162 public boolean getDoInput() { 1163 return file.canRead(); 1164 } 1165 public boolean getDoOutput() { 1166 if (! writeable) return false; 1167 File f = file; 1168 while (f != null) { 1169 if (f.exists()) { 1170 return f.canWrite(); 1171 } else { 1172 f = f.getParentFile(); 1173 } 1174 } 1175 return false; 1176 } 1177 1178 public InputStream getInputStream() throws IOException { 1179 if (! connected) connect(); 1180 return new FileInputStream(file); 1181 } 1182 public OutputStream getOutputStream() throws IOException { 1183 if (! connected) connect(); 1184 if (! writeable) { 1185 throw new UnknownServiceException("This file-connection does not allow writing."); 1186 } 1187 File parent = file.getParentFile(); 1189 if (parent != null) { 1190 if (! parent.exists()) { 1191 log.info("Creating subdirs for " + file); 1192 } 1193 parent.mkdirs(); 1194 if (! parent.exists()) { 1195 log.warn("Could not create directory for " + file + ": " + parent); 1196 } 1197 } else { 1198 log.warn("Parent of " + file + " is null ?!"); 1199 } 1200 if (file.isDirectory()) { 1201 final File directory = file; 1202 return new OutputStream() { 1203 public void write(byte[] b) throws IOException { 1204 if (b == null) { 1205 directory.delete(); 1206 } else { 1207 super.write(b); 1208 } 1209 } 1210 public void write(int b) throws IOException { 1211 throw new UnsupportedOperationException ("Cannot write bytes to a directory outputstream"); 1212 } 1213 }; 1214 1215 } else { 1216 return new FileOutputStream(file) { 1217 public void write(byte[] b) throws IOException { 1218 if (b == null) { 1219 file.delete(); 1220 } else { 1221 super.write(b); 1222 } 1223 } 1224 }; 1225 } 1226 } 1227 public long getLastModified() { 1228 return file.lastModified(); 1229 } 1230 1231 public String toString() { 1232 return "FileConnection " + file.toString(); 1233 } 1234 1235 } 1236 1237 1238 1241 protected class NodeURLStreamHandler extends PathURLStreamHandler { 1242 private int type; 1243 NodeURLStreamHandler(int type) { 1244 this.type = type; 1245 } 1246 NodeURLStreamHandler(NodeURLStreamHandler nf) { 1247 this.type = nf.type; 1248 } 1249 1250 protected String getName(URL u) { 1251 return u.getPath().substring(NODE_URL_CONTEXT.getPath().length()); 1252 } 1253 public URLConnection openConnection(String name) { 1254 URL u; 1255 try { 1256 u = new URL(NODE_URL_CONTEXT, name, this); 1257 } catch (MalformedURLException mfue) { 1258 throw new AssertionError (mfue.getMessage()); 1259 } 1260 return new NodeConnection(u, name, type); 1261 } 1262 public Set getPaths(final Set results, final Pattern pattern, final boolean recursive, final boolean directories) { 1263 if (ResourceLoader.resourceBuilder != null) { 1264 try { 1265 NodeQuery query = ResourceLoader.resourceBuilder.createQuery(); 1266 Constraint typeConstraint = Queries.createConstraint(query, TYPE_FIELD, Queries.getOperator("="), new Integer (type)); 1267 Constraint nameConstraint = Queries.createConstraint(query, RESOURCENAME_FIELD, Queries.getOperator("LIKE"), ResourceLoader.this.context.getPath().substring(1) + "%"); 1268 1269 BasicCompositeConstraint constraint = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_AND); 1270 1271 constraint.addChild(typeConstraint).addChild(nameConstraint); 1272 1273 1274 query.setConstraint(constraint); 1275 Iterator i = resourceBuilder.getList(query).iterator(); 1276 while (i.hasNext()) { 1277 Node node = (Node) i.next(); 1278 String url = node.getStringValue(RESOURCENAME_FIELD); 1279 String subUrl = url.substring(ResourceLoader.this.context.getPath().length() - 1); 1280 int pos = subUrl.indexOf('/'); 1281 1282 if (directories) { 1283 if (pos < 0) continue; do { 1285 String u = subUrl.substring(0, pos); 1286 if (pattern != null && ! pattern.matcher(u).matches()) { 1287 continue; 1288 } 1289 results.add(u); 1290 pos = subUrl.indexOf('/', pos + 1); 1291 } while (pos > 0 && recursive); 1292 } else { 1293 if (pos > 0 && ! recursive) continue; 1294 if (pattern != null && ! pattern.matcher(subUrl).matches()) { 1295 continue; 1296 } 1297 results.add(subUrl); 1298 } 1299 1300 } 1301 } catch (BridgeException sqe) { 1302 log.warn(sqe); 1303 } 1304 } 1305 return results; 1306 } 1307 public String toString() { 1308 return "nodes of type " + type; 1309 } 1310 1311 } 1312 1313 1317 private class NodeConnection extends URLConnection { 1318 Node node; 1319 String name; 1320 int type; 1321 NodeConnection(URL url, String name, int t) { 1322 super(url); 1323 this.name = name; 1324 this.type = t; 1325 } 1326 public void connect() throws IOException { 1327 if (ResourceLoader.resourceBuilder == null) { 1328 throw new IOException("No resources builder available."); 1329 } 1330 connected = true; 1331 } 1332 1336 public Node getResourceNode() { 1337 if (node != null) return node; 1338 if (name.equals("")) return null; 1339 String realName = (ResourceLoader.this.context.getPath() + name).substring(1); 1340 if (ResourceLoader.resourceBuilder != null) { 1341 try { 1342 NodeQuery query = resourceBuilder.createQuery(); 1343 Constraint constraint1 = Queries.createConstraint(query, RESOURCENAME_FIELD, Queries.getOperator("="), realName); 1344 Constraint constraint2 = Queries.createConstraint(query, TYPE_FIELD, Queries.getOperator("="), new Integer (type)); 1345 1346 BasicCompositeConstraint constraint = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_AND); 1347 constraint.addChild(constraint1); 1348 constraint.addChild(constraint2); 1349 1350 query.setConstraint(constraint); 1351 Iterator i = resourceBuilder.getList(query).iterator(); 1352 if (i.hasNext()) { 1353 node = (Node) i.next(); 1354 return node; 1355 } 1356 } catch (BridgeException sqe) { 1357 log.warn(sqe); 1358 } 1359 } 1360 return null; 1361 } 1362 1363 public boolean getDoInput() { 1364 return getResourceNode() != null; 1365 } 1366 1367 public boolean getDoOutput() { 1368 getResourceNode(); 1369 return 1370 (node != null && node.mayWrite()) || 1371 (ResourceLoader.resourceBuilder != null && ResourceLoader.resourceBuilder.mayCreateNode()); 1372 } 1373 1374 public InputStream getInputStream() throws IOException { 1375 getResourceNode(); 1376 if (node != null) { 1377 return node.getInputStreamValue(HANDLE_FIELD); 1378 } else { 1379 throw new IOException("No such (node) resource for " + name); 1380 } 1381 } 1382 public OutputStream getOutputStream() throws IOException { 1383 if (getResourceNode() == null) { 1384 if (ResourceLoader.resourceBuilder == null) return null; 1385 1386 node = ResourceLoader.resourceBuilder.createNode(); 1387 node.setContext(DEFAULT_CONTEXT); 1388 String resourceName = (ResourceLoader.this.context.getPath() + name).substring(1); 1389 node.setStringValue(RESOURCENAME_FIELD, resourceName); 1390 node.setIntValue(TYPE_FIELD, type); 1391 log.info("Creating node " + resourceName + " " + name + " " + type); 1392 node.commit(); 1393 } 1394 return new OutputStream() { 1395 ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 1396 public void close() throws IOException { 1397 byte[] b = bytes.toByteArray(); 1398 node.setValue(HANDLE_FIELD, b); 1399 String mimeType = URLConnection.guessContentTypeFromStream(new ByteArrayInputStream(b)); 1400 if (mimeType == null) { 1401 URLConnection.guessContentTypeFromName(name); 1402 } 1403 node.setValue("mimetype", mimeType); 1404 node.commit(); 1405 } 1406 public void write(int b) { 1407 bytes.write(b); 1408 } 1409 public void write(byte[] b) throws IOException { 1410 if (b == null) { 1411 node.delete(); 1412 node = null; 1413 } else { 1414 super.write(b); 1415 } 1416 } 1417 }; 1418 } 1419 public long getLastModified() { 1420 getResourceNode(); 1421 if (node != null) { 1422 Date lm = node.getDateValue(LASTMODIFIED_FIELD); 1423 if (lm != null) { 1424 return lm.getTime(); 1425 } 1426 } 1427 return -1; 1428 } 1429 1430 public String toString() { 1431 return "NodeConnection " + node; 1432 } 1433 1434 } 1435 1436 1440 private static boolean warned23 = false; 1441 1442 1445 protected class ServletResourceURLStreamHandler extends PathURLStreamHandler { 1446 private String root; 1447 ServletResourceURLStreamHandler(String r) { 1448 root = r; 1449 } 1450 ServletResourceURLStreamHandler(ServletResourceURLStreamHandler f) { 1451 root = f.root; 1452 } 1453 1454 1455 protected String getName(URL u) { 1456 return u.getPath().substring(root.length()); 1457 } 1458 public URLConnection openConnection(String name) { 1459 try { 1460 URL u = ResourceLoader.servletContext.getResource(root + ResourceLoader.this.context.getPath() + name); 1461 if (u == null) return NOT_AVAILABLE_URLSTREAM_HANDLER.openConnection(name); 1462 return u.openConnection(); 1463 } catch (IOException ioe) { 1464 return NOT_AVAILABLE_URLSTREAM_HANDLER.openConnection(name); 1465 } 1466 } 1467 public Set getPaths(final Set results, final Pattern pattern, final boolean recursive, final boolean directories) { 1468 if (log.isDebugEnabled()) { 1469 log.debug("Getting " + (directories ? "directories" : "files") + " matching '" + pattern + "' in '" + root + "'"); 1470 } 1471 return getPaths(results, pattern, recursive ? "" : null, directories); 1472 } 1473 1474 private Set getPaths(final Set results, final Pattern pattern, final String recursive, final boolean directories) { 1475 if (servletContext != null) { 1476 try { 1477 String currentRoot = root + ResourceLoader.this.context.getPath(); 1478 String resourcePath = currentRoot + (recursive == null ? "" : recursive); 1479 Collection c = servletContext.getResourcePaths(resourcePath); 1480 if (c == null) return results; 1481 Iterator j = c.iterator(); 1482 while (j.hasNext()) { 1483 String res = (String ) j.next(); 1484 if (res.equals(resourcePath + "/")) { 1485 continue; 1487 } 1488 1489 String newResourcePath = res.substring(currentRoot.length()); 1490 boolean isDir = newResourcePath.endsWith("/"); 1491 if (isDir) { 1492 if (recursive != null) { 1494 getPaths(results, pattern, newResourcePath.substring(0, newResourcePath.length() - 1), directories); 1495 } 1496 if (newResourcePath.equals("/")) continue; 1497 } 1498 if ((pattern == null || pattern.matcher(newResourcePath).matches()) && (directories == isDir)) { 1499 if (isDir) newResourcePath = newResourcePath.substring(0, newResourcePath.length() - 1) ; 1500 results.add(newResourcePath); 1501 } 1502 } 1503 } catch (NoSuchMethodError nsme) { 1504 if (! warned23) { 1505 log.warn("Servet 2.3 feature not supported! " + nsme.getMessage()); 1506 warned23 = true; 1507 } 1508 1510 } catch (Throwable t) { 1513 log.error(Logging.stackTrace(t)); 1514 } 1516 } 1517 return results; 1518 } 1519 1520 public String toString() { 1521 return "ServletResource " + root; 1522 } 1523 } 1524 1525 1526 protected class ClassLoaderURLStreamHandler extends PathURLStreamHandler { 1527 private String root; 1528 1529 1532 ClassLoaderURLStreamHandler(String r) { 1533 root = r; 1534 } 1535 ClassLoaderURLStreamHandler(ClassLoaderURLStreamHandler f) { 1536 root = f.root; 1537 } 1538 1539 1540 private ClassLoader getClassLoader() { 1541 ClassLoader cl = ResourceLoader.class.getClassLoader(); 1542 if (cl == null) { 1543 return ClassLoader.getSystemClassLoader(); 1545 } else { 1546 return cl; 1547 } 1548 } 1549 1550 protected String getName(URL u) { 1551 return u.getPath().substring((root + ResourceLoader.this.context.getPath()).length()); 1552 } 1553 private String getClassResourceName(final String name) throws MalformedURLException { 1554 String res = root + new URL(ResourceLoader.this.context, name).getPath(); 1555 while (res.startsWith("/")) { 1556 res = res.substring(1); 1557 } 1558 if (log.isDebugEnabled()) { 1559 log.debug("Name " + name + " is resource " + res); 1560 } 1561 return res; 1562 } 1563 1564 Enumeration getResources(final String name) throws IOException { 1565 try { 1566 return getClassLoader().getResources(getClassResourceName(name)); 1567 } catch (IOException ioe) { 1568 throw ioe; 1569 } catch (Throwable t) { 1570 log.warn(t); 1571 return Collections.enumeration(Collections.EMPTY_LIST); 1572 } 1573 } 1574 public URLConnection openConnection(String name) { 1575 try { 1576 URL u = getClassLoader().getResource(getClassResourceName(name)); 1577 if (u == null) { 1578 return NOT_AVAILABLE_URLSTREAM_HANDLER.openConnection(name); 1579 } 1580 return u.openConnection(); 1582 } catch (IOException ioe) { 1583 return NOT_AVAILABLE_URLSTREAM_HANDLER.openConnection(name); 1584 } 1585 } 1586 1587 public Set getPaths(final Set results, final Pattern pattern, final boolean recursive, final boolean directories) { 1588 return getPaths(results, pattern, recursive, directories, "", null); 1589 } 1590 1591 private Set getPaths(final Set results, final Pattern pattern, final boolean recursive, final boolean directories, String resourceDir, String searchUp) { 1592 try { 1593 List subDirs = new ArrayList(); 1594 Enumeration e = getResources("".equals(resourceDir) ? INDEX : resourceDir + INDEX); 1595 if (searchUp != null && resourceDir.startsWith("..")) resourceDir = ""; 1596 while (e.hasMoreElements()) { 1597 URL u = (URL) e.nextElement(); 1598 InputStream inputStream = u.openStream(); 1599 if (inputStream != null) { 1600 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 1601 try { 1602 while (true) { 1603 String line = reader.readLine(); 1604 if (line == null) break; 1605 if (line.startsWith("#")) continue; line = line.trim(); 1607 1608 if (line.startsWith("./")) line = line.substring(2); 1609 1610 if (searchUp != null) { 1611 if (line.startsWith(searchUp)) { 1612 line = line.substring(searchUp.length()); 1613 } else { 1614 continue; 1615 } 1616 } 1617 1618 if (directories) { 1619 line = getDirectory(line); 1620 } 1621 if (line.equals("")) continue; 1623 int firstSlash = line.indexOf('/'); 1624 if (firstSlash > 0 && firstSlash < line.length() && ! recursive) continue; 1625 1626 if (pattern == null || pattern.matcher(line).matches()) { 1627 results.add("".equals(resourceDir) ? line : resourceDir + line); 1628 } 1629 if (line.endsWith("/")) { 1630 subDirs.add("".equals(resourceDir) ? line : resourceDir + line); 1631 } 1632 } 1633 } catch (IOException ioe) { 1634 } finally { 1635 reader.close(); 1636 } 1637 } 1638 } 1639 if (recursive) { 1640 for (Iterator iter = subDirs.iterator(); iter.hasNext();) { 1641 String dir = (String ) iter.next(); 1642 String newDir = "".equals(resourceDir) ? dir : resourceDir + dir; 1643 getPaths(results, pattern, recursive, directories, newDir, null); 1644 } 1645 } 1646 if (searchUp == null) { 1647 searchUp = ResourceLoader.getDirectoryName(ResourceLoader.this.context.getFile()) + '/'; 1648 ResourceLoader p = ResourceLoader.this.parent; 1649 String rd = "../"; 1650 while (p != null) { 1651 getPaths(results, pattern, recursive, directories, rd, searchUp); 1652 searchUp = ResourceLoader.getDirectoryName(p.context.getFile()) + '/' + searchUp; 1653 p = p.getParentResourceLoader(); 1654 rd = "../" + rd; 1655 1656 } 1657 } 1658 } catch (IOException ioe) { 1659 } 1660 1671 return results; 1672 } 1673 1674 public String toString() { 1675 return "ClassLoader " + root; 1676 } 1677 } 1678 1679 1680 private static String NOT_FOUND = "/localhost/NOTFOUND/"; 1681 1682 1683 1687 private PathURLStreamHandler NOT_AVAILABLE_URLSTREAM_HANDLER = new PathURLStreamHandler() { 1688 1689 protected String getName(URL u) { 1690 String path = u.getPath(); 1691 return path.substring("/NOTFOUND/".length()); 1692 } 1693 1694 public URLConnection openConnection(String name) { 1695 URL u; 1696 try { 1697 u = new URL(null, "http:/" + NOT_FOUND + name, this); 1698 } catch (MalformedURLException mfue) { 1699 throw new AssertionError (mfue.getMessage()); 1700 } 1701 return new NotAvailableConnection(u, name); 1702 } 1703 1704 public Set getPaths(final Set results, final Pattern pattern, final boolean recursive, final boolean directories) { 1705 return new HashSet(); 1706 } 1707 }; 1708 1709 1710 1711 1714 private class NotAvailableConnection extends URLConnection { 1715 1716 private String name; 1717 1718 private NotAvailableConnection(URL u, String n) { 1719 super(u); 1720 name = n; 1721 } 1722 public void connect() throws IOException { throw new IOException("No such resource " + name); }; 1723 public boolean getDoInput() { return false; } 1724 public boolean getDoOutput() { return false; } 1725 public InputStream getInputStream() throws IOException { connect(); return null;} 1726 public OutputStream getOutputStream() throws IOException { connect(); return null; } 1727 public String toString() { 1728 return "NOTAVAILABLECONNECTION " + name; 1729 } 1730 }; 1731 1732 1733 1737 1738 private class MMURLStreamHandler extends URLStreamHandler implements java.io.Serializable { 1739 1740 MMURLStreamHandler() { 1741 super(); 1742 } 1743 protected URLConnection openConnection(URL u) throws IOException { 1744 return new MMURLConnection(u); 1745 } 1746 1750 protected String toExternalForm(URL u) { 1751 return new MMURLConnection(u).getInputConnection().getURL().toExternalForm(); 1752 } 1753 } 1754 1755 1756 1759 private class MMURLConnection extends URLConnection { 1760 1761 URLConnection inputConnection = null; 1762 URLConnection outputConnection = null; 1763 String name; 1764 1765 1766 MMURLConnection(URL u) { 1767 super(u); 1768 name = url.getPath().substring(1); 1769 if (! url.getProtocol().equals(PROTOCOL)) { 1771 throw new RuntimeException ("Only supporting URL's with protocol " + PROTOCOL); 1772 } 1773 } 1774 1775 1778 public void connect() { 1779 connected = true; 1780 } 1781 1782 1785 protected URLConnection getInputConnection() { 1786 if (inputConnection != null) { 1787 return inputConnection; 1788 } 1789 Iterator i = ResourceLoader.this.roots.iterator(); 1790 while(i.hasNext()) { 1791 PathURLStreamHandler cf = (PathURLStreamHandler) i.next(); 1792 URLConnection c = cf.openConnection(name); 1793 if (c.getDoInput()) { 1794 inputConnection = c; 1795 break; 1796 } 1797 } 1798 if (inputConnection == null) { 1799 setDoInput(false); 1800 inputConnection = NOT_AVAILABLE_URLSTREAM_HANDLER.openConnection(name); 1801 } else { 1802 setDoInput(true); 1803 } 1804 connect(); 1805 return inputConnection; 1806 } 1807 1808 1809 1810 1813 public boolean getDoInput() { 1814 return getInputConnection().getDoInput(); 1815 } 1816 1817 1818 1821 public InputStream getInputStream() throws IOException { 1822 return getInputConnection().getInputStream(); 1823 } 1824 1825 1829 protected URLConnection getOutputConnection() { 1830 if (outputConnection != null) { 1831 return outputConnection; 1832 } 1833 1834 ListIterator i = ResourceLoader.this.roots.listIterator(); 1836 while (i.hasNext()) { 1837 PathURLStreamHandler cf = (PathURLStreamHandler) i.next(); 1838 URLConnection c = cf.openConnection(name); 1839 if (c.getDoInput()) { 1840 if(c.getDoOutput()) { outputConnection = c; 1842 } 1843 break; 1844 } 1845 } 1846 if (outputConnection == null) { 1847 while (i.hasPrevious()) { 1850 PathURLStreamHandler cf = (PathURLStreamHandler) i.previous(); 1851 URLConnection c = cf.openConnection(name); 1852 if (c.getDoOutput()) { 1853 outputConnection = c; 1854 break; 1855 } 1856 } 1857 } 1858 1859 if (outputConnection == null) { 1860 setDoOutput(false); 1861 outputConnection = NOT_AVAILABLE_URLSTREAM_HANDLER.openConnection(name); 1862 } else { 1863 setDoOutput(true); 1864 } 1865 connect(); 1866 return outputConnection; 1867 } 1868 1869 1872 public boolean getDoOutput() { 1873 return getOutputConnection().getDoOutput(); 1874 } 1875 1878 public OutputStream getOutputStream() throws IOException { 1879 try { 1880 OutputStream os = getOutputConnection().getOutputStream(); 1881 if (os == null) { 1882 throw new IOException("Cannot create an OutputStream for " + url + ", it can no way written, and no resource-node could be created)"); 1884 } else { 1885 return os; 1886 } 1887 } catch (Exception ioe) { 1888 IOException i = new IOException("Cannot create an OutputStream for " + url + " " + ioe.getMessage()); 1889 i.initCause(ioe); 1890 throw i; 1891 } 1892 } 1893 1896 public long getLastModified() { 1897 return getInputConnection().getLastModified(); 1898 } 1899 1900 } 1901 1902 1906 public static void main(String [] argv) { 1907 ResourceLoader resourceLoader; 1908 1909 if (System.getProperty("mmbase.htmlroot") != null) { 1910 resourceLoader = getWebRoot(); 1911 } else if (System.getProperty("mmbase.config") != null) { 1912 resourceLoader = getConfigurationRoot(); 1913 } else { 1914 resourceLoader = getSystemRoot(); 1915 } 1916 try { 1917 if (argv.length == 0) { 1918 System.err.println("useage: java [-Dmmbase.config=<config dir>|-Dmmbase.htmlroot=<some other dir>] " + ResourceLoader.class.getName() + " [<sub directory>] [<resource-name>|*|**]"); 1919 return; 1920 } 1921 String arg = argv[0]; 1922 if (argv.length > 1) { 1923 resourceLoader = getConfigurationRoot().getChildResourceLoader(argv[0]); 1924 arg = argv[1]; 1925 } 1926 if (arg.equals("*") || arg.equals("**")) { 1927 Iterator i = resourceLoader.getResourcePaths(Pattern.compile(".*"), arg.equals("**")).iterator(); 1928 while (i.hasNext()) { 1929 System.out.println("" + i.next()); 1930 } 1931 } else { 1932 InputStream resource = resourceLoader.getResourceAsStream(arg); 1933 if (resource == null) { 1934 System.out.println("No such resource " + arg + " for " + resourceLoader.getResource(arg) + ". Creating now."); 1935 PrintWriter writer = new PrintWriter(resourceLoader.getWriter(arg)); 1936 writer.println("TEST"); 1937 writer.close(); 1938 return; 1939 } 1940 System.out.println("-------------------- resolved " + resourceLoader.getResourceList(arg) + " with " + resourceLoader + ": "); 1941 1942 BufferedReader reader = new BufferedReader(new InputStreamReader(resource)); 1943 1944 while(true) { 1945 String line = reader.readLine(); 1946 if (line == null) break; 1947 System.out.println(line); 1948 } 1949 } 1950 1951 } catch (Exception mfeu) { 1952 System.err.println(mfeu.getMessage() + Logging.stackTrace(mfeu)); 1953 } 1954 } 1955 1956 1957} 1958 1959
| Popular Tags
|