1 11 package org.eclipse.core.internal.dtree; 12 13 import org.eclipse.core.internal.utils.Messages; 14 import org.eclipse.core.internal.utils.StringPool; 15 import org.eclipse.core.runtime.IPath; 16 import org.eclipse.osgi.util.NLS; 17 18 23 public abstract class AbstractDataTreeNode { 24 27 static final AbstractDataTreeNode[] NO_CHILDREN = new AbstractDataTreeNode[0]; 28 protected AbstractDataTreeNode children[]; 29 protected String name; 30 31 32 public static final int T_COMPLETE_NODE = 0; 33 public static final int T_DELTA_NODE = 1; 34 public static final int T_DELETED_NODE = 2; 35 public static final int T_NO_DATA_DELTA_NODE = 3; 36 37 45 AbstractDataTreeNode(String name, AbstractDataTreeNode[] children) { 46 this.name = name; 47 if (children == null || children.length == 0) 48 this.children = AbstractDataTreeNode.NO_CHILDREN; 49 else 50 this.children = children; 51 } 52 53 61 abstract AbstractDataTreeNode asBackwardDelta(DeltaDataTree myTree, DeltaDataTree parentTree, IPath key); 62 63 67 AbstractDataTreeNode asReverseComparisonNode(IComparator comparator) { 68 return this; 69 } 70 71 78 static AbstractDataTreeNode[] assembleWith(AbstractDataTreeNode[] oldNodes, AbstractDataTreeNode[] newNodes, boolean keepDeleted) { 79 80 if (newNodes.length == 0) 82 return oldNodes; 83 84 87 AbstractDataTreeNode[] resultNodes = new AbstractDataTreeNode[oldNodes.length + newNodes.length]; 88 89 int oldIndex = 0; 91 int newIndex = 0; 92 int resultIndex = 0; 93 while (oldIndex < oldNodes.length && newIndex < newNodes.length) { 94 int compare = oldNodes[oldIndex].name.compareTo(newNodes[newIndex].name); 95 if (compare == 0) { 96 AbstractDataTreeNode node = oldNodes[oldIndex++].assembleWith(newNodes[newIndex++]); 97 if (node != null && (!node.isDeleted() || keepDeleted)) { 98 resultNodes[resultIndex++] = node; 99 } 100 } else if (compare < 0) { 101 resultNodes[resultIndex++] = oldNodes[oldIndex++]; 102 } else if (compare > 0) { 103 AbstractDataTreeNode node = newNodes[newIndex++]; 104 if (!node.isDeleted() || keepDeleted) { 105 resultNodes[resultIndex++] = node; 106 } 107 } 108 } 109 while (oldIndex < oldNodes.length) { 110 resultNodes[resultIndex++] = oldNodes[oldIndex++]; 111 } 112 while (newIndex < newNodes.length) { 113 AbstractDataTreeNode resultNode = newNodes[newIndex++]; 114 if (!resultNode.isDeleted() || keepDeleted) { 115 resultNodes[resultIndex++] = resultNode; 116 } 117 } 118 119 if (resultIndex < resultNodes.length) { 121 System.arraycopy(resultNodes, 0, resultNodes = new AbstractDataTreeNode[resultIndex], 0, resultIndex); 122 } 123 return resultNodes; 124 } 125 126 129 AbstractDataTreeNode assembleWith(AbstractDataTreeNode node) { 130 131 if (!node.isDelta() || this.isDeleted()) { 134 return node; 135 } 136 137 if (node.hasData()) { 139 if (this.isDelta()) { 140 AbstractDataTreeNode[] assembledChildren = assembleWith(children, node.children, true); 143 return new DataDeltaNode(name, node.getData(), assembledChildren); 144 } 145 AbstractDataTreeNode[] assembledChildren = assembleWith(children, node.children, false); 148 return new DataTreeNode(name, node.getData(), assembledChildren); 149 } 150 if (this.isDelta()) { 151 AbstractDataTreeNode[] assembledChildren = assembleWith(children, node.children, true); 152 if (this.hasData()) 153 return new DataDeltaNode(name, this.getData(), assembledChildren); 154 return new NoDataDeltaNode(name, assembledChildren); 155 } 156 AbstractDataTreeNode[] assembledChildren = assembleWith(children, node.children, false); 157 return new DataTreeNode(name, this.getData(), assembledChildren); 158 } 159 160 163 AbstractDataTreeNode assembleWith(AbstractDataTreeNode node, IPath key, int keyIndex) { 164 165 int keyLen = key.segmentCount(); 167 if (keyIndex == keyLen) { 168 return assembleWith(node); 169 } 170 171 int childIndex = indexOfChild(key.segment(keyIndex)); 173 if (childIndex >= 0) { 174 AbstractDataTreeNode copy = copy(); 175 copy.children[childIndex] = children[childIndex].assembleWith(node, key, keyIndex + 1); 176 return copy; 177 } 178 179 for (int i = keyLen - 2; i >= keyIndex; --i) { 182 node = new NoDataDeltaNode(key.segment(i), node); 183 } 184 node = new NoDataDeltaNode(name, node); 185 return assembleWith(node); 186 } 187 188 191 AbstractDataTreeNode childAt(String localName) { 192 AbstractDataTreeNode node = childAtOrNull(localName); 193 if (node != null) { 194 return node; 195 } 196 throw new ObjectNotFoundException(NLS.bind(Messages.dtree_missingChild, localName)); 197 } 198 199 206 AbstractDataTreeNode childAtOrNull(String localName) { 207 int index = indexOfChild(localName); 208 return index >= 0 ? children[index] : null; 209 } 210 211 220 AbstractDataTreeNode childAtIgnoreCase(String localName) { 221 AbstractDataTreeNode result = null; 222 for (int i = 0; i < children.length; i++) { 223 if (children[i].getName().equalsIgnoreCase(localName)) { 224 if (children[i].isDeleted()) 226 result = children[i]; 227 else 228 return children[i]; 229 } 230 } 231 return result; 232 } 233 234 236 protected static AbstractDataTreeNode[] compareWith(AbstractDataTreeNode[] oldNodes, AbstractDataTreeNode[] newNodes, IComparator comparator) { 237 238 int oldLen = oldNodes.length; 239 int newLen = newNodes.length; 240 int oldIndex = 0; 241 int newIndex = 0; 242 AbstractDataTreeNode[] comparedNodes = new AbstractDataTreeNode[oldLen + newLen]; 243 int count = 0; 244 245 while (oldIndex < oldLen && newIndex < newLen) { 246 DataTreeNode oldNode = (DataTreeNode) oldNodes[oldIndex]; 247 DataTreeNode newNode = (DataTreeNode) newNodes[newIndex]; 248 int compare = oldNode.name.compareTo(newNode.name); 249 if (compare < 0) { 250 251 int userComparison = comparator.compare(oldNode.getData(), null); 252 if (userComparison != 0) { 253 comparedNodes[count++] = convertToRemovedComparisonNode(oldNode, userComparison); 254 } 255 ++oldIndex; 256 } else if (compare > 0) { 257 258 int userComparison = comparator.compare(null, newNode.getData()); 259 if (userComparison != 0) { 260 comparedNodes[count++] = convertToAddedComparisonNode(newNode, userComparison); 261 } 262 ++newIndex; 263 } else { 264 AbstractDataTreeNode comparedNode = oldNode.compareWith(newNode, comparator); 265 NodeComparison comparison = (NodeComparison) comparedNode.getData(); 266 267 268 if (!(comparison.isUnchanged() && comparedNode.size() == 0)) { 269 comparedNodes[count++] = comparedNode; 270 } 271 ++oldIndex; 272 ++newIndex; 273 } 274 } 275 while (oldIndex < oldLen) { 276 DataTreeNode oldNode = (DataTreeNode) oldNodes[oldIndex++]; 277 278 279 int userComparison = comparator.compare(oldNode.getData(), null); 280 if (userComparison != 0) { 281 comparedNodes[count++] = convertToRemovedComparisonNode(oldNode, userComparison); 282 } 283 } 284 while (newIndex < newLen) { 285 DataTreeNode newNode = (DataTreeNode) newNodes[newIndex++]; 286 287 288 int userComparison = comparator.compare(null, newNode.getData()); 289 if (userComparison != 0) { 290 comparedNodes[count++] = convertToAddedComparisonNode(newNode, userComparison); 291 } 292 } 293 294 if (count == 0) { 295 return NO_CHILDREN; 296 } 297 if (count < comparedNodes.length) { 298 System.arraycopy(comparedNodes, 0, comparedNodes = new AbstractDataTreeNode[count], 0, count); 299 } 300 return comparedNodes; 301 } 302 303 305 protected static AbstractDataTreeNode[] compareWithParent(AbstractDataTreeNode[] nodes, IPath key, DeltaDataTree parent, IComparator comparator) { 306 307 AbstractDataTreeNode[] comparedNodes = new AbstractDataTreeNode[nodes.length]; 308 int count = 0; 309 for (int i = 0; i < nodes.length; ++i) { 310 AbstractDataTreeNode node = nodes[i]; 311 AbstractDataTreeNode comparedNode = node.compareWithParent(key.append(node.getName()), parent, comparator); 312 NodeComparison comparison = (NodeComparison) comparedNode.getData(); 313 if (!(comparison.isUnchanged() && comparedNode.size() == 0)) { 315 comparedNodes[count++] = comparedNode; 316 } 317 } 318 if (count == 0) { 319 return NO_CHILDREN; 320 } 321 if (count < comparedNodes.length) { 322 System.arraycopy(comparedNodes, 0, comparedNodes = new AbstractDataTreeNode[count], 0, count); 323 } 324 return comparedNodes; 325 } 326 327 abstract AbstractDataTreeNode compareWithParent(IPath key, DeltaDataTree parent, IComparator comparator); 328 329 static AbstractDataTreeNode convertToAddedComparisonNode(AbstractDataTreeNode newNode, int userComparison) { 330 AbstractDataTreeNode[] children = newNode.getChildren(); 331 int n = children.length; 332 AbstractDataTreeNode[] convertedChildren; 333 if (n == 0) { 334 convertedChildren = NO_CHILDREN; 335 } else { 336 convertedChildren = new AbstractDataTreeNode[n]; 337 for (int i = 0; i < n; ++i) { 338 convertedChildren[i] = convertToAddedComparisonNode(children[i], userComparison); 339 } 340 } 341 return new DataTreeNode(newNode.name, new NodeComparison(null, newNode.getData(), NodeComparison.K_ADDED, userComparison), convertedChildren); 342 } 343 344 static AbstractDataTreeNode convertToRemovedComparisonNode(AbstractDataTreeNode oldNode, int userComparison) { 345 AbstractDataTreeNode[] children = oldNode.getChildren(); 346 int n = children.length; 347 AbstractDataTreeNode[] convertedChildren; 348 if (n == 0) { 349 convertedChildren = NO_CHILDREN; 350 } else { 351 convertedChildren = new AbstractDataTreeNode[n]; 352 for (int i = 0; i < n; ++i) { 353 convertedChildren[i] = convertToRemovedComparisonNode(children[i], userComparison); 354 } 355 } 356 return new DataTreeNode(oldNode.name, new NodeComparison(oldNode.getData(), null, NodeComparison.K_REMOVED, userComparison), convertedChildren); 357 } 358 359 362 abstract AbstractDataTreeNode copy(); 363 364 369 protected void copyChildren(int from, int to, AbstractDataTreeNode otherNode, int start) { 370 int other = start; 371 for (int i = from; i <= to; i++, other++) { 372 this.children[i] = otherNode.children[other]; 373 } 374 } 375 376 379 public AbstractDataTreeNode[] getChildren() { 380 return children; 381 } 382 383 386 Object getData() { 387 throw new AbstractMethodError (Messages.dtree_subclassImplement); 388 } 389 390 393 public String getName() { 394 return name; 395 } 396 397 400 boolean hasData() { 401 return false; 402 } 403 404 408 boolean includesChild(String localName) { 409 return indexOfChild(localName) != -1; 410 } 411 412 415 protected int indexOfChild(String localName) { 416 AbstractDataTreeNode[] nodes = this.children; 417 int left = 0; 418 int right = nodes.length - 1; 419 while (left <= right) { 420 int mid = (left + right) / 2; 421 int compare = localName.compareTo(nodes[mid].name); 422 if (compare < 0) { 423 right = mid - 1; 424 } else if (compare > 0) { 425 left = mid + 1; 426 } else { 427 return mid; 428 } 429 } 430 return -1; 431 } 432 433 436 boolean isDeleted() { 437 return false; 438 } 439 440 444 boolean isDelta() { 445 return false; 446 } 447 448 451 boolean isEmptyDelta() { 452 return false; 453 } 454 455 458 String [] namesOfChildren() { 459 String names[] = new String [children.length]; 460 461 for (int i = children.length; --i >= 0;) 462 names[i] = children[i].getName(); 463 return names; 464 } 465 466 469 void replaceChild(String localName, DataTreeNode node) { 470 int i = indexOfChild(localName); 471 if (i >= 0) { 472 children[i] = node; 473 } else { 474 throw new ObjectNotFoundException(NLS.bind(Messages.dtree_missingChild, localName)); 475 } 476 } 477 478 481 protected void setChildren(AbstractDataTreeNode newChildren[]) { 482 children = newChildren; 483 } 484 485 488 void setName(String s) { 489 name = s; 490 } 491 492 495 protected static AbstractDataTreeNode[] simplifyWithParent(AbstractDataTreeNode[] nodes, IPath key, DeltaDataTree parent, IComparator comparer) { 496 497 AbstractDataTreeNode[] simplifiedNodes = new AbstractDataTreeNode[nodes.length]; 498 int simplifiedCount = 0; 499 for (int i = 0; i < nodes.length; ++i) { 500 AbstractDataTreeNode node = nodes[i]; 501 AbstractDataTreeNode simplifiedNode = node.simplifyWithParent(key.append(node.getName()), parent, comparer); 502 if (!simplifiedNode.isEmptyDelta()) { 503 simplifiedNodes[simplifiedCount++] = simplifiedNode; 504 } 505 } 506 if (simplifiedCount == 0) { 507 return NO_CHILDREN; 508 } 509 if (simplifiedCount < simplifiedNodes.length) { 510 System.arraycopy(simplifiedNodes, 0, simplifiedNodes = new AbstractDataTreeNode[simplifiedCount], 0, simplifiedCount); 511 } 512 return simplifiedNodes; 513 } 514 515 518 abstract AbstractDataTreeNode simplifyWithParent(IPath key, DeltaDataTree parent, IComparator comparer); 519 520 523 int size() { 524 return children.length; 525 } 526 527 530 public void storeStrings(StringPool set) { 531 name = set.add(name); 532 AbstractDataTreeNode[] nodes = children; 534 if (nodes != null) 535 for (int i = nodes.length; --i >= 0;) 536 nodes[i].storeStrings(set); 537 } 538 539 543 public String toString() { 544 return "an AbstractDataTreeNode(" + this.getName() + ") with " + getChildren().length + " children."; } 546 547 550 abstract int type(); 551 } 552 | Popular Tags |