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 boolean isEmpty() {
045                    return selector == null && params.isEmpty();
046            }
047            
048            public boolean addValue(String paramName, String value) {
049                    if (paramName == null || value == null || paramName.trim().length() == 0 || value.trim().length() == 0)
050                            throw new NullPointerException("paramName and value cannot be null or empty");
051                    if (this.selector != null)
052                            throw new IllegalArgumentException("Cannot mix manual and automatic selectors");
053                    
054                    Set<String> values = params.get(paramName);
055                    if (values == null) {
056                            values = new HashSet<String>();
057                            params.put(paramName, values);
058                    }
059                    return values.add(value);
060            }
061            
062            public void setSelector(String selector) {
063                    if (selector == null || selector.trim().length() == 0)
064                            throw new NullPointerException("selector cannot be null or empty");
065                    if (!this.params.isEmpty())
066                            throw new IllegalArgumentException("Cannot mix manual and automatic selectors");
067                    
068                    this.selector = selector;
069            }
070            
071            
072            public void append(StringBuilder sb) {
073    
074                    if (selector != null) {
075                            sb.append("(").append(selector).append(")");
076                            return;
077                    }
078    
079                    boolean f = true;
080                    for (Map.Entry<String, Set<String>> me : params.entrySet()) {
081                            if (f)
082                                    f = false;
083                            else
084                                    sb.append(" AND ");
085                            
086                            Set<String> values = me.getValue();
087                            if (values.size() == 1)
088                                    sb.append(me.getKey()).append(" = '").append(values.iterator().next()).append("'");
089                            else {
090                                    sb.append(me.getKey()).append(" IN (");
091                                    boolean ff = true;
092                                    for (String value : values) {
093                                            if (ff)
094                                                    ff = false;
095                                            else
096                                                    sb.append(", ");
097                                            sb.append("'").append(value).append("'");
098                                    }
099                                    sb.append(")");
100                            }
101                    }
102            }
103        
104        
105        private static boolean containsParams(List<DataObserveParams> selectors, DataObserveParams params) {
106            for (DataObserveParams selector : selectors) {
107                    if (selector.containsParams(params))
108                            return true;
109            }
110            return false;
111        }   
112        
113        private boolean containsParams(DataObserveParams params) {
114            if (this.selector != null && !this.selector.equals(params.selector))
115                    return false;
116            
117            for (Map.Entry<String, Set<String>> me : params.params.entrySet()) {
118                    Set<String> values = this.params.get(me.getKey());
119                    if (values == null || !values.containsAll(me.getValue()))
120                            return false;
121            }
122            
123            return params.params.keySet().containsAll(this.params.keySet());
124        }
125    
126            public String updateDataSelector(String dataSelector, List<DataObserveParams> selectors) {
127                    if (!containsParams(selectors, this)) {
128                            if (!isEmpty()) {
129                                    List<DataObserveParams> sels = new ArrayList<DataObserveParams>(selectors);
130                                    selectors.clear();
131                                    for (DataObserveParams s : sels) {
132                                            if (!this.containsParams(s))
133                                                    selectors.add(s);
134                                    }
135                                    selectors.add(this);
136                            }
137                            
138                            return buildSelectorString(selectors);
139                    }
140                    else if (dataSelector == null) {
141                            return TIDE_DATA_TYPE_KEY + " = 'UNINITIALIZED'";
142                    }
143                    return dataSelector;
144            }
145    
146            private String buildSelectorString(List<DataObserveParams> selectors) {
147                    StringBuilder sb = new StringBuilder(TIDE_DATA_TYPE_KEY + " = '" + TIDE_DATA_TYPE_VALUE + "'");
148                    
149                    if (!selectors.isEmpty()) {
150                            sb.append(" AND (");
151                            boolean first = true;
152                            for (DataObserveParams selector : selectors) {
153                                    if (first)
154                                            first = false;
155                                    else
156                                            sb.append(" OR ");
157                                    sb.append("(");
158                                    selector.append(sb);
159                                    sb.append(")");
160                            }
161                            sb.append(")");
162                    }
163                    
164                    return sb.toString();
165            }
166            
167            @Override
168            public String toString() {
169                    StringBuilder sb = new StringBuilder();
170                    append(sb);
171                    return sb.toString();
172            }
173    }