org.openmicroscopy.shoola.env.data.model.FileObject.java Source code

Java tutorial

Introduction

Here is the source code for org.openmicroscopy.shoola.env.data.model.FileObject.java

Source

/*
 *------------------------------------------------------------------------------
 *  Copyright (C) 2015 University of Dundee. All rights reserved.
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *------------------------------------------------------------------------------
 */
package org.openmicroscopy.shoola.env.data.model;

import ij.IJ;
import ij.ImagePlus;
import ij.io.FileInfo;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import loci.formats.codec.CompressionType;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.openmicroscopy.shoola.util.CommonsLangUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * Object hosting the information about the "file" to import.
 *
 * @author Jean-Marie Burel     
 * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
 * @since 5.0
 */
public class FileObject {

    /** The field identifying the image id.*/
    public static final String OMERO_ID = "Omero_iid";

    /** The field identifying the group id.*/
    public static final String OMERO_GROUP = "Omero_group";

    /** The file to import.
     * This could be a file on disk or an ImageJ object for example.
     */
    private Object file;

    /**
     * Flag indicating if the file is generated or not.
     */
    private boolean generated;

    /** 
     * List of associated files. Mainly for imageJ.
     */
    private List<FileObject> associatedFiles;

    /** The trueFile if available.*/
    private File trueFile;

    /**
     * Returns the Pixels node matching the index.
     *
     * @param doc The document to handle.
     * @return See above.
     */
    private Node getPixelsNode(Document doc) {

        NodeList l = doc.getElementsByTagName("Image");
        if (l == null || l.getLength() == 0)
            return null;
        NamedNodeMap attributes;
        String value;
        Node node;
        NodeList nodeList;
        int series = getIndex();
        for (int i = 0; i < l.getLength(); i++) {
            node = l.item(i);
            if (node.hasAttributes()) {
                attributes = node.getAttributes();
                value = attributes.getNamedItem("ID").getNodeValue();
                if (value.equals("Image:" + series)) {
                    nodeList = node.getChildNodes();
                    if (nodeList != null && nodeList.getLength() > 0) {
                        for (int j = 0; j < nodeList.getLength(); j++) {
                            Node n = nodeList.item(j);
                            if ("Pixels".equals(n.getNodeName())) {
                                return n;
                            }
                        }
                    }
                }
            }
        }
        return null;
    }

    /**
     * Parses the image's description.
     *
     * @param xmlStr The string to parse.
     * @return See above.
     */
    private Document xmlParser(String xmlStr) throws SAXException {
        InputSource stream = new InputSource();
        stream.setCharacterStream(new StringReader(xmlStr));
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        DocumentBuilder builder;
        Document doc = null;
        try {
            builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            doc = builder.parse(stream);
        } catch (ParserConfigurationException e) {
            e.printStackTrace(pw);
            IJ.log(sw.toString());
        } catch (IOException e) {
            e.printStackTrace(pw);
            IJ.log(sw.toString());
        } finally {
            try {
                sw.close();
            } catch (IOException e) {
                IJ.log("I/O Exception:" + e.getMessage());
            }
            pw.close();
        }
        return doc;
    }

    /**
     * Creates a new instance.
     *
     * @param file The file to import.
     */
    public FileObject(Object file) {
        if (file == null)
            throw new IllegalArgumentException("No object to import");
        this.file = file;
    }

    /**
     * Sets the omero image Id after saving the image.
     *
     * @param id The value to set.
     */
    public void setImageID(long id) {
        if (!isImagePlus())
            return;
        ImagePlus image = (ImagePlus) file;
        image.setProperty(OMERO_ID, id);
    }

    /**
     * Add the associated file if any.
     * 
     * @param file The file to add.
     */
    public void addAssociatedFile(FileObject file) {
        if (associatedFiles == null) {
            associatedFiles = new ArrayList<FileObject>();
        }
        if (file != null) {
            associatedFiles.add(file);
        }
    }

    /**
     * Returns the associated files if any or <code>null</code>.
     * 
     * @return See above.
     */
    public List<FileObject> getAssociatedFiles() {
        return associatedFiles;
    }

    /**
     * Returns the object to import.
     *
     * @return See above
     */
    public Object getFile() {
        return file;
    }

    /**
     * Returns the name of the object to import.
     *
     * @return See above.
     */
    public String getName() {
        if (file instanceof File) {
            return ((File) file).getName();
        } else if (file instanceof ImagePlus) {
            ImagePlus img = (ImagePlus) file;
            return img.getTitle();
        }
        return null;
    }

    /**
     * Returns the absolute path to the file.
     *
     * @return See above.
     */
    public String getAbsolutePath() {
        if (file instanceof File) {
            return ((File) file).getAbsolutePath();
        } else if (file instanceof ImagePlus) {
            File f = getTrueFile();
            if (f != null)
                return f.getAbsolutePath();
            return ((ImagePlus) file).getTitle();
        }
        return "";
    }

    /**
     * Returns the file to import.
     * @return See above.
     */
    public File getFileToImport() {
        File f = getTrueFile();
        if (f != null)
            return f;
        if (file instanceof ImagePlus) {
            //prepare command
            ImagePlus img = (ImagePlus) file;
            generated = true;
            try {
                //name w/o extension
                String baseName = FilenameUtils.getBaseName(FilenameUtils.removeExtension(img.getTitle()));
                baseName = CommonsLangUtils.deleteWhitespace(baseName);
                String n = baseName + ".ome.tif";
                f = File.createTempFile(img.getTitle(), ".ome.tif");
                File p = f.getParentFile();
                File[] list = p.listFiles();
                if (list != null) {
                    File toDelete = null;
                    for (int i = 0; i < list.length; i++) {
                        if (list[i].getName().equals(n)) {
                            toDelete = list[i];
                            break;
                        }
                    }
                    if (toDelete != null) {
                        toDelete.delete();
                    }
                }
                f = new File(p, n);
                f.deleteOnExit();
            } catch (Exception e) {
                return null;
            }
            StringBuffer buffer = new StringBuffer();
            buffer.append("outfile=" + f.getAbsolutePath());
            buffer.append(" splitz=false");
            buffer.append(" splitc=false");
            buffer.append(" splitt=false");
            buffer.append(" saveroi=false");
            buffer.append(" compression=" + CompressionType.UNCOMPRESSED.getCompression());
            buffer.append(" imageid=" + img.getID() + " ");
            IJ.runPlugIn("loci.plugins.LociExporter", buffer.toString());
            return f;
        }
        return null;
    }

    /**
     * Returns <code>true</code> if the file has been generated,
     * <code>false</code> otherwise.
     *
     * @return See above.
     */
    public boolean isGenerated() {
        return generated;
    }

    /**
     * Returns <code>true</code> if it is a new image from ImageJ,
     * <code>false</code> otherwise.
     *
     * @return See above.
     */
    public boolean isNewImage() {
        if (file instanceof ImagePlus) {
            ImagePlus img = (ImagePlus) file;
            if (img.changes)
                return true;
            FileInfo info = img.getOriginalFileInfo();
            if (info == null) {
                info = img.getFileInfo();
                String name = info.fileName;
                if (CommonsLangUtils.isBlank(name) || "Untitled".equals(name))
                    return true;
            }
            String xmlStr = info.description;
            if (CommonsLangUtils.isBlank(xmlStr))
                return false;
            //Get Current Dimensions
            int sizeC_cur = img.getNChannels();
            int sizeT_cur = img.getNFrames();
            int sizeZ_cur = img.getNSlices();
            int sizeC_org = sizeC_cur;
            int sizeT_org = sizeT_cur;
            int sizeZ_org = sizeZ_cur;
            Document doc = null;
            boolean xml = false;
            try {
                if (xmlStr.startsWith("<")) {
                    doc = xmlParser(xmlStr);
                }
            } catch (SAXException e) { //not XML or not possible to read it correctly
                xml = false;
            }
            if (!xml) {
                //try to parse the string
                String[] values = xmlStr.split("\n");
                String v;
                for (int i = 0; i < values.length; i++) {
                    v = values[i];
                    if (v.startsWith("slices")) {
                        String[] keys = v.split("=");
                        if (keys.length > 1) {
                            sizeZ_org = Integer.valueOf(keys[1]);
                        }
                    } else if (v.startsWith("channels")) {
                        String[] keys = v.split("=");
                        if (keys.length > 1) {
                            sizeC_org = Integer.valueOf(keys[1]);
                        }
                    } else if (v.startsWith("frames")) {
                        String[] keys = v.split("=");
                        if (keys.length > 1) {
                            sizeT_org = Integer.valueOf(keys[1]);
                        }
                    }
                }
            }
            if (doc != null) {
                Node node = getPixelsNode(doc);
                if (node == null)
                    return false;
                NamedNodeMap nnm = node.getAttributes();
                sizeC_org = Integer.valueOf(nnm.getNamedItem("SizeC").getNodeValue());
                sizeT_org = Integer.valueOf(nnm.getNamedItem("SizeT").getNodeValue());
                sizeZ_org = Integer.valueOf(nnm.getNamedItem("SizeZ").getNodeValue());
            }
            if (sizeC_cur != sizeC_org || sizeT_cur != sizeT_org || sizeZ_cur != sizeZ_org) {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns the file to import.
     *
     * @return See above.
     */
    public File getTrueFile() {
        if (file instanceof File) {
            return (File) file;
        } else if (file instanceof ImagePlus) {
            if (trueFile != null)
                return trueFile;
            ImagePlus img = (ImagePlus) file;
            if (!img.changes) {
                FileInfo info = img.getOriginalFileInfo();
                if (info != null) {
                    if (CommonsLangUtils.isNotEmpty(info.url)) {
                        //create a tmp file and copy the URL
                        String fname = img.getTitle();
                        String extension = FilenameUtils.getExtension(fname);
                        String baseName = FilenameUtils.getBaseName(FilenameUtils.removeExtension(fname));
                        try {
                            trueFile = File.createTempFile(baseName, "." + extension);
                            trueFile.deleteOnExit();
                            FileUtils.copyURLToFile(new URL(info.url), trueFile);
                        } catch (Exception e) {
                            //ignore.
                        }
                        return trueFile;
                    }
                    if (info.directory != null && info.fileName != null) {
                        trueFile = new File(info.directory, info.fileName);
                        return trueFile;
                    }
                }
            }
        }
        return null;
    }

    /**
     * Returns the name of the parent file if it exists.
     *
     * @return See above.
     */
    public String getParentName() {
        File f = getTrueFile();
        if (f == null || f.getParentFile() == null)
            return null;
        return f.getParentFile().getName();
    }

    /**
     * Returns the size of the file
     * 
     * @return See above.
     */
    public long getLength() {
        File f;
        if (file instanceof File) {
            f = (File) file;
            if (f.isFile())
                return f.length();
            return FileUtils.sizeOfDirectory(f);
        } else if (file instanceof ImagePlus) {
            f = getTrueFile();
            if (f != null)
                return f.length();
        }
        return 0;
    }

    /**
     * Returns <code>true</code> if it is a directory, <code>false</code>
     * otherwise.
     *
     * @return See above.
     */
    public boolean isDirectory() {
        if (file instanceof File) {
            File f = (File) file;
            return f.isDirectory();
        }
        return false;
    }

    /**
     * Returns <code>true</code> if it is a file, <code>false</code>
     * otherwise.
     *
     * @return See above.
     */
    public boolean isFile() {
        if (file instanceof File) {
            File f = (File) file;
            return f.isFile();
        }
        return true;
    }

    /**
     * Returns <code>true</code> if it is an image from ImageJ,
     * <code>false</code> otherwise.
     *
     * @return See above.
     */
    public boolean isImagePlus() {
        return file instanceof ImagePlus;
    }

    /**
     * Returns the index of the image if it is an image plus.
     *
     * @return See above.
     */
    public int getIndex() {
        if (!isImagePlus())
            return -1;
        ImagePlus image = (ImagePlus) file;
        Object value = image.getProperty("Series");
        if (value != null && value instanceof Integer)
            return ((Integer) value).intValue();
        return -1;
    }

    /**
     * Returns the <code>OMERO</code> id or <code>-1</code> if not set.
     *
     * @return See above.
     */
    public long getOMEROID() {
        if (!isImagePlus())
            return -1;
        ImagePlus image = (ImagePlus) file;
        Object value = image.getProperty(OMERO_ID);
        if (value != null && value instanceof Long)
            return ((Long) value).longValue();
        return -1;
    }

    /**
     * Returns the <code>OMERO</code> group id or <code>-1</code> if not set.
     *
     * @return See above.
     */
    public long getGroupID() {
        if (!isImagePlus())
            return -1;
        ImagePlus image = (ImagePlus) file;
        Object value = image.getProperty(OMERO_GROUP);
        if (value != null && value instanceof Long)
            return ((Long) value).longValue();
        return -1;
    }

    /**
     * Returns the name as container if option is on.
     *
     * @return See above.
     */
    public String getFolderAsContainerName() {
        File parentFile;
        if (file instanceof File) {
            File f = (File) file;
            if (f.isFile()) {
                parentFile = f.getParentFile();
                if (parentFile == null)
                    return null;
                return parentFile.getName();
            }
            return f.getName();
        } else {
            File f = getTrueFile();//image plus
            if (f != null && f.getParentFile() != null)
                return f.getParentFile().getName();
            return getName();
        }
    }
}