View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.neethi;
17  
18  import java.util.ArrayList;
19  import java.util.Iterator;
20  import java.util.List;
21  
22  import org.apache.neethi.util.PolicyComparator;
23  
24  /**
25   * AbstractPolicyOperator provides an implementation of few functions of 
26   * PolicyOperator interface that other PolicyOperators can use.
27   */
28  public abstract class AbstractPolicyOperator implements PolicyOperator {
29      protected ArrayList policyComponents = new ArrayList();
30  
31      public void addPolicyComponent(PolicyComponent component) {
32          policyComponents.add(component);
33      }
34  
35      public void addPolicyComponents(List components) {
36          policyComponents.addAll(components);
37      }
38  
39      public List getPolicyComponents() {
40          return policyComponents;
41      }
42  
43      public PolicyComponent getFirstPolicyComponent() {
44          return (PolicyComponent) policyComponents.get(0);
45      }
46  
47      public boolean isEmpty() {
48          return policyComponents.isEmpty();
49      }
50      
51      public boolean equal(PolicyComponent policyComponent) {
52          return PolicyComparator.compare(this, policyComponent);
53      }
54      
55      protected static Policy normalize(Policy policy, PolicyRegistry reg, boolean deep) {
56          Policy result = new Policy();
57          
58          String policyName = policy.getName();
59          if (policyName != null) {
60              result.setName(policyName);
61          }
62          
63          String id = policy.getId();
64          if (id != null) {
65              result.setId(id);
66          }
67          
68          
69          result.addPolicyComponent(normalizeOperator(policy,reg, deep));
70          return result;
71      }
72      
73      private static PolicyComponent normalizeOperator(PolicyOperator operator, PolicyRegistry reg, boolean deep) {
74                          
75          short type = operator.getType();
76                  
77          
78          if (operator.isEmpty()) {
79              ExactlyOne exactlyOne = new ExactlyOne();
80              
81              if (Constants.TYPE_EXACTLYONE != type) {
82                  exactlyOne.addPolicyComponent(new All());
83              }
84              return exactlyOne;
85          }
86                  
87          ArrayList childComponentsList = new ArrayList();
88          PolicyComponent policyComponent;
89          
90          for (Iterator iterator = operator.getPolicyComponents().iterator(); iterator.hasNext();) {
91              policyComponent = (PolicyComponent) iterator.next();
92              
93              if (policyComponent.getType() == Constants.TYPE_ASSERTION) {
94                  
95                  if (deep) {
96                      policyComponent = ((Assertion) policyComponent).normalize();                    
97                  }
98                  
99                  if (policyComponent.getType() == Constants.TYPE_POLICY) {
100                     childComponentsList.add(((Policy) policyComponent).getFirstPolicyComponent());
101                     
102                 } else  {
103                     ExactlyOne exactlyOne = new ExactlyOne();
104                     All all = new All();
105                     
106                     all.addPolicyComponent(policyComponent);
107                     exactlyOne.addPolicyComponent(all);
108                     childComponentsList.add(exactlyOne);
109                 }
110             } else if (policyComponent.getType() == Constants.TYPE_POLICY_REF) {
111                 String uri = ((PolicyReference) policyComponent).getURI();
112                 policyComponent = reg.lookup(uri);
113                 
114                 if (policyComponent == null) {
115                     throw new RuntimeException(uri + " can't be resolved");
116                 }
117                 
118             } else if (policyComponent.getType() == Constants.TYPE_POLICY) {
119                 All all = new All();
120                 all.addPolicyComponents(((Policy) policyComponent).getPolicyComponents());
121                 childComponentsList.add(AbstractPolicyOperator.normalizeOperator(all, reg, deep));
122                 
123             } else {
124                 childComponentsList.add(AbstractPolicyOperator.normalizeOperator((PolicyOperator) policyComponent, reg, deep));
125             }            
126         }
127         
128         return computeResultantComponent(childComponentsList, type);
129     }
130     
131     private static PolicyComponent computeResultantComponent(List normalizedInnerComponets, short componentType) {
132         
133         ExactlyOne exactlyOne = new ExactlyOne();
134         
135         if (componentType == Constants.TYPE_EXACTLYONE) {            
136             ExactlyOne innerExactlyOne;
137             
138             for (Iterator iter = normalizedInnerComponets.iterator(); iter.hasNext();) {
139                 innerExactlyOne = (ExactlyOne) iter.next();
140                 exactlyOne.addPolicyComponents(innerExactlyOne.getPolicyComponents());
141             }
142             
143         } else if ((componentType == Constants.TYPE_POLICY) || (componentType == Constants.TYPE_ALL)) {
144             // if the parent type is All then we have to get the cross product
145             if (normalizedInnerComponets.size() > 1) {
146                 // then we have to get the cross product with each other to process all elements
147                 Iterator iter = normalizedInnerComponets.iterator();
148                 // first get the first element
149                 exactlyOne = (ExactlyOne) iter.next();
150                 // if this is empty, this is an not admissible policy and total result is equalent to that
151                 if (!exactlyOne.isEmpty()) {
152                     ExactlyOne currentExactlyOne;
153 
154                     for (; iter.hasNext();) {
155                         currentExactlyOne = (ExactlyOne) iter.next();
156                         if (currentExactlyOne.isEmpty()) {
157                             // if this is empty, this is an not admissible policy and total result is equalent to that
158                             exactlyOne = currentExactlyOne;
159                             break;
160                         } else {
161                             exactlyOne = getCrossProduct(exactlyOne, currentExactlyOne);
162                         }
163                     }
164 
165                 }
166 
167             } else {
168                 // i.e only one element exists in the list then we can safely
169                 // return that element this is ok even if it is an empty element
170                 exactlyOne = (ExactlyOne) normalizedInnerComponets.iterator().next();
171             }
172         }
173         
174         return exactlyOne;
175     }
176     
177     private static ExactlyOne getCrossProduct(ExactlyOne exactlyOne1, ExactlyOne exactlyOne2) {
178         ExactlyOne crossProduct = new ExactlyOne();
179         All crossProductAll;
180 
181         All currentAll1;
182         All currentAll2;
183 
184         for (Iterator iter1 = exactlyOne1.getPolicyComponents().iterator(); iter1.hasNext();) {
185             currentAll1 = (All) iter1.next();
186 
187             for (Iterator iter2 = exactlyOne2.getPolicyComponents().iterator(); iter2.hasNext();) {
188                 currentAll2 = (All) iter2.next();
189                 crossProductAll = new All();
190                 crossProductAll.addPolicyComponents(currentAll1.getPolicyComponents());
191                 crossProductAll.addPolicyComponents(currentAll2.getPolicyComponents());
192                 crossProduct.addPolicyComponent(crossProductAll);
193             }
194         }
195 
196         return crossProduct;
197     }
198 }