001 //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/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 by the 048 * <code>SecurableObject</code> for which they apply to support an efficient implementation of the merge()-operation. 049 * The merge()-operation results in a <code>RightSet</code> that contains the logical rights of boths sets, but only one 050 * <code>Right</code> object of each <code>RightType</code> (and <code>SecurableObject</code>). This is accomplished by 051 * merging the constraints of the <code>Rights</code> of the same type (and object). 052 * 053 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a> 054 * @version $Revision: 32121 $ 055 */ 056 public class RightSet { 057 058 // keys are SecurableObjects (for which the rights are defined), values 059 // are Maps (keys are RightTypes, values are Rights) 060 private Map<SecurableObject, Map<RightType, Right>> secObjects = new HashMap<SecurableObject, Map<RightType, Right>>(); 061 062 private boolean isEmpty; 063 064 RightSet() { 065 } 066 067 /** 068 * @param rights 069 */ 070 public RightSet( Right[] rights ) { 071 this.isEmpty = rights == null || rights.length == 0; 072 for ( int i = 0; i < rights.length; i++ ) { 073 Map<RightType, Right> rightMap = secObjects.get( rights[i].getSecurableObject() ); 074 if ( rightMap == null ) { 075 rightMap = new HashMap<RightType, Right>(); 076 } 077 rightMap.put( rights[i].getType(), rights[i] ); 078 secObjects.put( rights[i].getSecurableObject(), rightMap ); 079 } 080 } 081 082 public boolean isEmpty() { 083 return isEmpty; 084 } 085 086 /** 087 * Checks if the <code>RightSet</code> contains the permissions for a <code>SecurableObject</code> and a concrete 088 * situation (the situation is represented by the given <code>Feature</code>). 089 * 090 * @param object 091 * @param type 092 * @param situation 093 * @return true, if the right applies 094 * @throws GeneralSecurityException 095 */ 096 public boolean applies( SecurableObject object, RightType type, Feature situation ) 097 throws GeneralSecurityException { 098 boolean applies = false; 099 Map<RightType, Right> rightMap = secObjects.get( object ); 100 if ( rightMap != null ) { 101 Right right = rightMap.get( type ); 102 if ( right != null ) { 103 applies = right.applies( object, situation ); 104 } 105 } 106 return applies; 107 } 108 109 /** 110 * Checks if the <code>RightSet</code> contains the (unrestricted) permissions for a <code>SecurableObject</code> 111 * and a certain type of right. 112 * 113 * @param object 114 * @param type 115 * @return true, if the right applies 116 */ 117 public boolean applies( SecurableObject object, RightType type ) { 118 boolean applies = false; 119 Map<RightType, Right> rightMap = secObjects.get( object ); 120 if ( rightMap != null ) { 121 Right right = rightMap.get( type ); 122 if ( right != null ) { 123 applies = right.applies( object ); 124 } 125 126 } 127 return applies; 128 } 129 130 /** 131 * @param secObject 132 * @param type 133 * @return the <code>Right</code> of the specified <code>RightType</code> that this <code>RightSet</code> defines on 134 * the specified <code>SecurableObject</code>. 135 */ 136 public Right getRight( SecurableObject secObject, RightType type ) { 137 Right right = null; 138 if ( secObjects.get( secObject ) != null ) { 139 right = secObjects.get( secObject ).get( type ); 140 } 141 return right; 142 } 143 144 /** 145 * @param secObject 146 * @return the encapulated <code>Rights</code> (for one <code>SecurableObject</code>) as an one-dimensional array. 147 */ 148 public Right[] toArray( SecurableObject secObject ) { 149 Right[] rights = new Right[0]; 150 Map<RightType, Right> rightMap = secObjects.get( secObject ); 151 if ( rightMap != null ) { 152 rights = rightMap.values().toArray( new Right[rightMap.size()] ); 153 } 154 return rights; 155 } 156 157 /** 158 * @return the encapulated <code>Rights</code> as a two-dimensional array: 159 * <ul> 160 * <li>first index: runs the different <code>SecurableObjects</code> 161 * <li>second index: runs the different <code>Rights</code> 162 * </ul> 163 */ 164 public Right[][] toArray2() { 165 ArrayList<Right[]> secObjectList = new ArrayList<Right[]>(); 166 Iterator<Map<RightType, Right>> it = secObjects.values().iterator(); 167 while ( it.hasNext() ) { 168 Map<RightType, Right> rightMap = it.next(); 169 Right[] rights = rightMap.values().toArray( new Right[rightMap.size()] ); 170 secObjectList.add( rights ); 171 } 172 return secObjectList.toArray( new Right[secObjectList.size()][] ); 173 } 174 175 /** 176 * Produces the logical disjunction of two <code>RightSets</code>. 177 * 178 * @param that 179 * @return the new right set 180 */ 181 public RightSet merge( RightSet that ) { 182 183 ArrayList<Right> mergedRights = new ArrayList<Right>( 20 ); 184 Iterator<SecurableObject> secObjectsIt = this.secObjects.keySet().iterator(); 185 186 // add all rights from 'this' (and merge them with corresponding right 187 // from 'that') 188 while ( secObjectsIt.hasNext() ) { 189 SecurableObject secObject = secObjectsIt.next(); 190 Map<RightType, Right> thisRightMap = this.secObjects.get( secObject ); 191 Map<RightType, Right> thatRightMap = that.secObjects.get( secObject ); 192 Iterator<RightType> rightIt = ( thisRightMap ).keySet().iterator(); 193 while ( rightIt.hasNext() ) { 194 RightType type = rightIt.next(); 195 Right mergedRight = thisRightMap.get( type ); 196 197 // find corresponding Right (if any) in the other RightSet 198 if ( thatRightMap != null && thatRightMap.get( type ) != null ) { 199 try { 200 mergedRight = mergedRight.merge( thatRightMap.get( type ) ); 201 } catch ( GeneralSecurityException e ) { 202 e.printStackTrace(); 203 } 204 } 205 mergedRights.add( mergedRight ); 206 } 207 } 208 209 // add role rights from 'that' 210 secObjectsIt = that.secObjects.keySet().iterator(); 211 while ( secObjectsIt.hasNext() ) { 212 SecurableObject secObject = secObjectsIt.next(); 213 Map<RightType, Right> thisRightMap = this.secObjects.get( secObject ); 214 Map<RightType, Right> thatRightMap = that.secObjects.get( secObject ); 215 216 Iterator<RightType> it = thatRightMap.keySet().iterator(); 217 while ( it.hasNext() ) { 218 Object o = it.next(); 219 RightType type = (RightType) o; 220 // find corresponding Right (if none, add) 221 if ( thisRightMap == null || thisRightMap.get( type ) == null ) { 222 mergedRights.add( thatRightMap.get( type ) ); 223 } 224 } 225 } 226 return new RightSet( mergedRights.toArray( new Right[mergedRights.size()] ) ); 227 } 228 229 @Override 230 public String toString() { 231 StringBuffer sb = new StringBuffer( "RightSet:" ); 232 Iterator<SecurableObject> it = secObjects.keySet().iterator(); 233 while ( it.hasNext() ) { 234 SecurableObject secObject = it.next(); 235 sb.append( "on SecurableObject " ).append( secObject ).append( "\n" ); 236 Map<RightType, Right> rightMap = secObjects.get( secObject ); 237 Iterator<RightType> rights = rightMap.keySet().iterator(); 238 while ( rights.hasNext() ) { 239 RightType rightType = rights.next(); 240 sb.append( "- Right " ).append( rightMap.get( rightType ) ).append( "\n" ); 241 } 242 } 243 return sb.toString(); 244 } 245 246 }