/* * 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 org.apache.jena.permissions.impl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import org.apache.jena.permissions.SecuredItem; /** * A generic InvocationHandler that handles the general invocation of the * security methods. */ public class SecuredItemInvoker implements InvocationHandler { // the equals() method private static Method EQUALS; // the toString() method private static Method TO_STRING; // the hashCode() method. private static Method HASH_CODE; // the instance of SecuredItem that this proxy is using. Must be // package-private for ItemHolder use. /* package-private */final SecuredItem securedItem; final Class<?> securedClass; // populate the static fields. static { try { SecuredItemInvoker.EQUALS = Object.class.getMethod("equals", Object.class); SecuredItemInvoker.TO_STRING = Object.class.getMethod("toString"); SecuredItemInvoker.HASH_CODE = Object.class.getMethod("hashCode"); } catch (final SecurityException e) { throw new RuntimeException(e); } catch (final NoSuchMethodException e) { throw new RuntimeException(e); } } /** * Constructor. * * @param securedClass * The class of the object that is being protected. * @param securedItem * The implementation of the SecuredItem version of the object. */ public SecuredItemInvoker( final Class<?> securedClass, final SecuredItem securedItem ) { this.securedItem = securedItem; this.securedClass = securedClass; } @Override public Object invoke( final Object proxy, final Method method, final Object[] args ) throws Throwable { // check for the special case methods if (SecuredItemInvoker.EQUALS.equals(method)) { if (Proxy.isProxyClass(args[0].getClass())) { return args[0].equals(securedItem); } else { return securedItem.equals(args[0]); } } if (SecuredItemInvoker.HASH_CODE.equals(method)) { return securedItem.hashCode(); } if (SecuredItemInvoker.TO_STRING.equals(method)) { return securedItem.toString(); } try { final Method m = securedItem.getClass().getMethod(method.getName(), method.getParameterTypes()); if (!Modifier.isAbstract(m.getModifiers())) { try { SecuredItemImpl.incrementUse(); try { return m.invoke(securedItem, args); } finally { SecuredItemImpl.decrementUse(); } } catch (final java.lang.reflect.InvocationTargetException e2) { if (e2.getTargetException() instanceof RuntimeException) { throw e2.getTargetException(); } throw e2; } } } catch (final NoSuchMethodException e2) { // acceptable } // if we get here then the method is not being proxied so call the // original method on the base item. return method.invoke(securedItem.getBaseItem(), args); } }