1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 package com.sun.star.comp.loader; 29 30 import com.sun.star.lib.unoloader.UnoClassLoader; 31 import com.sun.star.lib.util.WeakMap; 32 import java.io.File; 33 import java.io.IOException; 34 import java.net.URL; 35 import java.net.URLClassLoader; 36 import java.util.StringTokenizer; 37 import java.util.jar.Attributes; 38 39 final class RegistrationClassFinder { 40 public static Class find(String locationUrl) 41 throws ClassNotFoundException, IOException 42 { 43 synchronized (map) { 44 Class c = (Class) WeakMap.getValue(map.get(locationUrl)); 45 if (c != null) { 46 return c; 47 } 48 } 49 URL url = new URL(locationUrl); 50 checkAccess(url); 51 Attributes attr = UnoClassLoader.getJarMainAttributes(url); 52 String name = attr == null 53 ? null : attr.getValue("RegistrationClassName"); 54 if (name == null) { 55 return null; 56 } 57 ClassLoader cl1 = RegistrationClassFinder.class.getClassLoader(); 58 ClassLoader cl2; 59 if (cl1 instanceof UnoClassLoader) { 60 cl2 = ((UnoClassLoader) cl1).getClassLoader(url, attr); 61 } else { 62 cl2 = URLClassLoader.newInstance(new URL[] { url }, cl1); 63 } 64 Class c = cl2.loadClass(name); 65 synchronized (map) { 66 Class c2 = (Class) WeakMap.getValue(map.get(locationUrl)); 67 if (c2 != null) { 68 return c2; 69 } 70 map.put(locationUrl, c); 71 } 72 return c; 73 } 74 75 private RegistrationClassFinder() {} // do not instantiate 76 77 private static void checkAccess(URL url) throws ClassNotFoundException { 78 // The system property com.sun.star.comp.loader.CPLD_ACCESSPATH was 79 // introduced as a hack to restrict which UNO components can be 80 // instantiated. It seems to be unused nowadays, and should probably be 81 // replaced by the native Java security features, anyway. 82 if (accessPath != null) { 83 if (!url.getProtocol().equals("file")) { 84 throw new ClassNotFoundException( 85 "Access restriction: <" + url + "> is not a file URL"); 86 } 87 String p; 88 try { 89 p = new File(url.getFile()).getCanonicalPath(); 90 } catch (IOException e) { 91 throw new ClassNotFoundException( 92 "Access restriction: <" + url + "> is bad: " + e); 93 } 94 for (int i = 0; i < accessPath.length; ++i) { 95 String p2 = accessPath[i]; 96 if (p.startsWith(p2) && p.length() > p2.length() 97 && (p2.charAt(p2.length() - 1) == File.separatorChar 98 || p.charAt(p2.length()) == File.separatorChar)) 99 { 100 return; 101 } 102 } 103 throw new ClassNotFoundException( 104 "Access restriction: <" + url + "> is restricted"); 105 } 106 } 107 108 private static final WeakMap map = new WeakMap(); 109 110 private static final String[] accessPath; 111 static { 112 String[] ap = null; 113 String p = System.getProperty( 114 "com.sun.star.comp.loader.CPLD_ACCESSPATH"); 115 if (p != null) { 116 StringTokenizer t = new StringTokenizer(p, ";"); 117 ap = new String[t.countTokens()]; 118 int i = 0; 119 while (t.hasMoreTokens()) { 120 try { 121 ap[i] = new File(t.nextToken()).getCanonicalPath(); 122 ++i; 123 } catch (IOException e) {} 124 } 125 if (i != ap.length) { 126 String[] ap2 = new String[i]; 127 System.arraycopy(ap, 0, ap2, 0, i); 128 ap = ap2; 129 } 130 } 131 accessPath = ap; 132 } 133 } 134