    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 diseminate 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
    051         */
    052        public DataEvent(String name, int[] shape) {
    053                super(name);
    054                this.shape = shape;
    055                this.name  = name;
    056        }
    057
    058        @Override
    059        public String getSource() {
    060                return (String)super.getSource();
    061        }
    062
    063        public String getName() {
    064                return getSource();
    065        }
    066
    067        public void setName(String name) {
    068                this.name = name;
    069        }
    070
    071        public int[] getShape() {
    072                return shape;
    073        }
    074
    075        public void setShape(int[] shape) {
    076                this.shape = shape;
    077        }
    078
    079        public String getFilePath() {
    080                return filePath;
    081        }
    082
    083        public void setFilePath(String filePath) {
    084                this.filePath = filePath;
    085        }
    086
    087        /**
    088         * Encodes event to string
    089         * @return encoded string
    090         */
    091        public String encode() {
    092                final StringBuilder buf = new StringBuilder();
    093                buf.append("{");
    094                buf.append("\"name\" : \"");
    095                buf.append(getName());
    096                buf.append("\"");
    097                buf.append(", \"shape\" : ");
    098                buf.append(Arrays.toString(shape));
    099
    100                buf.append(", \"filepath\" : \"");
    101                buf.append(getFilePath());
    102                buf.append("\"");
    103
    104                buf.append("}");
    105                return buf.toString();
    106        }
    107
    108        /**
    109         * Decodes from String for instance {"name" : "Tests", "shape" : [1024, 1024], "filepath" : "C:/tmp/Fred.txt"}
    110         * @return DataEvent
    111         */
    112        public static DataEvent decode(String json) {
    113
    114                String name     = getValue(json, ".*\"name\" \\: \"([^\"]+)\".*");
    115                String filepath = getValue(json, ".*\"filepath\" \\: \"([^\"]+)\".*");
    116                String shape    = getValue(json, ".*\"shape\" \\: \\[([^\\]]+)\\].*");
    117
    118                DataEvent ret = new DataEvent(name, getArray(shape));
    119                if (filepath!=null && !"null".equals(filepath)) {
    120                        ret.setFilePath(filepath);
    121                }
    122                return ret;
    123        }
    124
    125
    126        private static String getValue(String json, String regex) {
    127                Matcher matcher = Pattern.compile(regex).matcher(json);
    128                if (matcher.matches()) {
    129                        return matcher.group(1);
    130                }
    131                throw new RuntimeException(regex+" unmatched in "+json);
    132        }
    133
    134        private static int[] getArray(String value) {
    135                String[] split = value.split(",");
    136                int[] ret      = new int[split.length];
    137                for (int i = 0; i < split.length; i++) ret[i] = Integer.parseInt(split[i].trim());
    138                return ret;
    139        }
    140
    141        @Override
    142        public int hashCode() {
    143                final int prime = 31;
    144                int result = 1;
    145                result = prime * result + ((filePath == null) ? 0 : filePath.hashCode());
    146                result = prime * result + ((name == null) ? 0 : name.hashCode());
    147                result = prime * result + Arrays.hashCode(shape);
    148                return result;
    149        }
    150
    151        @Override
    152        public boolean equals(Object obj) {
    153                if (this == obj)
    154                        return true;
    155                if (obj == null)
    156                        return false;
    157                if (getClass() != obj.getClass())
    158                        return false;
    159                DataEvent other = (DataEvent) obj;
    160                if (filePath == null) {
    161                        if (other.filePath != null)
    162                                return false;
    163                } else if (!filePath.equals(other.filePath))
    164                        return false;
    165                if (name == null) {
    166                        if (other.name != null)
    167                                return false;
    168                } else if (!name.equals(other.name))
    169                        return false;
    170                if (!Arrays.equals(shape, other.shape))
    171                        return false;
    172                return true;
    173        }
    174
    175}