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
18/**
19* @author Alexey V. Varlamov
20* @version $Revision$
21*/
22
23package org.apache.harmony.security;
24
25import java.net.URL;
26import java.security.CodeSigner;
27import java.security.CodeSource;
28import java.security.Permission;
29import java.security.Principal;
30import java.util.Collection;
31import java.util.Collections;
32
33import org.apache.harmony.security.fortress.PolicyUtils;
34
35/**
36 * This class represents an elementary block of a security policy. It associates
37 * a CodeSource of an executable code, Principals allowed to execute the code,
38 * and a set of granted Permissions.
39 *
40 * @see org.apache.harmony.security.fortress.DefaultPolicy
41 */
42public class PolicyEntry {
43
44    // Store CodeSource
45    private final CodeSource cs;
46
47    // Array of principals
48    private final Principal[] principals;
49
50    // Permissions collection
51    private final Collection<Permission> permissions;
52
53    /**
54     * Constructor with initialization parameters. Passed collections are not
55     * referenced directly, but copied.
56     */
57    public PolicyEntry(CodeSource cs, Collection<? extends Principal> prs,
58            Collection<? extends Permission> permissions) {
59        this.cs = (cs != null) ? normalizeCodeSource(cs) : null;
60        this.principals = (prs == null || prs.isEmpty()) ? null
61                : (Principal[]) prs.toArray(new Principal[prs.size()]);
62        this.permissions = (permissions == null || permissions.isEmpty()) ? null
63                : Collections.unmodifiableCollection(permissions);
64    }
65
66    /**
67     * Checks if passed CodeSource matches this PolicyEntry. Null CodeSource of
68     * PolicyEntry implies any CodeSource; non-null CodeSource forwards to its
69     * imply() method.
70     */
71    public boolean impliesCodeSource(CodeSource codeSource) {
72        if (cs == null) {
73            return true;
74        }
75
76        if (codeSource == null) {
77            return false;
78        }
79        return cs.implies(normalizeCodeSource(codeSource));
80    }
81
82    private CodeSource normalizeCodeSource(CodeSource codeSource) {
83        URL codeSourceURL = PolicyUtils.normalizeURL(codeSource.getLocation());
84        CodeSource result = codeSource;
85
86        if (codeSourceURL != codeSource.getLocation()) {
87            // URL was normalized - recreate codeSource with new URL
88            CodeSigner[] signers = codeSource.getCodeSigners();
89            if (signers == null) {
90                result = new CodeSource(codeSourceURL, codeSource
91                        .getCertificates());
92            } else {
93                result = new CodeSource(codeSourceURL, signers);
94            }
95        }
96        return result;
97    }
98
99    /**
100     * Checks if specified Principals match this PolicyEntry. Null or empty set
101     * of Principals of PolicyEntry implies any Principals; otherwise specified
102     * array must contain all Principals of this PolicyEntry.
103     */
104    public boolean impliesPrincipals(Principal[] prs) {
105        return PolicyUtils.matchSubset(principals, prs);
106    }
107
108    /**
109     * Returns unmodifiable collection of permissions defined by this
110     * PolicyEntry, may be <code>null</code>.
111     */
112    public Collection<Permission> getPermissions() {
113        return permissions;
114    }
115
116    /**
117     * Returns true if this PolicyEntry defines no Permissions, false otherwise.
118     */
119    public boolean isVoid() {
120        return permissions == null || permissions.size() == 0;
121    }
122}
123