KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > policy > PolicyFactory


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.repo.policy;
18
19 import java.lang.reflect.InvocationHandler JavaDoc;
20 import java.lang.reflect.InvocationTargetException JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.lang.reflect.Proxy JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.Collections JavaDoc;
26 import java.util.List JavaDoc;
27
28
29 /**
30  * A Policy Factory is responsible for creating Policy implementations.
31  *
32  * @author David Caruana
33  *
34  * @param <B> the type of binding
35  * @param <P> the policy interface
36  */

37 /*package*/ class PolicyFactory<B extends BehaviourBinding, P extends Policy>
38 {
39     // Behaviour Index to query
40
private BehaviourIndex<B> index;
41     
42     // The policy interface class
43
private Class JavaDoc<P> policyClass;
44     
45     
46     /**
47      * Construct.
48      *
49      * @param policyClass the policy class
50      * @param index the behaviour index to query
51      */

52     /*package*/ PolicyFactory(Class JavaDoc<P> policyClass, BehaviourIndex<B> index)
53     {
54         this.policyClass = policyClass;
55         this.index = index;
56     }
57     
58     
59     /**
60      * Gets the Policy class created by this factory
61      *
62      * @return the policy class
63      */

64     protected Class JavaDoc<P> getPolicyClass()
65     {
66         return policyClass;
67     }
68     
69
70     /**
71      * Construct a Policy implementation for the specified binding
72      *
73      * @param binding the binding
74      * @return the policy implementation
75      */

76     public P create(B binding)
77     {
78         Collection JavaDoc<P> policyInterfaces = createList(binding);
79         return toPolicy(policyInterfaces);
80     }
81     
82
83     /**
84      * Construct a collection of Policy implementations for the specified binding
85      *
86      * @param binding the binding
87      * @return the collection of policy implementations
88      */

89     @SuppressWarnings JavaDoc("unchecked")
90     public Collection JavaDoc<P> createList(B binding)
91     {
92         Collection JavaDoc<BehaviourDefinition> behaviourDefs = index.find(binding);
93         List JavaDoc<P> policyInterfaces = new ArrayList JavaDoc<P>(behaviourDefs.size());
94         for (BehaviourDefinition behaviourDef : behaviourDefs)
95         {
96             Behaviour behaviour = behaviourDef.getBehaviour();
97             P policyIF = behaviour.getInterface(policyClass);
98             policyInterfaces.add(policyIF);
99         }
100         
101         return policyInterfaces;
102     }
103     
104     
105     /**
106      * Construct a single aggregate policy implementation for the specified
107      * collection of policy implementations.
108      *
109      * @param policyList the policy implementations to aggregate
110      * @return the aggregate policy implementation
111      */

112     @SuppressWarnings JavaDoc("unchecked")
113     public P toPolicy(Collection JavaDoc<P> policyList)
114     {
115         if (policyList.size() == 1)
116         {
117             return policyList.iterator().next();
118         }
119         else if (policyList.size() == 0)
120         {
121             return (P)Proxy.newProxyInstance(policyClass.getClassLoader(),
122                     new Class JavaDoc[]{policyClass}, new NOOPHandler());
123         }
124         else
125         {
126             return (P)Proxy.newProxyInstance(policyClass.getClassLoader(),
127                     new Class JavaDoc[]{policyClass, PolicyList.class}, new MultiHandler<P>(policyList));
128         }
129     }
130     
131
132     /**
133      * NOOP Invocation Handler.
134      *
135      * @author David Caruana
136      *
137      */

138     private static class NOOPHandler implements InvocationHandler JavaDoc
139     {
140         /* (non-Javadoc)
141          * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
142          */

143         public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc
144         {
145             if (method.getName().equals("toString"))
146             {
147                 return toString();
148             }
149             else if (method.getName().equals("hashCode"))
150             {
151                 return hashCode();
152             }
153             else if (method.getName().equals("equals"))
154             {
155                 return equals(args[0]);
156             }
157             return null;
158         }
159     }
160         
161
162     /**
163      * Multi-policy Invocation Handler.
164      *
165      * @author David Caruana
166      *
167      * @param <P> policy interface
168      */

169     @SuppressWarnings JavaDoc("hiding")
170     private static class MultiHandler<P> implements InvocationHandler JavaDoc, PolicyList
171     {
172         private Collection JavaDoc<P> policyInterfaces;
173        
174         /**
175          * Construct
176          *
177          * @param policyInterfaces the collection of policy implementations
178          */

179         public MultiHandler(Collection JavaDoc<P> policyInterfaces)
180         {
181             this.policyInterfaces = Collections.unmodifiableCollection(policyInterfaces);
182         }
183         
184         /* (non-Javadoc)
185          * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
186          */

187         public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc
188         {
189             // Handle PolicyList level methods
190
if (method.getDeclaringClass().equals(PolicyList.class))
191             {
192                 return method.invoke(this, args);
193             }
194             
195             // Handle Object level methods
196
if (method.getName().equals("toString"))
197             {
198                 return toString() + ": wrapped " + policyInterfaces.size() + " policies";
199             }
200             else if (method.getName().equals("hashCode"))
201             {
202                 return hashCode();
203             }
204             else if (method.getName().equals("equals"))
205             {
206                 return equals(args[0]);
207             }
208
209             // Invoke each wrapped policy in turn
210
try
211             {
212                 Object JavaDoc result = null;
213                 for (P policyInterface : policyInterfaces)
214                 {
215                     result = method.invoke(policyInterface, args);
216                 }
217                 return result;
218             }
219             catch (InvocationTargetException JavaDoc e)
220             {
221                 throw e.getTargetException();
222             }
223         }
224
225         /* (non-Javadoc)
226          * @see org.alfresco.repo.policy.PolicyList#getPolicies()
227          */

228         public Collection JavaDoc getPolicies()
229         {
230             return policyInterfaces;
231         }
232     }
233     
234 }
235
Popular Tags