/* * $Id$ * * 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.HashMap; import java.util.Map; import java.util.concurrent.Callable; import ome.api.RawFileStore; import ome.services.blitz.util.BlitzExecutor; import ome.services.blitz.util.ServiceFactoryAware; import ome.services.util.Executor; import ome.util.SqlAction; import omero.RLong; import omero.ServerError; import omero.api.AMD_RawFileStore_exists; import omero.api.AMD_RawFileStore_getFileId; import omero.api.AMD_RawFileStore_read; import omero.api.AMD_RawFileStore_save; import omero.api.AMD_RawFileStore_setFileId; import omero.api.AMD_RawFileStore_size; import omero.api.AMD_RawFileStore_truncate; import omero.api.AMD_RawFileStore_write; import omero.api.RawFileStorePrx; import omero.api._RawFileStoreOperations; import omero.api._RawFileStoreTie; import omero.constants.CLIENTUUID; import omero.grid.RepositoryPrx; import omero.grid.RepositoryPrxHelper; import omero.model.OriginalFile; import omero.util.IceMapper; import omero.util.TieAware; import org.springframework.transaction.annotation.Transactional; import Ice.Current; import Ice.TieBase; /** * Implementation of the RawFileStore service. * * @author Josh Moore, josh at glencoesoftware.com * @since 3.0-Beta4 * @see ome.api.RawFileStore */ public class RawFileStoreI extends AbstractCloseableAmdServant implements _RawFileStoreOperations, ServiceFactoryAware, TieAware { private ServiceFactoryI sf; private _RawFileStoreTie tie; public RawFileStoreI(RawFileStore service, BlitzExecutor be) { super(service, be); } public void setServiceFactory(ServiceFactoryI sf) throws ServerError { this.sf = sf; setHolder(sf.holder); } public ServiceFactoryI getServiceFactory() throws ServerError { return this.sf; } public void setTie(TieBase tie) throws ServerError { if (!(tie instanceof _RawFileStoreTie)) { throw new RuntimeException("Bad tie: " + tie); } this.tie = (_RawFileStoreTie) tie; } // Interface methods // ========================================================================= public void exists_async(AMD_RawFileStore_exists __cb, Current __current) throws ServerError { callInvokerOnRawArgs(__cb, __current); } public void read_async(AMD_RawFileStore_read __cb, long position, int length, Current __current) throws ServerError { callInvokerOnRawArgs(__cb, __current, position, length); } public void getFileId_async(AMD_RawFileStore_getFileId __cb, Current __current) throws ServerError { callInvokerOnRawArgs(__cb, __current); } public void setFileId_async(AMD_RawFileStore_setFileId __cb, long fileId, Current __current) throws ServerError { try { if (__redirect(fileId, tie, __current)) { __cb.ice_response(); } else { callInvokerOnRawArgs(__cb, __current, fileId); } } catch (ome.conditions.SecurityViolation e) { final omero.SecurityViolation sv = new omero.SecurityViolation(); IceMapper.fillServerError(sv, e); __cb.ice_exception(sv); } catch (Exception e) { __cb.ice_exception((Exception) e); } catch (Throwable e) { final omero.InternalException ie = new omero.InternalException(); IceMapper.fillServerError(ie, e); __cb.ice_exception(ie); } } public void size_async(AMD_RawFileStore_size __cb, Current __current) throws ServerError { callInvokerOnRawArgs(__cb, __current); } public void truncate_async(AMD_RawFileStore_truncate __cb, long length, Current __current) throws ServerError { callInvokerOnRawArgs(__cb, __current, length); } public void write_async(AMD_RawFileStore_write __cb, byte[] buf, long position, int length, Current __current) throws ServerError { callInvokerOnRawArgs(__cb, __current, buf, position, length); } public void save_async(AMD_RawFileStore_save __cb, Current __current) throws ServerError { callInvokerOnRawArgs(__cb, __current); } // // Close logic // @Override protected void preClose(Current current) throws Throwable { // no-op } @Override protected void postClose(Current current) { // no-op } // // Redirect // public boolean __redirect(final long fileId, final _RawFileStoreTie rfsTie, final Ice.Current current) throws ServerError { final String repo = (String) sf.executor .executeSql(new Executor.SimpleSqlWork(this, "__redirect", fileId) { @Transactional(readOnly = true) public Object doWork(SqlAction sql) { return sql.fileRepo(fileId); } }); // This implementation is intended only for local use (i.e. // ${omero.data.dir}) if (repo == null) { return false; } // WORKAROUND: store the current session in the context. // If this isn't available, it won't be possible for this instance // to be registered with Map<String, String> adjustedCtx = new HashMap<String, String>(current.ctx); adjustedCtx.put(omero.constants.SESSIONUUID.value, current.id.category); adjustedCtx.put(omero.constants.CLIENTUUID.value, current.ctx.get(CLIENTUUID.value)); final Ice.ObjectPrx prx = sf.getAdapter().createProxy( Ice.Util.stringToIdentity("PublicRepository-" + repo)); final RepositoryPrx repoPrx = RepositoryPrxHelper.checkedCast(prx); final RawFileStorePrx rfsPrx = repoPrx.fileById(fileId, adjustedCtx); OpsDelegate ops = new OpsDelegate(be, rfsTie, this, rfsPrx); ops.setApplicationContext(ctx); ops.setHolder(holder); tie.ice_delegate(ops); return true; } private static class OpsDelegate extends AbstractCloseableAmdServant implements _RawFileStoreOperations { final private _RawFileStoreTie tie; final private RawFileStoreI impl; final private RawFileStorePrx prx; OpsDelegate(BlitzExecutor be, _RawFileStoreTie tie, RawFileStoreI impl, RawFileStorePrx prx) { super(null, be); this.tie = tie; this.impl = impl; this.prx = prx; } public void exists_async(AMD_RawFileStore_exists __cb, Current __current) throws ServerError { safeRunnableCall(__current, __cb, false, new Callable<Boolean>() { public Boolean call() throws Exception { return prx.exists(); } }); } public void getFileId_async(AMD_RawFileStore_getFileId __cb, Current __current) throws ServerError { safeRunnableCall(__current, __cb, false, new Callable<RLong>() { public RLong call() throws Exception { return prx.getFileId(); } }); } public void read_async(AMD_RawFileStore_read __cb, final long position, final int length, Current __current) throws ServerError { safeRunnableCall(__current, __cb, false, new Callable<byte[]>() { public byte[] call() throws Exception { return prx.read(position, length); } }); } public void size_async(AMD_RawFileStore_size __cb, Current __current) throws ServerError { safeRunnableCall(__current, __cb, false, new Callable<Long>() { public Long call() throws Exception { return prx.size(); } }); } public void truncate_async(AMD_RawFileStore_truncate __cb, final long length, Current __current) throws ServerError { safeRunnableCall(__current, __cb, false, new Callable<Boolean>() { public Boolean call() throws Exception { return prx.truncate(length); } }); } public void save_async(AMD_RawFileStore_save __cb, Current __current) throws ServerError { safeRunnableCall(__current, __cb, false, new Callable<OriginalFile>() { public OriginalFile call() throws Exception { return prx.save(); } }); } /** * Resets the original implementation, allowing for the creation * of another delegate. */ public void setFileId_async(AMD_RawFileStore_setFileId __cb, long fileId, Current __current) throws ServerError { tie.ice_delegate(impl); // Remove self. Frees for GC. tie.setFileId_async(__cb, fileId, __current); } public void write_async(AMD_RawFileStore_write __cb, final byte[] buf, final long position, final int length, Current __current) throws ServerError { safeRunnableCall(__current, __cb, true, new Callable<Object>() { public Object call() throws Exception { prx.write(buf, position, length); return null; } }); } @Override protected void preClose(Current current) throws Throwable { prx.close(current.ctx); } @Override protected void postClose(Current current) { // no-op } } }