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}