Properties.java revision 1472:c18cbe5936b8
1/* 2 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24package com.sun.hotspot.igv.data; 25 26import java.io.Serializable; 27import java.util.ArrayList; 28import java.util.Collection; 29import java.util.Iterator; 30import java.util.List; 31import java.util.regex.Matcher; 32import java.util.regex.Pattern; 33 34 35/** 36 * 37 * @author Thomas Wuerthinger 38 */ 39public class Properties implements Serializable, Iterable<Property> { 40 41 public static final long serialVersionUID = 1L; 42 private String[] map = new String[4]; 43 44 public Properties() { 45 } 46 47 @Override 48 public boolean equals(java.lang.Object o) { 49 if (!(o instanceof Properties)) { 50 return false; 51 } 52 53 Properties p = (Properties) o; 54 55 for (Property prop : this) { 56 String value = p.get(prop.getName()); 57 if (value == null || !value.equals(prop.getValue())) { 58 return false; 59 } 60 } 61 return true; 62 } 63 64 @Override 65 public int hashCode() { 66 int hash = 5; 67 hash = 83 * hash + (this.map != null ? this.map.hashCode() : 0); 68 return hash; 69 } 70 71 public Properties(String name, String value) { 72 this(); 73 this.setProperty(name, value); 74 } 75 76 public Properties(String name, String value, String name1, String value1) { 77 this(name, value); 78 this.setProperty(name1, value1); 79 } 80 81 public Properties(String name, String value, String name1, String value1, String name2, String value2) { 82 this(name, value, name1, value1); 83 this.setProperty(name2, value2); 84 } 85 86 public Properties(Properties p) { 87 map = new String[p.map.length]; 88 System.arraycopy(map, 0, p.map, 0, p.map.length); 89 } 90 91 public static class Entity implements Provider { 92 93 private Properties properties; 94 95 public Entity() { 96 properties = new Properties(); 97 } 98 99 public Entity(Properties.Entity object) { 100 properties = new Properties(object.getProperties()); 101 } 102 103 public Properties getProperties() { 104 return properties; 105 } 106 } 107 108 private String getProperty(String key) { 109 for (int i = 0; i < map.length; i += 2) 110 if (map[i] != null && map[i].equals(key)) { 111 return map[i + 1]; 112 } 113 return null; 114 } 115 116 public interface PropertyMatcher { 117 118 String getName(); 119 120 boolean match(String value); 121 } 122 123 public static class InvertPropertyMatcher implements PropertyMatcher { 124 125 private PropertyMatcher matcher; 126 127 public InvertPropertyMatcher(PropertyMatcher matcher) { 128 this.matcher = matcher; 129 } 130 131 public String getName() { 132 return matcher.getName(); 133 } 134 135 public boolean match(String p) { 136 return !matcher.match(p); 137 } 138 } 139 140 public static class StringPropertyMatcher implements PropertyMatcher { 141 142 private String name; 143 private String value; 144 145 public StringPropertyMatcher(String name, String value) { 146 this.name = name; 147 this.value = value; 148 } 149 150 public String getName() { 151 return name; 152 } 153 154 public boolean match(String p) { 155 return p.equals(value); 156 } 157 } 158 159 public static class RegexpPropertyMatcher implements PropertyMatcher { 160 161 private String name; 162 private Pattern valuePattern; 163 164 public RegexpPropertyMatcher(String name, String value) { 165 this.name = name; 166 valuePattern = Pattern.compile(value); 167 } 168 169 public String getName() { 170 return name; 171 } 172 173 public boolean match(String p) { 174 Matcher m = valuePattern.matcher(p); 175 return m.matches(); 176 } 177 } 178 179 public Property selectSingle(PropertyMatcher matcher) { 180 String value = null; 181 for (int i = 0; i < map.length; i += 2) { 182 if (map[i] != null && matcher.getName().equals(map[i])) { 183 value = map[i + 1]; 184 break; 185 } 186 } 187 if (value != null && matcher.match(value)) { 188 return new Property(matcher.getName(), value); 189 } else { 190 return null; 191 } 192 } 193 194 public interface Provider { 195 196 public Properties getProperties(); 197 } 198 199 @Override 200 public String toString() { 201 StringBuilder sb = new StringBuilder(); 202 sb.append("["); 203 for (int i = 0; i < map.length; i += 2) { 204 if (map[i + 1] != null) { 205 String p = map[i + 1]; 206 sb.append(map[i] + " = " + map[i + 1] + "; "); 207 } 208 } 209 return sb.append("]").toString(); 210 } 211 212 public static class PropertySelector<T extends Properties.Provider> { 213 214 private Collection<T> objects; 215 216 public PropertySelector(Collection<T> objects) { 217 this.objects = objects; 218 } 219 220 public T selectSingle(final String name, final String value) { 221 return selectSingle(new StringPropertyMatcher(name, value)); 222 } 223 224 public T selectSingle(PropertyMatcher matcher) { 225 226 for (T t : objects) { 227 Property p = t.getProperties().selectSingle(matcher); 228 if (p != null) { 229 return t; 230 } 231 } 232 233 return null; 234 } 235 236 public List<T> selectMultiple(final String name, final String value) { 237 return selectMultiple(new StringPropertyMatcher(name, value)); 238 } 239 240 public List<T> selectMultiple(PropertyMatcher matcher) { 241 List<T> result = new ArrayList<T>(); 242 for (T t : objects) { 243 Property p = t.getProperties().selectSingle(matcher); 244 if (p != null) { 245 result.add(t); 246 } 247 } 248 return result; 249 } 250 } 251 252 public String get(String key) { 253 for (int i = 0; i < map.length; i += 2) { 254 if (map[i] != null && map[i].equals(key)) { 255 return map[i + 1]; 256 } 257 } 258 return null; 259 } 260 261 public void setProperty(String name, String value) { 262 for (int i = 0; i < map.length; i += 2) { 263 if (map[i] != null && map[i].equals(name)) { 264 String p = map[i + 1]; 265 if (value == null) { 266 // remove this property 267 map[i] = null; 268 map[i + 1] = null; 269 } else { 270 map[i + 1] = value; 271 } 272 return; 273 } 274 } 275 if (value == null) { 276 return; 277 } 278 for (int i = 0; i < map.length; i += 2) { 279 if (map[i] == null) { 280 map[i] = name; 281 map[i + 1] = value; 282 return; 283 } 284 } 285 String[] newMap = new String[map.length + 4]; 286 System.arraycopy(map, 0, newMap, 0, map.length); 287 newMap[map.length] = name; 288 newMap[map.length + 1] = value; 289 map = newMap; 290 } 291 292 public Iterator<Property> getProperties() { 293 return iterator(); 294 } 295 296 public void add(Properties properties) { 297 for (Property p : properties) { 298 add(p); 299 } 300 } 301 302 public void add(Property property) { 303 assert property.getName() != null; 304 assert property.getValue() != null; 305 setProperty(property.getName(), property.getValue()); 306 } 307 class PropertiesIterator implements Iterator<Property>, Iterable<Property> { 308 public Iterator<Property> iterator() { 309 return this; 310 } 311 312 int index; 313 314 public boolean hasNext() { 315 while (index < map.length && map[index + 1] == null) 316 index += 2; 317 return index < map.length; 318 } 319 320 public Property next() { 321 if (index < map.length) { 322 index += 2; 323 return new Property(map[index - 2], map[index - 1]); 324 } 325 return null; 326 } 327 328 public void remove() { 329 throw new UnsupportedOperationException("Not supported yet."); 330 } 331 332 } 333 public Iterator<Property> iterator() { 334 return new PropertiesIterator(); 335 } 336} 337