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