001/* 
002    Licensed to the Apache Software Foundation (ASF) under one
003    or more contributor license agreements.  See the NOTICE file
004    distributed with this work for additional information
005    regarding copyright ownership.  The ASF licenses this file
006    to you under the Apache License, Version 2.0 (the
007    "License"); you may not use this file except in compliance
008    with the License.  You may obtain a copy of the License at
009
010       http://www.apache.org/licenses/LICENSE-2.0
011
012    Unless required by applicable law or agreed to in writing,
013    software distributed under the License is distributed on an
014    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015    KIND, either express or implied.  See the License for the
016    specific language governing permissions and limitations
017    under the License.  
018 */
019package org.apache.wiki.auth.permissions;
020
021import java.security.Permission;
022import java.security.PermissionCollection;
023import java.util.Enumeration;
024import java.util.Hashtable;
025
026/**
027 * A collection of AllPermission objects.
028 */
029public class AllPermissionCollection extends PermissionCollection
030{
031
032    private static final long serialVersionUID = 1L;
033
034    private boolean           m_notEmpty;
035
036    private boolean           m_readOnly;
037
038    protected final Hashtable<Permission, Permission> m_permissions    = new Hashtable<>();
039
040    /**
041     * Adds an AllPermission object to this AllPermissionCollection. If this
042     * collection was previously marked read-only, or if the permission supplied
043     * is not of type {@link AllPermission}, a {@link SecurityException} is
044     * thrown.
045     * @see java.security.PermissionCollection#add(java.security.Permission)
046     * 
047     * @param permission {@inheritDoc}
048     */
049    @Override
050    public void add( final Permission permission )
051    {
052        if ( !PermissionChecks.isJSPWikiPermission( permission ) )
053        {
054            throw new IllegalArgumentException(
055                    "Permission must be of type org.apache.wiki.permissions.*Permission." );
056        }
057
058        if ( m_readOnly )
059        {
060            throw new SecurityException( "attempt to add a Permission to a readonly PermissionCollection" );
061        }
062
063        m_notEmpty = true;
064
065        // This is a filthy hack, but it keeps us from having to write our own
066        // Enumeration implementation
067        m_permissions.put( permission, permission );
068    }
069
070    /**
071     * Returns an enumeration of all AllPermission objects stored in this
072     * collection.
073     * @see java.security.PermissionCollection#elements()
074     * 
075     * @return {@inheritDoc}
076     */
077    @Override
078    public Enumeration<Permission> elements()
079    {
080        return m_permissions.elements();
081    }
082
083    /**
084     * Iterates through the AllPermission objects stored by this
085     * AllPermissionCollection and determines if any of them imply a supplied
086     * Permission. If the Permission is not of type {@link AllPermission},
087     * {@link PagePermission} or {@link WikiPermission}, this method will
088     * return <code>false</code>. If none of the AllPermissions stored in
089     * this collection imply the permission, the method returns
090     * <code>false</code>; conversely, if one of the AllPermission objects
091     * implies the permission, the method returns <code>true</code>.
092     * @param permission the Permission to test. It may be any Permission type,
093     * but only the AllPermission, PagePermission or WikiPermission types are
094     * actually evaluated.
095     * @see java.security.PermissionCollection#implies(java.security.Permission)
096     * 
097     * @return {@inheritDoc}
098     */
099    @Override
100    public boolean implies(final Permission permission )
101    {
102        // If nothing in the collection yet, fail fast
103        if ( !m_notEmpty )
104        {
105            return false;
106        }
107
108        // If not one of our permission types, it's not implied
109        if ( !PermissionChecks.isJSPWikiPermission( permission ) )
110        {
111            return false;
112        }
113
114        // Step through each AllPermission
115        final Enumeration<Permission> permEnum = m_permissions.elements();
116        while( permEnum.hasMoreElements() )
117        {
118            final Permission storedPermission = permEnum.nextElement();
119            if ( storedPermission.implies( permission ) )
120            {
121                return true;
122            }
123        }
124        return false;
125    }
126
127    /**
128     * {@inheritDoc}
129     */
130    @Override
131    public boolean isReadOnly()
132    {
133        return m_readOnly;
134    }
135
136    /**
137     * @see java.security.PermissionCollection#setReadOnly()
138     */
139    @Override
140    public void setReadOnly()
141    {
142        m_readOnly = true;
143    }
144}