1
/*
2
 * $Id$
3
 *
4
 * Copyright (C) 2003-2009 JNode.org
5
 *
6
 * This library is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU Lesser General Public License as published
8
 * by the Free Software Foundation; either version 2.1 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful, but 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
14
 * License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this library; If not, write to the Free Software Foundation, Inc., 
18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
 */
20
 
21
package org.jnode.vm;
22
23
import java.security.AccessControlException;
24
import java.security.Permission;
25
import java.security.ProtectionDomain;
26
import java.util.ArrayList;
27
import java.util.List;
28
29
/**
30
 * Representation of the current access control context.
31
 *
32
 * @author Ewout Prangsma (epr@users.sourceforge.net)
33
 */
34
public final class VmAccessControlContext {
35
36
    private final ProtectionDomain domains[];
37
38
    /**
39
     * Initialize this instance.
40
     *
41
     * @param context
42
     * @param inheritedContext
43
     */
44
    public VmAccessControlContext(ProtectionDomain[] context,
45
                                  VmAccessControlContext inheritedContext) {
46
        final ArrayList<ProtectionDomain> ctxList = new ArrayList<ProtectionDomain>();
47
        if (context != null) {
48
            addUniqueToList(ctxList, context);
49
        }
50
        if ((inheritedContext != null) && (inheritedContext.domains != null)) {
51
            addUniqueToList(ctxList, inheritedContext.domains);
52
        }
53
        if (ctxList.isEmpty()) {
54
            this.domains = null;
55
        } else {
56
            this.domains = (ProtectionDomain[]) ctxList
57
                .toArray(new ProtectionDomain[ctxList.size()]);
58
        }
59
    }
60
61
    /**
62
     * Determines whether or not the specific permission is granted depending
63
     * on the context it is within.
64
     *
65
     * @param perm a permission to check
66
     * @throws AccessControlException if the permssion is not permitted
67
     */
68
    public final void checkPermission(Permission perm)
69
        throws AccessControlException {
70
        if (domains != null) {
71
            final int count = domains.length;
72
            for (int i = 0; i < count; i++) {
73
                if (!domains[i].implies(perm)) {
74
                    throw new AccessControlException(
75
                        "Permission \"" + perm + "\" not granted");
76
                }
77
            }
78
        }
79
    }
80
81
    /**
82
     * Checks if two AccessControlContexts are equal.
83
     * <p/>
84
     * It first checks if obj is an AccessControlContext class, and then checks
85
     * if each ProtectionDomain matches.
86
     *
87
     * @param obj The object to compare this class to
88
     * @return true if equal, false otherwise
89
     */
90
    public final boolean equals(Object obj) {
91
        if (obj instanceof VmAccessControlContext) {
92
            final VmAccessControlContext acc = (VmAccessControlContext) obj;
93
            final int count = (domains == null) ? 0 : domains.length;
94
95
            if (acc.domains.length != count) {
96
                return false;
97
            }
98
99
            for (int i = 0; i < count; i++) {
100
                if (acc.domains[i] != domains[i]) {
101
                    return false;
102
                }
103
            }
104
            return true;
105
        }
106
        return false;
107
    }
108
109
    /**
110
     * Computes a hash code of this class
111
     *
112
     * @return a hash code representing this class
113
     */
114
    public final int hashCode() {
115
        int h = 0;
116
        final int count = (domains == null) ? 0 : domains.length;
117
        for (int i = 0; i < count; i++) {
118
            h ^= domains[i].hashCode();
119
        }
120
        return h;
121
    }
122
123
    private final void addUniqueToList(List<ProtectionDomain> ctxList,
124
                                       ProtectionDomain[] context) {
125
        final int count = context.length;
126
        for (int i = 0; i < count; i++) {
127
            final ProtectionDomain pd = context[i];
128
            if (pd != null) {
129
                if (!ctxList.contains(pd)) {
130
                    ctxList.add(pd);
131
                }
132
            }
133
        }
134
    }
135
}