View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    * 
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.river.outrigger.proxy;
19  
20  import org.apache.river.admin.DestroyAdmin;
21  import org.apache.river.proxy.ConstrainableProxyUtil;
22  import java.io.IOException;
23  import java.io.ObjectInputStream;
24  import java.io.ObjectOutputStream;
25  import java.lang.reflect.Method;
26  import java.rmi.RemoteException;
27  import net.jini.admin.JoinAdmin;
28  import net.jini.core.constraint.MethodConstraints;
29  import net.jini.core.constraint.RemoteMethodControl;
30  import net.jini.core.discovery.LookupLocator;
31  import net.jini.core.entry.Entry;
32  import net.jini.core.transaction.Transaction;
33  import net.jini.core.transaction.TransactionException;
34  import net.jini.id.Uuid;
35  import net.jini.security.proxytrust.ProxyTrustIterator;
36  import net.jini.security.proxytrust.SingletonProxyTrustIterator;
37  import org.apache.river.api.io.AtomicSerial;
38  import org.apache.river.api.io.AtomicSerial.GetArg;
39  import org.apache.river.admin.AdminIterator;
40  import org.apache.river.admin.JavaSpaceAdmin;
41  
42  /**
43   * Constrainable subclass of <code>AdminProxy</code>
44   *
45   * @author Sun Microsystems, Inc.
46   * @since 2.0
47   */
48  @AtomicSerial
49  public final class ConstrainableAdminProxy extends AdminProxy
50      implements RemoteMethodControl, ConstrainableJavaSpaceAdmin
51  {
52      static final long serialVersionUID = 1L;
53  
54      /**
55       * Array containing element pairs in which each pair of elements
56       * represents a mapping between two methods having the following
57       * characteristics:
58       * <ul>
59       * <li> the first element in the pair is one of the public, remote
60       *      method(s) that may be invoked by the client through 
61       *      <code>AdminProxy</code>.
62       * <li> the second element in the pair is the method, implemented
63       *      in the backend server class, that is ultimately executed in
64       *      the server's backend when the client invokes the corresponding
65       *      method in this proxy.
66       * </ul>
67       */
68      private static final Method[] methodMapArray =  {
69  	ProxyUtil.getMethod(JoinAdmin.class, "getLookupAttributes", 
70  			    new Class[] {}),
71  	ProxyUtil.getMethod(JoinAdmin.class, "getLookupAttributes",
72  			    new Class[] {}),
73  
74  
75  	ProxyUtil.getMethod(JoinAdmin.class, "addLookupAttributes", 
76  			    new Class[] {Entry[].class}),
77  	ProxyUtil.getMethod(JoinAdmin.class, "addLookupAttributes", 
78  			    new Class[] {Entry[].class}),
79  
80  
81  	ProxyUtil.getMethod(JoinAdmin.class, "modifyLookupAttributes", 
82  			    new Class[] {Entry[].class, Entry[].class}),
83  	ProxyUtil.getMethod(JoinAdmin.class, "modifyLookupAttributes", 
84  			    new Class[] {Entry[].class, Entry[].class}),
85  
86  
87  	ProxyUtil.getMethod(JoinAdmin.class, "getLookupGroups",
88  			    new Class[] {}),
89  	ProxyUtil.getMethod(JoinAdmin.class, "getLookupGroups",
90  			    new Class[] {}),
91  
92  	ProxyUtil.getMethod(JoinAdmin.class, "setLookupGroups", 
93  			    new Class[] {String[].class}),
94  	ProxyUtil.getMethod(JoinAdmin.class, "setLookupGroups", 
95  			    new Class[] {String[].class}),
96  
97  
98  	ProxyUtil.getMethod(JoinAdmin.class, "removeLookupGroups", 
99  			    new Class[] {String[].class}),
100 	ProxyUtil.getMethod(JoinAdmin.class, "removeLookupGroups", 
101 			    new Class[] {String[].class}),
102 
103 
104 	ProxyUtil.getMethod(JoinAdmin.class, "addLookupGroups", 
105 			    new Class[] {String[].class}),
106 	ProxyUtil.getMethod(JoinAdmin.class, "addLookupGroups", 
107 			    new Class[] {String[].class}),
108 
109 
110 	ProxyUtil.getMethod(JoinAdmin.class, "getLookupLocators", 
111 			    new Class[] {}),
112 	ProxyUtil.getMethod(JoinAdmin.class, "getLookupLocators", 
113 			    new Class[] {}),
114 
115 
116 
117 	ProxyUtil.getMethod(JoinAdmin.class, "setLookupLocators", 
118 			    new Class[] {LookupLocator[].class} ),
119 	ProxyUtil.getMethod(JoinAdmin.class, "setLookupLocators", 
120 			    new Class[] {LookupLocator[].class} ),
121 
122 
123 	ProxyUtil.getMethod(JoinAdmin.class, "addLookupLocators", 
124 			    new Class[] {LookupLocator[].class} ),
125 	ProxyUtil.getMethod(JoinAdmin.class, "addLookupLocators", 
126 			    new Class[] {LookupLocator[].class} ),
127 
128 
129 	ProxyUtil.getMethod(JoinAdmin.class, "removeLookupLocators", 
130 			    new Class[] {LookupLocator[].class} ),
131 	ProxyUtil.getMethod(JoinAdmin.class, "removeLookupLocators", 
132 			    new Class[] {LookupLocator[].class} ),
133 
134 
135 	ProxyUtil.getMethod(DestroyAdmin.class, "destroy", new Class[] {}),
136 	ProxyUtil.getMethod(DestroyAdmin.class, "destroy", new Class[] {}),
137 
138 
139 	ProxyUtil.getMethod(JavaSpaceAdmin.class, "space", new Class[] {}),
140 	ProxyUtil.getMethod(OutriggerAdmin.class, "space", new Class[] {}),
141 
142 
143 	ProxyUtil.getMethod(ConstrainableJavaSpaceAdmin.class, "contents", 
144 			    new Class[] {Entry.class,
145 					 Transaction.class,
146 					 int.class,
147 					 MethodConstraints.class}),
148 	ProxyUtil.getMethod(OutriggerAdmin.class, "contents", 
149 			    new Class[] {EntryRep.class,
150 					 Transaction.class} )
151     }; // end methodMapArray
152 
153     /** 
154      * Client constraints placed on this proxy (may be <code>null</code> 
155      * @serial
156      */
157     private final MethodConstraints methodConstraints;
158     
159     /**
160      * Create a new <code>ConstrainableAdminProxy</code>.
161      * @param admin reference to remote server for the space.
162      * @param spaceUuid universal unique ID for the space.
163      * @param methodConstraints the client method constraints to place on
164      *                          this proxy (may be <code>null</code>).
165      * @throws NullPointerException if <code>admin</code> or
166      *         <code>spaceUuid</code> is <code>null</code>.     
167      * @throws ClassCastException if <code>admin</code>
168      *         does not implement <code>RemoteMethodControl</code>.
169      */
170     public ConstrainableAdminProxy(OutriggerAdmin admin, Uuid spaceUuid, 
171 			    MethodConstraints methodConstraints)
172     {
173 	super(constrainServer(admin, methodConstraints), spaceUuid);
174 	this.methodConstraints = methodConstraints;
175     }
176 
177     ConstrainableAdminProxy(GetArg arg)throws IOException {
178 	super(check(arg));
179 	methodConstraints = (MethodConstraints) 
180 		arg.get("methodConstraints", null);
181     }
182     
183     private static GetArg check(GetArg arg) throws IOException {
184 	AdminProxy ap = new AdminProxy(arg);
185 	MethodConstraints methodConstraints = (MethodConstraints) 
186 		arg.get("methodConstraints", null);
187 	/* basic validation of admin and spaceUuid was performed by
188 	 * AdminProxy.readObject(), we just need to verify than space
189 	 * implements RemoteMethodControl and that it has appropriate
190 	 * constraints.
191 	 */
192 	ConstrainableProxyUtil.verifyConsistentConstraints(
193 	    methodConstraints, ap.admin, methodMapArray);
194 	return arg;
195     }
196 
197     /**
198      * Returns a copy of the given <code>OutriggerAdmin</code> proxy
199      * having the client method constraints that result after
200      * mapping defined by methodMapArray is applied.
201      * @param server The proxy to attach constrains too.
202      * @param constraints The source method constraints.
203      * @throws NullPointerException if <code>server</code> is 
204      *         <code>null</code>.
205      * @throws ClassCastException if <code>server</code>
206      *         does not implement <code>RemoteMethodControl</code>.
207      */
208     private static OutriggerAdmin constrainServer(OutriggerAdmin server,
209         MethodConstraints constraints)
210     {
211 	final MethodConstraints serverRefConstraints 
212 	    = ConstrainableProxyUtil.translateConstraints(constraints,
213 							  methodMapArray);
214 	final RemoteMethodControl constrainedServer = 
215 	    ((RemoteMethodControl)server).
216 	    setConstraints(serverRefConstraints);
217 
218 	return (OutriggerAdmin)constrainedServer;
219     }
220 
221     public RemoteMethodControl setConstraints(MethodConstraints constraints)
222     {
223 	return new ConstrainableAdminProxy(admin, spaceUuid, constraints);
224     }
225 
226     public MethodConstraints getConstraints() {
227 	return methodConstraints;
228     }
229 
230     /** 
231      * Returns a proxy trust iterator that is used in 
232      * <code>ProxyTrustVerifier</code> to retrieve this object's
233      * trust verifier.
234      */
235     private ProxyTrustIterator getProxyTrustIterator() {
236 	return new SingletonProxyTrustIterator(admin);
237     }
238 
239     private void writeObject(ObjectOutputStream out) throws IOException {
240 	out.defaultWriteObject();
241     }
242     private void readObject(ObjectInputStream s)  
243 	throws IOException, ClassNotFoundException
244     {
245 	s.defaultReadObject();
246 
247 	/* basic validation of admin and spaceUuid was performed by
248 	 * AdminProxy.readObject(), we just need to verify than space
249 	 * implements RemoteMethodControl and that it has appropriate
250 	 * constraints.
251 	 */
252 	ConstrainableProxyUtil.verifyConsistentConstraints(
253 	    methodConstraints, admin, methodMapArray);
254     }
255 
256     /**
257      * Override super class to create secure <code>IteratorProxy</code>s
258      */
259     public AdminIterator contents(Entry tmpl, Transaction tr, int fetchSize)
260 	throws TransactionException, RemoteException
261     {
262 	return contents(tmpl, tr, fetchSize, null);
263     }
264 
265 
266     public AdminIterator contents(Entry tmpl, Transaction txn, int fetchSize,
267 				  MethodConstraints constraints)
268 	throws TransactionException, RemoteException
269     {
270 	return new ConstrainableIteratorProxy(
271 	    admin.contents(SpaceProxy2.repFor(tmpl), txn), admin, fetchSize,
272 			   constraints);
273     }
274 
275 }