001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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 }