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