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     */
022    package org.granite.tide.data;
023    
024    import java.io.Serializable;
025    import java.util.ArrayList;
026    import java.util.HashMap;
027    import java.util.HashSet;
028    import java.util.List;
029    import java.util.Map;
030    import java.util.Set;
031    import static org.granite.tide.data.DataDispatcher.TIDE_DATA_TYPE_KEY;
032    import static org.granite.tide.data.DataDispatcher.TIDE_DATA_TYPE_VALUE;
033    
034    
035    
036    public 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    }