1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package com.sun.star.comp.loader;
25 
26 import com.sun.star.lib.unoloader.UnoClassLoader;
27 import com.sun.star.lib.util.WeakMap;
28 import java.io.File;
29 import java.io.IOException;
30 import java.net.URL;
31 import java.net.URLClassLoader;
32 import java.util.StringTokenizer;
33 import java.util.jar.Attributes;
34 
35 final class RegistrationClassFinder {
find(String locationUrl)36     public static Class find(String locationUrl)
37         throws ClassNotFoundException, IOException
38     {
39         synchronized (map) {
40             Class c = (Class) WeakMap.getValue(map.get(locationUrl));
41             if (c != null) {
42                 return c;
43             }
44         }
45         URL url = new URL(locationUrl);
46         checkAccess(url);
47         Attributes attr = UnoClassLoader.getJarMainAttributes(url);
48         String name = attr == null
49             ? null : attr.getValue("RegistrationClassName");
50         if (name == null) {
51             return null;
52         }
53         ClassLoader cl1 = RegistrationClassFinder.class.getClassLoader();
54         ClassLoader cl2;
55         if (cl1 instanceof UnoClassLoader) {
56             cl2 = ((UnoClassLoader) cl1).getClassLoader(url, attr);
57         } else {
58             cl2 = URLClassLoader.newInstance(new URL[] { url }, cl1);
59         }
60         Class c = cl2.loadClass(name);
61         synchronized (map) {
62             Class c2 = (Class) WeakMap.getValue(map.get(locationUrl));
63             if (c2 != null) {
64                 return c2;
65             }
66             map.put(locationUrl, c);
67         }
68         return c;
69     }
70 
RegistrationClassFinder()71     private RegistrationClassFinder() {} // do not instantiate
72 
checkAccess(URL url)73     private static void checkAccess(URL url) throws ClassNotFoundException {
74         // The system property com.sun.star.comp.loader.CPLD_ACCESSPATH was
75         // introduced as a hack to restrict which UNO components can be
76         // instantiated.  It seems to be unused nowadays, and should probably be
77         // replaced by the native Java security features, anyway.
78         if (accessPath != null) {
79             if (!url.getProtocol().equals("file")) {
80                 throw new ClassNotFoundException(
81                     "Access restriction: <" + url + "> is not a file URL");
82             }
83             String p;
84             try {
85                 p = new File(url.getFile()).getCanonicalPath();
86             } catch (IOException e) {
87                 throw new ClassNotFoundException(
88                     "Access restriction: <" + url + "> is bad: " + e);
89             }
90             for (int i = 0; i < accessPath.length; ++i) {
91                 String p2 = accessPath[i];
92                 if (p.startsWith(p2) && p.length() > p2.length()
93                     && (p2.charAt(p2.length() - 1) == File.separatorChar
94                         || p.charAt(p2.length()) == File.separatorChar))
95                 {
96                     return;
97                 }
98             }
99             throw new ClassNotFoundException(
100                 "Access restriction: <" + url + "> is restricted");
101         }
102     }
103 
104     private static final WeakMap map = new WeakMap();
105 
106     private static final String[] accessPath;
107     static {
108         String[] ap = null;
109         String p = System.getProperty(
110             "com.sun.star.comp.loader.CPLD_ACCESSPATH");
111         if (p != null) {
112             StringTokenizer t = new StringTokenizer(p, ";");
113             ap = new String[t.countTokens()];
114             int i = 0;
115             while (t.hasMoreTokens()) {
116                 try {
117                     ap[i] = new File(t.nextToken()).getCanonicalPath();
118                     ++i;
119                 } catch (IOException e) {}
120             }
121             if (i != ap.length) {
122                 String[] ap2 = new String[i];
System.arraycopy(ap, 0, ap2, 0, i)123                 System.arraycopy(ap, 0, ap2, 0, i);
124                 ap = ap2;
125             }
126         }
127         accessPath = ap;
128     }
129 }
130