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    public boolean implies( final Permission permission )
100    {
101        // If nothing in the collection yet, fail fast
102        if ( !m_notEmpty )
103        {
104            return false;
105        }
106
107        // If not one of our permission types, it's not implied
108        if ( !PermissionChecks.isJSPWikiPermission( permission ) )
109        {
110            return false;
111        }
112
113        // Step through each AllPermission
114        final Enumeration<Permission> permEnum = m_permissions.elements();
115        while( permEnum.hasMoreElements() )
116        {
117            final Permission storedPermission = permEnum.nextElement();
118            if ( storedPermission.implies( permission ) )
119            {
120                return true;
121            }
122        }
123        return false;
124    }
125
126    /**
127     * {@inheritDoc}
128     */
129    public boolean isReadOnly()
130    {
131        return m_readOnly;
132    }
133
134    /**
135     * @see java.security.PermissionCollection#setReadOnly()
136     */
137    public void setReadOnly()
138    {
139        m_readOnly = true;
140    }
141}