View Javadoc

1   /*
2    * Copyright 2005 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at 
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software 
11   * distributed under the License is distributed on an "AS IS" BASIS, 
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
15   */
16  
17  package org.apache.jdo.impl.enhancer.util;
18  
19  import java.util.List;
20  import java.util.ArrayList;
21  import java.util.Enumeration;
22  import java.util.StringTokenizer;
23  
24  import java.io.IOException;
25  import java.io.FileNotFoundException;
26  import java.io.PrintWriter;
27  import java.io.File;
28  import java.io.InputStream;
29  
30  import java.net.URL;
31  import java.net.URLClassLoader;
32  
33  /***
34   * Searches resources within a path.
35   */
36  public class PathResourceLocator
37      extends ResourceLocatorBase
38      implements ResourceLocator
39  {
40      /***
41       * The class loader for loading jdo resources.
42       */
43      final private URLClassLoader classLoader;
44  
45      /***
46       * Returns a classloader initialized on the path provided to constructor.
47       */
48      public URLClassLoader getClassLoader() {
49          return classLoader;
50      }
51  
52      /***
53       * Creates an instance.
54       */
55      public PathResourceLocator(PrintWriter out,
56                                 boolean verbose,
57                                 String path)
58          throws IOException
59      {
60          super(out, verbose);
61          affirm(path != null);
62  
63          // convert path into list of URLs
64          final List urls = new ArrayList();
65          for (Enumeration e = new StringTokenizer(path, File.pathSeparator);
66               e.hasMoreElements();) {
67              final String s = (String)e.nextElement();
68  
69              // canonicalize file name
70              final File file = new File(s).getCanonicalFile();
71              final URL url = file.toURL();
72              final String canonicalName = url.toString();
73              affirm(canonicalName != null);
74  
75              // ensure path element is readable
76              if (!file.canRead()) {
77                  final String msg
78                      = getI18N("enhancer.cannot_read_resource",
79                                file.toString());
80                  throw new IOException(msg);
81              }
82  
83              // ensure path element is either directory or a jar/zip file
84              final String l = s.toLowerCase();
85              if (!(file.isDirectory()
86                    || (file.isFile()
87                        && (l.endsWith(".jar") || l.endsWith(".zip"))))) {
88                  final String msg
89                      = getI18N("enhancer.illegal_path_element",
90                                file.toString());
91                  throw new IOException(msg);
92              }
93  
94              urls.add(url);
95              printMessage(getI18N("enhancer.using_path_element",
96                                   canonicalName));
97          }
98  
99          // create class loader
100         final URL[] urlArray = (URL[])urls.toArray(new URL[urls.size()]);
101         classLoader = new URLClassLoader(urlArray, null);
102         affirm(classLoader != null);
103     }
104 
105     /***
106      * Finds a resource with a given name.
107      */
108     public InputStream getInputStreamForResource(String resourceName)
109     {
110         //printMessage("PathResourceLocator.getInputStreamForResource() : resourceName = " + resourceName);
111 
112         affirm(resourceName != null);
113 
114         // not using getResourceAsStream() to catch IOExceptions
115         final URL url = classLoader.findResource(resourceName);
116         if (url == null) {
117             printMessage(getI18N("enhancer.not_found_resource", resourceName));
118             return null;
119         }
120 
121         // return input stream
122         final InputStream stream;
123         try {
124             stream = url.openStream();
125         } catch (IOException ex) {
126             // would be better to throw an IOException but currently
127             // not supported by the JDOModel's JavaModel interface
128             final String msg
129                 = getI18N("enhancer.io_error_while_reading_resource",
130                           url.toString(), ex.getMessage());
131             throw new RuntimeException(msg);
132         }
133         affirm(stream != null);
134         printMessage(getI18N("enhancer.found_resource", resourceName));
135         return stream;
136     }
137 }