    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/security/drm/model/RightSet.java $
    002    /*----------------------------------------------------------------------------
    003     This file is part of deegree, http://deegree.org/
    004     Copyright (C) 2001-2009 by:
    005       Department of Geography, University of Bonn
    006     and
    007       lat/lon GmbH
    008
    009     This library is free software; you can redistribute it and/or modify it under
    010     the terms of the GNU Lesser General Public License as published by the Free
    011     Software Foundation; either version 2.1 of the License, or (at your option)
    012     any later version.
    013     This library is distributed in the hope that it will be useful, but WITHOUT
    014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    016     details.
    017     You should have received a copy of the GNU Lesser General Public License
    018     along with this library; if not, write to the Free Software Foundation, Inc.,
    019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    020
    021     Contact information:
    022
    023     lat/lon GmbH
    024     Aennchenstr. 19, 53177 Bonn
    025     Germany
    026     http://lat-lon.de/
    027
    028     Department of Geography, University of Bonn
    029     Prof. Dr. Klaus Greve
    030     Postfach 1147, 53001 Bonn
    031     Germany
    032     http://www.geographie.uni-bonn.de/deegree/
    033
    034     e-mail: info@deegree.org
    035    ----------------------------------------------------------------------------*/
    036    package org.deegree.security.drm.model;
    037
    038    import java.util.ArrayList;
    039    import java.util.HashMap;
    040    import java.util.Iterator;
    041    import java.util.Map;
    042
    043    import org.deegree.model.feature.Feature;
    044    import org.deegree.security.GeneralSecurityException;
    045
    046    /**
    047     * A <code>RightSet</code> encapsulates a number of <code>Right</code> objects. This are grouped
    048     * by the <code>SecurableObject</code> for which they apply to support an efficient implementation
    049     * of the merge()-operation. The merge()-operation results in a <code>RightSet</code> that
    050     * contains the logical rights of boths sets, but only one <code>Right</code> object of each
    051     * <code>RightType</code> (and <code>SecurableObject</code>). This is accomplished by merging
    052     * the constraints of the <code>Rights</code> of the same type (and object).
    053     *
    054     * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a>
    055     * @version $Revision: 18195 $
    056     */
    057    public class RightSet {
    058
    059        // keys are SecurableObjects (for which the rights are defined), values
    060        // are Maps (keys are RightTypes, values are Rights)
    061        private Map<SecurableObject, Map<RightType, Right>> secObjects = new HashMap<SecurableObject, Map<RightType, Right>>();
    062
    063        RightSet() {
    064        }
    065
    066        /**
    067         * @param rights
    068         */
    069        public RightSet( Right[] rights ) {
    070            for ( int i = 0; i < rights.length; i++ ) {
    071                Map<RightType, Right> rightMap = secObjects.get( rights[i].getSecurableObject() );
    072                if ( rightMap == null ) {
    073                    rightMap = new HashMap<RightType, Right>();
    074                }
    075                rightMap.put( rights[i].getType(), rights[i] );
    076                secObjects.put( rights[i].getSecurableObject(), rightMap );
    077            }
    078        }
    079
    080        /**
    081         * Checks if the <code>RightSet</code> contains the permissions for a
    082         * <code>SecurableObject</code> and a concrete situation (the situation is represented by the
    083         * given <code>Feature</code>).
    084         *
    085         * @param object
    086         * @param type
    087         * @param situation
    088         * @return true, if the right applies
    089         * @throws GeneralSecurityException
    090         */
    091        public boolean applies( SecurableObject object, RightType type, Feature situation )
    092                                throws GeneralSecurityException {
    093            boolean applies = false;
    094            Map<RightType, Right> rightMap = secObjects.get( object );
    095            if ( rightMap != null ) {
    096                Right right = rightMap.get( type );
    097                if ( right != null ) {
    098                    applies = right.applies( object, situation );
    099                }
    100            }
    101            return applies;
    102        }
    103
    104        /**
    105         * Checks if the <code>RightSet</code> contains the (unrestricted) permissions for a
    106         * <code>SecurableObject</code> and a certain type of right.
    107         *
    108         * @param object
    109         * @param type
    110         * @return true, if the right applies
    111         */
    112        public boolean applies( SecurableObject object, RightType type ) {
    113            boolean applies = false;
    114            Map<RightType, Right> rightMap = secObjects.get( object );
    115            if ( rightMap != null ) {
    116                Right right = rightMap.get( type );
    117                if ( right != null ) {
    118                    applies = right.applies( object );
    119                }
    120
    121            }
    122            return applies;
    123        }
    124
    125        /**
    126         * @param secObject
    127         * @param type
    128         * @return the <code>Right</code> of the specified <code>RightType</code> that this
    129         * <code>RightSet</code> defines on the specified <code>SecurableObject</code>.
    130         */
    131        public Right getRight( SecurableObject secObject, RightType type ) {
    132            Right right = null;
    133            if ( secObjects.get( secObject ) != null ) {
    134                right = secObjects.get( secObject ).get( type );
    135            }
    136            return right;
    137        }
    138
    139        /**
    140         * @param secObject
    141         * @return the encapulated <code>Rights</code> (for one <code>SecurableObject</code>) as an
    142         * one-dimensional array.
    143         */
    144        public Right[] toArray( SecurableObject secObject ) {
    145            Right[] rights = new Right[0];
    146            Map<RightType, Right> rightMap = secObjects.get( secObject );
    147            if ( rightMap != null ) {
    148                rights = rightMap.values().toArray( new Right[rightMap.size()] );
    149            }
    150            return rights;
    151        }
    152
    153        /**
    154         * @return the encapulated <code>Rights</code> as a two-dimensional array:
    155         * <ul>
    156         * <li>first index: runs the different <code>SecurableObjects</code>
    157         * <li>second index: runs the different <code>Rights</code>
    158         * </ul>
    159         */
    160        public Right[][] toArray2() {
    161            ArrayList<Right[]> secObjectList = new ArrayList<Right[]>();
    162            Iterator<Map<RightType, Right>> it = secObjects.values().iterator();
    163            while ( it.hasNext() ) {
    164                Map<RightType, Right> rightMap = it.next();
    165                Right[] rights = rightMap.values().toArray( new Right[rightMap.size()] );
    166                secObjectList.add( rights );
    167            }
    168            return secObjectList.toArray( new Right[secObjectList.size()][] );
    169        }
    170
    171        /**
    172         * Produces the logical disjunction of two <code>RightSets</code>.
    173         *
    174         * @param that
    175         * @return the new right set
    176         */
    177        public RightSet merge( RightSet that ) {
    178
    179            ArrayList<Right> mergedRights = new ArrayList<Right>( 20 );
    180            Iterator<SecurableObject> secObjectsIt = this.secObjects.keySet().iterator();
    181
    182            // add all rights from 'this' (and merge them with corresponding right
    183            // from 'that')
    184            while ( secObjectsIt.hasNext() ) {
    185                SecurableObject secObject = secObjectsIt.next();
    186                Map<RightType, Right> thisRightMap = this.secObjects.get( secObject );
    187                Map<RightType, Right> thatRightMap = that.secObjects.get( secObject );
    188                Iterator<RightType> rightIt = ( thisRightMap ).keySet().iterator();
    189                while ( rightIt.hasNext() ) {
    190                    RightType type = rightIt.next();
    191                    Right mergedRight = thisRightMap.get( type );
    192
    193                    // find corresponding Right (if any) in the other RightSet
    194                    if ( thatRightMap != null && thatRightMap.get( type ) != null ) {
    195                        try {
    196                            mergedRight = mergedRight.merge( thatRightMap.get( type ) );
    197                        } catch ( GeneralSecurityException e ) {
    198                            e.printStackTrace();
    199                        }
    200                    }
    201                    mergedRights.add( mergedRight );
    202                }
    203            }
    204
    205            // add role rights from 'that'
    206            secObjectsIt = that.secObjects.keySet().iterator();
    207            while ( secObjectsIt.hasNext() ) {
    208                SecurableObject secObject = secObjectsIt.next();
    209                Map<RightType, Right> thisRightMap = this.secObjects.get( secObject );
    210                Map<RightType, Right> thatRightMap = that.secObjects.get( secObject );
    211
    212                Iterator<RightType> it = thatRightMap.keySet().iterator();
    213                while ( it.hasNext() ) {
    214                    Object o = it.next();
    215                    RightType type = (RightType) o;
    216                    // find corresponding Right (if none, add)
    217                    if ( thisRightMap == null || thisRightMap.get( type ) == null ) {
    218                        mergedRights.add( thatRightMap.get( type ) );
    219                    }
    220                }
    221            }
    222            return new RightSet( mergedRights.toArray( new Right[mergedRights.size()] ) );
    223        }
    224
    225        @Override
    226        public String toString() {
    227            StringBuffer sb = new StringBuffer( "RightSet:" );
    228            Iterator<SecurableObject> it = secObjects.keySet().iterator();
    229            while ( it.hasNext() ) {
    230                SecurableObject secObject = it.next();
    231                sb.append( "on SecurableObject " ).append( secObject ).append( "\n" );
    232                Map<RightType, Right> rightMap = secObjects.get( secObject );
    233                Iterator<RightType> rights = rightMap.keySet().iterator();
    234                while ( rights.hasNext() ) {
    235                    RightType rightType = rights.next();
    236                    sb.append( "- Right " ).append( rightMap.get( rightType ) ).append( "\n" );
    237                }
    238            }
    239            return sb.toString();
    240        }
    241
    242    }