1 19 20 package org.netbeans.modules.scripting.php.dbginterface.models; 21 22 import java.beans.Customizer ; 23 import java.beans.PropertyChangeEvent ; 24 import java.beans.PropertyChangeListener ; 25 import java.util.ArrayList ; 26 import java.util.Collection ; 27 import java.util.HashMap ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.Set ; 33 import org.netbeans.modules.scripting.php.dbginterface.api.VariableNode; 34 import org.netbeans.spi.viewmodel.ModelEvent; 35 import org.openide.util.NbBundle; 36 37 41 public class Variable implements VariableNode, PropertyChangeListener , Customizer , Cloneable { 42 public static final String PROP_VALUE = "value"; public static enum Type { 44 UNDEFINED, 45 LONG, 46 DOUBLE, 47 STRING, 48 ARRAY, 49 OBJECT, 50 BOOLEAN, 51 RESOURCE, 52 REFERENCE, 53 SOFT_REFERENCE }; 54 55 private static final Map <Type, String > typeStringMap; 56 static { 57 typeStringMap = new HashMap <Type, String >(); 58 typeStringMap.put(Type.UNDEFINED, NbBundle.getBundle(Variable.class).getString("TYPE_undefined")); typeStringMap.put(Type.LONG, NbBundle.getBundle(Variable.class).getString("TYPE_long")); typeStringMap.put(Type.DOUBLE, NbBundle.getBundle(Variable.class).getString("TYPE_double")); typeStringMap.put(Type.STRING, NbBundle.getBundle(Variable.class).getString("TYPE_string")); typeStringMap.put(Type.ARRAY, NbBundle.getBundle(Variable.class).getString("TYPE_array")); typeStringMap.put(Type.OBJECT, NbBundle.getBundle(Variable.class).getString("TYPE_object")); typeStringMap.put(Type.BOOLEAN, NbBundle.getBundle(Variable.class).getString("TYPE_boolean")); typeStringMap.put(Type.RESOURCE, NbBundle.getBundle(Variable.class).getString("TYPE_resource")); typeStringMap.put(Type.REFERENCE, NbBundle.getBundle(Variable.class).getString("TYPE_reference")); typeStringMap.put(Type.SOFT_REFERENCE, NbBundle.getBundle(Variable.class).getString("TYPE_soft_reference")); } 69 70 private String name; 72 private String longName; private Variable parent; 74 private Type type; 75 private String typeString; 76 private String value; private Variable ref; private List <Variable> children; 79 private Set <PropertyChangeListener > listeners = new HashSet <PropertyChangeListener >(); 80 81 82 public Variable(Variable parent, String name, Type type, String typeString) { 83 this.parent = parent; 84 this.type = type; 85 this.typeString = typeString; 86 setName(name); 87 88 if (typeString == null || typeString.length() == 0) { 89 this.typeString = typeStringMap.get(type); 90 } 91 92 if (parent != null) { 93 addPropertyChangeListener(parent); 94 } 95 } 96 97 public Variable(Variable parent, String name, Type type, String typeString, String value) { 98 this(parent, name, type, typeString); 99 100 this.value = value; 101 } 102 103 public String getValue() { 104 return value; 105 } 106 107 public void setValue(String str) { 108 String v; 109 110 if (type == Type.STRING) { 111 v = longName + "=\"" + str + "\""; 112 } 113 else { 114 v = longName + "=" + str; 115 } 116 117 List <Variable> ret = new ArrayList <Variable>(); 118 120 for (Variable va : ret) { 121 if (va.longName.equals(longName)) { 122 value = va.value; 123 type = va.type; 124 fireValueChanged(this); 125 126 break; 127 } 128 } 129 } 130 131 public void setChildren(List <Variable> cList) { 132 this.children = cList; 133 } 134 135 public VariableNode[] getChildren(int from, int to) { 136 Variable[] ret = new Variable[to - from]; 137 138 for (int i = from; i < to; i++) { 139 ret[i - from] = children.get(i); 140 } 141 142 return ret; 143 } 144 145 public boolean isLeaf() { 146 return children == null || children.size() == 0; 147 } 148 149 public int getChildrenCount() { 150 if (children == null) { 151 return 0; 152 } 153 154 return children.size(); 155 } 156 157 public String getTypeName() { 158 return typeString; 159 } 160 161 public void setRef(Variable ref) { 162 this.ref = ref; 163 } 164 165 public void setName(String name) { 166 if (parent == null || parent.name == null || parent.name.length() == 0) { 167 this.name = name; 168 this.longName = name; 169 } 170 else { 171 switch (parent.type) { 172 case ARRAY: 173 this.name = "[" + name + "]"; 174 this.longName = parent.longName + this.name; 175 break; 176 case OBJECT: 177 this.name = name; 178 this.longName = parent.longName + "->" + this.name; 179 break; 180 default: 181 this.name = name; 182 this.longName = name; 183 } 184 } 185 } 186 187 public void setObject(Object bean) { 188 if (bean instanceof String ) { 189 setValue((String )bean); 190 } 191 else { 192 throw new IllegalArgumentException ("" + bean); 193 } 194 } 195 196 public String toString() { 197 return longName + " = " + getTooltipValue(); 198 } 199 200 201 public void addPropertyChangeListener(PropertyChangeListener l) { 202 synchronized (listeners) { 203 listeners.add(l); 204 } 205 } 206 207 public void removePropertyChangeListener(PropertyChangeListener l) { 208 synchronized (listeners) { 209 listeners.remove(l); 210 } 211 } 212 213 public void propertyChange(PropertyChangeEvent e) { 214 if (children.contains(e.getSource())) { 215 fireValueChanged(e.getSource()); 216 217 return; 218 } 219 throw new UnsupportedOperationException ("Not supported yet."); 220 } 221 222 private void fireValueChanged(Object value) { 223 PropertyChangeEvent evt = new PropertyChangeEvent (this, PROP_VALUE, null, value); 224 PropertyChangeListener [] ls; 225 226 synchronized (listeners) { 227 ls = listeners.toArray(new PropertyChangeListener [listeners.size()]); 228 } 229 230 for (int i = 0; i < ls.length; i++) { 231 ls[i].propertyChange(evt); 232 } 233 } 234 235 public String getName() { 236 return name; 237 } 238 239 public String getDisplayName() { 240 return longName; 241 } 242 243 public String getShortDescription() { 244 return null; 245 } 246 247 public String getIconBase() { 248 return LOCAL_VARIABLE_ICON; 250 } 251 252 253 public boolean isReadOnly() { 254 return type != Type.BOOLEAN && type != Type.DOUBLE && type != Type.LONG && type != Type.STRING ; 255 } 256 257 public String getTooltipValue() { 258 String ret = ""; 259 260 if (children != null) { 261 boolean first = true; 262 263 ret += "[ "; 264 265 for (Variable child : children) { 266 if (!first) { 267 ret += ", "; 268 } 269 ret += child.toString(); 270 first = false; 271 } 272 273 ret += " ]"; 274 } 275 else if (ref != null) { 276 ret += " -> " + ref.longName; 277 } 278 else { 279 ret += value; 280 } 281 282 return ret; 283 } 284 285 public void collectUpdates(Object source, 286 Collection <ModelEvent> events, 287 VariableNode n) { 288 Variable newVar = (Variable)n; 289 boolean hasChanged = false; 290 291 assert name.equals(newVar.getName()); 292 293 if (type != newVar.type) { 294 type = newVar.type; 295 hasChanged = true; 296 } 297 298 if (!typeString.equals(newVar.typeString)) { 299 typeString = newVar.typeString; 300 hasChanged = true; 301 } 302 303 if (value == null && newVar.value != null || 304 newVar.value != null && !newVar.value.equals(value)) { 305 value = newVar.value; 306 hasChanged = true; 307 } 308 309 if (ref == null && newVar.ref != null || 310 newVar.ref != null && !newVar.ref.longName.equals(ref.longName)) { 311 ref = newVar.ref; 312 hasChanged = true; 313 } 314 315 if (children == null && newVar.children != null) { 316 children = newVar.children; 317 hasChanged = true; 318 } 319 else if (children != null) { 320 Iterator <Variable> it = children.iterator(); 321 322 while (it.hasNext()) { 323 Variable child = it.next(); 324 Variable newChild = newVar.findChild(child.name); 325 326 if (newChild != null) { 327 newVar.removeChild(newChild); 328 child.collectUpdates(source, events, newChild); 329 } 330 else { 331 it.remove(); 332 hasChanged = true; 333 } 334 } 335 336 if (newVar.children != null && newVar.children.size() > 0) { 337 it = newVar.children.iterator(); 338 339 while (it.hasNext()) { 340 Variable newChild = it.next(); 341 342 it.remove(); 343 addChild(newChild); 344 hasChanged = true; 345 } 346 } 347 } 348 349 if (hasChanged) { 350 events.add(new ModelEvent.NodeChanged(source, this)); 351 } 352 } 353 354 private Variable findChild(String n) { 355 if (children == null || n == null || n.length() == 0) { 356 return null; 357 } 358 359 for (Variable child : children) { 360 if (child.name.equals(n)) { 361 return child; 362 } 363 } 364 365 return null; 366 } 367 368 private void removeChild(Variable child) { 369 if (child == null || children == null) { 370 return; 371 } 372 373 children.remove(child); 374 child.parent = null; 375 } 377 378 private void addChild(Variable child) { 379 if (child == null) { 380 return; 381 } 382 383 if (children == null) { 384 children = new ArrayList <Variable>(); 385 } 386 387 children.add(child); 388 child.parent = this; 389 } 391 392 public int getType() { 393 return TYPE_LOCAL_FIELD; 394 } 395 } 396 | Popular Tags |