1 5 6 package org.exoplatform.services.jcr.impl.core; 7 8 9 import java.io.InputStream ; 10 import java.util.ArrayList ; 11 import java.util.Calendar ; 12 import java.util.Collection ; 13 import java.util.Iterator ; 14 import java.util.List ; 15 16 import javax.jcr.ActionVetoedException; 17 import javax.jcr.BinaryValue; 18 import javax.jcr.BooleanValue; 19 import javax.jcr.DateValue; 20 import javax.jcr.DoubleValue; 21 import javax.jcr.Item; 22 import javax.jcr.ItemExistsException; 23 import javax.jcr.ItemNotFoundException; 24 import javax.jcr.ItemVisitor; 25 import javax.jcr.LongValue; 26 import javax.jcr.MergeException; 27 import javax.jcr.NoSuchWorkspaceException; 28 import javax.jcr.Node; 29 import javax.jcr.NodeIterator; 30 import javax.jcr.PathNotFoundException; 31 import javax.jcr.Property; 32 import javax.jcr.PropertyIterator; 33 import javax.jcr.PropertyType; 34 import javax.jcr.RepositoryException; 35 import javax.jcr.StringIterator; 36 import javax.jcr.StringValue; 37 import javax.jcr.UnsupportedRepositoryOperationException; 38 import javax.jcr.Value; 39 import javax.jcr.ValueFormatException; 40 import javax.jcr.access.AccessDeniedException; 41 import javax.jcr.nodetype.ConstraintViolationException; 42 import javax.jcr.nodetype.NoSuchNodeTypeException; 43 import javax.jcr.nodetype.NodeDef; 44 import javax.jcr.nodetype.NodeType; 45 import javax.jcr.nodetype.PropertyDef; 46 import javax.jcr.version.Version; 47 import javax.jcr.version.VersionHistory; 48 49 import org.exoplatform.services.jcr.core.ItemLocation; 50 import org.exoplatform.services.jcr.core.NodeData; 51 import org.exoplatform.services.jcr.impl.core.itemfilters.AllAcceptedFilter; 52 import org.exoplatform.services.jcr.impl.core.itemfilters.ItemFilter; 53 import org.exoplatform.services.jcr.impl.core.itemfilters.NamePatternFilter; 54 import org.exoplatform.services.jcr.impl.core.nodetype.NodeDefImpl; 55 import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeImpl; 56 import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl; 57 import org.exoplatform.services.jcr.impl.util.EntityCollection; 58 import org.exoplatform.services.jcr.impl.util.PropertyConvertor; 59 60 66 67 public class NodeImpl extends ItemImpl implements NodeData { 68 69 private List properties; 70 71 72 75 public NodeImpl(String absPath) throws PathNotFoundException { 76 this(absPath, "nt:default"); 77 } 78 79 public NodeImpl(String absPath, String type) throws PathNotFoundException { 80 super(absPath); 81 properties = new ArrayList (); 82 try { 83 properties.add(new PropertyImpl(location.getPath() + "/jcr:primaryType", 84 new StringValue(type), PropertyType.STRING)); 85 } catch (Exception e) { 86 throw new PathNotFoundException("NodeImpl() failed. Reason: " + e.getMessage()); 87 } 88 89 } 90 91 public NodeImpl(String absPath, List props) throws PathNotFoundException { 92 super(absPath); 93 this.properties = props; 94 } 95 96 public NodeImpl(NodeImpl node) throws PathNotFoundException, RepositoryException { 98 super(node.getPath()); 99 refresh(node); 100 101 } 102 103 104 122 public Node getNode(String path) throws PathNotFoundException, RepositoryException { 123 ItemLocation loc = new ItemLocation(this.location.getPath(), path); 124 if (loc.equals(this.location)) 125 return this; 126 else 127 return ticket.getNodeByAbsPath(loc.getPath()); 128 } 129 130 136 public NodeIterator getNodes() throws RepositoryException { 137 log.debug("get nodes"); 138 return retrieveChildNodes(new AllAcceptedFilter()); 139 } 140 141 155 public NodeIterator getNodes(String namePattern) throws RepositoryException { 156 return retrieveChildNodes(new NamePatternFilter(namePattern)); 157 } 158 159 170 public Property getProperty(String path) throws PathNotFoundException, RepositoryException { 171 ItemLocation loc = new ItemLocation(this.location.getPath(), path); 172 if (!this.location.getPath().equals(loc.getParentPath())) { 173 Node node = ticket.getNodeByAbsPath(loc.getParentPath()); 174 return node.getProperty(loc.getName()); 175 } 176 177 EntityCollection res = retrieveProperties(new NamePatternFilter(loc.getName())); 178 if (res.hasNext()) { 179 PropertyImpl property = (PropertyImpl) res.nextProperty(); 180 property.setTicket(ticket); 181 return property; 182 } else 183 throw new PathNotFoundException("No property at the path '" + loc.getPath() + "'"); 184 } 185 186 187 193 public PropertyIterator getProperties() { 194 return retrieveProperties(new AllAcceptedFilter()); 195 } 196 197 211 public PropertyIterator getProperties(String namePattern) { 212 return retrieveProperties(new NamePatternFilter(namePattern)); 213 } 214 215 226 public Property findProperty(Value value) throws RepositoryException { 227 PropertyIterator iterator = findProperties(value); 228 if (iterator.hasNext()) 229 return iterator.nextProperty(); 230 return null; 231 } 232 233 242 public PropertyIterator findProperties(Value value) throws RepositoryException { 243 log.debug("find properties"); 244 if (value == null) 245 throw new RepositoryException("Value must not be null"); 246 247 ArrayList props = new ArrayList (); 248 PropertyIterator propsI = retrieveProperties(new AllAcceptedFilter()); 249 while (propsI.hasNext()) { 250 PropertyImpl prop = (PropertyImpl) propsI.nextProperty(); 251 Value convertedValue = null; 252 try { 253 convertedValue = PropertyConvertor.convert(prop.getValue(), value.getType()); 254 log.debug("find properties - test if "+value+" of "+prop+" equals "+convertedValue+" result="+value.equals(convertedValue)); 255 256 if (value.equals(convertedValue)) 257 props.add(prop); 258 259 } catch (IllegalStateException e) { 260 } catch (RepositoryException e) { 261 } 262 } 263 return new EntityCollection(props); 264 } 265 266 public ItemIterator getItems(ItemFilter filter) { 267 List items = retrieveChildNodes(filter).getList(); 268 items.addAll(retrieveProperties(filter).getList()); 269 return new EntityCollection(items); 270 } 271 272 286 public Item getPrimaryItem() throws ItemNotFoundException, RepositoryException { 287 NodeImpl node = this; 288 289 ItemImpl item = findPrimaryItem(node); 291 292 294 if (item.equals(this)) 295 throw new ItemNotFoundException("NodeImpl.getPrimaryItem() Node does not have the primary items!"); 296 else 297 return item; 298 } 299 300 311 public String getUUID() throws UnsupportedRepositoryOperationException, RepositoryException { 312 try { 313 return getProperty("jcr:uuid").getString(); 314 } catch (PathNotFoundException e) { 315 throw new UnsupportedRepositoryOperationException("that node should have mix:referenceable mixin type", e); 316 } 317 } 318 319 320 324 public boolean hasNode(String relPath) throws RepositoryException { 325 try { 326 getNode(relPath); 327 } catch (PathNotFoundException e) { 328 return false; 330 } 331 return true; 332 } 333 334 339 public boolean hasNodes() throws RepositoryException { 340 return getNodes().hasNext(); 341 } 342 343 347 public boolean hasProperty(String relPath) throws RepositoryException { 348 try { 349 if (getProperty(relPath) != null) 350 return true; 351 } catch (RepositoryException e) { 352 } 353 return false; 354 } 355 356 360 public boolean hasProperties() throws RepositoryException { 361 return getProperties().hasNext(); 362 } 363 364 387 public Node addNode(String path) throws ItemExistsException, PathNotFoundException, 388 ConstraintViolationException, RepositoryException { 389 390 ItemLocation loc = new ItemLocation(location.getPath(), path); 391 String name = loc.getName(); 392 NodeImpl parent = getParentToAddNodeTo(loc.getParentPath()); 393 394 if (!parent.getPrimaryNodeType().canAddChildNode(name)) { 395 ticket.getNodesManager().addValidationError(loc.getPath(), 396 new ConstraintViolationException("Can't add node " + name) ); 397 } 398 399 400 String nodeTypeName = findNodeType(parent, name); 402 403 if (nodeTypeName == null) 404 throw new ConstraintViolationException("Can not define node type : for <" + name + "> !"); 405 406 return addNode(path, nodeTypeName); 407 } 408 409 private String findNodeType(NodeImpl parent, String name) { 410 String nodeTypeName = null; 411 NodeDef[] nodeDefs = parent.getPrimaryNodeType().getChildNodeDefs(); 412 boolean residualFlag = false; 413 if (nodeDefs != null) { 414 for (int i = 0; i < nodeDefs.length; i++) { 415 NodeDef nodeDef = nodeDefs[i]; 416 if (nodeDef.getName() != null) { 417 if (nodeDef.getName().equals(name)) { 418 return nodeDef.getDefaultPrimaryType().getName(); 419 } 420 } else { 421 residualFlag = true; 422 } 423 } 424 if (residualFlag) { 426 for (int i = 0; i < nodeDefs.length; i++) { 427 NodeDef nodeDef = nodeDefs[i]; 428 if (nodeDef.getName() == null) { 429 return nodeDef.getDefaultPrimaryType().getName(); 430 } 431 } 432 } 433 } 434 return nodeTypeName; 435 } 436 437 448 public Node addNode(String path, String nodeTypeName) 449 throws ItemExistsException, PathNotFoundException, NoSuchNodeTypeException, 450 ConstraintViolationException, RepositoryException { 451 NodeType type = null; 453 454 ItemLocation loc = new ItemLocation(location.getPath(), path); 455 String name = loc.getName(); 456 NodeImpl parent = getParentToAddNodeTo(loc.getParentPath()); 457 458 if( ticket.getNodesManager().getNodeByPath(loc.getPath()) != null ) 459 ticket.getNodesManager().addValidationError(loc.getPath(), new ItemExistsException("Can't add node " + path + ". The node " 460 + loc.getPath() + " already exists") ); 461 462 NodeType parentNodeType = parent.getPrimaryNodeType(); 463 if (!parentNodeType.canAddChildNode(name, nodeTypeName)) { 464 log.debug("Can't add node " + name + " type " + nodeTypeName+ " to parent type "+parentNodeType.getName()); 465 ticket.getNodesManager().addValidationError(loc.getPath(), new ConstraintViolationException("Can't add node " + name 466 + " type " + nodeTypeName+ " to parent type "+parentNodeType.getName())); 467 } 468 469 if (nodeTypeName != null) { 471 type = NodeTypeManagerImpl.getInstance().getNodeType(nodeTypeName); 472 } else { 473 throw new ConstraintViolationException("Add Node failed: Node Type <" + nodeTypeName + "> not found!"); 474 } 475 476 if (type.isMixin()) 477 throw new ConstraintViolationException("Add Node failed: Node Type <" + nodeTypeName + "> is MIXIN type!"); 478 479 log.debug("Add node. Parent: " + parent + " path: " + path + " type " + type); 480 NodeImpl node = createNode(parent, name, type); 481 482 return node; 483 } 484 485 private NodeImpl getParentToAddNodeTo(String parentPath) throws PathNotFoundException, ConstraintViolationException { 486 try { 487 return (NodeImpl) getNode(parentPath); 488 } catch (RepositoryException e) { 489 try { 490 getProperty(parentPath); 491 } catch (RepositoryException e1) { 492 throw new PathNotFoundException("Add Node failed: parent node at <" + parentPath + "> not found!"); 493 } 494 throw new ConstraintViolationException("Can not add a node to a property item"); 495 } 496 } 497 498 517 public Node addExistingNode(String absPath) throws PathNotFoundException, RepositoryException { 518 ItemLocation location = new ItemLocation(absPath); 519 return addExistingNode(absPath, location.getName()); 520 } 522 523 534 public Node addExistingNode(String absPath, String newName) throws PathNotFoundException, RepositoryException { 535 536 NodeImpl realNode = (NodeImpl)ticket.getNodesManager().getNodeByPath(absPath); 537 if(realNode == null) 538 throw new PathNotFoundException("There are no node at "+realNode); 539 540 Property uuid = realNode.getPermanentProperty("jcr:uuid"); 541 if (uuid == null) { 542 ticket.getNodesManager().addValidationError(absPath, new ConstraintViolationException("Can't add reference as " + realNode + " is not referenceable.")); 543 log.debug("Can't add reference as " + absPath + " is not referenceable."); 544 } 545 546 String refPath = new ItemLocation(getPath(), newName).getPath(); 547 549 ticket.getNodesManager().addReference(uuid.getString(), refPath); 550 551 return realNode; 552 553 } 555 556 557 576 public Property setProperty(String name, Value value) throws ValueFormatException, RepositoryException { 577 if (value == null) 578 throw new ValueFormatException("Set Property failed: value type could not be recognized!"); 579 580 return setProperty(name, value, value.getType()); 581 } 582 583 586 public Property setProperty(String name, Value value, int type) 587 throws ValueFormatException, RepositoryException { 588 Value[] array = {value}; 589 return setProperty(name, array, type); 590 } 591 592 593 613 public Property setProperty(String name, Value[] values, int type) 614 throws ValueFormatException, RepositoryException { 615 if (name == null) 616 throw new IllegalArgumentException ("Property name can not be null"); 617 618 if(values.length > 1){ 619 PropertyDef propertyDef = ((NodeTypeImpl)getPrimaryNodeType()).getPropertyDef(name); 620 if(propertyDef != null && !propertyDef.isMultiple()) 621 throw new ValueFormatException("Can not add multiple value to this property"); 622 } 623 624 values = PropertyConvertor.convert(values, type); 625 626 ItemLocation loc = new ItemLocation(location.getPath(), name); 627 628 if (values.length == 1) { 629 if (!getPrimaryNodeType().canSetProperty(name, values[0])) 630 ticket.getNodesManager().addValidationError(loc.getParentPath(), 631 new ConstraintViolationException("Can't set prop " + name)); 632 } 633 634 PropertyDef[] propertyDef = getPrimaryNodeType().getPropertyDefs(); 635 int residualNb = 0; 636 Collection residuals = new ArrayList (); 637 for (int i = 0; i < propertyDef.length; i++) { 638 PropertyDef def = propertyDef[i]; 639 if (def != null) { 640 if (def.getName() == null) { 641 residuals.add(def); 643 residualNb++; 644 } else if (name.equals(def.getName())) { 645 int requiredType = def.getRequiredType(); 646 if (requiredType != type && requiredType != PropertyType.UNDEFINED) { 647 return updateProperty(name, requiredType, PropertyConvertor.convert(values, requiredType)); 648 } else { 649 return updateProperty(name, type, values); 650 } 651 } 652 } 653 } 654 if (residualNb == 1) { 655 int requiredType = ((PropertyDef) residuals.iterator().next()).getRequiredType(); 656 if (requiredType != type && requiredType != PropertyType.UNDEFINED) { 657 return updateProperty(name, requiredType, PropertyConvertor.convert(values, requiredType)); 658 } else { 659 return updateProperty(name, type, values); 660 } 661 } else if (residualNb > 1) { 662 for (Iterator iterator = residuals.iterator(); iterator.hasNext();) { 663 PropertyDef def = (PropertyDef) iterator.next(); 664 int requiredType = def.getRequiredType(); 665 if (requiredType == type) { 666 return updateProperty(name, type, values); 667 } 668 } 669 throw new RepositoryException("Can not resolve property type due to multi residuals"); 670 } 671 PropertyImpl prop = updateProperty(name, type, values); 672 return prop; 673 } 674 675 678 public Property setProperty(String name, String value, int type) 679 throws ValueFormatException, RepositoryException { 680 return setProperty(name, new StringValue(value), type); 681 } 682 683 703 public Property setProperty(String name, String [] values, int type) 704 throws ValueFormatException, RepositoryException { 705 Value[] convertedValues = new Value[values.length]; 706 for (int i = 0; i < values.length; i++) { 707 String value = values[i]; 708 convertedValues[i] = new StringValue(value); 709 } 710 return setProperty(name, convertedValues, type); 711 } 712 713 716 public Property setProperty(String name, String value) throws ValueFormatException, RepositoryException { 717 return setProperty(name, new StringValue(value), PropertyType.STRING); 718 } 719 720 723 public Property setProperty(String name, InputStream value) throws ValueFormatException, RepositoryException { 724 return setProperty(name, new BinaryValue(value), PropertyType.BINARY); 725 } 726 727 730 public Property setProperty(String name, boolean value) throws ValueFormatException, RepositoryException { 731 return setProperty(name, new BooleanValue(value), PropertyType.BOOLEAN); 732 } 733 734 737 public Property setProperty(String name, Calendar value) throws ValueFormatException, RepositoryException { 738 return setProperty(name, new DateValue(value), PropertyType.DATE); 739 } 740 741 744 public Property setProperty(String name, double value) throws ValueFormatException, RepositoryException { 745 return setProperty(name, new DoubleValue(value), PropertyType.DOUBLE); 746 } 747 748 751 public Property setProperty(String name, long value) throws ValueFormatException, RepositoryException { 752 return setProperty(name, new LongValue(value), PropertyType.LONG); 753 } 754 755 775 public void remove(String path) throws PathNotFoundException, RepositoryException { 776 log.debug("Node.remove(" + path + ")") ; 778 ItemLocation loc = new ItemLocation(location.getPath(), path); 779 String name = loc.getName(); 780 NodeImpl parent = (NodeImpl) getNode(loc.getParentPath()); 781 782 if (parent == null) 783 throw new PathNotFoundException("Remove failed: parent node for <" + path + "> not found!"); 784 785 if (!parent.getPrimaryNodeType().checkRemoveItem(name)) 786 ticket.getNodesManager().addValidationError(loc.getPath(), 787 new ConstraintViolationException("Can't remove item " + name)); 788 789 ItemIterator items = parent.getItems(new NamePatternFilter(name)); 790 if (!items.hasNext()) { 791 log.debug("Can not find item : " + name + " with parent : " + parent.getPath()); 792 return; 793 } 794 795 ItemImpl item = (ItemImpl)items.nextItem(); 796 item.setTicket(ticket); 797 if(item.isNode()) 798 ticket.getNodesManager().delete((NodeImpl)item); 799 else { 800 parent.removePermanentProperty(name); 801 ticket.getNodesManager().update(parent); 802 } 803 804 806 } 807 808 809 831 public void save(boolean shallow) throws AccessDeniedException, ConstraintViolationException, 832 ActionVetoedException, RepositoryException { 833 if(!ticket.getNodesManager().hasPersistedParent(this)) 834 throw new ConstraintViolationException("parent node does not exist or is not persisted yet"); 835 ticket.getNodesManager().validate(this, shallow); 836 ticket.getNodesManager().commit(this, shallow); 837 } 838 839 840 845 public NodeType getPrimaryNodeType() { 846 PropertyImpl nodeTypeProp = (PropertyImpl) getPermanentProperty ("jcr:primaryType"); 848 NodeType type; 849 if (nodeTypeProp != null) { 850 try { 851 type = NodeTypeManagerImpl.getInstance().getNodeType(nodeTypeProp.getString()); 852 } catch (NoSuchNodeTypeException e) { 853 throw new RuntimeException ("NodeImpl.getNodeType() error: NodeType <" + nodeTypeProp.toString() + 854 "> not found in NodeTypeManager!", e); 855 } 856 return type; 857 } else { 858 log.warn("getNodeType() jcr:primaryType not found for " + getPath() + " nt:default is applied."); 859 return new org.exoplatform.services.jcr.impl.core.nodetype.nt.Default(); 860 } 861 } 862 863 869 public NodeType[] getMixinNodeTypes() { 870 871 if(getPermanentProperty("jcr:mixinType") == null) 872 return new NodeType[0]; 873 874 try { 875 Value[] mixinNodeTypeNames = getPermanentProperty("jcr:mixinType").getValues(); 876 NodeType[] mixinTypes = new NodeType[mixinNodeTypeNames.length]; 877 for(int i=0; i<mixinNodeTypeNames.length; i++) { 878 mixinTypes[i] = NodeTypeManagerImpl.getInstance().getNodeType(mixinNodeTypeNames[i].getString()); 879 880 } 881 return mixinTypes; 882 } catch (Exception e) { 883 e.printStackTrace(); 884 log.error("NoSuchNodeTypeException (getMixinNodeTypes) "+e); 885 return null; 886 } 887 888 } 890 891 896 public boolean isNodeType(String nodeTypeName) throws RepositoryException { 897 NodeType testNodeType; 898 try { 899 testNodeType = NodeTypeManagerImpl.getInstance().getNodeType(nodeTypeName); 900 } catch (NoSuchNodeTypeException e) { 901 log.error("Node.isNodeType() No such node: "+nodeTypeName); 902 return false; 903 } 905 906 if(NodeTypeImpl.isSameOrSubType(testNodeType, getPrimaryNodeType())) 907 return true; 908 else { 909 for(int i=0; i<getMixinNodeTypes().length; i++) { 910 if(NodeTypeImpl.isSameOrSubType(testNodeType, getMixinNodeTypes()[i])) 911 return true; 912 } 913 } 914 return false; 915 } 918 919 928 public void addMixin(String mixinName) { 929 930 NodeType type = null; 931 try { 932 type = NodeTypeManagerImpl.getInstance().getNodeType(mixinName); 933 log.debug("Node.addMixin "+type); 934 } catch (NoSuchNodeTypeException e) { 935 log.error("Node.addMixin failed: "+e); 937 } 938 939 if(type == null || !type.isMixin()) { 940 ticket.getNodesManager().addValidationError(getPath(), new ConstraintViolationException("Node Type " + mixinName + 941 " not found or not mixin type.")); 942 return; 943 } 944 945 Value[] values; 946 Property mixinProperty = getPermanentProperty("jcr:mixinType"); 947 try { 948 if(mixinProperty == null) { 949 values = new Value[1]; 950 values[0] = new StringValue(mixinName); 951 } else { 952 if(hasSameOrSubtypeMixin((NodeTypeImpl)type)) { 954 log.warn("The node has already exist mixin type "+ mixinName + " or its subtype. Adding of mixin ignored."); 955 return; 956 } 957 values = new Value[mixinProperty.getValues().length+1]; 958 for(int i=0; i<values.length - 1; i++) 959 values[i] = mixinProperty.getValues()[i]; 960 values[values.length - 1] = new StringValue(mixinName); 961 } 962 addPermanentProperty(new PropertyImpl(getPath()+"/"+"jcr:mixinType", values, PropertyType.STRING)); 963 log.debug("Node.addMixin "+mixinName+ " added"); 964 addAutoCreatedItems(type); 965 } catch (Exception e) { 966 ticket.getNodesManager().addValidationError(getPath(), new ConstraintViolationException("Unexpected exception while adding mixin type " + mixinName + 967 " Reason: "+e)); 968 } 969 } 971 972 private boolean hasSameOrSubtypeMixin(NodeTypeImpl type) throws RepositoryException, ValueFormatException { 973 974 Value[] mixinValues = getPermanentProperty("jcr:mixinType").getValues(); 975 for(int i=0; i<mixinValues.length; i++) { 976 NodeType testNodeType; 977 try { 978 testNodeType = NodeTypeManagerImpl.getInstance().getNodeType(mixinValues[i].getString()); 979 } catch (NoSuchNodeTypeException e) { 980 throw new RepositoryException("No such node: "+mixinValues[i].getString()); 981 } 982 983 if(NodeTypeImpl.isSameOrSubType(type, testNodeType)) 984 return true; 985 } 986 return false; 987 988 } 989 990 997 public NodeDef getDefinition() { 998 NodeTypeImpl parentNodeType; 999 try { 1000 Node parent = getParent(); 1001 if (parent != null) 1002 parentNodeType = (NodeTypeImpl) parent.getPrimaryNodeType(); 1003 else 1004 throw new RuntimeException ("Parent is NULL!"); 1005 } catch (Exception e) { 1006 throw new RuntimeException (e.getMessage()); 1007 } 1008 NodeDef def = parentNodeType.getChildNodeDef(getName()); 1009 1010 if (def == null) 1011 def = new NodeDefImpl(); 1012 return def; 1013 } 1014 1015 1030 public Version checkin() throws UnsupportedRepositoryOperationException, RepositoryException { 1031 1035 throw new UnsupportedRepositoryOperationException("Node.checkin() is not supported yet!"); 1036 1037 } 1039 1040 public void checkout() throws RepositoryException, UnsupportedRepositoryOperationException { 1041 throw new UnsupportedRepositoryOperationException("Node.checkout() is not supported by Level 1 of JCR."); 1042 } 1043 1044 1061 public void update(String srcWorkspaceName, boolean shallow) throws NoSuchWorkspaceException, RepositoryException { 1062 } 1063 1064 1088 public void merge(String srcWorkspace, boolean shallow) throws UnsupportedRepositoryOperationException, NoSuchWorkspaceException, MergeException, RepositoryException { 1089 throw new UnsupportedRepositoryOperationException("Node.merge() is not supported by Level 1 of JCR."); 1090 } 1091 1092 1100 public boolean isCheckedOut() throws UnsupportedRepositoryOperationException, RepositoryException { 1101 throw new UnsupportedRepositoryOperationException("Node.isCheckedOut() is not supported by Level 1 of JCR."); 1102 } 1103 1104 1112 public void restore(String versionName) throws UnsupportedRepositoryOperationException, RepositoryException { 1113 throw new UnsupportedRepositoryOperationException("Node.restore() is not supported by Level 1 of JCR."); 1114 } 1115 1116 1124 public void restore(Version version) throws UnsupportedRepositoryOperationException, RepositoryException { 1125 throw new UnsupportedRepositoryOperationException("Node.restore() is not supported by Level 1 of JCR."); 1126 } 1127 1128 1136 public void restore(Calendar date) throws UnsupportedRepositoryOperationException, RepositoryException { 1137 throw new UnsupportedRepositoryOperationException("Node.restore() is not supported by Level 1 of JCR."); 1138 } 1139 1140 1149 public void restoreByLabel(String versionLabel) throws UnsupportedRepositoryOperationException, RepositoryException { 1150 throw new UnsupportedRepositoryOperationException("Node.restore() is not supported by Level 1 of JCR."); 1151 } 1152 1153 1163 public VersionHistory getVersionHistory() throws UnsupportedRepositoryOperationException, RepositoryException { 1164 throw new UnsupportedRepositoryOperationException("Node.getVersionHistory() is not supported by Level 1 of JCR."); 1165 } 1166 1167 1175 public Version getBaseVersion() throws UnsupportedRepositoryOperationException, RepositoryException { 1176 throw new UnsupportedRepositoryOperationException("Node.getBaseVersion() is not supported by Level 1 of JCR."); 1177 } 1178 1179 public void accept(ItemVisitor visitor) throws RepositoryException { 1181 visitor.visit(this); 1182 } 1183 1184 public boolean isNode() { 1185 return true; 1186 } 1187 1188 protected boolean isItemIdentical(Item otherItem) { 1189 try { 1190 NodeIterator nodes = getNodes(); 1191 Node otherNode = (Node) otherItem; 1192 while (nodes.hasNext()) { 1193 if (otherNode.hasNode(nodes.nextNode().getName())) 1194 return false; 1195 } 1196 PropertyIterator props = this.getProperties(); 1197 while (props.hasNext()) { 1198 Property prop1 = props.nextProperty(); 1199 Property prop2 = null; 1200 try { 1201 prop2 = otherNode.getProperty(prop1.getName()); 1202 } catch (PathNotFoundException e) { 1203 return false; 1204 } 1205 if (!prop1.isIdentical(prop2)) 1206 return false; 1207 } 1208 return true; 1209 } catch (Exception e) { 1210 log.error("Node.isIdentical() failed. Reason: "+e); 1211 return false; 1212 } 1214 1215 } 1216 1217 public StringIterator getPaths() { 1218 ArrayList list = new ArrayList (); 1219 Property uuid = getPermanentProperty("jcr:uuid"); 1220 if( uuid != null) 1221 list.addAll(ticket.getNodesManager().getPaths(uuid.getString())); 1222 else 1223 list.add(getPath()); 1224 EntityCollection paths = new EntityCollection(list); 1225 return paths; 1226 } 1227 1228 1229 public void addPermanentProperty(Property property) { 1231 removePermanentProperty(property.getName()); 1232 properties.add(property); 1233 log.debug("Add permanent property "+property+" hash="+property.hashCode() ); 1234 } 1235 1236 public void removePermanentProperty(String name) { 1237 for (int i = 0; i < properties.size(); i++) { 1238 PropertyImpl prop = (PropertyImpl) properties.get(i); 1239 if (prop.getName().equals(name)) { 1240 properties.remove(i); 1241 log.debug("Remove permanent property "+prop+" hash="+prop.hashCode() ); 1242 } 1243 } 1244 } 1245 1246 public Property getPermanentProperty(String name) { 1247 for (int i = 0; i < properties.size(); i++) { 1248 PropertyImpl prop = (PropertyImpl) properties.get(i); 1249 if (prop.getName().equals(name)) 1250 return prop; 1251 } 1252 return null; 1253 } 1254 1255 public List getPermanentProperties() { 1256 return properties; 1257 } 1258 1259 public void refresh(Node withNode) throws PathNotFoundException, RepositoryException { 1260 properties = new ArrayList (); 1261 List props = ((NodeImpl)withNode).getPermanentProperties(); 1262 for(int i=0; i<props.size(); i++) 1263 this.properties.add( new PropertyImpl((PropertyImpl)props.get(i)) ); 1264 } 1265 1266 1267 1269 public String toString() { 1270 int psize = (properties == null) ? 0 : properties.size(); 1271 NodeType ntype = getPrimaryNodeType(); 1272 return "Node:( path=" + getPath() + 1273 " type=" + ntype + 1274 " properties=" + psize 1275 + ")"; 1276 } 1277 1278 PropertyImpl updateProperty(String name, int type, Value[] values) throws ConstraintViolationException { 1279 1280 PropertyImpl property = null; 1281 try { 1282 ItemLocation loc = new ItemLocation(getPath(), name); 1283 property = new PropertyImpl(loc.getPath(), values, type); 1284 log.debug("NodeImpl.updateProperty-- "+this.getPermanentProperty(name)+" with "+property+" type = "+type); 1285 property.setTicket(ticket); 1286 1287 addPermanentProperty(property); 1289 ticket.getNodesManager().update(this); 1290 1291 } catch (Exception e) { 1293 e.printStackTrace(); 1294 throw new ConstraintViolationException("Node.updateProperty() failed for '" + name, e); 1295 } 1296 log.debug("createProperty (" + property + ") " + getPath()); 1297 return property; 1298 } 1299 1300 protected NodeImpl createNode(NodeImpl parent, String name, NodeType type) throws ConstraintViolationException { 1301 NodeImpl node = null; 1302 try { 1303 String nodePath = new ItemLocation(parent.getPath(), name).getPath(); 1304 node = new NodeImpl(nodePath, type.getName()); 1305 } catch (PathNotFoundException e) { 1306 throw new ConstraintViolationException("Node.createNode() failed Reason: " + e); 1307 } 1308 node.setTicket(ticket); 1309 log.debug("Create node " + node.getPath() + " type =" + type + " manager " + ticket); 1310 ticket.getNodesManager().add(node); 1311 node.addAutoCreatedItems(type); 1312 return node; 1313 } 1314 1315 private EntityCollection retrieveChildNodes(ItemFilter filter) { 1316 ArrayList list = new ArrayList (); 1317 Iterator children = ticket.getNodesManager().getChildren(getPath()).iterator(); 1318 while(children.hasNext()) { 1319 String path = (String ) children.next(); 1320 NodeImpl item = (NodeImpl) ticket.getNodesManager().getNodeByPath(path); 1321 item.setTicket(ticket); 1322 log.debug("Retrieve item : " + item.getPath()); 1323 if (filter.accept(item)) 1324 list.add(item); 1325 } 1326 return new EntityCollection(list); 1327 } 1328 1329 private EntityCollection retrieveProperties(ItemFilter filter) { 1330 1331 log.debug("retrieve properties of node : " + this.getPath()); 1332 ArrayList list = new ArrayList (); 1333 1335 for (int i = 0; i < properties.size(); i++) { 1336 Property prop = (Property) properties.get(i); 1337 if (prop != null && filter.accept(prop)) { 1338 log.debug("retrieve filtered property " + prop.getName()); 1339 list.add(prop); 1340 } 1341 } 1342 return new EntityCollection(list); 1343 } 1344 1345 void addAutoCreatedItems(NodeType type) throws ConstraintViolationException { 1346 NodeDef[] nodeDefs = type.getChildNodeDefs(); 1347 PropertyDef[] propDefs = type.getPropertyDefs(); 1348 1349 for (int i = 0; i < propDefs.length; i++) { 1350 if (propDefs[i].isAutoCreate()) { 1351 Value propVal = propDefs[i].getDefaultValue(); 1353 String name = propDefs[i].getName(); 1354 1355 if (name.equals("jcr:primaryType")) 1357 propVal = new StringValue(type.getName()); 1358 1359 1360 Value[] array = { propVal }; 1361 log.debug("AutoCreate Property-> for " + this.getName() + " property name " + propDefs[i].getName() + " " + 1362 propDefs[i].getRequiredType()+ " "+ getPermanentProperty ("jcr:primaryType")); 1363 PropertyImpl prop = updateProperty(name, propDefs[i].getRequiredType(), array); 1364 } 1365 } 1366 1367 if (nodeDefs == null) 1368 return; 1369 for (int i = 0; i < nodeDefs.length; i++) { 1370 log.debug("AutoCreate nodedef ->" + nodeDefs[i].getName()); 1371 if (nodeDefs[i].isAutoCreate()) { 1372 createNode(this, nodeDefs[i].getName(), nodeDefs[i].getDefaultPrimaryType()); 1373 log.debug("AutoCreate Node->" + this + " " + nodeDefs[i].getName()); 1374 } 1375 } 1376 } 1377 1378 private ItemImpl findPrimaryItem(NodeImpl parent) 1379 throws ItemNotFoundException, AccessDeniedException, RepositoryException { 1380 PropertyIterator properties = parent.getProperties(); 1381 while (properties.hasNext()) { 1383 PropertyImpl prop = (PropertyImpl) properties.nextProperty(); 1384 prop.setTicket(ticket); 1385 if (prop.getDefinition() != null && prop.getDefinition().isPrimaryItem()) { 1386 return (PropertyImpl) prop; 1387 } 1388 } 1389 1390 NodeIterator nodes = parent.getNodes(); 1392 1393 NodeImpl primaryItem = null; 1394 while (nodes.hasNext()) { 1395 NodeImpl node = (NodeImpl) nodes.nextNode(); 1396 node.setTicket(ticket); 1397 if (node.getDefinition() != null && node.getDefinition().isPrimaryItem()) { 1398 return findPrimaryItem((NodeImpl) node); 1400 } 1401 } 1402 return parent; 1403 } 1404 1405} 1406 | Popular Tags |