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 }