/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.jini.jeri; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.security.Permission; import java.rmi.Remote; import java.rmi.server.ExportException; import java.security.Permission; import java.util.Collection; import net.jini.core.constraint.MethodConstraints; import net.jini.core.constraint.RemoteMethodControl; import net.jini.security.proxytrust.TrustEquivalence; /** * A basic implementation of an {@link InvocationLayerFactory}. This * factory is used to create a {@link Proxy} instance with a {@link * BasicInvocationHandler} and to create a {@link * BasicInvocationDispatcher} for a remote object being exported. This * factory is used in conjunction with the {@link BasicJeriExporter} class. * * @author Sun Microsystems, Inc. * @since 2.0 **/ public class BasicILFactory extends AbstractILFactory { /** * The server constraints, or null; */ private final MethodConstraints serverConstraints; /** * The permission class, or null. */ private final Class permissionClass; /** * Creates a <code>BasicILFactory</code> instance with no server * constraints, no permission class, and a <code>null</code> class * loader. **/ public BasicILFactory() { this.serverConstraints = null; this.permissionClass = null; } /** * Creates a <code>BasicILFactory</code> with the specified server * constraints, permission class, and a <code>null</code> class * loader. * * @param serverConstraints the server constraints, or <code>null</code> * @param permissionClass the permission class, or <code>null</code> * @throws IllegalArgumentException if the permission class is * abstract, is not a subclass of {@link Permission}, or does * not have a public constructor that has either one * <code>String</code> parameter or one {@link Method} * parameter and has no declared exceptions **/ public BasicILFactory(MethodConstraints serverConstraints, Class permissionClass) { this(serverConstraints, permissionClass, null); } /** * Creates a <code>BasicILFactory</code> with the specified server * constraints, permission class, and class loader. The server * constraints, if not <code>null</code>, are used to enforce minimum * constraints for remote calls. The permission class, if not * <code>null</code>, is used to perform server-side access control on * incoming remote calls. The class loader, which may be * <code>null</code>, is passed to the superclass constructor and is * used by the {@link #createInstances createInstances} * method. * * @param serverConstraints the server constraints, or <code>null</code> * @param permissionClass the permission class, or <code>null</code> * @param loader the class loader, or <code>null</code> * @throws IllegalArgumentException if the permission class is * abstract, is not a subclass of {@link Permission}, or does * not have a public constructor that has either one * <code>String</code> parameter or one {@link Method} * parameter and has no declared exceptions **/ public BasicILFactory(MethodConstraints serverConstraints, Class permissionClass, ClassLoader loader) { super(loader); BasicInvocationDispatcher.checkPermissionClass(permissionClass); this.serverConstraints = serverConstraints; this.permissionClass = permissionClass; } /** * Returns an invocation handler to use with a {@link Proxy} instance * implementing the specified interfaces, communicating with the * specified remote object using the specified object endpoint. * * <p><code>BasicILFactory</code> implements this method to * return a {@link BasicInvocationHandler} constructed with the * specified object endpoint and this factory's server constraints. * * @throws NullPointerException {@inheritDoc} **/ protected InvocationHandler createInvocationHandler(Class[] interfaces, Remote impl, ObjectEndpoint oe) throws ExportException { for (int i = interfaces.length; --i >= 0; ) { if (interfaces[i] == null) { throw new NullPointerException(); } } if (impl == null) { throw new NullPointerException(); } return new BasicInvocationHandler(oe, serverConstraints); } /** * Returns a new array containing any additional interfaces that the * proxy should implement, beyond the interfaces obtained by passing * <code>impl</code> to the {@link #getRemoteInterfaces * getRemoteInterfaces} method. * * <p><code>BasicILFactory</code> implements this method to return a * new array containing the {@link RemoteMethodControl} and {@link * TrustEquivalence} interfaces, in that order. * * @throws NullPointerException {@inheritDoc} **/ protected Class[] getExtraProxyInterfaces(Remote impl) { if (impl == null) { throw new NullPointerException(); } return new Class[]{RemoteMethodControl.class, TrustEquivalence.class}; } /** * Returns an invocation dispatcher to receive incoming remote calls * for the specified methods to the specified remote object, for a * server and transport with the specified capabilities. * * <p><code>BasicILFactory</code> implements this method to return a * {@link BasicInvocationDispatcher} instance constructed with the * specified methods, server capabilities, and this factory's * server constraints, permission class, and class loader specified * at construction. * * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} **/ protected InvocationDispatcher createInvocationDispatcher(Collection methods, Remote impl, ServerCapabilities caps) throws ExportException { if (impl == null) { throw new NullPointerException("impl is null"); } return new BasicInvocationDispatcher(methods, caps, serverConstraints, permissionClass, getClassLoader()); } /** * Returns the server constraints, if any. * * @return the server constraints, or <code>null</code> **/ public final MethodConstraints getServerConstraints() { return serverConstraints; } /** * Returns the permission class, if any. * * @return the permission class, or <code>null</code> */ public final Class getPermissionClass() { return permissionClass; } /** * Returns a hash code value for this factory. **/ public int hashCode() { int h = super.hashCode(); if (serverConstraints != null) { h += serverConstraints.hashCode(); } if (permissionClass != null) { h += permissionClass.hashCode(); } return h; } /** * Compares the specified object with this invocation layer factory for * equality. * * <p><code>BasicILFactory</code> implements this method to return * <code>true</code> if and only if invoking the superclass's * <code>equals</code> method passing the specified object returns * <code>true</code>, the specified object has the same class as this * object, and the server constraints and permission class are equal to * the ones in this object. **/ public boolean equals(Object obj) { if (!super.equals(obj)) { return false; } BasicILFactory ilf = (BasicILFactory) obj; return (permissionClass == ilf.permissionClass && (serverConstraints == ilf.serverConstraints || (serverConstraints != null && serverConstraints.equals(ilf.serverConstraints)))); } /** * Returns a string representation of this factory. **/ public String toString() { return (super.toString() + "[" + serverConstraints + (permissionClass != null ? ", " + permissionClass.getName() : "") + "]"); } }