/* * Copyright 2008 Glencoe Software, Inc. All rights reserved. * Use is subject to license terms supplied in LICENSE.txt */ package ome.services.blitz.impl; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; import ome.api.ServiceInterface; import ome.logic.HardWiredInterceptor; import ome.services.blitz.fire.AopContextInitializer; import ome.services.blitz.util.BlitzExecutor; import ome.services.blitz.util.IceMethodInvoker; import ome.services.throttling.Task; import ome.services.throttling.ThrottlingStrategy; import ome.services.util.Executor; import ome.system.OmeroContext; import omero.ServerError; import omero.api.AMD_StatefulServiceInterface_activate; import omero.api.AMD_StatefulServiceInterface_close; import omero.api.AMD_StatefulServiceInterface_getCurrentEventContext; import omero.api.AMD_StatefulServiceInterface_passivate; import omero.api._ServiceInterfaceOperations; import omero.util.IceMapper; import omero.util.ServantHolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.BeansException; import org.springframework.beans.FatalBeanException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import Ice.Current; /** * {@link ThrottlingStrategy throttled} implementation base class which can be * used by {@link _ServiceInterfaceOperations} implementors and injected into a * tie servant. * * @author Josh Moore, josh at glencoesoftware.com * @since 3.0-Beta4 */ public abstract class AbstractAmdServant implements ApplicationContextAware { final protected Logger log = LoggerFactory.getLogger(getClass()); final protected BlitzExecutor be; /** * If there is no undering ome.* service, then this value can be null. */ protected ServiceInterface service; /** * If a service is provided, then an invoker will be created to cache all of * its methods. */ protected IceMethodInvoker invoker; protected OmeroContext ctx; protected ServantHolder holder; public AbstractAmdServant(ServiceInterface service, BlitzExecutor be) { this.be = be; this.service = service; } /** * Sets the {@link ServantHolder} for the current session so that on * {@link AbstractCloseableAmdServant#close_async(AMD_StatefulServiceInterface_close, Current)} * it will be possible to cleanup the resources. * @param holder */ public void setHolder(ServantHolder holder) { this.holder = holder; } /** * Creates an {@link IceMethodInvoker} for this instance if {@link #service} * is non-null. Otherwise gives subclasses a chance to use the {@link OmeroContext} * via {@link #onSetOmeroContext(OmeroContext)} */ public final void setApplicationContext(ApplicationContext ctx) throws BeansException { this.ctx = (OmeroContext) ctx; if (service != null) { this.invoker = new IceMethodInvoker(service, this.ctx); } try { onSetOmeroContext(this.ctx); } catch (Exception e) { throw new FatalBeanException("Error on setOmeroContext", e); } } /** * To be overridden by subclasses. */ public void onSetOmeroContext(OmeroContext context) throws Exception { //no-op } /** * Applies the hard-wired intercepting to this instance. It is not possible * to configure hard-wired interceptors in Spring, instead they must be * passed in at runtime from a properly compiled class. */ public final void applyHardWiredInterceptors( List<HardWiredInterceptor> cptors, AopContextInitializer initializer) { if (service != null) { ProxyFactory wiredService = new ProxyFactory(); wiredService.setInterfaces(service.getClass().getInterfaces()); wiredService.setTarget(service); List<HardWiredInterceptor> reversed = new ArrayList<HardWiredInterceptor>( cptors); Collections.reverse(reversed); for (HardWiredInterceptor hwi : reversed) { wiredService.addAdvice(0, hwi); } wiredService.addAdvice(0, initializer); service = (ServiceInterface) wiredService.getProxy(); } } public final void callInvokerOnRawArgs(Object __cb, Ice.Current __current, Object... args) { if (service == null) { throw new ome.conditions.InternalException( "Null service; cannot use callInvoker()"); } this.be.callInvokerOnRawArgs(service, invoker, __cb, __current, args); } public final void callInvokerOnMappedArgs(IceMapper mapper, Object __cb, Ice.Current __current, Object... args) { if (service == null) { throw new ome.conditions.InternalException( "Null service; cannot use callInvoker()"); } this.be.callInvokerWithMappedArgs(service, invoker, mapper, __cb, __current, args); } public final void runnableCall(Ice.Current __current, Task r) { this.be.runnableCall(__current, r); } public final <R> void safeRunnableCall(Ice.Current __current, Object cb, boolean isVoid, Callable<R> callable) { this.be.safeRunnableCall(__current, cb, isVoid, callable); } public final void executorWorkCall(Executor.Work work) { throw new UnsupportedOperationException(); } // // StatefulServiceInterface // public final void activate_async(AMD_StatefulServiceInterface_activate __cb, Current __current) { // Do nothing for the moment } public final void passivate_async(AMD_StatefulServiceInterface_passivate __cb, Current __current) { // Do nothing for the moment } public final void getCurrentEventContext_async( AMD_StatefulServiceInterface_getCurrentEventContext __cb, Current __current) throws ServerError { callInvokerOnRawArgs(__cb, __current); } }