SubjectDomainCombiner.java revision 32c2297a959b72abdb18743f0519e1d8b7c7ea88
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package javax.security.auth;
19
20import java.security.DomainCombiner;
21import java.security.Principal;
22import java.security.ProtectionDomain;
23import java.util.Set;
24
25/**
26 * Merges permissions based on code source and code signers with permissions
27 * granted to the specified {@link Subject}.
28 */
29public class SubjectDomainCombiner implements DomainCombiner {
30
31    // subject to be associated
32    private Subject subject;
33
34    // permission required to get a subject object
35    private static final AuthPermission _GET = new AuthPermission(
36            "getSubjectFromDomainCombiner");
37
38    /**
39     * Creates a domain combiner for the entity provided in {@code subject}.
40     *
41     * @param subject
42     *            the entity to which this domain combiner is associated.
43     */
44    public SubjectDomainCombiner(Subject subject) {
45        if (subject == null) {
46            throw new NullPointerException();
47        }
48        this.subject = subject;
49    }
50
51    /**
52     * Returns the entity to which this domain combiner is associated.
53     *
54     * @return the entity to which this domain combiner is associated.
55     */
56    public Subject getSubject() {
57        return subject;
58    }
59
60    /**
61     * Merges the {@code ProtectionDomain} with the {@code Principal}s
62     * associated with the subject of this {@code SubjectDomainCombiner}.
63     *
64     * @param currentDomains
65     *            the {@code ProtectionDomain}s associated with the context of
66     *            the current thread. The domains must be sorted according to
67     *            the execution order, the most recent residing at the
68     *            beginning.
69     * @param assignedDomains
70     *            the {@code ProtectionDomain}s from the parent thread based on
71     *            code source and signers.
72     * @return a single {@code ProtectionDomain} array computed from the two
73     *         provided arrays, or {@code null}.
74     * @see ProtectionDomain
75     */
76    public ProtectionDomain[] combine(ProtectionDomain[] currentDomains,
77            ProtectionDomain[] assignedDomains) {
78        // get array length for combining protection domains
79        int len = 0;
80        if (currentDomains != null) {
81            len += currentDomains.length;
82        }
83        if (assignedDomains != null) {
84            len += assignedDomains.length;
85        }
86        if (len == 0) {
87            return null;
88        }
89
90        ProtectionDomain[] pd = new ProtectionDomain[len];
91
92        // for each current domain substitute set of principal with subject's
93        int cur = 0;
94        if (currentDomains != null) {
95
96            Set<Principal> s = subject.getPrincipals();
97            Principal[] p = s.toArray(new Principal[s.size()]);
98
99            for (cur = 0; cur < currentDomains.length; cur++) {
100                ProtectionDomain newPD;
101                newPD = new ProtectionDomain(currentDomains[cur].getCodeSource(),
102                        currentDomains[cur].getPermissions(), currentDomains[cur]
103                                .getClassLoader(), p);
104                pd[cur] = newPD;
105            }
106        }
107
108        // copy assigned domains
109        if (assignedDomains != null) {
110            System.arraycopy(assignedDomains, 0, pd, cur, assignedDomains.length);
111        }
112
113        return pd;
114    }
115}
116