OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [net/] [loader/] [JarURLLoader.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
package gnu.java.net.loader;
2
 
3
import gnu.java.net.IndexListParser;
4
 
5
import java.io.IOException;
6
import java.net.JarURLConnection;
7
import java.net.MalformedURLException;
8
import java.net.URL;
9
import java.net.URLClassLoader;
10
import java.net.URLStreamHandlerFactory;
11
import java.util.ArrayList;
12
import java.util.Iterator;
13
import java.util.LinkedHashMap;
14
import java.util.Map;
15
import java.util.Set;
16
import java.util.StringTokenizer;
17
import java.util.jar.Attributes;
18
import java.util.jar.JarEntry;
19
import java.util.jar.JarFile;
20
import java.util.jar.Manifest;
21
 
22
/**
23
 * A <code>JarURLLoader</code> is a type of <code>URLLoader</code>
24
 * only loading from jar url.
25
 */
26
public final class JarURLLoader extends URLLoader
27
{
28
  // True if we've initialized -- i.e., tried open the jar file.
29
  boolean initialized;
30
  // The jar file for this url.
31
  JarFile jarfile;
32
  // Base jar: url for all resources loaded from jar.
33
  final URL baseJarURL;
34
  // The "Class-Path" attribute of this Jar's manifest.
35
  ArrayList<URLLoader> classPath;
36
  // If not null, a mapping from INDEX.LIST for this jar only.
37
  // This is a set of all prefixes and top-level files that
38
  // ought to be available in this jar.
39
  Set indexSet;
40
 
41
  // This constructor is used internally.  It purposely does not open
42
  // the jar file -- it defers this until later.  This allows us to
43
  // implement INDEX.LIST lazy-loading semantics.
44
  private JarURLLoader(URLClassLoader classloader, URLStreamHandlerCache cache,
45
                       URLStreamHandlerFactory factory,
46
                       URL baseURL, URL absoluteUrl,
47
                       Set indexSet)
48
  {
49
    super(classloader, cache, factory, baseURL, absoluteUrl);
50
 
51
    URL newBaseURL = null;
52
    try
53
      {
54
        // Cache url prefix for all resources in this jar url.
55
        String base = baseURL.toExternalForm() + "!/";
56
        newBaseURL = new URL("jar", "", -1, base, cache.get(factory, "jar"));
57
      }
58
    catch (MalformedURLException ignore)
59
      {
60
        // Ignore.
61
      }
62
    this.baseJarURL = newBaseURL;
63
    this.classPath = null;
64
    this.indexSet = indexSet;
65
  }
66
 
67
  // This constructor is used by URLClassLoader.  It will immediately
68
  // try to read the jar file, in case we've found an index or a class-path
69
  // setting.  FIXME: it would be nice to defer this as well, but URLClassLoader
70
  // makes this hard.
71
  public JarURLLoader(URLClassLoader classloader, URLStreamHandlerCache cache,
72
                      URLStreamHandlerFactory factory,
73
                      URL baseURL, URL absoluteUrl)
74
  {
75
    this(classloader, cache, factory, baseURL, absoluteUrl, null);
76
    initialize();
77
  }
78
 
79
  private void initialize()
80
  {
81
    JarFile jarfile = null;
82
    try
83
      {
84
        jarfile =
85
          ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
86
 
87
        Manifest manifest;
88
        Attributes attributes;
89
        String classPathString;
90
 
91
        IndexListParser parser = new IndexListParser(jarfile, baseJarURL,
92
                                                     baseURL);
93
        LinkedHashMap<URL, Set<String>> indexMap = parser.getHeaders();
94
        if (indexMap != null)
95
          {
96
            // Note that the index also computes
97
            // the resulting Class-Path -- there are jars out there
98
            // where the index lists some required jars which do
99
            // not appear in the Class-Path attribute in the manifest.
100
            this.classPath = new ArrayList<URLLoader>();
101
            Iterator<Map.Entry<URL, Set<String>>> it = indexMap.entrySet().iterator();
102
            while (it.hasNext())
103
              {
104
                Map.Entry<URL, Set<String>> entry = it.next();
105
                URL subURL = entry.getKey();
106
                Set<String> prefixes = entry.getValue();
107
                if (subURL.equals(baseURL))
108
                  this.indexSet = prefixes;
109
                else
110
                  {
111
                    JarURLLoader subLoader = new JarURLLoader(classloader,
112
                                                              cache,
113
                                                              factory, subURL,
114
                                                              subURL,
115
                                                              prefixes);
116
                    // Note that we don't care if the sub-loader itself has an
117
                    // index or a class-path -- only the top-level jar
118
                    // file gets this treatment; its index should cover
119
                    // everything.
120
                    this.classPath.add(subLoader);
121
                  }
122
              }
123
          }
124
        else if ((manifest = jarfile.getManifest()) != null
125
                 && (attributes = manifest.getMainAttributes()) != null
126
                 && ((classPathString
127
                      = attributes.getValue(Attributes.Name.CLASS_PATH))
128
                     != null))
129
          {
130
            this.classPath = new ArrayList<URLLoader>();
131
            StringTokenizer st = new StringTokenizer(classPathString, " ");
132
            while (st.hasMoreElements ())
133
              {
134
                String e = st.nextToken ();
135
                try
136
                  {
137
                    URL subURL = new URL(baseURL, e);
138
                    // We've seen at least one jar file whose Class-Path
139
                    // attribute includes the original jar.  If we process
140
                    // that normally we end up with infinite recursion.
141
                    if (subURL.equals(baseURL))
142
                      continue;
143
                    JarURLLoader subLoader = new JarURLLoader(classloader,
144
                                                              cache, factory,
145
                                                              subURL, subURL);
146
                    this.classPath.add(subLoader);
147
                    ArrayList<URLLoader> extra = subLoader.getClassPath();
148
                    if (extra != null)
149
                      this.classPath.addAll(extra);
150
                  }
151
                catch (java.net.MalformedURLException xx)
152
                  {
153
                    // Give up
154
                  }
155
              }
156
          }
157
      }
158
    catch (IOException ioe)
159
      {
160
        /* ignored */
161
      }
162
 
163
    this.jarfile = jarfile;
164
    this.initialized = true;
165
  }
166
 
167
  /** get resource with the name "name" in the jar url */
168
  public Resource getResource(String name)
169
  {
170
    if (name.startsWith("/"))
171
      name = name.substring(1);
172
    if (indexSet != null)
173
      {
174
        // Trust the index.
175
        String basename = name;
176
        int offset = basename.lastIndexOf('/');
177
        if (offset != -1)
178
          basename = basename.substring(0, offset);
179
        if (! indexSet.contains(basename))
180
          return null;
181
        // FIXME: if the index claim to hold the resource, and jar file
182
        // doesn't have it, we're supposed to throw an exception.  However,
183
        // in our model this is tricky to implement, as another URLLoader from
184
        // the same top-level jar may have an overlapping index entry.
185
      }
186
 
187
    if (! initialized)
188
      initialize();
189
    if (jarfile == null)
190
      return null;
191
 
192
    JarEntry je = jarfile.getJarEntry(name);
193
    if (je != null)
194
      return new JarURLResource(this, name, je);
195
    else
196
      return null;
197
  }
198
 
199
  public Manifest getManifest()
200
  {
201
    try
202
      {
203
        return (jarfile == null) ? null : jarfile.getManifest();
204
      }
205
    catch (IOException ioe)
206
      {
207
        return null;
208
      }
209
  }
210
 
211
  public ArrayList<URLLoader> getClassPath()
212
  {
213
    return classPath;
214
  }
215
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.