001/* 002 * Copyright 2010 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.repository.metadata.jcr; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.Date; 021import java.util.GregorianCalendar; 022import java.util.HashSet; 023import java.util.List; 024import java.util.Set; 025import java.util.regex.Pattern; 026 027import javax.jcr.Node; 028import javax.jcr.NodeIterator; 029import javax.jcr.PathNotFoundException; 030import javax.jcr.Property; 031import javax.jcr.PropertyIterator; 032import javax.jcr.PropertyType; 033import javax.jcr.RepositoryException; 034import javax.jcr.Value; 035import javax.jcr.lock.Lock; 036import javax.jcr.lock.LockManager; 037 038import org.ametys.core.user.UserIdentity; 039import org.ametys.plugins.repository.AmetysObjectResolver; 040import org.ametys.plugins.repository.AmetysRepositoryException; 041import org.ametys.plugins.repository.ModifiableTraversableAmetysObject; 042import org.ametys.plugins.repository.RepositoryConstants; 043import org.ametys.plugins.repository.jcr.NodeTypeHelper; 044import org.ametys.plugins.repository.metadata.CommentableCompositeMetadata; 045import org.ametys.plugins.repository.metadata.MetadataComment; 046import org.ametys.plugins.repository.metadata.ModifiableBinaryMetadata; 047import org.ametys.plugins.repository.metadata.ModifiableCompositeMetadata; 048import org.ametys.plugins.repository.metadata.ModifiableFile; 049import org.ametys.plugins.repository.metadata.ModifiableFolder; 050import org.ametys.plugins.repository.metadata.ModifiableResource; 051import org.ametys.plugins.repository.metadata.ModifiableRichText; 052import org.ametys.plugins.repository.metadata.UnknownMetadataException; 053 054/** 055 * JCR implementation of a CompositeMetadata.<br> 056 * This implementation is based on a child node of the Node supporting the actual content. 057 */ 058public class JCRCompositeMetadata implements ModifiableCompositeMetadata, CommentableCompositeMetadata 059{ 060 /** Prefix for jcr properties and nodes names */ 061 public static final String METADATA_PREFIX = RepositoryConstants.NAMESPACE_PREFIX + ':'; 062 063 /** Comments metadata suffix */ 064 public static final String METADATA_COMMENTS_SUFFIX = "_comments"; 065 066 /** The JCR nodetype of object collection metadatas. */ 067 public static final String OBJECT_COLLECTION_METADATA_NODETYPE = METADATA_PREFIX + "objectCollectionMetadata"; 068 069 private static Pattern __metadataNamePattern; 070 071 private Node _node; 072 private boolean _lockAlreadyChecked; 073 private AmetysObjectResolver _resolver; 074 075 /** 076 * Constructor 077 * @param metadataNode the Node supporting this composite metadata 078 * @param resolver The resolver, used to resolve object collections. 079 */ 080 public JCRCompositeMetadata(Node metadataNode, AmetysObjectResolver resolver) 081 { 082 _node = metadataNode; 083 _resolver = resolver; 084 } 085 086 /** 087 * Retrieves the underlying node. 088 * @return the underlying node. 089 */ 090 public Node getNode() 091 { 092 return _node; 093 } 094 095 public boolean hasMetadata(String metadataName) throws AmetysRepositoryException 096 { 097 try 098 { 099 // TODO filter sub-nodes by type (like in getMetadataNames). 100 return _node.hasProperty(METADATA_PREFIX + metadataName) || _node.hasNode(METADATA_PREFIX + metadataName); 101 } 102 catch (RepositoryException e) 103 { 104 throw new AmetysRepositoryException(e); 105 } 106 } 107 108 @Override 109 public void rename(String newName) throws AmetysRepositoryException 110 { 111 try 112 { 113 getNode().getSession().move(getNode().getPath(), getNode().getParent().getPath() + "/" + newName); 114 } 115 catch (RepositoryException e) 116 { 117 throw new AmetysRepositoryException(e); 118 } 119 } 120 121 public void removeMetadata(String metadataName) throws AmetysRepositoryException 122 { 123 try 124 { 125 _checkLock(); 126 String realMetadataName = METADATA_PREFIX + metadataName; 127 128 if (_node.hasProperty(realMetadataName)) 129 { 130 _node.getProperty(realMetadataName).remove(); 131 } 132 else if (_node.hasNode(realMetadataName)) 133 { 134 // Remove all existing nodes 135 NodeIterator it = _node.getNodes(realMetadataName); 136 while (it.hasNext()) 137 { 138 Node next = it.nextNode(); 139 next.remove(); 140 } 141 } 142 else 143 { 144 throw new UnknownMetadataException("No metadata for name: " + metadataName); 145 } 146 } 147 catch (RepositoryException e) 148 { 149 throw new AmetysRepositoryException("Unable to remove metadata " + metadataName, e); 150 } 151 } 152 153 @Override 154 public void copyTo(ModifiableCompositeMetadata metadata) throws AmetysRepositoryException 155 { 156 String[] metadataNames = getMetadataNames(); 157 for (String metadataName : metadataNames) 158 { 159 if (hasMetadata(metadataName)) 160 { 161 MetadataType type = getType(metadataName); 162 163 boolean multiple = isMultiple(metadataName); 164 switch (type) 165 { 166 case COMPOSITE: 167 ModifiableCompositeMetadata compositeMetadata = metadata.getCompositeMetadata(metadataName, true); 168 getCompositeMetadata(metadataName).copyTo(compositeMetadata); 169 break; 170 case USER: 171 if (multiple) 172 { 173 metadata.setMetadata(metadataName, getUserArray(metadataName)); 174 } 175 else 176 { 177 metadata.setMetadata(metadataName, getUser(metadataName)); 178 } 179 break; 180 case BOOLEAN: 181 if (multiple) 182 { 183 metadata.setMetadata(metadataName, getBooleanArray(metadataName)); 184 } 185 else 186 { 187 metadata.setMetadata(metadataName, getBoolean(metadataName)); 188 } 189 break; 190 case DATE: 191 if (multiple) 192 { 193 metadata.setMetadata(metadataName, getDateArray(metadataName)); 194 } 195 else 196 { 197 metadata.setMetadata(metadataName, getDate(metadataName)); 198 } 199 break; 200 case DOUBLE: 201 if (multiple) 202 { 203 metadata.setMetadata(metadataName, getDoubleArray(metadataName)); 204 } 205 else 206 { 207 metadata.setMetadata(metadataName, getDouble(metadataName)); 208 } 209 break; 210 case LONG: 211 if (multiple) 212 { 213 metadata.setMetadata(metadataName, getLongArray(metadataName)); 214 } 215 else 216 { 217 metadata.setMetadata(metadataName, getLong(metadataName)); 218 } 219 break; 220 case BINARY: 221 ModifiableBinaryMetadata binaryMetadata = metadata.getBinaryMetadata(metadataName, true); 222 ModifiableBinaryMetadata srcBinary = getBinaryMetadata(metadataName); 223 224 binaryMetadata.setFilename(srcBinary.getFilename()); 225 binaryMetadata.setMimeType(srcBinary.getMimeType()); 226 binaryMetadata.setLastModified(srcBinary.getLastModified()); 227 binaryMetadata.setEncoding(srcBinary.getEncoding()); 228 binaryMetadata.setInputStream(srcBinary.getInputStream()); 229 break; 230 case RICHTEXT: 231 ModifiableRichText richText = metadata.getRichText(metadataName, true); 232 ModifiableRichText srcRichText = getRichText(metadataName); 233 234 richText.setInputStream(srcRichText.getInputStream()); 235 richText.setEncoding(srcRichText.getEncoding()); 236 richText.setLastModified(srcRichText.getLastModified()); 237 richText.setMimeType(srcRichText.getMimeType()); 238 239 // Copy additional data 240 _copyDataFolder (srcRichText.getAdditionalDataFolder(), richText.getAdditionalDataFolder()); 241 break; 242 default: 243 if (multiple) 244 { 245 metadata.setMetadata(metadataName, getStringArray(metadataName)); 246 } 247 else 248 { 249 metadata.setMetadata(metadataName, getString(metadataName)); 250 } 251 break; 252 } 253 } 254 } 255 } 256 257 private void _copyDataFolder (ModifiableFolder srcDataFolder, ModifiableFolder targetDataFolder) 258 { 259 // Copy folders 260 Collection<ModifiableFolder> folders = srcDataFolder.getFolders(); 261 for (ModifiableFolder srcSubfolder : folders) 262 { 263 ModifiableFolder targetSubFolder = targetDataFolder.addFolder(srcSubfolder.getName()); 264 _copyDataFolder (srcSubfolder, targetSubFolder); 265 } 266 267 // Copy files 268 Collection<ModifiableFile> files = srcDataFolder.getFiles(); 269 for (ModifiableFile srcFile : files) 270 { 271 _copyFile (srcFile, targetDataFolder); 272 } 273 } 274 275 private void _copyFile (ModifiableFile srcFile, ModifiableFolder targetDataFolder) 276 { 277 ModifiableResource srcResource = srcFile.getResource(); 278 279 ModifiableFile targetFile = targetDataFolder.addFile(srcFile.getName()); 280 ModifiableResource targetResource = targetFile.getResource(); 281 282 targetResource.setLastModified(srcResource.getLastModified()); 283 targetResource.setMimeType(srcResource.getMimeType()); 284 targetResource.setEncoding(srcResource.getEncoding()); 285 targetResource.setInputStream(srcResource.getInputStream()); 286 } 287 288 public MetadataType getType(String metadataName) throws AmetysRepositoryException 289 { 290 try 291 { 292 String realMetadataName = METADATA_PREFIX + metadataName; 293 294 if (_node.hasNode(realMetadataName)) 295 { 296 Node node = _node.getNode(realMetadataName); 297 String type = node.getPrimaryNodeType().getName(); 298 if ("nt:frozenNode".equals(_node.getPrimaryNodeType().getName())) 299 { 300 // on version history 301 type = node.getProperty("jcr:frozenPrimaryType").getString(); 302 } 303 304 if (type.equals(OBJECT_COLLECTION_METADATA_NODETYPE)) 305 { 306 return MetadataType.OBJECT_COLLECTION; 307 } 308 else if (type.equals(METADATA_PREFIX + "binaryMetadata")) 309 { 310 return MetadataType.BINARY; 311 } 312 else if (type.equals(METADATA_PREFIX + "richText")) 313 { 314 return MetadataType.RICHTEXT; 315 } 316 else if (type.equals(METADATA_PREFIX + "user")) 317 { 318 return MetadataType.USER; 319 } 320 else 321 { 322 return MetadataType.COMPOSITE; 323 } 324 } 325 326 if (_node.hasProperty(realMetadataName)) 327 { 328 Property property = _node.getProperty(realMetadataName); 329 int type = property.getType(); 330 331 switch (type) 332 { 333 case PropertyType.STRING: 334 return MetadataType.STRING; 335 case PropertyType.BOOLEAN: 336 return MetadataType.BOOLEAN; 337 case PropertyType.DATE: 338 return MetadataType.DATE; 339 case PropertyType.DOUBLE: 340 return MetadataType.DOUBLE; 341 case PropertyType.LONG: 342 return MetadataType.LONG; 343 default: 344 throw new AmetysRepositoryException("Unhandled JCR property type : " + PropertyType.nameFromValue(type)); 345 } 346 } 347 348 throw new UnknownMetadataException("No metadata for name: " + metadataName); 349 } 350 catch (RepositoryException e) 351 { 352 throw new AmetysRepositoryException("Unable to get property type", e); 353 } 354 } 355 356 public String getString(String metadataName) 357 { 358 return _getString(metadataName, null, true); 359 } 360 361 @Override 362 public String getString(String metadataName, String defaultValue) 363 { 364 return _getString(metadataName, defaultValue, false); 365 } 366 367 private String _getString(String metadataName, String defaultValue, boolean failIfNotExist) 368 { 369 try 370 { 371 Property property = _node.getProperty(METADATA_PREFIX + metadataName); 372 373 if (property.getDefinition().isMultiple()) 374 { 375 Value[] values = property.getValues(); 376 377 if (values.length > 0) 378 { 379 return values[0].getString(); 380 } 381 else 382 { 383 throw new AmetysRepositoryException("Cannot get a String from an empty array"); 384 } 385 } 386 387 return property.getString(); 388 } 389 catch (PathNotFoundException e) 390 { 391 if (failIfNotExist) 392 { 393 throw new UnknownMetadataException("Unknown metadata " + METADATA_PREFIX + metadataName + " of " + _node, e); 394 } 395 else 396 { 397 return defaultValue; 398 } 399 } 400 catch (RepositoryException e) 401 { 402 throw new AmetysRepositoryException("Unable to get String property", e); 403 } 404 } 405 406 public String[] getStringArray(String metadataName) throws AmetysRepositoryException 407 { 408 return _getStringArray(metadataName, null, true); 409 } 410 411 public String[] getStringArray(String metadataName, String[] defaultValues) 412 { 413 return _getStringArray(metadataName, defaultValues, false); 414 } 415 416 private String[] _getStringArray(String metadataName, String[] defaultValues, boolean failIfNotExist) 417 { 418 try 419 { 420 Property property = _node.getProperty(METADATA_PREFIX + metadataName); 421 422 if (property.getDefinition().isMultiple()) 423 { 424 Value[] values = property.getValues(); 425 426 String[] results = new String[values.length]; 427 for (int i = 0; i < values.length; i++) 428 { 429 Value value = values[i]; 430 results[i] = value.getString(); 431 } 432 433 return results; 434 } 435 436 Value value = property.getValue(); 437 return new String[] {value.getString()}; 438 } 439 catch (PathNotFoundException e) 440 { 441 if (failIfNotExist) 442 { 443 throw new UnknownMetadataException("Unknown metadata " + METADATA_PREFIX + metadataName + " of " + _node, e); 444 } 445 else 446 { 447 return defaultValues; 448 } 449 } 450 catch (RepositoryException e) 451 { 452 throw new AmetysRepositoryException("Unable to get String array property", e); 453 } 454 } 455 456 public boolean getBoolean(String metadataName) throws UnknownMetadataException, AmetysRepositoryException 457 { 458 return _getBoolean(metadataName, null, true); 459 } 460 461 public boolean getBoolean(String metadataName, boolean defaultValue) throws AmetysRepositoryException 462 { 463 return _getBoolean(metadataName, defaultValue, false); 464 } 465 466 private boolean _getBoolean(String metadataName, Boolean defaultValue, boolean failIfNotExist) 467 { 468 try 469 { 470 Property property = _node.getProperty(METADATA_PREFIX + metadataName); 471 472 if (property.getDefinition().isMultiple()) 473 { 474 Value[] values = property.getValues(); 475 476 if (values.length > 0) 477 { 478 return values[0].getBoolean(); 479 } 480 else 481 { 482 throw new AmetysRepositoryException("Cannot get a boolean from an empty array"); 483 } 484 } 485 486 return property.getBoolean(); 487 } 488 catch (PathNotFoundException e) 489 { 490 if (failIfNotExist) 491 { 492 throw new UnknownMetadataException("Unknown metadata " + METADATA_PREFIX + metadataName + " of " + _node, e); 493 } 494 else 495 { 496 return defaultValue; 497 } 498 } 499 catch (RepositoryException e) 500 { 501 throw new AmetysRepositoryException("Unable to get boolean property", e); 502 } 503 } 504 505 public boolean[] getBooleanArray(String metadataName) throws AmetysRepositoryException 506 { 507 return _getBooleanArray(metadataName, null, true); 508 } 509 510 public boolean[] getBooleanArray(String metadataName, boolean[] defaultValues) 511 { 512 return _getBooleanArray(metadataName, defaultValues, false); 513 } 514 515 private boolean[] _getBooleanArray(String metadataName, boolean[] defaultValues, boolean failIfNotExist) 516 { 517 try 518 { 519 Property property = _node.getProperty(METADATA_PREFIX + metadataName); 520 521 if (property.getDefinition().isMultiple()) 522 { 523 Value[] values = property.getValues(); 524 525 boolean[] results = new boolean[values.length]; 526 for (int i = 0; i < values.length; i++) 527 { 528 Value value = values[i]; 529 results[i] = value.getBoolean(); 530 } 531 532 return results; 533 } 534 535 Value value = property.getValue(); 536 return new boolean[] {value.getBoolean()}; 537 } 538 catch (PathNotFoundException e) 539 { 540 if (failIfNotExist) 541 { 542 throw new UnknownMetadataException("Unknown metadata " + METADATA_PREFIX + metadataName + " of " + _node, e); 543 } 544 else 545 { 546 return defaultValues; 547 } 548 } 549 catch (RepositoryException e) 550 { 551 throw new AmetysRepositoryException("Unable to get boolean array property", e); 552 } 553 } 554 555 public Date getDate(String metadataName) throws AmetysRepositoryException 556 { 557 return _getDate(metadataName, null, true); 558 } 559 560 public Date getDate(String metadataName, Date defaultValue) throws AmetysRepositoryException 561 { 562 return _getDate(metadataName, defaultValue, false); 563 } 564 565 private Date _getDate(String metadataName, Date defaultValue, boolean failIfNotExist) 566 { 567 try 568 { 569 Property property = _node.getProperty(METADATA_PREFIX + metadataName); 570 571 if (property.getDefinition().isMultiple()) 572 { 573 Value[] values = property.getValues(); 574 575 if (values.length > 0) 576 { 577 return values[0].getDate().getTime(); 578 } 579 else 580 { 581 throw new AmetysRepositoryException("Cannot get a date from an empty array"); 582 } 583 } 584 585 return property.getDate().getTime(); 586 } 587 catch (PathNotFoundException e) 588 { 589 if (failIfNotExist) 590 { 591 throw new UnknownMetadataException("Unknown metadata " + METADATA_PREFIX + metadataName + " of " + _node, e); 592 } 593 else 594 { 595 return defaultValue; 596 } 597 } 598 catch (RepositoryException e) 599 { 600 throw new AmetysRepositoryException("Unable to get date property", e); 601 } 602 } 603 604 public Date[] getDateArray(String metadataName) throws AmetysRepositoryException 605 { 606 return _getDateArray(metadataName, null, true); 607 } 608 609 public Date[] getDateArray(String metadataName, Date[] defaultValues) 610 { 611 return _getDateArray(metadataName, defaultValues, false); 612 } 613 614 private Date[] _getDateArray(String metadataName, Date[] defaultValues, boolean failIfNotExist) 615 { 616 try 617 { 618 Property property = _node.getProperty(METADATA_PREFIX + metadataName); 619 620 if (property.getDefinition().isMultiple()) 621 { 622 Value[] values = property.getValues(); 623 624 Date[] results = new Date[values.length]; 625 for (int i = 0; i < values.length; i++) 626 { 627 Value value = values[i]; 628 results[i] = value.getDate().getTime(); 629 } 630 631 return results; 632 } 633 634 Value value = property.getValue(); 635 return new Date[] {value.getDate().getTime()}; 636 } 637 catch (PathNotFoundException e) 638 { 639 if (failIfNotExist) 640 { 641 throw new UnknownMetadataException("Unknown metadata " + METADATA_PREFIX + metadataName + " of " + _node, e); 642 } 643 else 644 { 645 return defaultValues; 646 } 647 } 648 catch (RepositoryException e) 649 { 650 throw new AmetysRepositoryException("Unable to get date array property", e); 651 } 652 } 653 654 public long getLong(String metadataName) throws AmetysRepositoryException 655 { 656 return _getLong(metadataName, null, true); 657 } 658 659 public long getLong(String metadataName, long defaultValue) throws AmetysRepositoryException 660 { 661 return _getLong(metadataName, defaultValue, false); 662 } 663 664 private long _getLong(String metadataName, Long defaultValue, boolean failIfNotExist) 665 { 666 try 667 { 668 Property property = _node.getProperty(METADATA_PREFIX + metadataName); 669 670 if (property.getDefinition().isMultiple()) 671 { 672 Value[] values = property.getValues(); 673 674 if (values.length > 0) 675 { 676 return values[0].getLong(); 677 } 678 else 679 { 680 throw new AmetysRepositoryException("Cannot get a long from an empty array"); 681 } 682 } 683 684 return property.getLong(); 685 } 686 catch (PathNotFoundException e) 687 { 688 if (failIfNotExist) 689 { 690 throw new UnknownMetadataException("Unknown metadata " + METADATA_PREFIX + metadataName + " of " + _node, e); 691 } 692 else 693 { 694 return defaultValue; 695 } 696 } 697 catch (RepositoryException e) 698 { 699 throw new AmetysRepositoryException("Unable to get long property", e); 700 } 701 } 702 703 public long[] getLongArray(String metadataName) throws AmetysRepositoryException 704 { 705 return _getLongArray(metadataName, null, true); 706 } 707 708 public long[] getLongArray(String metadataName, long[] defaultValues) 709 { 710 return _getLongArray(metadataName, defaultValues, false); 711 } 712 713 private long[] _getLongArray(String metadataName, long[] defaultValues, boolean failIfNotExist) 714 { 715 try 716 { 717 Property property = _node.getProperty(METADATA_PREFIX + metadataName); 718 719 if (property.getDefinition().isMultiple()) 720 { 721 Value[] values = property.getValues(); 722 723 long[] results = new long[values.length]; 724 for (int i = 0; i < values.length; i++) 725 { 726 Value value = values[i]; 727 results[i] = value.getLong(); 728 } 729 730 return results; 731 } 732 733 Value value = property.getValue(); 734 return new long[] {value.getLong()}; 735 } 736 catch (PathNotFoundException e) 737 { 738 if (failIfNotExist) 739 { 740 throw new UnknownMetadataException("Unknown metadata " + METADATA_PREFIX + metadataName + " of " + _node, e); 741 } 742 else 743 { 744 return defaultValues; 745 } 746 } 747 catch (RepositoryException e) 748 { 749 throw new AmetysRepositoryException("Unable to get long array property", e); 750 } 751 } 752 753 public double getDouble(String metadataName) throws AmetysRepositoryException 754 { 755 return _getDouble(metadataName, null, true); 756 } 757 758 public double getDouble(String metadataName, double defaultValue) throws AmetysRepositoryException 759 { 760 return _getDouble(metadataName, defaultValue, false); 761 } 762 763 private double _getDouble(String metadataName, Double defaultValue, boolean failIfNotExist) 764 { 765 try 766 { 767 Property property = _node.getProperty(METADATA_PREFIX + metadataName); 768 769 if (property.getDefinition().isMultiple()) 770 { 771 Value[] values = property.getValues(); 772 773 if (values.length > 0) 774 { 775 return values[0].getDouble(); 776 } 777 else 778 { 779 throw new AmetysRepositoryException("Cannot get a double from an empty array"); 780 } 781 } 782 783 return property.getDouble(); 784 } 785 catch (PathNotFoundException e) 786 { 787 if (failIfNotExist) 788 { 789 throw new UnknownMetadataException("Unknown metadata " + METADATA_PREFIX + metadataName + " of " + _node, e); 790 } 791 else 792 { 793 return defaultValue; 794 } 795 } 796 catch (RepositoryException e) 797 { 798 throw new AmetysRepositoryException("Unable to get double property", e); 799 } 800 } 801 802 public double[] getDoubleArray(String metadataName) throws AmetysRepositoryException 803 { 804 return _getDoubleArray(metadataName, null, true); 805 } 806 807 public double[] getDoubleArray(String metadataName, double[] defaultValues) 808 { 809 return _getDoubleArray(metadataName, defaultValues, false); 810 } 811 812 private double[] _getDoubleArray(String metadataName, double[] defaultValues, boolean failIfNotExist) 813 { 814 try 815 { 816 Property property = _node.getProperty(METADATA_PREFIX + metadataName); 817 818 if (property.getDefinition().isMultiple()) 819 { 820 Value[] values = property.getValues(); 821 822 double[] results = new double[values.length]; 823 for (int i = 0; i < values.length; i++) 824 { 825 Value value = values[i]; 826 results[i] = value.getDouble(); 827 } 828 829 return results; 830 } 831 832 Value value = property.getValue(); 833 return new double[] {value.getDouble()}; 834 } 835 catch (PathNotFoundException e) 836 { 837 if (failIfNotExist) 838 { 839 throw new UnknownMetadataException("Unknown metadata " + METADATA_PREFIX + metadataName + " of " + _node, e); 840 } 841 else 842 { 843 return defaultValues; 844 } 845 } 846 catch (RepositoryException e) 847 { 848 throw new AmetysRepositoryException("Unable to get double array property", e); 849 } 850 } 851 852 public UserIdentity getUser(String metadataName) throws AmetysRepositoryException 853 { 854 return _getUser(metadataName, null, true); 855 } 856 857 public UserIdentity getUser(String metadataName, UserIdentity defaultValue) throws AmetysRepositoryException 858 { 859 return _getUser(metadataName, defaultValue, false); 860 } 861 862 private UserIdentity _getUser(String metadataName, UserIdentity defaultValue, boolean failIfNotExist) throws AmetysRepositoryException 863 { 864 try 865 { 866 Node userNode = _node.getNode(METADATA_PREFIX + metadataName); 867 return new UserIdentity(userNode.getProperty("ametys:login").getString(), userNode.getProperty("ametys:population").getString()); 868 } 869 catch (PathNotFoundException e) 870 { 871 if (failIfNotExist) 872 { 873 throw new UnknownMetadataException("Unknown metadata " + METADATA_PREFIX + metadataName + " of " + _node, e); 874 } 875 else 876 { 877 return defaultValue; 878 } 879 } 880 catch (RepositoryException e) 881 { 882 throw new AmetysRepositoryException("Unable to get User metadata", e); 883 } 884 } 885 886 public UserIdentity[] getUserArray(String metadataName) throws AmetysRepositoryException 887 { 888 return _getUserArray(metadataName, null, true); 889 } 890 891 public UserIdentity[] getUserArray(String metadataName, UserIdentity[] defaultValues) throws AmetysRepositoryException 892 { 893 return _getUserArray(metadataName, defaultValues, false); 894 } 895 896 private UserIdentity[] _getUserArray(String metadataName, UserIdentity[] defaultValues, boolean failIfNotExist) throws AmetysRepositoryException 897 { 898 try 899 { 900 if (_node.hasNode(METADATA_PREFIX + metadataName)) 901 { 902 List<UserIdentity> results = new ArrayList<>(); 903 904 NodeIterator it = _node.getNodes(METADATA_PREFIX + metadataName); 905 while (it.hasNext()) 906 { 907 Node next = (Node) it.next(); 908 results.add(new UserIdentity(next.getProperty("ametys:login").getString(), next.getProperty("ametys:population").getString())); 909 } 910 911 return results.toArray(new UserIdentity[results.size()]); 912 } 913 else if (failIfNotExist) 914 { 915 throw new UnknownMetadataException("The metadata '" + metadataName + "' does not exist"); 916 } 917 else 918 { 919 return defaultValues; 920 } 921 } 922 catch (RepositoryException e) 923 { 924 throw new AmetysRepositoryException("Unable to get User array metadata", e); 925 } 926 } 927 928 public void setMetadata(String metadataName, String value) throws AmetysRepositoryException 929 { 930 if (value == null) 931 { 932 throw new NullPointerException("metadata value cannot be null"); 933 } 934 935 _checkMetadataName(metadataName); 936 937 try 938 { 939 _checkLock(); 940 _node.setProperty(METADATA_PREFIX + metadataName, value); 941 } 942 catch (RepositoryException e) 943 { 944 throw new AmetysRepositoryException("Unable to set property", e); 945 } 946 } 947 948 public void setMetadata(String metadataName, String[] value) throws AmetysRepositoryException 949 { 950 if (value == null) 951 { 952 throw new NullPointerException("metadata value cannot be null"); 953 } 954 955 _checkMetadataName(metadataName); 956 957 try 958 { 959 _checkLock(); 960 _node.setProperty(METADATA_PREFIX + metadataName, value); 961 } 962 catch (RepositoryException e) 963 { 964 throw new AmetysRepositoryException("Unable to set property", e); 965 } 966 } 967 968 public void setMetadata(String metadataName, Date value) throws AmetysRepositoryException 969 { 970 if (value == null) 971 { 972 throw new NullPointerException("metadata value cannot be null"); 973 } 974 975 GregorianCalendar calendar = new GregorianCalendar(); 976 calendar.setTime(value); 977 978 _checkMetadataName(metadataName); 979 980 try 981 { 982 _checkLock(); 983 _node.setProperty(METADATA_PREFIX + metadataName, calendar); 984 } 985 catch (RepositoryException e) 986 { 987 throw new AmetysRepositoryException("Unable to set property", e); 988 } 989 } 990 991 public void setMetadata(String metadataName, Date[] values) throws AmetysRepositoryException 992 { 993 if (values == null) 994 { 995 throw new NullPointerException("metadata value cannot be null"); 996 } 997 998 _checkMetadataName(metadataName); 999 1000 try 1001 { 1002 _checkLock(); 1003 Value[] jcrValues = new Value[values.length]; 1004 1005 for (int i = 0; i < values.length; i++) 1006 { 1007 Date value = values[i]; 1008 1009 GregorianCalendar calendar = new GregorianCalendar(); 1010 calendar.setTime(value); 1011 1012 jcrValues[i] = _node.getSession().getValueFactory().createValue(calendar); 1013 } 1014 1015 _node.setProperty(METADATA_PREFIX + metadataName, jcrValues); 1016 } 1017 catch (RepositoryException e) 1018 { 1019 throw new AmetysRepositoryException("Unable to set property", e); 1020 } 1021 } 1022 1023 public void setMetadata(String metadataName, long value) throws AmetysRepositoryException 1024 { 1025 _checkMetadataName(metadataName); 1026 1027 try 1028 { 1029 _checkLock(); 1030 _node.setProperty(METADATA_PREFIX + metadataName, value); 1031 } 1032 catch (RepositoryException e) 1033 { 1034 throw new AmetysRepositoryException("Unable to set property", e); 1035 } 1036 } 1037 1038 public void setMetadata(String metadataName, double value) throws AmetysRepositoryException 1039 { 1040 _checkMetadataName(metadataName); 1041 1042 try 1043 { 1044 _checkLock(); 1045 _node.setProperty(METADATA_PREFIX + metadataName, value); 1046 } 1047 catch (RepositoryException e) 1048 { 1049 throw new AmetysRepositoryException("Unable to set property", e); 1050 } 1051 } 1052 1053 public void setMetadata(String metadataName, long[] values) throws AmetysRepositoryException 1054 { 1055 if (values == null) 1056 { 1057 throw new NullPointerException("metadata value cannot be null"); 1058 } 1059 1060 _checkMetadataName(metadataName); 1061 1062 try 1063 { 1064 _checkLock(); 1065 Value[] jcrValues = new Value[values.length]; 1066 1067 for (int i = 0; i < values.length; i++) 1068 { 1069 long value = values[i]; 1070 jcrValues[i] = _node.getSession().getValueFactory().createValue(value); 1071 } 1072 1073 _node.setProperty(METADATA_PREFIX + metadataName, jcrValues); 1074 } 1075 catch (RepositoryException e) 1076 { 1077 throw new AmetysRepositoryException("Unable to set property", e); 1078 } 1079 } 1080 1081 public void setMetadata(String metadataName, double[] values) throws AmetysRepositoryException 1082 { 1083 if (values == null) 1084 { 1085 throw new NullPointerException("metadata value cannot be null"); 1086 } 1087 1088 _checkMetadataName(metadataName); 1089 1090 try 1091 { 1092 _checkLock(); 1093 Value[] jcrValues = new Value[values.length]; 1094 1095 for (int i = 0; i < values.length; i++) 1096 { 1097 double value = values[i]; 1098 jcrValues[i] = _node.getSession().getValueFactory().createValue(value); 1099 } 1100 1101 _node.setProperty(METADATA_PREFIX + metadataName, jcrValues); 1102 } 1103 catch (RepositoryException e) 1104 { 1105 throw new AmetysRepositoryException("Unable to set property", e); 1106 } 1107 } 1108 1109 public void setMetadata(String metadataName, boolean value) throws AmetysRepositoryException 1110 { 1111 _checkMetadataName(metadataName); 1112 1113 try 1114 { 1115 _checkLock(); 1116 _node.setProperty(METADATA_PREFIX + metadataName, value); 1117 } 1118 catch (RepositoryException e) 1119 { 1120 throw new AmetysRepositoryException("Unable to set property", e); 1121 } 1122 } 1123 1124 public void setMetadata(String metadataName, boolean[] values) throws AmetysRepositoryException 1125 { 1126 if (values == null) 1127 { 1128 throw new NullPointerException("metadata value cannot be null"); 1129 } 1130 1131 _checkMetadataName(metadataName); 1132 1133 try 1134 { 1135 _checkLock(); 1136 Value[] jcrValues = new Value[values.length]; 1137 1138 for (int i = 0; i < values.length; i++) 1139 { 1140 boolean value = values[i]; 1141 jcrValues[i] = _node.getSession().getValueFactory().createValue(value); 1142 } 1143 1144 _node.setProperty(METADATA_PREFIX + metadataName, jcrValues); 1145 } 1146 catch (RepositoryException e) 1147 { 1148 throw new AmetysRepositoryException("Unable to set property", e); 1149 } 1150 } 1151 1152 public void setMetadata(String metadataName, UserIdentity value) throws AmetysRepositoryException 1153 { 1154 _checkMetadataName(metadataName); 1155 1156 try 1157 { 1158 _checkLock(); 1159 1160 Node userNode = null; 1161 if (_node.hasNode(METADATA_PREFIX + metadataName)) 1162 { 1163 userNode = _node.getNode(METADATA_PREFIX + metadataName); 1164 } 1165 else 1166 { 1167 userNode = _node.addNode(METADATA_PREFIX + metadataName, RepositoryConstants.USER_NODETYPE); 1168 } 1169 userNode.setProperty(METADATA_PREFIX + "login", value.getLogin()); 1170 userNode.setProperty(METADATA_PREFIX + "population", value.getPopulationId()); 1171 } 1172 catch (RepositoryException e) 1173 { 1174 throw new AmetysRepositoryException("Unable to set property", e); 1175 } 1176 } 1177 1178 public void setMetadata(String metadataName, UserIdentity[] values) throws AmetysRepositoryException 1179 { 1180 if (values == null) 1181 { 1182 throw new NullPointerException("metadata value cannot be null"); 1183 } 1184 1185 _checkMetadataName(metadataName); 1186 1187 try 1188 { 1189 _checkLock(); 1190 1191 NodeIterator it = _node.getNodes(METADATA_PREFIX + metadataName); 1192 while (it.hasNext()) 1193 { 1194 Node next = (Node) it.next(); 1195 next.remove(); 1196 } 1197 1198 for (UserIdentity value : values) 1199 { 1200 Node userNode = _node.addNode(METADATA_PREFIX + metadataName, RepositoryConstants.USER_NODETYPE); 1201 userNode.setProperty(METADATA_PREFIX + "login", value.getLogin()); 1202 userNode.setProperty(METADATA_PREFIX + "population", value.getPopulationId()); 1203 } 1204 } 1205 catch (RepositoryException e) 1206 { 1207 throw new AmetysRepositoryException("Unable to set property", e); 1208 } 1209 } 1210 1211 public String[] getMetadataNames() throws AmetysRepositoryException 1212 { 1213 try 1214 { 1215 PropertyIterator itProp = _node.getProperties(METADATA_PREFIX + "*"); 1216 NodeIterator itNode = _node.getNodes(METADATA_PREFIX + "*"); 1217 1218 Set<String> names = new HashSet<>(); 1219 1220 while (itProp.hasNext()) 1221 { 1222 Property property = itProp.nextProperty(); 1223 names.add(property.getName().substring(METADATA_PREFIX.length())); 1224 } 1225 1226 while (itNode.hasNext()) 1227 { 1228 Node node = itNode.nextNode(); 1229 1230 // Filtering out AmetysObjects: they're not metadata (except object collections and users). 1231 if (!NodeTypeHelper.isNodeType(node, AmetysObjectResolver.OBJECT_TYPE) || NodeTypeHelper.isNodeType(node, OBJECT_COLLECTION_METADATA_NODETYPE) || NodeTypeHelper.isNodeType(node, RepositoryConstants.USER_NODETYPE)) 1232 { 1233 names.add(node.getName().substring(METADATA_PREFIX.length())); 1234 } 1235 } 1236 1237 String[] result = new String[names.size()]; 1238 names.toArray(result); 1239 1240 return result; 1241 } 1242 catch (RepositoryException e) 1243 { 1244 throw new AmetysRepositoryException("Unable to get metadata names", e); 1245 } 1246 } 1247 1248 public boolean isMultiple(String metadataName) throws AmetysRepositoryException 1249 { 1250 try 1251 { 1252 String realMetadataName = METADATA_PREFIX + metadataName; 1253 1254 if (_node.hasProperty(realMetadataName)) 1255 { 1256 Property property = _node.getProperty(realMetadataName); 1257 1258 if (property.getDefinition().isMultiple()) 1259 { 1260 return true; 1261 } 1262 1263 return false; 1264 } 1265 1266 if (_node.hasNode(realMetadataName)) 1267 { 1268 String nodeType = NodeTypeHelper.getNodeTypeName(_node.getNode(realMetadataName)); 1269 1270 // Object collection is multi-valued. 1271 if (OBJECT_COLLECTION_METADATA_NODETYPE.equals(nodeType)) 1272 { 1273 return true; 1274 } 1275 1276 // User metadata 1277 if (nodeType.equals(METADATA_PREFIX + "user")) 1278 { 1279 return _node.getNodes(realMetadataName).getSize() > 1; 1280 } 1281 1282 1283 // All other complex metadata are single valued. 1284 return false; 1285 } 1286 1287 throw new UnknownMetadataException("No metadata for name: " + metadataName); 1288 } 1289 catch (RepositoryException e) 1290 { 1291 throw new AmetysRepositoryException("Unable to determine if metadata " + metadataName + " is multiple", e); 1292 } 1293 } 1294 1295 /** 1296 * Check if the metadata name is valid. 1297 * @param metadataName The metadata name to check. 1298 * @throws AmetysRepositoryException If the metadata name is invalid. 1299 */ 1300 protected void _checkMetadataName(String metadataName) throws AmetysRepositoryException 1301 { 1302 // Id null 1303 if (metadataName == null) 1304 { 1305 throw new AmetysRepositoryException("Invalid metadata name (null)"); 1306 } 1307 1308 // Id valide 1309 if (!_getMetadataNamePattern().matcher(metadataName).matches()) 1310 { 1311 throw new AmetysRepositoryException("Invalid metadata name '" + metadataName + "'. This value is not permitted: only [a-zA-Z][a-zA-Z0-9-_]* are allowed."); 1312 } 1313 } 1314 1315 /** 1316 * Get the metadata name pattern to test validity. 1317 * @return The metadata name pattern. 1318 */ 1319 protected static Pattern _getMetadataNamePattern() 1320 { 1321 if (__metadataNamePattern == null) 1322 { 1323 // [a-zA-Z][a-zA-Z0-9_]* 1324 __metadataNamePattern = Pattern.compile("[a-z][a-z0-9-_]*", Pattern.CASE_INSENSITIVE); 1325 } 1326 1327 return __metadataNamePattern; 1328 } 1329 1330 public ModifiableBinaryMetadata getBinaryMetadata(String metadataName) throws AmetysRepositoryException 1331 { 1332 return getBinaryMetadata(metadataName, false); 1333 } 1334 1335 public ModifiableBinaryMetadata getBinaryMetadata(String metadataName, boolean createNew) throws AmetysRepositoryException 1336 { 1337 try 1338 { 1339 if (_node.hasNode(METADATA_PREFIX + metadataName)) 1340 { 1341 Node node = _node.getNode(METADATA_PREFIX + metadataName); 1342 return new JCRBinaryMetadata(node); 1343 } 1344 else if (createNew) 1345 { 1346 _checkLock(); 1347 Node node = _node.addNode(METADATA_PREFIX + metadataName, METADATA_PREFIX + "binaryMetadata"); 1348 return new JCRBinaryMetadata(node); 1349 } 1350 else 1351 { 1352 throw new UnknownMetadataException("No BinaryMetadata named " + metadataName); 1353 } 1354 } 1355 catch (RepositoryException e) 1356 { 1357 throw new AmetysRepositoryException(e); 1358 } 1359 } 1360 1361 public ModifiableCompositeMetadata getCompositeMetadata(String metadataName) throws AmetysRepositoryException 1362 { 1363 return getCompositeMetadata(metadataName, false); 1364 } 1365 1366 public ModifiableCompositeMetadata getCompositeMetadata(String metadataName, boolean createNew) throws AmetysRepositoryException 1367 { 1368 try 1369 { 1370 if (_node.hasNode(METADATA_PREFIX + metadataName)) 1371 { 1372 Node node = _node.getNode(METADATA_PREFIX + metadataName); 1373 return new JCRCompositeMetadata(node, _resolver); 1374 } 1375 else if (createNew) 1376 { 1377 _checkLock(); 1378 Node node = _node.addNode(METADATA_PREFIX + metadataName, "ametys:compositeMetadata"); 1379 return new JCRCompositeMetadata(node, _resolver); 1380 } 1381 else 1382 { 1383 throw new UnknownMetadataException("No CompositeMetadata named " + metadataName); 1384 } 1385 } 1386 catch (RepositoryException e) 1387 { 1388 throw new AmetysRepositoryException(e); 1389 } 1390 } 1391 1392 public ModifiableRichText getRichText(String metadataName) throws UnknownMetadataException, AmetysRepositoryException 1393 { 1394 return getRichText(metadataName, false); 1395 } 1396 1397 public ModifiableRichText getRichText(String metadataName, boolean createNew) throws UnknownMetadataException, AmetysRepositoryException 1398 { 1399 try 1400 { 1401 if (_node.hasNode(METADATA_PREFIX + metadataName)) 1402 { 1403 Node node = _node.getNode(METADATA_PREFIX + metadataName); 1404 return new JCRRichText(node, _resolver); 1405 } 1406 else if (createNew) 1407 { 1408 _checkLock(); 1409 Node node = _node.addNode(METADATA_PREFIX + metadataName, METADATA_PREFIX + "richText"); 1410 return new JCRRichText(node, _resolver); 1411 } 1412 else 1413 { 1414 throw new UnknownMetadataException("No RichText named " + metadataName); 1415 } 1416 } 1417 catch (RepositoryException e) 1418 { 1419 throw new AmetysRepositoryException(e); 1420 } 1421 } 1422 1423 public ModifiableTraversableAmetysObject getObjectCollection(String metadataName) throws AmetysRepositoryException 1424 { 1425 return getObjectCollection(metadataName, false); 1426 } 1427 1428 public ModifiableTraversableAmetysObject getObjectCollection(String metadataName, boolean createNew) throws AmetysRepositoryException 1429 { 1430 try 1431 { 1432 if (_node.hasNode(METADATA_PREFIX + metadataName)) 1433 { 1434 Node node = _node.getNode(METADATA_PREFIX + metadataName); 1435 return _resolver.resolve(node, false); 1436 } 1437 else if (createNew) 1438 { 1439 _checkLock(); 1440 Node node = _node.addNode(METADATA_PREFIX + metadataName, OBJECT_COLLECTION_METADATA_NODETYPE); 1441 return _resolver.resolve(node, false); 1442 } 1443 else 1444 { 1445 throw new UnknownMetadataException("No object collection metadata named " + metadataName); 1446 } 1447 } 1448 catch (RepositoryException e) 1449 { 1450 throw new AmetysRepositoryException(e); 1451 } 1452 } 1453 1454 @Override 1455 public List<MetadataComment> getComments(String metadataName) 1456 { 1457 List<MetadataComment> comments = new ArrayList<>(); 1458 String commentsNodeName = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + metadataName + METADATA_COMMENTS_SUFFIX; 1459 1460 try 1461 { 1462 if (_node.hasNode(commentsNodeName)) 1463 { 1464 Node commentsNode = _node.getNode(commentsNodeName); 1465 NodeIterator iterator = commentsNode.getNodes(); 1466 1467 while (iterator.hasNext()) 1468 { 1469 Node node = iterator.nextNode(); 1470 1471 String text = node.getProperty(METADATA_PREFIX + "comment").getString(); 1472 Date date = node.getProperty(METADATA_PREFIX + "date").getDate().getTime(); 1473 String author = node.getProperty(METADATA_PREFIX + "author").getString(); 1474 1475 comments.add(new MetadataComment(text, date, author)); 1476 } 1477 } 1478 1479 return comments; 1480 } 1481 catch (RepositoryException e) 1482 { 1483 throw new AmetysRepositoryException("Unable to retrieves the comments for metadata : " + metadataName); 1484 } 1485 } 1486 1487 @Override 1488 public boolean hasComments(String metadataName) 1489 { 1490 String commentsNodeName = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + metadataName + METADATA_COMMENTS_SUFFIX; 1491 1492 try 1493 { 1494 if (_node.hasNode(commentsNodeName)) 1495 { 1496 Node commentsNode = _node.getNode(commentsNodeName); 1497 return commentsNode.getNodes().hasNext(); 1498 } 1499 1500 return false; 1501 } 1502 catch (RepositoryException e) 1503 { 1504 throw new AmetysRepositoryException("Unable to determine if this node has at least one comment for metadata : " + metadataName, e); 1505 } 1506 } 1507 1508 @Override 1509 public boolean hasComment(String metadataName, int index) 1510 { 1511 String name = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + metadataName + METADATA_COMMENTS_SUFFIX + '/' + RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + index; 1512 try 1513 { 1514 return _node.hasNode(name); 1515 } 1516 catch (RepositoryException e) 1517 { 1518 throw new AmetysRepositoryException("Unable to determine if this node has a comment for metadata : " + metadataName, e); 1519 } 1520 } 1521 1522 @Override 1523 public void addComment(String metadataName, String text, String author, Date date) 1524 { 1525 if (text == null) 1526 { 1527 throw new NullPointerException("text of the comment cannot be null"); 1528 } 1529 1530 String commentsNodeName = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + metadataName + METADATA_COMMENTS_SUFFIX; 1531 1532 try 1533 { 1534 if (!_node.hasNode(commentsNodeName)) 1535 { 1536 _node.addNode(commentsNodeName, "ametys:compositeMetadata"); 1537 } 1538 1539 Node commentsNode = _node.getNode(commentsNodeName); 1540 String nodeName = null; 1541 int i = 0; 1542 1543 // Loop over existing comments 1544 do 1545 { 1546 nodeName = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + ++i; 1547 } while (commentsNode.hasNode(nodeName)); 1548 1549 // Add the new comment node at the end 1550 _checkLock(); 1551 Node commentNode = commentsNode.addNode(nodeName, "ametys:compositeMetadata"); 1552 1553 GregorianCalendar calendar = new GregorianCalendar(); 1554 if (date != null) 1555 { 1556 calendar.setTime(date); 1557 } 1558 1559 commentNode.setProperty(METADATA_PREFIX + "comment", text); 1560 commentNode.setProperty(METADATA_PREFIX + "date", calendar); 1561 commentNode.setProperty(METADATA_PREFIX + "author", author); 1562 } 1563 catch (RepositoryException e) 1564 { 1565 throw new AmetysRepositoryException("Unable to add a comment for metadata : " + metadataName); 1566 } 1567 } 1568 1569 @Override 1570 public void editComment(String metadataName, int index, String text, String author, Date date) 1571 { 1572 if (text == null) 1573 { 1574 throw new NullPointerException("text of the comment cannot be null"); 1575 } 1576 1577 String commentNodeName = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + metadataName + METADATA_COMMENTS_SUFFIX + '/' + RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + index; 1578 1579 try 1580 { 1581 _checkLock(); 1582 Node commentNode = _node.getNode(commentNodeName); 1583 1584 GregorianCalendar calendar = new GregorianCalendar(); 1585 if (date != null) 1586 { 1587 calendar.setTime(date); 1588 } 1589 1590 commentNode.setProperty(METADATA_PREFIX + "comment", text); 1591 commentNode.setProperty(METADATA_PREFIX + "date", calendar); 1592 commentNode.setProperty(METADATA_PREFIX + "author", author); 1593 } 1594 catch (RepositoryException e) 1595 { 1596 throw new AmetysRepositoryException("Unable to edit the comment at index +" + index + " for metadata : " + metadataName); 1597 } 1598 } 1599 1600 @Override 1601 public void deleteComment(String metadataName, int index) 1602 { 1603 String commentNodeName = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + metadataName + METADATA_COMMENTS_SUFFIX + '/' + RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + index; 1604 1605 try 1606 { 1607 _checkLock(); 1608 _node.getNode(commentNodeName).remove(); 1609 } 1610 catch (RepositoryException e) 1611 { 1612 throw new AmetysRepositoryException("Unable to remove the comment at index +" + index + " for metadata : " + metadataName); 1613 } 1614 } 1615 1616 private void _checkLock() throws RepositoryException 1617 { 1618 if (!_lockAlreadyChecked && _node.isLocked()) 1619 { 1620 LockManager lockManager = _node.getSession().getWorkspace().getLockManager(); 1621 1622 Lock lock = lockManager.getLock(_node.getPath()); 1623 Node lockHolder = lock.getNode(); 1624 1625 lockManager.addLockToken(lockHolder.getProperty(RepositoryConstants.METADATA_LOCKTOKEN).getString()); 1626 _lockAlreadyChecked = true; 1627 } 1628 } 1629}