001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Alexander V. Astapchuk
020: * @version $Revision$
021: */package java.security;
022:
023: import java.nio.ByteBuffer;
024: import java.util.HashMap;
025:
026: /**
027: * SecureClassLoaders are used to dynamically load, link and install classes
028: * into a running image. Additionally, they (optionally) associate the classes
029: * they create with a code source and provide mechanisms to allow the relevant
030: * permissions to be retrieved.
031: *
032: */
033:
034: public class SecureClassLoader extends ClassLoader {
035:
036: // A cache of ProtectionDomains for a given CodeSource
037: private HashMap pds = new HashMap();
038:
039: /**
040: * @com.intel.drl.spec_ref
041: */
042: protected SecureClassLoader() {
043: super ();
044: }
045:
046: /**
047: * @com.intel.drl.spec_ref
048: */
049: protected SecureClassLoader(ClassLoader parent) {
050: super (parent);
051: }
052:
053: /**
054: * @com.intel.drl.spec_ref
055: */
056: protected PermissionCollection getPermissions(CodeSource codesource) {
057: // Do nothing by default, ProtectionDomain will take care about
058: // permissions in dynamic
059: return new Permissions();
060: }
061:
062: /**
063: * @com.intel.drl.spec_ref
064: */
065: protected final Class<?> defineClass(String name, byte[] b,
066: int off, int len, CodeSource cs) {
067: return cs == null ? defineClass(name, b, off, len)
068: : defineClass(name, b, off, len, getPD(cs));
069: }
070:
071: /**
072: * @com.intel.drl.spec_ref
073: */
074: protected final Class<?> defineClass(String name, ByteBuffer b,
075: CodeSource cs) {
076: //FIXME 1.5 - remove b.array(), call super.defineClass(,ByteBuffer,)
077: // directly
078: byte[] data = b.array();
079: return cs == null ? defineClass(name, data, 0, data.length)
080: : defineClass(name, data, 0, data.length, getPD(cs));
081: }
082:
083: // Constructs and caches ProtectionDomain for the given CodeSource
084: // object.<br>
085: // It calls {@link getPermissions()} to get a set of permissions.
086: //
087: // @param cs CodeSource object
088: // @return ProtectionDomain for the passed CodeSource object
089: private ProtectionDomain getPD(CodeSource cs) {
090: if (cs == null) {
091: return null;
092: }
093: // need to cache PDs, otherwise every class from a given CodeSource
094: // will have it's own ProtectionDomain, which does not look right.
095: ProtectionDomain pd;
096: synchronized (pds) {
097: if ((pd = (ProtectionDomain) pds.get(cs)) != null) {
098: return pd;
099: }
100: PermissionCollection perms = getPermissions(cs);
101: pd = new ProtectionDomain(cs, perms, this, null);
102: pds.put(cs, pd);
103: }
104: return pd;
105: }
106: }
|