org.cellprofiler.subimager.TestImageJHandlerBase.java Source code

Java tutorial

Introduction

Here is the source code for org.cellprofiler.subimager.TestImageJHandlerBase.java

Source

/**
 * CellProfiler is distributed under the GNU General Public License.
 * See the accompanying file README for details.
 *
 * Developed by the Broad Institute
 * Copyright 2003-2011
 * Website: http://www.cellprofiler.org
 */
package org.cellprofiler.subimager;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import imagej.ext.module.ModuleException;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import junit.framework.AssertionFailedError;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.RequestContext;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.castor.xml.XMLProperties;
import org.cellprofiler.subimager.NDImage.FormatException;
import org.cellprofiler.subimager.imagejrequest.CreateContext;
import org.cellprofiler.subimager.imagejrequest.CreateContextResponse;
import org.cellprofiler.subimager.imagejrequest.GetModules;
import org.cellprofiler.subimager.imagejrequest.GetModulesRequestType;
import org.cellprofiler.subimager.imagejrequest.GetModulesResponse;
import org.cellprofiler.subimager.imagejrequest.ImageValue;
import org.cellprofiler.subimager.imagejrequest.ModuleInfoType;
import org.cellprofiler.subimager.imagejrequest.Parameter;
import org.cellprofiler.subimager.imagejrequest.Request;
import org.cellprofiler.subimager.imagejrequest.Response;
import org.cellprofiler.subimager.imagejrequest.RunModuleRequestType;
import org.cellprofiler.subimager.imagejrequest.RunModuleResponse;
import org.cellprofiler.subimager.imagejrequest.types.AxisType;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
import org.exolab.castor.xml.ValidationException;

/**
 * @author Lee Kamentsky
 *
 * Base class for testing calls to the ImageJ handler
 */
public class TestImageJHandlerBase extends TestImageHandlerBase {
    protected static Parameter getParameterByName(RunModuleResponse rmr, String name) {
        for (Parameter p : rmr.getRunModuleResponseTypeSequence().getParameter()) {
            if (p.getName().equals(name)) {
                return p;
            }
        }
        throw new AssertionFailedError(String.format("Could not find parameter, \"%s\".", name));
    }

    protected String getContext() {
        Request request = new Request();
        request.setCreateContext(new CreateContext());
        Response response = post(request, new HashMap<String, NDImage>(), new HashMap<String, NDImage>());
        CreateContextResponse ccResponse = response.getResponseTypeChoice().getCreateContextResponse();
        return ccResponse.getContextID().getContextID();
    }

    /**
     * Get the module ID for a module with a given name
     * 
     * @param contextID the context from a call to getContext()
     * @param moduleName the name of the module from ModuleInfo.getName()
     * 
     * @return the module ID, suitable for use in a run module call
     */
    protected String getModuleIDByName(String contextID, String moduleName) {
        Request request = new Request();
        GetModules gmRequest = new GetModules();
        gmRequest.setContextID(contextID);
        request.setGetModules(gmRequest);
        Response response = post(request, new HashMap<String, NDImage>(), new HashMap<String, NDImage>());
        GetModulesResponse gmResponse = response.getResponseTypeChoice().getGetModulesResponse();
        for (ModuleInfoType mi : gmResponse.getModule()) {
            if ((mi.getName() != null) && (mi.getName().equals(moduleName)))
                return mi.getModuleID();
        }
        throw new AssertionError("Could not find module " + moduleName);
    }

    /**
     * Get the module ID for a module with a given title
     * 
     * @param contextID the context from a call to getContext()
     * @param delegateClassName the delegate class name from the module info
     * 
     * @return the module ID, suitable for use in a run module call
     */
    protected String getModuleIDByTitle(String contextID, String title) {
        Request request = new Request();
        GetModules gmRequest = new GetModules();
        gmRequest.setContextID(contextID);
        request.setGetModules(gmRequest);
        Response response = post(request, new HashMap<String, NDImage>(), new HashMap<String, NDImage>());
        GetModulesResponse gmResponse = response.getResponseTypeChoice().getGetModulesResponse();
        for (ModuleInfoType mi : gmResponse.getModule()) {
            if (mi.getTitle().equals(title))
                return mi.getModuleID();
        }
        throw new AssertionError("Could not find module " + title);
    }

    protected Response post(Request request, Map<String, NDImage> ndimagesIn, Map<String, NDImage> ndimagesOut) {
        StringWriter writer = new StringWriter();
        try {
            Marshaller marshaller = new Marshaller(writer);
            marshaller.marshal(request);
        } catch (MarshalException e2) {
            throw new AssertionError(e2.getMessage());
        } catch (ValidationException e2) {
            throw new AssertionError(e2.getMessage());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            throw new AssertionError(e.getMessage());
        }
        String xml = writer.toString();

        ArrayList<Part> parts = new ArrayList<Part>();
        parts.add(new StringPart(ImageJHandler.NAME_REQUEST, xml));
        String sURL = String.format("http://localhost:%d/imagej", getPort());
        final PostMethod post = new PostMethod(sURL);
        for (Map.Entry<String, NDImage> entry : ndimagesIn.entrySet()) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try {
                entry.getValue().encode(bos);
            } catch (IOException e1) {
                e1.printStackTrace();
                throw new AssertionError("Failed to encode image: " + e1.getMessage());
            }
            ByteArrayPartSource src = new ByteArrayPartSource(entry.getKey(), bos.toByteArray());
            FilePart filePart = new FilePart(entry.getKey(), src, "application/octet-stream", "binary");
            parts.add(filePart);
        }
        post.setRequestEntity(new MultipartRequestEntity(parts.toArray(new Part[0]), post.getParams()));
        HttpClient client = new HttpClient();
        int responseCode;
        try {
            responseCode = client.executeMethod(post);
        } catch (HttpException e) {
            throw new AssertionError(e.getMessage());
        } catch (IOException e) {
            throw new AssertionError(e.getMessage());
        }
        assertEquals(HttpURLConnection.HTTP_OK, responseCode);
        final String contentType = post.getResponseHeader("Content-Type").getValue();
        assertTrue(contentType.startsWith("multipart/form-data"));
        final long contentLength = post.getResponseContentLength();
        try {
            final InputStream responseBodyStream = post.getResponseBodyAsStream();
            FileUpload upload = new FileUpload();
            FileItemIterator fileItemIterator;
            fileItemIterator = upload.getItemIterator(new RequestContext() {

                public String getCharacterEncoding() {
                    if (post.getResponseHeader("Content-Encoding") == null)
                        return null;
                    return post.getResponseHeader("Content-Encoding").getValue();
                }

                public String getContentType() {
                    return contentType;
                }

                public int getContentLength() {
                    return (int) contentLength;
                }

                InputStream tmpStream = null;

                public InputStream getInputStream() throws IOException {
                    if (tmpStream == null) {
                        byte[] buf = new byte[(int) contentLength];
                        int offset = 0;
                        while (offset < buf.length) {
                            offset += responseBodyStream.read(buf, offset, buf.length - offset);
                        }
                        tmpStream = new ByteArrayInputStream(buf);
                    }
                    return tmpStream;
                }
            });
            assertTrue(fileItemIterator.hasNext());
            FileItemStream fis = fileItemIterator.next();
            assertEquals(fis.getFieldName(), ImageJHandler.NAME_RESPONSE);
            Reader rdr = new InputStreamReader(fis.openStream(), "utf-8");
            Unmarshaller unmarshaller = new Unmarshaller(Response.class);
            unmarshaller.setProperty(XMLProperties.LENIENT_INTEGER_VALIDATION, "true");
            Object oresponse = unmarshaller.unmarshal(rdr);
            assertTrue(oresponse instanceof Response);
            Response response = (Response) oresponse;
            while (fileItemIterator.hasNext()) {
                fis = fileItemIterator.next();
                String name = fis.getFieldName();
                NDImage ndimage = NDImage.decode(fis.openStream());
                ndimagesOut.put(name, ndimage);
            }
            return response;
        } catch (IOException e) {
            e.printStackTrace();
            throw new AssertionError(e.getMessage());
        } catch (FileUploadException e) {
            e.printStackTrace();
            throw new AssertionError(e.getMessage());
        } catch (MarshalException e) {
            e.printStackTrace();
            throw new AssertionError(e.getMessage());
        } catch (ValidationException e) {
            e.printStackTrace();
            throw new AssertionError(e.getMessage());
        } catch (FormatException e) {
            e.printStackTrace();
            throw new AssertionError(e.getMessage());
        }

    }

    /**
     * Make an image value parameter containing a random image
     * 
     * @param dim dimensions of image
     * @param r an instance of Random that provides the random values
     * @param displayName the name of the display to be created
     * @param fieldName the name of the parameter field to set.
     * @param inputMap put the image here so that it can get posted to Subimager
     * @return an ImageValue parameter set up for the image 
     * 
     * @throws IndexOutOfBoundsException
     */
    protected Parameter makeImageValueParameter(int[] dim, Random r, String fieldName, String displayName,
            Map<String, NDImage> inputMap) throws IndexOutOfBoundsException {
        double[] buffer = new double[dim[0] * dim[1]];
        for (int i = 0; i < buffer.length; i++)
            buffer[i] = r.nextDouble();
        NDImage ndimage = new NDImage(buffer, dim);
        String imageID = "IMG" + UUID.randomUUID().toString();
        inputMap.put(imageID, ndimage);
        Parameter p = new Parameter();
        ImageValue iv = new ImageValue();
        iv.setImageName(displayName);
        iv.setImageID(imageID);
        iv.addAxis(AxisType.X);
        iv.addAxis(AxisType.Y);
        p.setImageValue(iv);
        p.setName(fieldName);
        return p;
    }

}