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  
19  package org.apache.river.phoenix.group;
20  
21  import java.rmi.MarshalledObject;
22  import java.rmi.Remote;
23  import java.rmi.RemoteException;
24  import java.rmi.activation.ActivationDesc;
25  import java.rmi.activation.ActivationException;
26  import java.rmi.activation.ActivationID;
27  import java.rmi.activation.ActivationInstantiator;
28  import java.rmi.server.ExportException;
29  import net.jini.export.Exporter;
30  import net.jini.jrmp.JrmpExporter;
31  import org.apache.river.phoenix.common.LocalAccess;
32  
33  /**
34   * Exporter that wraps an <code>ActivationInstantiator</code> instance so that
35   * it only accepts calls from the local host.
36   *
37   * @author Sun Microsystems, Inc.
38   * 
39   * @since 2.0
40   */
41  public class InstantiatorAccessExporter implements Exporter {
42      /**
43       * The underlying exporter.
44       */
45      private final Exporter exporter;
46      /**
47       * The wrapped impl.
48       */
49      private Remote wrapped;
50  
51      /**
52       * Creates an exporter with an underlying {@link JrmpExporter} that
53       * exports on an anonymous port.
54       */
55      public InstantiatorAccessExporter() {
56  	this.exporter = new JrmpExporter();
57      }
58  
59      /**
60       * Creates an exporter with the specified underlying exporter.
61       *
62       * @param exporter the underlying exporter
63       */
64      public InstantiatorAccessExporter(Exporter exporter) {
65  	this.exporter = exporter;
66      }
67  
68      /**
69       * Wraps the specified remote object in an
70       * <code>ActivationInstantiator</code> implementation that only accepts
71       * calls from the local host before delegating to the specified remote
72       * object, exports the wrapper with the underlying exporter, and returns
73       * the resulting proxy. The wrapper is strongly referenced by this
74       * exporter. For the <code>newInstance</code> method, the wrapper throws an
75       * <code>AccessControlException</code> if the client is not calling from
76       * the local host.
77       *
78       * @throws IllegalArgumentException if <code>impl</code> does not
79       * implement <code>ActivationInstantiator</code>
80       * @throws NullPointerException {@inheritDoc}
81       * @throws IllegalStateException {@inheritDoc}
82       */
83      public Remote export(Remote impl) throws ExportException {
84  	if (!(impl instanceof ActivationInstantiator)) {
85  	    throw new IllegalArgumentException(
86  					    "not an ActivationInstantiator");
87  	}
88  	Remote wrapped = new InstantiatorImpl((ActivationInstantiator) impl);
89  	Remote proxy = exporter.export(wrapped);
90  	this.wrapped = wrapped;
91  	return proxy;
92      }
93  
94      /**
95       * @throws IllegalStateException {@inheritDoc}
96       */
97      public boolean unexport(boolean force) {
98  	return exporter.unexport(force);
99      }
100 
101     private static class InstantiatorImpl extends AbstractInstantiator {
102 	private final ActivationInstantiator impl;
103 
104 	InstantiatorImpl(ActivationInstantiator impl) {
105 	    this.impl = impl;
106 	}
107 
108 	public MarshalledObject newInstance(ActivationID id,
109 					    ActivationDesc desc)
110 	    throws ActivationException, RemoteException
111 	{
112 	    LocalAccess.check();
113 	    return impl.newInstance(id, desc);
114 	}
115     }
116 }