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}