    001/*-
    002 * Copyright 2015, 2016 Diamond Light Source Ltd.
    003 *
    004 * All rights reserved. This program and the accompanying materials
    005 * are made available under the terms of the Eclipse Public License v1.0
    006 * which accompanies this distribution, and is available at
    007 * http://www.eclipse.org/legal/epl-v10.html
    008 */
    009
    010package org.eclipse.january.dataset;
    011
    012import java.util.Arrays;
    013import java.util.EventObject;
    014import java.util.regex.Matcher;
    015import java.util.regex.Pattern;
    016
    017/**
    018 * Event fired to disseminate information about a dataset changing.
    019 * For instance if an image represents a live stream.
    020 *
    021 * This event is passed over web-sockets. To keep dependencies to a
    022 * minimum and since it is really simple, we have added an encode and
    023 * decode to JSON without the need for an API like Jackson.
    024 */
    025public class DataEvent extends EventObject {
    026
    027        /**
    028         *
    029         */
    030        private static final long serialVersionUID = 751125872769278449L;
    031
    032        private int[]  shape;
    033
    034        /**
    035         * Optionally, we can indicate where the file path was.
    036         */
    037        private String filePath;
    038
    039        /**
    040         * The name of the dataset, may be ""
    041         */
    042        private String name;
    043
    044        public DataEvent() {
    045                this("", new int[] { 1 });
    046        }
    047
    048        /**
    049         * Creates an event to notify that this data has changed.
    050         * @param name of event
    051         * @param shape of dataset
    052         */
    053        public DataEvent(String name, int[] shape) {
    054                super(name);
    055                this.shape = shape;
    056                this.name  = name;
    057        }
    058
    059        @Override
    060        public String getSource() {
    061                return (String)super.getSource();
    062        }
    063
    064        public String getName() {
    065                return getSource();
    066        }
    067
    068        public void setName(String name) {
    069                this.name = name;
    070        }
    071
    072        public int[] getShape() {
    073                return shape;
    074        }
    075
    076        public void setShape(int[] shape) {
    077                this.shape = shape;
    078        }
    079
    080        public String getFilePath() {
    081                return filePath;
    082        }
    083
    084        public void setFilePath(String filePath) {
    085                this.filePath = filePath;
    086        }
    087
    088        /**
    089         * Encodes event to string
    090         * @return encoded string
    091         */
    092        public String encode() {
    093                final StringBuilder buf = new StringBuilder();
    094                buf.append("{");
    095                buf.append("\"name\" : \"");
    096                buf.append(getName());
    097                buf.append("\"");
    098                buf.append(", \"shape\" : ");
    099                buf.append(Arrays.toString(shape));
    100
    101                buf.append(", \"filepath\" : \"");
    102                buf.append(getFilePath());
    103                buf.append("\"");
    104
    105                buf.append("}");
    106                return buf.toString();
    107        }
    108
    109        /**
    110         * Decodes from input for instance {"name" : "Tests", "shape" : [1024, 1024], "filepath" : "C:/tmp/Fred.txt"}
    111         * @param json input
    112         * @return DataEvent
    113         */
    114        public static DataEvent decode(String json) {
    115
    116                String name     = getValue(json, ".*\"name\" \\: \"([^\"]+)\".*");
    117                String filepath = getValue(json, ".*\"filepath\" \\: \"([^\"]+)\".*");
    118                String shape    = getValue(json, ".*\"shape\" \\: \\[([^\\]]+)\\].*");
    119
    120                DataEvent ret = new DataEvent(name, getArray(shape));
    121                if (filepath!=null && !"null".equals(filepath)) {
    122                        ret.setFilePath(filepath);
    123                }
    124                return ret;
    125        }
    126
    127
    128        private static String getValue(String json, String regex) {
    129                Matcher matcher = Pattern.compile(regex).matcher(json);
    130                if (matcher.matches()) {
    131                        return matcher.group(1);
    132                }
    133                throw new RuntimeException(regex+" unmatched in "+json);
    134        }
    135
    136        private static int[] getArray(String value) {
    137                String[] split = value.split(",");
    138                int[] ret      = new int[split.length];
    139                for (int i = 0; i < split.length; i++) ret[i] = Integer.parseInt(split[i].trim());
    140                return ret;
    141        }
    142
    143        @Override
    144        public int hashCode() {
    145                final int prime = 31;
    146                int result = 1;
    147                result = prime * result + ((filePath == null) ? 0 : filePath.hashCode());
    148                result = prime * result + ((name == null) ? 0 : name.hashCode());
    149                result = prime * result + Arrays.hashCode(shape);
    150                return result;
    151        }
    152
    153        @Override
    154        public boolean equals(Object obj) {
    155                if (this == obj)
    156                        return true;
    157                if (obj == null)
    158                        return false;
    159                if (getClass() != obj.getClass())
    160                        return false;
    161                DataEvent other = (DataEvent) obj;
    162                if (filePath == null) {
    163                        if (other.filePath != null)
    164                                return false;
    165                } else if (!filePath.equals(other.filePath))
    166                        return false;
    167                if (name == null) {
    168                        if (other.name != null)
    169                                return false;
    170                } else if (!name.equals(other.name))
    171                        return false;
    172                if (!Arrays.equals(shape, other.shape))
    173                        return false;
    174                return true;
    175        }
    176
    177}