001/* 002 GRANITE DATA SERVICES 003 Copyright (C) 2011 GRANITE DATA SERVICES S.A.S. 004 005 This file is part of Granite Data Services. 006 007 Granite Data Services is free software; you can redistribute it and/or modify 008 it under the terms of the GNU Library General Public License as published by 009 the Free Software Foundation; either version 2 of the License, or (at your 010 option) any later version. 011 012 Granite Data Services is distributed in the hope that it will be useful, but 013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License 015 for more details. 016 017 You should have received a copy of the GNU Library General Public License 018 along with this library; if not, see <http://www.gnu.org/licenses/>. 019*/ 020 021package org.granite.tide.data; 022 023import java.io.Serializable; 024import java.util.ArrayList; 025import java.util.HashMap; 026import java.util.HashSet; 027import java.util.List; 028import java.util.Map; 029import java.util.Set; 030import static org.granite.tide.data.DataDispatcher.TIDE_DATA_TYPE_KEY; 031import static org.granite.tide.data.DataDispatcher.TIDE_DATA_TYPE_VALUE; 032 033 034 035public class DataObserveParams implements Serializable { 036 037 private static final long serialVersionUID = 1L; 038 039 040 private Map<String, Set<String>> params = new HashMap<String, Set<String>>(); 041 private String selector = null; 042 043 044 public DataObserveParams() { 045 } 046 047 private DataObserveParams(Map<String, Set<String>> params, String selector) { 048 this.params = params; 049 this.selector = selector; 050 } 051 052 public boolean isEmpty() { 053 return selector == null && params.isEmpty(); 054 } 055 056 public boolean addValue(String paramName, String value) { 057 if (paramName == null || value == null || paramName.trim().length() == 0 || value.trim().length() == 0) 058 throw new NullPointerException("paramName and value cannot be null or empty"); 059 if (this.selector != null) 060 throw new IllegalArgumentException("Cannot mix manual and automatic selectors"); 061 062 Set<String> values = params.get(paramName); 063 if (values == null) { 064 values = new HashSet<String>(); 065 params.put(paramName, values); 066 } 067 return values.add(value); 068 } 069 070 public void setSelector(String selector) { 071 if (selector == null || selector.trim().length() == 0) 072 throw new NullPointerException("selector cannot be null or empty"); 073 if (!this.params.isEmpty()) 074 throw new IllegalArgumentException("Cannot mix manual and automatic selectors"); 075 076 this.selector = selector; 077 } 078 079 080 public void append(StringBuilder sb) { 081 082 if (selector != null) { 083 sb.append("(").append(selector).append(")"); 084 return; 085 } 086 087 boolean f = true; 088 for (Map.Entry<String, Set<String>> me : params.entrySet()) { 089 if (f) 090 f = false; 091 else 092 sb.append(" AND "); 093 094 Set<String> values = me.getValue(); 095 if (values.size() == 1) 096 sb.append(me.getKey()).append(" = '").append(values.iterator().next()).append("'"); 097 else { 098 sb.append(me.getKey()).append(" IN ("); 099 boolean ff = true; 100 for (String value : values) { 101 if (ff) 102 ff = false; 103 else 104 sb.append(", "); 105 sb.append("'").append(value).append("'"); 106 } 107 sb.append(")"); 108 } 109 } 110 } 111 112 113 private static boolean containsParams(List<DataObserveParams> selectors, DataObserveParams params) { 114 for (DataObserveParams selector : selectors) { 115 if (selector.containsParams(params)) 116 return true; 117 } 118 return false; 119 } 120 121 private boolean containsParams(DataObserveParams params) { 122 if (this.selector != null && !this.selector.equals(params.selector)) 123 return false; 124 125 for (Map.Entry<String, Set<String>> me : params.params.entrySet()) { 126 Set<String> values = this.params.get(me.getKey()); 127 if (values == null || !values.containsAll(me.getValue())) 128 return false; 129 } 130 131 return params.params.keySet().containsAll(this.params.keySet()); 132 } 133 134 public static boolean containsSame(List<DataObserveParams> selectors1, List<DataObserveParams> selectors2) { 135 for (DataObserveParams selector : selectors2) { 136 if (!containsParams(selectors1, selector)) 137 return false; 138 } 139 for (DataObserveParams selector : selectors1) { 140 if (!containsParams(selectors2, selector)) 141 return false; 142 } 143 return true; 144 } 145 146 public String updateDataSelector(String dataSelector, List<DataObserveParams> selectors) { 147 if (!containsParams(selectors, this)) { 148 if (!isEmpty()) { 149 List<DataObserveParams> sels = new ArrayList<DataObserveParams>(selectors); 150 selectors.clear(); 151 for (DataObserveParams s : sels) { 152 if (!this.containsParams(s)) 153 selectors.add(s); 154 } 155 selectors.add(this); 156 } 157 158 return buildSelectorString(selectors); 159 } 160 else if (dataSelector == null) { 161 return TIDE_DATA_TYPE_KEY + " = 'UNINITIALIZED'"; 162 } 163 return dataSelector; 164 } 165 166 private String buildSelectorString(List<DataObserveParams> selectors) { 167 StringBuilder sb = new StringBuilder(TIDE_DATA_TYPE_KEY + " = '" + TIDE_DATA_TYPE_VALUE + "'"); 168 169 if (!selectors.isEmpty()) { 170 sb.append(" AND ("); 171 boolean first = true; 172 for (DataObserveParams selector : selectors) { 173 if (first) 174 first = false; 175 else 176 sb.append(" OR "); 177 sb.append("("); 178 selector.append(sb); 179 sb.append(")"); 180 } 181 sb.append(")"); 182 } 183 184 return sb.toString(); 185 } 186 187 public static Object[] toSerializableForm(List<DataObserveParams> selectors) { 188 Object[] array = new Object[selectors.size()]; 189 for (int i = 0; i < selectors.size(); i++) { 190 DataObserveParams params = selectors.get(i); 191 array[i] = params.selector != null ? params.selector : params.params; 192 } 193 return array; 194 } 195 196 @SuppressWarnings("unchecked") 197 public static List<DataObserveParams> fromSerializableForm(Object[] array) { 198 List<DataObserveParams> selectors = new ArrayList<DataObserveParams>(array != null ? array.length : 5); 199 if (array != null) { 200 for (int i = 0; i < array.length; i++) { 201 selectors.add(array[i] instanceof String 202 ? new DataObserveParams(null, (String)array[i]) 203 : new DataObserveParams((Map<String, Set<String>>)array[i], null)); 204 } 205 } 206 return selectors; 207 } 208 209 @Override 210 public String toString() { 211 StringBuilder sb = new StringBuilder(); 212 append(sb); 213 return sb.toString(); 214 } 215}