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}