/******************************************************************************* * Copyright (c) 2007, 2014 compeople AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * compeople AG - initial API and implementation *******************************************************************************/ package org.eclipse.riena.internal.communication.publisher; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashSet; import java.util.Set; import javax.security.auth.Subject; import org.eclipse.riena.communication.core.RemoteServiceDescription; import org.eclipse.riena.communication.core.hooks.AbstractHooksProxy; import org.eclipse.riena.communication.core.hooks.IServiceHook; import org.eclipse.riena.communication.core.hooks.IServiceMessageContext; import org.eclipse.riena.communication.core.hooks.IServiceMessageContextAccessor; import org.eclipse.riena.communication.core.hooks.ServiceContext; import org.eclipse.riena.core.wire.InjectService; import org.eclipse.riena.core.wire.Wire; public class ServiceHooksProxy extends AbstractHooksProxy implements InvocationHandler { private final Set<IServiceHook> serviceHooks = new HashSet<IServiceHook>(); private RemoteServiceDescription rsd; private IServiceMessageContextAccessor mca; private Subject subject; public ServiceHooksProxy(final Object serviceInstance) { super(serviceInstance); Wire.instance(this).andStart(Activator.getDefault().getContext()); } @Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { if (method.getName().equals("equals") || method.getName().equals("hashCode")) { //$NON-NLS-1$ //$NON-NLS-2$ return new UnsupportedOperationException("method :" + method.getName() + " not supported for " //$NON-NLS-1$ //$NON-NLS-2$ + this.getServiceInstance()); } if (method.getName().equals("toString")) { //$NON-NLS-1$ return this.getServiceInstance().toString(); } IServiceMessageContext mc = null; if (mca != null) { mc = mca.getMessageContext(); } ServiceContext context = null; // only create context (it might be expensive), if you have serviceHooks if (serviceHooks.size() > 0) { context = new ServiceContext(rsd, method, getServiceInstance(), mc); // call before service hook for (final IServiceHook sHook : serviceHooks) { sHook.beforeService(context); } final Object s = context.getProperty("riena.subject"); //$NON-NLS-1$ if (s instanceof Subject) { subject = (Subject) s; } } try { return super.invoke(proxy, method, args); } catch (final InvocationTargetException e) { if (context != null) { context.setTargetException(e.getTargetException()); } throw e.getTargetException(); } finally { // context might be null, but serviceHooks were injected during invoke if (context != null) { for (final IServiceHook sHook : serviceHooks) { sHook.afterService(context); } if (context.getTargetException() != null) { throw context.getTargetException(); } } } } @InjectService public void bind(final IServiceHook serviceHook) { serviceHooks.add(serviceHook); } public void unbind(final IServiceHook serviceHook) { serviceHooks.remove(serviceHook); } public Object getServiceInstance() { return getProxiedInstance(); } public void setRemoteServiceDescription(final RemoteServiceDescription rsd) { this.rsd = rsd; } public void setMessageContextAccessor(final IServiceMessageContextAccessor mca) { this.mca = mca; } @Override public Subject getSubject() { return subject; } }