1 19 package org.openide.explorer.propertysheet; 20 21 import org.openide.nodes.*; 22 import org.openide.util.*; 23 24 import java.beans.PropertyChangeEvent ; 25 26 import java.util.*; 27 import java.util.logging.Level ; 28 import java.util.logging.Logger ; 29 import org.openide.nodes.Node.PropertySet; 30 31 32 37 final class ProxyNode extends AbstractNode { 38 private static final int MAX_NAMES = 2; 39 private Node[] original; 40 private ArrayList<Node.PropertySet[]> originalPropertySets; 41 private NodeListener pcl; 42 String displayName = null; 43 private String shortDescription = null; 44 45 ProxyNode(Node[] original) { 46 super(Children.LEAF); 47 this.original = original; 48 pcl = new NodeAdapter() { 49 public void propertyChange(PropertyChangeEvent pce) { 50 String nm = pce.getPropertyName(); 51 52 if (PROP_COOKIE.equals(nm)) { 53 fireCookieChange(); 54 } else if (PROP_DISPLAY_NAME.equals(nm)) { 55 displayName = null; 56 fireDisplayNameChange((String ) pce.getOldValue(), getDisplayName()); 57 } else if (PROP_ICON.equals(nm)) { 58 fireIconChange(); 59 } else if (PROP_OPENED_ICON.equals(nm)) { 60 fireOpenedIconChange(); 61 } else if (PROP_NAME.equals(nm)) { 62 fireNameChange((String ) pce.getOldValue(), getName()); 63 } else if (PROP_PROPERTY_SETS.equals(nm)) { 64 PropertySet[] old = getPropertySets(); 65 setSheet(createSheet()); 66 firePropertySetsChange(old, getPropertySets()); 67 } else if (PROP_SHORT_DESCRIPTION.equals(nm)) { 68 fireShortDescriptionChange((String ) pce.getOldValue(), getShortDescription()); 69 } else if (PROP_LEAF.equals(nm)) { 70 } else if (PROP_PARENT_NODE.equals(nm)) { 72 } else { 74 Node.PropertySet[] pss = getPropertySets(); 75 boolean exists = false; 76 77 for (int i = 0; i < pss.length && !exists; i++) { 78 Node.Property[] ps = pss[i].getProperties(); 79 80 for (int j = 0; j < ps.length && !exists; j++) { 81 if (ps[j].getName().equals(nm)) { 82 exists = true; 83 } 84 } 85 } 86 if( exists ) { 87 firePropertyChange(pce.getPropertyName(), pce.getOldValue(), pce.getNewValue()); 88 } 89 } 90 } 91 92 public void nodeDestroyed(NodeEvent ev) { 93 int idx = Arrays.asList(ProxyNode.this.original).indexOf((Node) ev.getSource()); 94 95 if (idx != -1) { 96 HashSet<Node> set = new HashSet<Node>(Arrays.asList(ProxyNode.this.original)); 97 set.remove(ev.getSource()); 98 ProxyNode.this.original = set.toArray(new Node[0]); 99 100 if (set.size() == 0) { 101 ProxyNode.this.fireNodeDestroyed(); 102 } 103 } 104 } 105 }; 106 107 for (int i = 0; i < original.length; i++) { 108 original[i].addPropertyChangeListener(org.openide.util.WeakListeners.propertyChange(pcl, original[i])); 109 original[i].addNodeListener( 110 org.openide.util.WeakListeners.create(NodeListener.class, pcl, original[i]) 111 ); 112 } 113 } 114 115 public HelpCtx getHelpCtx() { 116 for (int i = 0; i < original.length; i++) { 117 if (original[i].getHelpCtx() != HelpCtx.DEFAULT_HELP) { 118 return original[i].getHelpCtx(); 119 } 120 } 121 122 return HelpCtx.DEFAULT_HELP; 123 } 124 125 public Node cloneNode() { 126 return new ProxyNode(original); 127 } 128 129 protected Sheet createSheet() { 130 Sheet sheet = super.createSheet(); 131 Sheet.Set[] computedSet = computePropertySets(); 132 133 for (int i = 0; i < computedSet.length; i++) { 134 sheet.put(computedSet[i]); 135 } 136 137 return sheet; 138 } 139 140 141 Node[] getOriginalNodes() { 142 return original; 143 } 144 145 public String getDisplayName() { 146 if (displayName == null) { 147 displayName = getConcatenatedName(MAX_NAMES); 150 } 151 152 return displayName; 153 } 154 155 private String getConcatenatedName(int limit) { 156 Node[] n = getOriginalNodes(); 157 StringBuffer name = new StringBuffer (); 158 String delim = NbBundle.getMessage(ProxyNode.class, "CTL_List_Delimiter"); 160 for (int i = 0; i < n.length; i++) { 161 name.append(n[i].getDisplayName()); 162 163 if (i != (n.length - 1)) { 164 name.append(delim); 165 } 166 167 if ((i >= limit) && (i != (n.length - 1))) { 168 name.append(NbBundle.getMessage(ProxyNode.class, "MSG_ELLIPSIS")); 169 170 break; 171 } 172 } 173 174 return name.toString(); 175 } 176 177 public String getShortDescription() { 178 if (getOriginalNodes().length < MAX_NAMES) { 179 return NbBundle.getMessage(ProxyNode.class, "CTL_Multiple_Selection"); } else { 181 if (shortDescription == null) { 182 shortDescription = getConcatenatedName(Integer.MAX_VALUE); 183 } 184 185 return shortDescription; 186 } 187 } 188 189 private ArrayList<Node.PropertySet[]> getOriginalPropertySets() { 190 if( null == originalPropertySets ) { 191 originalPropertySets = new ArrayList<Node.PropertySet[]>( original.length ); 192 193 for( int i=0; i<original.length; i++) { 194 Node.PropertySet[] p = original[i].getPropertySets(); 195 originalPropertySets.add( p ); 196 } 197 198 } 199 return originalPropertySets; 200 } 201 202 205 private Sheet.Set[] computePropertySets() { 206 if (original.length > 0) { 207 Node.PropertySet[] firstSet = getOriginalPropertySets().get( 0 ); 208 java.util.Set <Node.PropertySet> sheets = new HashSet<Node.PropertySet>(Arrays.asList(firstSet)); 209 210 for (int i = 1; i < original.length; i++) { 212 sheets.retainAll(new HashSet(Arrays.asList(getOriginalPropertySets().get(i)))); 213 } 214 215 ArrayList<Sheet.Set> resultSheets = new ArrayList<Sheet.Set>(sheets.size()); 216 217 for (int i = 0; i < firstSet.length; i++) { 219 if (!sheets.contains(firstSet[i]) || firstSet[i].isHidden()) { 220 continue; 221 } 222 223 Node.PropertySet current = firstSet[i]; 224 225 Sheet.Set res = new Sheet.Set(); 227 res.setName(current.getName()); 228 res.setDisplayName(current.getDisplayName()); 229 res.setShortDescription(current.getShortDescription()); 230 231 String tabName = (String ) current.getValue("tabName"); 233 if (tabName != null) { 234 res.setValue("tabName", tabName); } 236 237 java.util.Set <Property> props = new HashSet<Property>(Arrays.asList(current.getProperties())); 238 239 String propsHelpID = null; 240 241 for (int j = 0; j < original.length; j++) { 243 Node.PropertySet[] p = getOriginalPropertySets().get(j); 244 245 for (int k = 0; k < p.length; k++) { 246 if (current.getName().equals(p[k].getName())) { 247 props.retainAll(new HashSet<Property>(Arrays.asList(p[k].getProperties()))); 248 } 249 } 250 } 251 252 Node.Property[] p = current.getProperties(); 253 254 for (int j = 0; j < p.length; j++) { 255 if (!props.contains(p[j])) { 256 continue; 257 } 258 259 if (p[j].isHidden()) { 260 continue; 261 } 262 263 ProxyProperty pp = createProxyProperty(p[j].getName(), res.getName()); 264 res.put(pp); 265 } 266 267 resultSheets.add(res); 268 } 269 270 return resultSheets.toArray(new Sheet.Set[resultSheets.size()]); 271 } 272 273 return new Sheet.Set[0]; 274 } 275 276 279 private ProxyProperty createProxyProperty(String propName, String setName) { 280 Node.Property[] arr = new Node.Property[original.length]; 281 282 for (int i = 0; i < original.length; i++) { 283 Node.PropertySet[] p = getOriginalPropertySets().get(i); 284 285 for (int j = 0; j < p.length; j++) { 286 if (p[j].getName().equals(setName)) { 287 Node.Property[] np = p[j].getProperties(); 288 289 for (int k = 0; k < np.length; k++) { 290 if (np[k].getName().equals(propName)) { 291 arr[i] = np[k]; 292 } 293 } 294 } 295 } 296 } 297 298 return new ProxyProperty(arr); 299 } 300 301 305 private static class ProxyProperty extends Node.Property { 306 private Node.Property[] original; 307 308 311 public ProxyProperty(Node.Property[] original) { 312 super(original[0].getValueType()); 313 this.original = original; 314 setName(original[0].getName()); 315 setDisplayName(original[0].getDisplayName()); 316 setShortDescription(original[0].getShortDescription()); 317 } 318 319 322 public boolean canWrite() { 323 for (int i = 0; i < original.length; i++) { 324 if (!original[i].canWrite()) { 325 return false; 326 } 327 } 328 329 return true; 330 } 331 332 336 public boolean canRead() { 337 for (int i = 0; i < original.length; i++) { 338 if (!original[i].canRead()) { 339 return false; 340 } 341 } 342 343 return true; 344 } 345 346 351 public Object getValue() throws IllegalAccessException , java.lang.reflect.InvocationTargetException { 352 Object o = original[0].getValue(); 353 354 if (o == null) { 355 return null; 356 } 357 358 for (int i = 0; i < original.length; i++) { 359 if (!o.equals(original[i].getValue())) { 360 throw new DifferentValuesException(); 361 } 362 } 363 364 return o; 365 } 366 367 373 public void setValue(Object val) 374 throws IllegalAccessException , IllegalArgumentException , java.lang.reflect.InvocationTargetException { 375 for (int i = 0; i < original.length; i++) { 376 original[i].setValue(val); 377 } 378 } 379 380 386 public Object getValue(String attributeName) { 387 Object o = original[0].getValue(attributeName); 388 389 if (Boolean.FALSE.equals(o)) { 390 return o; 394 } 395 396 if (o == null) { 397 return null; 398 } 399 400 for (int i = 1; i < original.length; i++) { 401 if (Boolean.FALSE.equals(original[i])) { 402 return original[i]; 404 } 405 if (!o.equals(original[i].getValue(attributeName))) { 406 if (Boolean.getBoolean("netbeans.ps.logDifferentValues")) { 408 Logger.getLogger(ProxyNode.class.getName()).log(Level.WARNING, null, 409 new DifferentValuesException("Different values in attribute " + 410 attributeName + 411 " for proxy property " + 412 getDisplayName() + 413 "(" + 414 this + 415 ") first value=" + 416 o + 417 " property " + 418 i + "(" + 419 original[i].getClass().getName() + 420 " returns " + 421 original[i].getValue(attributeName))); 422 } 423 return null; 424 } 425 } 426 427 return o; 428 } 429 430 434 public void setValue(String attributeName, Object value) { 435 for (int i = 0; i < original.length; i++) { 436 original[i].setValue(attributeName, value); 437 } 438 } 439 440 443 public java.beans.PropertyEditor getPropertyEditor() { 444 return original[0].getPropertyEditor(); 445 } 446 447 452 public boolean supportsDefaultValue() { 453 for (int i = 0; i < original.length; i++) { 454 if (!original[i].supportsDefaultValue()) { 455 return false; 456 } 457 } 458 459 return true; 460 } 461 462 467 public void restoreDefaultValue() throws IllegalAccessException , java.lang.reflect.InvocationTargetException { 468 for (int i = 0; i < original.length; i++) { 469 original[i].restoreDefaultValue(); 470 } 471 } 472 473 public String toString() { 474 StringBuffer sb = new StringBuffer ("Proxy property for: "); 475 sb.append(getDisplayName()); 476 sb.append('['); 477 478 for (int i = 0; i < original.length; i++) { 479 sb.append(original[i].getClass().getName()); 480 481 if (i < (original.length - 1)) { 482 sb.append(','); 483 } 484 } 485 486 sb.append(']'); 487 488 return sb.toString(); 489 } 490 } 491 492 493 static class DifferentValuesException extends RuntimeException { 494 public DifferentValuesException() { 495 super(); 496 } 497 498 public DifferentValuesException(String message) { 499 super(message); 500 } 501 } 502 } 503 | Popular Tags |