uk.ac.diamond.scisoft.analysis.rcp.inspector.AxisSelection.java Source code

Java tutorial

Introduction

Here is the source code for uk.ac.diamond.scisoft.analysis.rcp.inspector.AxisSelection.java

Source

/*
 * Copyright (c) 2012 Diamond Light Source Ltd.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */

package uk.ac.diamond.scisoft.analysis.rcp.inspector;

import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.Transformer;
import org.eclipse.dawnsci.analysis.api.dataset.ILazyDataset;

import uk.ac.diamond.scisoft.analysis.axis.AxisChoice;
import uk.ac.diamond.scisoft.analysis.rcp.explorers.AbstractExplorer;

/**
 * Class to hold a list of axis names and dataset from which an axis can be selected
 */
public class AxisSelection extends InspectorProperty implements Iterable<String> {
    class AxisSelData implements Comparable<AxisSelData> {
        private boolean selected;
        private int order; // possible order in a list of choices (0 signifies leave to end of list) 
        private AxisChoice data;

        public AxisSelData(AxisChoice axisData, boolean axisSelected) {
            setData(axisData);
            setSelected(axisSelected);
        }

        /**
         * @param selected The selected to set.
         */
        public void setSelected(boolean selected) {
            this.selected = selected;
        }

        /**
         * @return Returns the selected.
         */
        public boolean isSelected() {
            return selected;
        }

        /**
         * @param order The order to set.
         */
        public void setOrder(int order) {
            this.order = order;
        }

        /**
         * @return Returns the order.
         */
        public int getOrder() {
            return order;
        }

        /**
         * @param data The data to set.
         */
        public void setData(AxisChoice data) {
            this.data = data;
        }

        /**
         * @return Returns the data.
         */
        public AxisChoice getData() {
            return data;
        }

        @Override
        public int compareTo(AxisSelData axisSelData) {
            int cOrder = axisSelData.getOrder();
            if (order == 0)
                return cOrder == 0 ? 0 : 1;
            if (cOrder == 0)
                return -1;
            return order - cOrder;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((data == null) ? 0 : data.hashCode());
            result = prime * result + order;
            result = prime * result + (selected ? 1231 : 1237);
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            AxisSelData other = (AxisSelData) obj;
            if (data == null) {
                if (other.data != null)
                    return false;
            } else if (!data.equals(other.data))
                return false;
            if (order != other.order)
                return false;
            if (selected != other.selected)
                return false;
            return true;
        }
    }

    private final static String propName = "axisselection";
    private int dim; // dimension (or position index) of dataset
    private int length; // length of axis
    private List<AxisSelData> asData;
    private List<String> names;
    private final String suffix;

    Transformer orderTransformer = new Transformer() {
        @Override
        public Object transform(Object o) {
            if (o instanceof AxisSelData)
                return ((AxisSelData) o).getOrder();
            return null;
        }
    };

    Predicate axisSelectionPredicate = new Predicate() {
        @Override
        public boolean evaluate(Object o) {
            if (o instanceof AxisSelData)
                return ((AxisSelData) o).isSelected();
            return false;
        }
    };

    class OrderPredicate implements Predicate {
        int order;

        public void setOrder(int order) {
            this.order = order;
        }

        @Override
        public boolean evaluate(Object obj) {
            AxisSelData a = (AxisSelData) obj;
            int o = a.getOrder();
            return o == 0 || order < o;
        }
    }

    OrderPredicate orderPredicate = new OrderPredicate();

    /**
     * Create an axis selection that corresponds to a dataset dimension of given length
     * @param length 
     * @param dimension
     */
    public AxisSelection(int length, int dimension) {
        dim = dimension;
        this.length = length;
        asData = new ArrayList<AxisSelData>();
        names = new ArrayList<String>();
        suffix = ":" + (dim + 1);
    }

    /**
     * @return Returns the length
     */
    public int getLength() {
        return length;
    }

    @Override
    public String toString() {
        StringBuilder text = new StringBuilder();
        text.append('(');
        for (AxisSelData a : asData) {
            text.append(a.getData().getName());
            if (a.isSelected()) {
                text.append('*');
            }
            text.append(", ");
        }
        if (text.length() > 0) {
            text.deleteCharAt(text.length() - 1);
            text.deleteCharAt(text.length() - 1);
        }
        text.append(')');
        return text.toString();
    }

    /**
     * Add axis choice with given order and sets choice to first
     * @param axis
     * @param order (can be zero to denote last)
     */
    public void addChoice(AxisChoice axis, int order) {
        String name = axis.getName();
        if (axis.getRank() > 1 && !name.startsWith(AbstractExplorer.DIM_PREFIX))
            name += suffix;
        addChoice(name, axis, order);
    }

    /**
     * Add axis choice with given name and order and sets choice to first
     * @param name
     * @param axis
     * @param order (can be zero to denote last)
     */
    public void addChoice(String name, AxisChoice axis, int order) {
        AxisSelData a;
        int i = names.indexOf(name);
        if (i >= 0) { // existing axis so replace
            a = asData.get(i);
            if (axis != a.getData())
                a.setData(axis);
            int o = a.getOrder();
            if (o == order)
                return;

            names.remove(i);
            asData.remove(i);
        } else {
            a = new AxisSelData(axis, false);
        }

        a.setOrder(order);
        if (order == 0) {
            names.add(name);
            asData.add(a);
        } else {
            orderPredicate.setOrder(order); // find first >= order
            Object first = CollectionUtils.find(asData, orderPredicate);
            if (first == null) {
                names.add(name);
                asData.add(a);
            } else {
                int j = asData.indexOf(first);
                names.add(j, name);
                asData.add(j, a);
            }
        }
        selectAxis(0);
    }

    /**
     * @param axes
     */
    public void setChoices(ILazyDataset[] axes) {
        names.clear();
        asData.clear();
        int i = 1;
        for (ILazyDataset l : axes) {
            AxisSelData a = new AxisSelData(new AxisChoice(l), false);
            int r = l.getRank();
            if (r > 1) {
                int[] map = new int[r];
                for (int j = 0; j < r; j++) {
                    map[j] = j;
                }
                a.getData().setIndexMapping(map);
            } else {
                a.getData().setIndexMapping(dim);
            }
            a.setOrder(i++);
            names.add(l.getName());
            asData.add(a);
        }
        selectAxis(0);
    }

    /**
     * @param name
     * @return true if name is one of possible selections
     */
    public boolean containsAxis(String name) {
        return names.contains(name);
    }

    /**
     * Select an axis with given name
     * @param name
     * @param fire
     */
    public void selectAxis(String name, boolean fire) {
        int i = names.indexOf(name);
        if (i < 0)
            return;

        String oldName = getSelectedName();
        for (AxisSelData d : asData)
            d.setSelected(false);

        AxisSelData a = asData.get(i);
        a.setSelected(true);

        if (fire)
            fire(new PropertyChangeEvent(this, propName, oldName, name));
    }

    /**
     * Select an axis with given index
     * @param index 
     */
    public void selectAxis(int index) {
        selectAxis(index, false);
    }

    /**
     * Select an axis with given index
     * @param index 
     * @param fire
     */
    public void selectAxis(int index, boolean fire) {
        AxisSelData a = (AxisSelData) CollectionUtils.find(asData, axisSelectionPredicate);
        if (a != null)
            a.setSelected(false);

        asData.get(index).setSelected(true);
        if (!fire) {
            return;
        }

        String oldName = a == null ? null : names.get(asData.indexOf(a));
        fire(new PropertyChangeEvent(this, propName, oldName, names.get(index)));
    }

    /**
     * @param index 
     * @return axis name of given index
     */
    public String getName(int index) {
        return names.get(index);
    }

    /**
     * @return axis names
     */
    public List<String> getNames() {
        return names;
    }

    /**
     * @param index 
     * @return axis order of given index
     */
    public int getOrder(int index) {
        AxisSelData a = asData.get(index);
        return a == null ? -1 : a.getOrder();
    }

    /**
     * @param index 
     * @return axis choice of given index
     */
    public AxisChoice getAxis(int index) {
        AxisSelData a = asData.get(index);
        return a == null ? null : a.getData();
    }

    /**
     * @param name
     * @return axis choice of given name
     */
    public AxisChoice getAxis(String name) {
        int i = names.indexOf(name);
        return i < 0 ? null : asData.get(i).getData();
    }

    /**
     * Remove axis choice of given index
     * @param index
     */
    public void removeChoice(int index) {
        names.remove(index);
        asData.remove(index);
    }

    /**
     * Remove axis choice of given name
     * @param name
     */
    public void removeChoice(String name) {
        int i = names.indexOf(name);
        if (i < 0)
            return;
        removeChoice(i);
    }

    /**
     * @return number of choices
     */
    public int size() {
        return names.size();
    }

    /**
     * @param index
     * @return selection status
     */
    public boolean isSelected(int index) {
        AxisSelData a = asData.get(index);
        return (a == null) ? false : a.isSelected();
    }

    /**
     * Get name of selected axis
     * @return name or null if nothing selected
     */
    public String getSelectedName() {
        int i = getSelectedIndex();
        return i < 0 ? null : names.get(i);
    }

    /**
     * Get index of selected axis
     * @return index or -1 if nothing selected
     */
    public int getSelectedIndex() {
        AxisSelData a = (AxisSelData) CollectionUtils.find(asData, axisSelectionPredicate);
        return asData.indexOf(a);
    }

    /**
     * @return selected dimensions
     */
    public int[] getSelectedIndexMapping() {
        AxisChoice choice = getSelectedAxis();
        if (choice != null)
            return choice.getIndexMapping();
        return null;
    }

    /**
     * @return selected choice
     */
    public AxisChoice getSelectedAxis() {
        AxisSelData a = (AxisSelData) CollectionUtils.find(asData, axisSelectionPredicate);
        return (a == null) ? null : a.getData();
    }

    /**
     * @return maximum order
     */
    @SuppressWarnings({ "unchecked" })
    public int getMaxOrder() {
        List<Integer> orders = (List<Integer>) CollectionUtils.collect(asData, orderTransformer);
        return orders.size() > 0 ? (Integer) Collections.max(orders) : 0;
    }

    /**
     * @return true if names and axis datasets have same values
     */
    @Override
    public boolean equals(Object other) {
        if (this == other)
            return true;

        if (other instanceof AxisSelection) {
            AxisSelection that = (AxisSelection) other;

            if (!that.names.equals(names))
                return false;

            if (!asData.equals(that.asData))
                return false;

            return true;

        }
        return false;
    }

    @Override
    public int hashCode() {
        int hash = length;
        for (String n : names)
            hash = hash * 17 + n.hashCode();
        for (AxisSelData n : asData)
            hash = hash * 17 + n.hashCode();
        return hash;
    }

    /**
     * Clone everything but axis choice values
     */
    @Override
    public AxisSelection clone() {
        AxisSelection selection = new AxisSelection(length, dim);
        for (int i = 0, imax = asData.size(); i < imax; i++) {
            AxisSelData a = asData.get(i);
            selection.addChoice(names.get(i), a.getData().clone(), a.getOrder());
            if (a.isSelected())
                selection.selectAxis(i);
        }

        return selection;
    }

    /**
     * @return iterator over names
     */
    @Override
    public Iterator<String> iterator() {
        return names.iterator();
    }
}