ome.services.throttling.Task.java Source code

Java tutorial

Introduction

Here is the source code for ome.services.throttling.Task.java

Source

/*
 *   $Id$
 *
 *   Copyright 2008 Glencoe Software, Inc. All rights reserved.
 *   Use is subject to license terms supplied in LICENSE.txt
 *
 */

package ome.services.throttling;

import java.lang.reflect.Method;

import ome.system.OmeroContext;
import omero.InternalException;
import omero.util.IceMapper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Simple base task which contains logic for routing calls reflectively to
 * ice_response and ice_exception of any AMD callback.
 * 
 * @since Beta4
 */
public abstract class Task {

    private final static Log log = LogFactory.getLog(Task.class);

    protected final Object cb;

    protected final boolean isVoid;

    protected final Ice.Current current;

    protected final Method response;

    protected final Method exception;

    public Task(Object callback, Ice.Current current, boolean isVoid) {
        this.current = current;
        this.isVoid = isVoid;
        this.cb = callback;
        if (callback != null) {
            response = getMethod(callback, "ice_response");
            exception = getMethod(callback, "ice_exception");
        } else {
            response = null;
            exception = null;
        }
    }

    public abstract void run(OmeroContext ctx);

    /**
     * Calls the response method
     */
    protected void response(Object rv, OmeroContext ctx) {
        try {
            if (isVoid) {
                response.invoke(cb);
            } else {
                response.invoke(cb, rv);
            }
        } catch (Exception e) {
            InternalException ie = new InternalException();
            IceMapper.fillServerError(ie, e);
            ie.message = "Failed to invoke: " + this.toString();
            log.error(ie.message, e);
            exception(ie, ctx);
        }
    }

    protected void exception(Throwable ex, OmeroContext ctx) {
        try {
            if (!(ex instanceof Exception)) {
                log.error("Throwable thrown!", ex);
            }
            IceMapper mapper = new IceMapper();
            ex = mapper.handleException(ex, ctx);
            exception.invoke(cb, ex);
        } catch (Exception e2) {
            String msg = "Failed to invoke exception()";
            log.error(msg, e2);
            throw new RuntimeException("Failed to invoke exception()", e2);
        }
    }

    // Helpers
    // =========================================================================

    Method getMethod(Object o, String methodName) {
        Class c = getPublicInterface(o.getClass());
        Method[] methods = c.getMethods();
        Method rv = null;
        for (int i = 0; i < methods.length; i++) {
            Method m = methods[i];
            if (methodName.equals(m.getName())) {
                if (rv != null) {
                    throw new RuntimeException(methodName + " exists twice!");
                } else {
                    rv = m;
                }
            }
        }
        return rv;
    }

    /**
     * The Ice AMD-implementations are package-private and so cannot be executed
     * on. Instead, we have to find the public interface and use its methods.
     */
    private Class getPublicInterface(Class c) {
        if (!c.getName().startsWith("AMD_")) {
            while (!c.equals(Object.class)) {
                Class[] ifaces = c.getInterfaces();
                for (Class c2 : ifaces) {
                    if (c2.getSimpleName().startsWith("AMD_")) {
                        return c2;
                    }
                }
                // Ok. We didn't find anything so recurse into the superclass
                c = c.getSuperclass();
            }
            throw new RuntimeException("No public AMD_ interface found.");
        } else {
            return c;
        }
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(super.toString());
        sb.append(" (");
        sb.append(cb);
        sb.append(" )");
        return sb.toString();
    }

}