1 17 package org.alfresco.jcr.session; 18 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.io.OutputStream ; 22 import java.io.UnsupportedEncodingException ; 23 import java.security.AccessControlException ; 24 import java.util.HashMap ; 25 import java.util.List ; 26 import java.util.Map ; 27 28 import javax.jcr.AccessDeniedException; 29 import javax.jcr.Credentials; 30 import javax.jcr.ImportUUIDBehavior; 31 import javax.jcr.InvalidItemStateException; 32 import javax.jcr.InvalidSerializedDataException; 33 import javax.jcr.Item; 34 import javax.jcr.ItemExistsException; 35 import javax.jcr.ItemNotFoundException; 36 import javax.jcr.LoginException; 37 import javax.jcr.NamespaceException; 38 import javax.jcr.NoSuchWorkspaceException; 39 import javax.jcr.Node; 40 import javax.jcr.PathNotFoundException; 41 import javax.jcr.Repository; 42 import javax.jcr.RepositoryException; 43 import javax.jcr.Session; 44 import javax.jcr.UnsupportedRepositoryOperationException; 45 import javax.jcr.ValueFactory; 46 import javax.jcr.Workspace; 47 import javax.jcr.lock.LockException; 48 import javax.jcr.nodetype.ConstraintViolationException; 49 import javax.jcr.nodetype.NoSuchNodeTypeException; 50 import javax.jcr.version.VersionException; 51 import javax.transaction.HeuristicMixedException ; 52 import javax.transaction.HeuristicRollbackException ; 53 import javax.transaction.NotSupportedException ; 54 import javax.transaction.RollbackException ; 55 import javax.transaction.SystemException ; 56 import javax.transaction.UserTransaction ; 57 58 import org.alfresco.error.AlfrescoRuntimeException; 59 import org.alfresco.jcr.dictionary.JCRNamespacePrefixResolver; 60 import org.alfresco.jcr.dictionary.NamespaceRegistryImpl; 61 import org.alfresco.jcr.dictionary.NodeTypeManagerImpl; 62 import org.alfresco.jcr.exporter.JCRDocumentXMLExporter; 63 import org.alfresco.jcr.exporter.JCRSystemXMLExporter; 64 import org.alfresco.jcr.importer.JCRImportHandler; 65 import org.alfresco.jcr.item.ItemImpl; 66 import org.alfresco.jcr.item.ItemResolver; 67 import org.alfresco.jcr.item.JCRPath; 68 import org.alfresco.jcr.item.JCRTypeConverter; 69 import org.alfresco.jcr.item.NodeImpl; 70 import org.alfresco.jcr.item.ValueFactoryImpl; 71 import org.alfresco.jcr.repository.RepositoryImpl; 72 import org.alfresco.jcr.util.JCRProxyFactory; 73 import org.alfresco.repo.importer.ImporterComponent; 74 import org.alfresco.repo.transaction.AlfrescoTransactionSupport; 75 import org.alfresco.service.cmr.lock.LockService; 76 import org.alfresco.service.cmr.lock.LockType; 77 import org.alfresco.service.cmr.repository.ChildAssociationRef; 78 import org.alfresco.service.cmr.repository.NodeRef; 79 import org.alfresco.service.cmr.repository.NodeService; 80 import org.alfresco.service.cmr.repository.Path; 81 import org.alfresco.service.cmr.repository.StoreRef; 82 import org.alfresco.service.cmr.security.AccessStatus; 83 import org.alfresco.service.cmr.security.PermissionService; 84 import org.alfresco.service.cmr.view.ExporterCrawlerParameters; 85 import org.alfresco.service.cmr.view.ExporterService; 86 import org.alfresco.service.cmr.view.ImporterBinding; 87 import org.alfresco.service.cmr.view.ImporterException; 88 import org.alfresco.service.cmr.view.Location; 89 import org.alfresco.service.namespace.NamespacePrefixResolver; 90 import org.alfresco.service.namespace.QName; 91 import org.alfresco.util.ParameterCheck; 92 import org.dom4j.io.OutputFormat; 93 import org.dom4j.io.XMLWriter; 94 import org.xml.sax.ContentHandler ; 95 import org.xml.sax.InputSource ; 96 import org.xml.sax.SAXException ; 97 import org.xml.sax.XMLReader ; 98 import org.xml.sax.helpers.XMLReaderFactory ; 99 100 101 106 public class SessionImpl implements Session 107 { 108 109 private RepositoryImpl repository; 110 111 112 private String trxId; 113 114 115 private Map <String , Object > attributes; 116 117 118 private StoreRef workspaceStore; 119 120 121 private WorkspaceImpl workspace = null; 122 123 124 private JCRTypeConverter typeConverter = null; 125 126 127 private NamespaceRegistryImpl namespaceResolver; 128 129 130 private NodeTypeManagerImpl typeManager = null; 131 132 133 private ValueFactoryImpl valueFactory = null; 134 135 136 private Session proxy = null; 137 138 139 private SessionIsolation sessionIsolation = null; 140 141 142 private String ticket = null; 143 144 145 151 public SessionImpl(RepositoryImpl repository) 152 { 153 this.repository = repository; 155 this.typeConverter = new JCRTypeConverter(this); 156 this.namespaceResolver = new NamespaceRegistryImpl(true, new JCRNamespacePrefixResolver(repository.getServiceRegistry().getNamespaceService())); 157 this.typeManager = new NodeTypeManagerImpl(this, namespaceResolver.getNamespaceService()); 158 this.valueFactory = new ValueFactoryImpl(this); 159 } 160 161 169 public void init(String ticket, String workspaceName, Map <String , Object > attributes) 170 throws RepositoryException 171 { 172 String trxId = AlfrescoTransactionSupport.getTransactionId(); 175 sessionIsolation = (trxId == null) ? new InnerTransaction() : new OuterTransaction(); 176 sessionIsolation.begin(); 177 178 this.ticket = ticket; 180 this.attributes = (attributes == null) ? new HashMap <String , Object >() : attributes; 181 this.workspaceStore = getWorkspaceStore(workspaceName); 182 } 183 184 189 public Session getProxy() 190 { 191 if (proxy == null) 192 { 193 proxy = (Session)JCRProxyFactory.create(this, Session.class, this); 194 } 195 return proxy; 196 } 197 198 203 public RepositoryImpl getRepositoryImpl() 204 { 205 return repository; 206 } 207 208 213 public String getTicket() 214 { 215 return ticket; 216 } 217 218 223 public String getTransactionId() 224 { 225 return trxId; 226 } 227 228 233 public JCRTypeConverter getTypeConverter() 234 { 235 return typeConverter; 236 } 237 238 243 public NodeTypeManagerImpl getTypeManager() 244 { 245 return typeManager; 246 } 247 248 253 public NamespacePrefixResolver getNamespaceResolver() 254 { 255 return namespaceResolver.getNamespaceService(); 256 } 257 258 263 public StoreRef getWorkspaceStore() 264 { 265 return workspaceStore; 266 } 267 268 269 273 276 public Repository getRepository() 277 { 278 return repository; 279 } 280 281 284 public String getUserID() 285 { 286 return getRepositoryImpl().getServiceRegistry().getAuthenticationService().getCurrentUserName(); 287 } 288 289 292 public Object getAttribute(String name) 293 { 294 return attributes.get(name); 295 } 296 297 300 public String [] getAttributeNames() 301 { 302 String [] names = (String []) attributes.keySet().toArray(new String [attributes.keySet().size()]); 303 return names; 304 } 305 306 309 public Workspace getWorkspace() 310 { 311 if (workspace == null) 312 { 313 workspace = new WorkspaceImpl(this); 314 } 315 return workspace.getProxy(); 316 } 317 318 321 public Session impersonate(Credentials credentials) throws LoginException, RepositoryException 322 { 323 throw new LoginException("Insufficient permission to impersonate"); 325 } 326 327 330 public Node getRootNode() throws RepositoryException 331 { 332 NodeRef nodeRef = getRepositoryImpl().getServiceRegistry().getNodeService().getRootNode(workspaceStore); 333 NodeImpl nodeImpl = new NodeImpl(this, nodeRef); 334 return nodeImpl.getProxy(); 335 } 336 337 340 public Node getNodeByUUID(String uuid) throws ItemNotFoundException, RepositoryException 341 { 342 NodeRef nodeRef = new NodeRef(workspaceStore, uuid); 343 boolean exists = getRepositoryImpl().getServiceRegistry().getNodeService().exists(nodeRef); 344 if (exists == false) 345 { 346 throw new ItemNotFoundException(); 347 } 348 NodeImpl nodeImpl = new NodeImpl(this, nodeRef); 349 return nodeImpl.getProxy(); 350 } 351 352 355 public Item getItem(String absPath) throws PathNotFoundException, RepositoryException 356 { 357 NodeRef nodeRef = getRepositoryImpl().getServiceRegistry().getNodeService().getRootNode(workspaceStore); 358 ItemImpl itemImpl = ItemResolver.findItem(this, nodeRef, absPath); 359 return itemImpl.getProxy(); 360 } 361 362 365 public boolean itemExists(String absPath) throws RepositoryException 366 { 367 ParameterCheck.mandatoryString("absPath", absPath); 368 NodeRef nodeRef = getRepositoryImpl().getServiceRegistry().getNodeService().getRootNode(workspaceStore); 369 return ItemResolver.itemExists(this, nodeRef, absPath); 370 } 371 372 375 public void move(String srcAbsPath, String destAbsPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException 376 { 377 ParameterCheck.mandatoryString("srcAbsPath", srcAbsPath); 378 ParameterCheck.mandatoryString("destAbsPath", destAbsPath); 379 380 NodeService nodeService = getRepositoryImpl().getServiceRegistry().getNodeService(); 382 NodeRef rootRef = nodeService.getRootNode(workspaceStore); 383 NodeRef sourceRef = ItemResolver.getNodeRef(this, rootRef, srcAbsPath); 384 if (sourceRef == null) 385 { 386 throw new PathNotFoundException("Source path " + srcAbsPath + " cannot be found."); 387 } 388 389 NodeRef destRef = null; 391 QName destName = null; 392 Path destPath = new JCRPath(getNamespaceResolver(), destAbsPath).getPath(); 393 if (destPath.size() == 1) 394 { 395 destRef = rootRef; 396 destName = ((JCRPath.SimpleElement)destPath.get(0)).getQName(); 397 } 398 else 399 { 400 Path destParentPath = destPath.subPath(destPath.size() -2); 401 destRef = ItemResolver.getNodeRef(this, rootRef, destParentPath.toPrefixString(getNamespaceResolver())); 402 if (destRef == null) 403 { 404 throw new PathNotFoundException("Destination path " + destParentPath + " cannot be found."); 405 } 406 destName = ((JCRPath.SimpleElement)destPath.get(destPath.size() -1)).getQName(); 407 } 408 409 if (destName.getLocalName().indexOf('[') != -1 || destName.getLocalName().indexOf(']') != -1) 412 { 413 throw new RepositoryException("Node name '" + destName + "' is invalid"); 414 } 415 416 ChildAssociationRef childAssocRef = nodeService.getPrimaryParent(sourceRef); 418 419 nodeService.moveNode(sourceRef, destRef, childAssocRef.getTypeQName(), destName); 421 } 422 423 426 public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException 427 { 428 sessionIsolation.commit(); 429 sessionIsolation.begin(); 431 } 432 433 436 public void refresh(boolean keepChanges) throws RepositoryException 437 { 438 if (keepChanges) 439 { 440 throw new UnsupportedRepositoryOperationException("Keep changes is not supported."); 441 } 442 sessionIsolation.rollback(); 443 sessionIsolation.begin(); 445 } 446 447 450 public boolean hasPendingChanges() throws RepositoryException 451 { 452 return AlfrescoTransactionSupport.isDirty(); 453 } 454 455 458 public ValueFactory getValueFactory() throws UnsupportedRepositoryOperationException, RepositoryException 459 { 460 return valueFactory.getProxy(); 461 } 462 463 466 public void checkPermission(String absPath, String actions) throws AccessControlException , RepositoryException 467 { 468 NodeService nodeService = getRepositoryImpl().getServiceRegistry().getNodeService(); 470 NodeRef rootRef = nodeService.getRootNode(getWorkspaceStore()); 471 NodeRef nodeRef = ItemResolver.getNodeRef(this, rootRef, absPath); 472 if (nodeRef == null) 473 { 474 throw new AccessControlException ("Unable to determine access control for path " + absPath); 475 } 476 477 PermissionService permissionService = getRepositoryImpl().getServiceRegistry().getPermissionService(); 479 String [] checkActions = actions.split(","); 480 for (String checkAction : checkActions) 481 { 482 checkAction = checkAction.trim(); 483 AccessStatus accessStatus = null; 484 if (checkAction.equals("add_node")) 485 { 486 accessStatus = permissionService.hasPermission(nodeRef, PermissionService.ADD_CHILDREN); 487 } 488 else if (checkAction.equals("set_property")) 489 { 490 accessStatus = permissionService.hasPermission(nodeRef, PermissionService.WRITE_PROPERTIES); 491 } 492 else if (checkAction.equals("remove")) 493 { 494 accessStatus = permissionService.hasPermission(nodeRef, PermissionService.DELETE); 495 } 496 else if (checkAction.equals("read")) 497 { 498 accessStatus = permissionService.hasPermission(nodeRef, PermissionService.READ); 499 } 500 else 501 { 502 accessStatus = permissionService.hasPermission(nodeRef, checkAction); 504 } 505 506 if (accessStatus == AccessStatus.DENIED) 508 { 509 throw new AccessControlException ("Permission " + checkAction + " not granted on path " + absPath); 510 } 511 } 512 } 513 514 517 public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws PathNotFoundException, ConstraintViolationException, VersionException, LockException, RepositoryException 518 { 519 NodeService nodeService = getRepositoryImpl().getServiceRegistry().getNodeService(); 521 NodeRef rootRef = nodeService.getRootNode(getWorkspaceStore()); 522 NodeRef nodeRef = ItemResolver.getNodeRef(this, rootRef, parentAbsPath); 523 if (nodeRef == null) 524 { 525 throw new PathNotFoundException("Parent path " + parentAbsPath + " does not exist."); 526 } 527 528 JCRImportHandler jcrImportHandler = new JCRImportHandler(this); 530 ImporterComponent importerComponent = getRepositoryImpl().getImporterComponent(); 531 return importerComponent.handlerImport(nodeRef, null, jcrImportHandler, new JCRImportBinding(uuidBehavior), null); 532 } 533 534 537 public void importXML(String parentAbsPath, InputStream in, int uuidBehavior) throws IOException , PathNotFoundException, ItemExistsException, ConstraintViolationException, VersionException, InvalidSerializedDataException, LockException, RepositoryException 538 { 539 ContentHandler handler = getImportContentHandler(parentAbsPath, uuidBehavior); 540 541 try 542 { 543 XMLReader parser = XMLReaderFactory.createXMLReader(); 544 parser.setContentHandler(handler); 545 parser.setFeature("http://xml.org/sax/features/namespaces", true); 546 parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false); 547 parser.parse(new InputSource (in)); 548 } 549 catch (SAXException se) 550 { 551 Exception e = se.getException(); 553 if (e != null && e instanceof AlfrescoRuntimeException) 554 { 555 throw (AlfrescoRuntimeException) e; 556 } 557 else 558 { 559 throw new InvalidSerializedDataException("Failed to import provided xml stream", se); 560 } 561 } 562 } 563 564 567 public void exportSystemView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse) throws PathNotFoundException, SAXException , RepositoryException 568 { 569 JCRSystemXMLExporter exporter = new JCRSystemXMLExporter(this, contentHandler); 570 ExporterCrawlerParameters parameters = createExportParameters(absPath, skipBinary, noRecurse); 571 ExporterService exporterService = getRepositoryImpl().getServiceRegistry().getExporterService(); 572 exporterService.exportView(exporter, parameters, null); 573 } 574 575 578 public void exportSystemView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse) throws IOException , PathNotFoundException, RepositoryException 579 { 580 JCRSystemXMLExporter exporter = new JCRSystemXMLExporter(this, createExportContentHandler(out)); 581 ExporterCrawlerParameters parameters = createExportParameters(absPath, skipBinary, noRecurse); 582 ExporterService exporterService = getRepositoryImpl().getServiceRegistry().getExporterService(); 583 exporterService.exportView(exporter, parameters, null); 584 } 585 586 589 public void exportDocumentView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse) throws PathNotFoundException, SAXException , RepositoryException 590 { 591 JCRDocumentXMLExporter exporter = new JCRDocumentXMLExporter(this, contentHandler); 592 ExporterCrawlerParameters parameters = createExportParameters(absPath, skipBinary, noRecurse); 593 ExporterService exporterService = getRepositoryImpl().getServiceRegistry().getExporterService(); 594 exporterService.exportView(exporter, parameters, null); 595 } 596 597 600 public void exportDocumentView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse) throws IOException , PathNotFoundException, RepositoryException 601 { 602 JCRDocumentXMLExporter exporter = new JCRDocumentXMLExporter(this, createExportContentHandler(out)); 603 ExporterCrawlerParameters parameters = createExportParameters(absPath, skipBinary, noRecurse); 604 ExporterService exporterService = getRepositoryImpl().getServiceRegistry().getExporterService(); 605 exporterService.exportView(exporter, parameters, null); 606 } 607 608 611 public void setNamespacePrefix(String prefix, String uri) throws NamespaceException, RepositoryException 612 { 613 namespaceResolver.registerNamespace(prefix, uri); 614 } 615 616 619 public String [] getNamespacePrefixes() throws RepositoryException 620 { 621 return namespaceResolver.getPrefixes(); 622 } 623 624 627 public String getNamespaceURI(String prefix) throws NamespaceException, RepositoryException 628 { 629 return namespaceResolver.getURI(prefix); 630 } 631 632 635 public String getNamespacePrefix(String uri) throws NamespaceException, RepositoryException 636 { 637 return namespaceResolver.getPrefix(uri); 638 } 639 640 643 public void logout() 644 { 645 if (isLive()) 646 { 647 getRepositoryImpl().getServiceRegistry().getAuthenticationService().invalidateTicket(getTicket()); 649 ticket = null; 650 651 try 653 { 654 sessionIsolation.rollback(); 655 } 656 catch(RepositoryException e) 657 { 658 } 660 repository.deregisterSession(); 661 } 662 } 663 664 667 public boolean isLive() 668 { 669 return ticket != null; 670 } 671 672 675 public void addLockToken(String lt) 676 { 677 } 679 680 683 public String [] getLockTokens() 684 { 685 LockService lockService = getRepositoryImpl().getServiceRegistry().getLockService(); 686 List <NodeRef> nodeRefs = lockService.getLocks(getWorkspaceStore(), LockType.WRITE_LOCK); 687 String [] tokens = new String [nodeRefs.size()]; 688 int i = 0; 689 for (NodeRef nodeRef : nodeRefs) 690 { 691 tokens[i++] = nodeRef.toString(); 692 } 693 return tokens; 694 } 695 696 699 public void removeLockToken(String lt) 700 { 701 } 703 704 711 private StoreRef getWorkspaceStore(String workspaceName) 712 throws NoSuchWorkspaceException 713 { 714 if (workspaceName == null) 715 { 716 throw new NoSuchWorkspaceException("A default workspace could not be established."); 718 } 719 720 StoreRef workspace = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, workspaceName); 721 NodeService nodeService = getRepositoryImpl().getServiceRegistry().getNodeService(); 722 boolean exists = false; 723 try 724 { 725 exists = nodeService.exists(workspace); 726 } 727 catch(org.alfresco.repo.security.permissions.AccessDeniedException e) 728 { 729 } 731 732 if (!exists) 733 { 734 throw new NoSuchWorkspaceException("Workspace " + workspaceName + " does not exist."); 735 } 736 return workspace; 737 } 738 739 745 private ContentHandler createExportContentHandler(OutputStream output) 746 throws RepositoryException 747 { 748 OutputFormat format = OutputFormat.createPrettyPrint(); 750 format.setNewLineAfterDeclaration(false); 751 format.setIndentSize(2); 752 format.setEncoding("UTF-8"); 753 754 try 756 { 757 return new XMLWriter(output, format); 758 } 759 catch (UnsupportedEncodingException e) 760 { 761 throw new RepositoryException("Failed to create content handler for export", e); 762 } 763 } 764 765 773 private ExporterCrawlerParameters createExportParameters(String exportPath, boolean skipBinary, boolean noRecurse) 774 { 775 ExporterCrawlerParameters parameters = new ExporterCrawlerParameters(); 777 Location exportFrom = new Location(getWorkspaceStore()); 778 exportFrom.setPath(exportPath); 779 parameters.setExportFrom(exportFrom); 780 parameters.setCrawlSelf(true); 781 parameters.setCrawlContent(!skipBinary); 782 parameters.setCrawlChildNodes(!noRecurse); 783 parameters.setCrawlNullProperties(false); 784 return parameters; 785 } 786 787 790 private class JCRImportBinding implements ImporterBinding 791 { 792 private ImporterBinding.UUID_BINDING uuidBinding; 793 794 799 private JCRImportBinding(int uuidBehaviour) 800 { 801 switch (uuidBehaviour) 802 { 803 case ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW: 804 uuidBinding = ImporterBinding.UUID_BINDING.CREATE_NEW; 805 break; 806 case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING: 807 uuidBinding = ImporterBinding.UUID_BINDING.REMOVE_EXISTING; 808 break; 809 case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING: 810 uuidBinding = ImporterBinding.UUID_BINDING.REPLACE_EXISTING; 811 break; 812 case ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW: 813 uuidBinding = ImporterBinding.UUID_BINDING.THROW_ON_COLLISION; 814 break; 815 default: 816 throw new ImporterException("Unknown Import UUID Behaviour: " + uuidBehaviour); 817 } 818 } 819 820 824 public UUID_BINDING getUUIDBinding() 825 { 826 return uuidBinding; 827 } 828 829 833 public String getValue(String key) 834 { 835 return null; 836 } 837 838 842 public boolean allowReferenceWithinTransaction() 843 { 844 return false; 845 } 846 } 847 848 852 855 private interface SessionIsolation 856 { 857 public void begin() throws RepositoryException; 859 860 public void commit() throws RepositoryException; 862 863 public void rollback() throws RepositoryException; 865 } 866 867 868 874 private class OuterTransaction implements SessionIsolation 875 { 876 879 public void begin() throws RepositoryException 880 { 881 } 882 883 886 public void commit() throws RepositoryException 887 { 888 } 889 890 893 public void rollback() throws RepositoryException 894 { 895 } 896 } 897 898 903 private class InnerTransaction implements SessionIsolation 904 { 905 private UserTransaction userTransaction = null; 906 907 910 public void begin() 911 throws RepositoryException 912 { 913 try 914 { 915 UserTransaction trx = repository.getServiceRegistry().getTransactionService().getUserTransaction(); 916 trx.begin(); 917 userTransaction = trx; 918 } 919 catch (NotSupportedException e) 920 { 921 throw new RepositoryException("Failed to start Repository transaction", e); 922 } 923 catch (SystemException e) 924 { 925 throw new RepositoryException("Failed to start Repository transaction", e); 926 } 927 } 928 929 932 public void commit() 933 throws RepositoryException 934 { 935 try 936 { 937 userTransaction.commit(); 938 } 939 catch (HeuristicRollbackException e) 940 { 941 throw new RepositoryException("Failed to commit Repository transaction", e); 942 } 943 catch (HeuristicMixedException e) 944 { 945 throw new RepositoryException("Failed to commit Repository transaction", e); 946 } 947 catch (RollbackException e) 948 { 949 throw new RepositoryException("Failed to commit Repository transaction", e); 950 } 951 catch (SystemException e) 952 { 953 throw new RepositoryException("Failed to commit Repository transaction", e); 954 } 955 } 956 957 960 public void rollback() 961 throws RepositoryException 962 { 963 try 964 { 965 userTransaction.rollback(); 966 } 967 catch (SystemException e) 968 { 969 throw new RepositoryException("Failed to rollback Repository transaction", e); 970 } 971 } 972 } 973 } | Popular Tags |