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 }