1 23 24 package org.apache.slide.webdav.util; 25 import java.io.IOException ; 26 import java.io.StringReader ; 27 import java.util.Date ; 28 import java.util.Enumeration ; 29 import java.util.Hashtable ; 30 import java.util.Iterator ; 31 import java.util.Vector ; 32 33 import javax.servlet.http.HttpServletRequest ; 34 import javax.servlet.http.HttpServletResponse ; 35 36 import org.apache.slide.common.Domain; 37 import org.apache.slide.common.NamespaceAccessToken; 38 import org.apache.slide.common.ServiceAccessException; 39 import org.apache.slide.common.SlideException; 40 import org.apache.slide.common.SlideToken; 41 import org.apache.slide.common.SlideTokenWrapper; 42 import org.apache.slide.content.Content; 43 import org.apache.slide.content.NodeProperty; 44 import org.apache.slide.content.NodeRevisionContent; 45 import org.apache.slide.content.NodeRevisionDescriptor; 46 import org.apache.slide.content.NodeRevisionDescriptors; 47 import org.apache.slide.content.NodeRevisionNumber; 48 import org.apache.slide.content.RevisionDescriptorNotFoundException; 49 import org.apache.slide.content.NodeProperty.NamespaceCache; 50 import org.apache.slide.event.VetoException; 51 import org.apache.slide.lock.Lock; 52 import org.apache.slide.lock.LockTokenNotFoundException; 53 import org.apache.slide.lock.NodeLock; 54 import org.apache.slide.lock.ObjectLockedException; 55 import org.apache.slide.macro.ConflictException; 56 import org.apache.slide.macro.Macro; 57 import org.apache.slide.search.BadQueryException; 58 import org.apache.slide.search.Search; 59 import org.apache.slide.search.SearchQuery; 60 import org.apache.slide.search.SearchQueryResult; 61 import org.apache.slide.search.SlideUri; 62 import org.apache.slide.search.basic.Literals; 63 import org.apache.slide.security.AccessDeniedException; 64 import org.apache.slide.structure.ActionNode; 65 import org.apache.slide.structure.LinkedObjectNotFoundException; 66 import org.apache.slide.structure.ObjectNotFoundException; 67 import org.apache.slide.structure.Structure; 68 import org.apache.slide.structure.SubjectNode; 69 import org.apache.slide.util.Configuration; 70 import org.apache.slide.util.XMLValue; 71 import org.apache.slide.webdav.WebdavException; 72 import org.apache.slide.webdav.WebdavServletConfig; 73 import org.apache.slide.webdav.method.MethodNotAllowedException; 74 import org.apache.slide.webdav.util.resourcekind.AbstractResourceKind; 75 import org.apache.slide.webdav.util.resourcekind.CheckedInVersionControlled; 76 import org.apache.slide.webdav.util.resourcekind.CheckedOut; 77 import org.apache.slide.webdav.util.resourcekind.CheckedOutVersionControlled; 78 import org.apache.slide.webdav.util.resourcekind.DeltavCompliantUnmappedUrl; 79 import org.apache.slide.webdav.util.resourcekind.ResourceKind; 80 import org.apache.slide.webdav.util.resourcekind.Version; 81 import org.apache.slide.webdav.util.resourcekind.VersionControlled; 82 import org.apache.slide.webdav.util.resourcekind.VersionControlledImpl; 83 import org.apache.slide.webdav.util.resourcekind.VersionHistoryImpl; 84 import org.apache.slide.webdav.util.resourcekind.VersionImpl; 85 import org.apache.slide.webdav.util.resourcekind.Working; 86 import org.apache.slide.webdav.util.resourcekind.WorkingImpl; 87 import org.apache.slide.webdav.util.resourcekind.WorkspaceImpl; 88 import org.jdom.Document; 89 import org.jdom.Element; 90 import org.jdom.JDOMException; 91 import org.jdom.input.SAXBuilder; 92 93 94 99 100 public class VersioningHelper extends AbstractWebdavHelper { 101 102 105 public static VersioningHelper 106 getVersioningHelper( SlideToken sToken, NamespaceAccessToken nsaToken, 107 HttpServletRequest req, HttpServletResponse resp, WebdavServletConfig sConf ) { 108 109 return new VersioningHelper( sToken, nsaToken, req, resp, sConf ); 110 } 111 112 115 protected static SAXBuilder saxBuilder = null; 116 117 private Content content = null; 118 private Structure structure = null; 119 private Macro macro = null; 120 private Lock lock = null; 121 private HttpServletRequest req = null; 122 private HttpServletResponse resp = null; 123 private WebdavServletConfig sConf = null; 124 private PropertyHelper pHelp = null; 125 private String slideContextPath = null; 127 128 131 protected final String modifyMetadataUri; 132 133 136 protected final String modifyContentUri; 137 138 139 142 protected VersioningHelper( SlideToken sToken, NamespaceAccessToken nsaToken, 143 HttpServletRequest req, HttpServletResponse resp, 144 WebdavServletConfig sConf ) { 145 super( sToken, nsaToken ); 146 this.req = req; 147 this.resp = resp; 148 this.sConf = sConf; 149 this.content = nsaToken.getContentHelper(); 150 this.structure = nsaToken.getStructureHelper(); 151 this.macro = nsaToken.getMacroHelper(); 152 this.lock = nsaToken.getLockHelper(); 153 this.pHelp = PropertyHelper.getPropertyHelper( sToken, nsaToken, sConf ); 154 this.slideContextPath = req.getContextPath(); 155 if (!sConf.isDefaultServlet()) { 156 this.slideContextPath += req.getServletPath(); 157 } 158 ActionNode actionNode = nsaToken.getNamespaceConfig().getModifyRevisionMetadataAction(); 159 if (actionNode != null) { 160 modifyMetadataUri = actionNode.getUri(); 161 } 162 else { 163 modifyMetadataUri = ""; 164 } 165 actionNode = nsaToken.getNamespaceConfig().getModifyRevisionContentAction(); 166 if (actionNode != null) { 167 modifyContentUri = actionNode.getUri(); 168 } 169 else { 170 modifyContentUri = ""; 171 } 172 } 174 175 195 public String getLabeledResourceUri(String resourcePath, String label) throws SlideException, LabeledRevisionNotFoundException { 196 if (label == null) { 197 return resourcePath; 198 } 199 else { 200 SlideToken lightSToken = sToken; 201 if (sToken.isForceStoreEnlistment() || sToken.isForceLock()) { 202 lightSToken = new SlideTokenWrapper(sToken); 203 lightSToken.setForceLock(false); 204 } 205 return getLabeledResourceUri(nsaToken, lightSToken, content, resourcePath, label); 206 } 207 } 208 209 224 public NodeRevisionDescriptor retrieveLabeledRevision(String resourcePath, String label) throws SlideException, LabeledRevisionNotFoundException { 225 return retrieveLabeledRevision(nsaToken, sToken, content, resourcePath, label); 226 } 227 228 234 public void versionControl( String resourcePath ) throws SlideException { 235 UriHandler rUh = UriHandler.getUriHandler( resourcePath ); 236 Iterator i; 237 Enumeration j; 238 239 NodeRevisionDescriptors rNrds = content.retrieve( sToken, resourcePath ); 240 NodeRevisionDescriptor rNrd = content.retrieve( sToken, rNrds ); 241 ResourceKind rRk = AbstractResourceKind.determineResourceKind( nsaToken, resourcePath, rNrd ); 242 if( !rRk.isSupportedMethod(req.getMethod()) ) { 243 throw new MethodNotAllowedException( rRk ); 244 } 245 246 if( rRk instanceof VersionControlled ) { 248 return; 250 } 251 252 UriHandler vhrUh = UriHandler.createNextHistoryUri( sToken, nsaToken, rUh ); 254 String vhrUri = String.valueOf(vhrUh); 255 256 NodeRevisionDescriptor vrNrd = 258 new NodeRevisionDescriptor(req.getContentLength()); 259 i = pHelp.createInitialProperties(VersionImpl.getInstance(), vhrUri).iterator(); 260 while( i.hasNext() ) 261 vrNrd.setProperty( (NodeProperty)i.next() ); 262 263 j = rNrd.enumerateProperties(); 265 while( j.hasMoreElements() ) { 266 NodeProperty p = (NodeProperty)j.nextElement(); 267 if( p.isLiveProperty() ) 268 continue; 269 if( !vrNrd.exists(p.getName()) ) 270 vrNrd.setProperty( p ); 271 } 272 273 NodeRevisionContent rNrc = content.retrieve( sToken, rNrds, rNrd ); 275 vrNrd.setContentType(rNrd.getContentType()); vrNrd.setContentLength(rNrd.getContentLength()); vrNrd.setContentLanguage(rNrd.getContentLanguage()); String comment = "INITIAL VERSION. "; 279 if( rNrd.exists(P_COMMENT) ) 280 comment += (String )rNrd.getProperty(P_COMMENT).getValue(); 281 vrNrd.setProperty( 282 new NodeProperty(P_COMMENT, comment) ); 283 284 Vector vhrLabels = new Vector (); 286 Hashtable vhrProps = new Hashtable (); 287 String vhrBranch = NodeRevisionDescriptors.MAIN_BRANCH; 288 NodeRevisionDescriptor vhrNrd = 289 new NodeRevisionDescriptor( NodeRevisionNumber.HIDDEN_0_0, vhrBranch, vhrLabels, vhrProps ); 290 i = pHelp.createInitialProperties(VersionHistoryImpl.getInstance(), vhrUri).iterator(); 291 while( i.hasNext() ) 292 vhrNrd.setProperty( (NodeProperty)i.next() ); 293 294 i = pHelp.createInitialProperties(VersionControlledImpl.getInstance(), resourcePath).iterator(); 296 while( i.hasNext() ) { 297 NodeProperty p = (NodeProperty)i.next(); 298 if( !rNrd.exists(p.getName()) ) 299 rNrd.setProperty( p ); 300 } 301 302 SubjectNode vhrNode = new SubjectNode(); 304 structure.create( sToken, vhrNode, String.valueOf(vhrUh) ); 305 content.create( sToken, vhrUri, true ); content.create( sToken, vhrUri, vrNrd, rNrc ); 307 content.create( 309 sToken, vhrUri, null, vhrNrd, null ); 311 NodeRevisionNumber vrVersion = vrNrd.getRevisionNumber(); 313 SubjectNode vrNode = new SubjectNode(); 314 UriHandler vrUh = 315 UriHandler.createVersionUri( vhrUh, String.valueOf(vrVersion) ); 316 String vrUri = String.valueOf( vrUh ); 317 structure.create( sToken, vrNode, String.valueOf(vrUh) ); 318 319 vrNrd.setName(rUh.getName()); rNrd.setProperty( 322 new NodeProperty(P_CHECKED_IN, pHelp.createHrefValue(vrUri)) ); 323 vhrNrd.setCreationDate( new Date () ); setCreationUser(vhrNrd); 325 vhrNrd.setLastModified( new Date () ); vhrNrd.setContentLength( 0 ); vhrNrd.setETag( PropertyHelper.computeEtag(vhrUri, vhrNrd) ); vhrNrd.setName( rNrd.getName() ); vhrNrd.setProperty( 331 new NodeProperty(P_VERSION_SET, pHelp.createHrefValue(vrUri)) ); 332 vrNrd.setCreationDate( new Date () ); setCreationUser(vrNrd); 334 vrNrd.setLastModified( new Date () ); vrNrd.setETag( PropertyHelper.computeEtag(vrUri, vrNrd)); vrNrd.setProperty( 337 new NodeProperty(P_VERSION_NAME, vrUh.getVersionName()) ); 338 339 content.store( sToken, resourcePath, rNrd, null ); content.store( sToken, vhrUri, vhrNrd, null ); content.store( sToken, vhrUri, vrNrd, null ); } 344 345 353 public void versionControl( String resourcePath, String existingVersionPath ) throws SlideException { 354 Iterator i; 355 356 UriHandler rUh = UriHandler.getUriHandler( resourcePath ); 357 UriHandler evUh = UriHandler.getUriHandler( existingVersionPath ); 358 if ( ! evUh.isVersionUri() ) { 359 throw new PreconditionViolationException( 360 new ViolatedPrecondition(C_MUST_BE_VERSION, WebdavStatus.SC_CONFLICT), resourcePath); 361 } 362 NodeRevisionDescriptors rNrds = null; 364 NodeRevisionDescriptor rNrd = null; 365 NodeRevisionDescriptor vcrNrd = null; 367 NodeRevisionDescriptors evNrds = null; 368 NodeRevisionDescriptor evNrd = null; 369 370 try { 371 rNrds = content.retrieve( sToken, resourcePath ); 372 rNrd = content.retrieve( sToken, rNrds ); 373 } 374 catch( ObjectNotFoundException e ) {}; try { 376 evNrds = content.retrieve( sToken, existingVersionPath ); 377 evNrd = content.retrieve( sToken, evNrds ); } 381 catch( ObjectNotFoundException e ) {}; 383 ViolatedPrecondition violatedPrecondition = 384 getVersionControlPreconditionViolation(resourcePath, 385 rNrd, 386 rUh, 387 existingVersionPath, 388 evNrd, 389 evUh); 390 if (violatedPrecondition != null) { 391 throw new PreconditionViolationException(violatedPrecondition, 392 resourcePath); 393 } 394 395 String vcrUri = String.valueOf(rUh); 397 String evUri = String.valueOf(evUh); 398 UriHandler vcrUh = UriHandler.getUriHandler( vcrUri ); 399 vcrNrd = new NodeRevisionDescriptor(0); 400 i = pHelp.createInitialProperties(VersionControlledImpl.getInstance(), resourcePath).iterator(); 401 while( i.hasNext() ) 402 vcrNrd.setProperty( (NodeProperty)i.next() ); 403 404 vcrNrd.setLastModified( new Date () ); vcrNrd.setContentLength( evNrd.getContentLength() ); vcrNrd.setETag( PropertyHelper.computeEtag(vcrUri, vcrNrd)); vcrNrd.setContentType( evNrd.getContentType() ); vcrNrd.setContentLanguage(evNrd.getContentLanguage()); 411 String [] utok = vcrUh.getUriTokens(); 412 413 if (!Configuration.useBinding(nsaToken.getUri(sToken, vcrUri).getStore())) { 414 vcrNrd.setName( utok[utok.length - 1] ); } 416 vcrNrd.setCreationDate( new Date () ); setCreationUser(vcrNrd); 418 vcrNrd.setProperty( new NodeProperty(P_CHECKED_IN, 419 pHelp.createHrefValue(evUri)) ); 420 setWorkspaceProperty( vcrUri, vcrNrd ); 422 423 SubjectNode vcrNode = new SubjectNode(); 425 structure.create( sToken, vcrNode, vcrUri ); 426 NodeRevisionContent evContent = 427 content.retrieve( sToken, evNrds, evNrd ); 428 content.create( sToken, vcrUri, vcrNrd, evContent ); 429 430 resp.setStatus( WebdavStatus.SC_CREATED ); 432 } 433 434 455 public ViolatedPrecondition getVersionControlPreconditionViolation(String resourcePath, 456 NodeRevisionDescriptor resourceNrd, 457 UriHandler resourceUrihandler, 458 String existingVersionPath, 459 NodeRevisionDescriptor existingVersionNrd, 460 UriHandler existingVersionUrihandler) throws SlideException { 461 462 ResourceKind rRk = AbstractResourceKind.determineResourceKind( nsaToken, resourcePath, resourceNrd ); 463 ResourceKind evRk = AbstractResourceKind.determineResourceKind( nsaToken, existingVersionPath, existingVersionNrd ); 464 465 if( !(rRk instanceof DeltavCompliantUnmappedUrl) ) { 466 return new ViolatedPrecondition(C_CANNOT_ADD_TO_EXISTING_HISTORY, WebdavStatus.SC_CONFLICT); 467 } 468 if( !(evRk instanceof Version) || existingVersionNrd == null) { 469 return new ViolatedPrecondition(C_MUST_BE_VERSION, WebdavStatus.SC_CONFLICT); 470 } 471 472 String scope = resourceUrihandler.getAssociatedWorkspaceUri(); 473 if( scope == null ) 474 scope = UriHandler.bestMatchingScope(nsaToken.getName(), resourceUrihandler).toString(); 475 String historyPath = existingVersionUrihandler.getAssociatedHistoryUri(); 476 SearchQueryResult queryResult = searchResourcesWithGivenHistory(historyPath, scope, Integer.MAX_VALUE); 477 Iterator queryResultIterator = queryResult.iterator(); 478 if (queryResultIterator.hasNext()) { 479 return new ViolatedPrecondition(C_ONE_VERSION_CONTROLLED_RESOURCE_PER_HISTORY_PER_WORKSPACE, 480 WebdavStatus.SC_CONFLICT); 481 } 482 483 return null; 484 } 485 486 500 protected SearchQueryResult searchResourcesWithGivenHistory(String historyPath, String scope, int maxDepth) throws ServiceAccessException, BadQueryException, VetoException { 501 502 SlideUri slideUri = SlideUri.createWithRequestUri( 503 this.slideContextPath, req.getRequestURI()); 504 String absPath = slideUri.getContextPath (scope); 505 506 Element basicSearch = getResourcesWithVersionHistoryQueryElement(absPath, 507 historyPath); 508 String grammarNamespace = basicSearch.getNamespaceURI(); 509 Search searchHelper = nsaToken.getSearchHelper(); 510 SearchQuery searchQuery = searchHelper.createSearchQuery(grammarNamespace, 511 basicSearch, 512 sToken, 513 maxDepth, 514 req.getRequestURI()); 515 516 SearchQueryResult queryResult = searchHelper.search(sToken, searchQuery); 517 return queryResult; 518 } 519 520 521 532 protected Element getResourcesWithVersionHistoryQueryElement(String scope, String historyPath) { 533 534 Element resourcesWithVersionHistoryQueryElement = new Element(DaslConstants.E_BASICSEARCH, NamespaceCache.DEFAULT_NAMESPACE); 535 536 Element select = new Element(DaslConstants.E_SELECT, NamespaceCache.DEFAULT_NAMESPACE); 537 resourcesWithVersionHistoryQueryElement.addContent(select); 538 Element prop = new Element(E_PROP, NamespaceCache.DEFAULT_NAMESPACE); 539 select.addContent(prop); 540 Element checkedIn = new Element(P_CHECKED_IN, NamespaceCache.DEFAULT_NAMESPACE); 541 prop.addContent(checkedIn); 542 Element checkedOut = new Element(P_CHECKED_OUT, NamespaceCache.DEFAULT_NAMESPACE); 543 prop.addContent(checkedOut); 544 545 Element from = new Element(DaslConstants.E_FROM, NamespaceCache.DEFAULT_NAMESPACE); 546 resourcesWithVersionHistoryQueryElement.addContent(from); 547 Element scopeElement = new Element(DaslConstants.E_SCOPE, NamespaceCache.DEFAULT_NAMESPACE); 548 from.addContent(scopeElement); 549 Element href = new Element(E_HREF, NamespaceCache.DEFAULT_NAMESPACE); 550 scopeElement.addContent(href); 551 href.setText(scope); 552 553 Element where = new Element(DaslConstants.E_WHERE, NamespaceCache.DEFAULT_NAMESPACE); 554 resourcesWithVersionHistoryQueryElement.addContent(where); 555 Element or = new Element(Literals.OR, NamespaceCache.DEFAULT_NAMESPACE); 556 where.addContent(or); 557 558 Element propcontains = new Element(DaslConstants.E_PROPCONTAINS, NamespaceCache.SLIDE_NAMESPACE); 559 or.addContent(propcontains); 560 prop = new Element(E_PROP, NamespaceCache.DEFAULT_NAMESPACE); 561 propcontains.addContent(prop); 562 prop.addContent((Element)checkedIn.clone()); 563 Element literal = new Element(DaslConstants.E_LITERAL, NamespaceCache.DEFAULT_NAMESPACE); 564 propcontains.addContent(literal); 565 literal.setText(historyPath); 566 567 propcontains = new Element(DaslConstants.E_PROPCONTAINS, NamespaceCache.SLIDE_NAMESPACE); 568 or.addContent(propcontains); 569 prop = new Element(E_PROP, NamespaceCache.DEFAULT_NAMESPACE); 570 propcontains.addContent(prop); 571 prop.addContent((Element)checkedOut.clone()); 572 literal = new Element(DaslConstants.E_LITERAL, NamespaceCache.DEFAULT_NAMESPACE); 573 propcontains.addContent(literal); 574 literal.setText(historyPath); 575 576 return resourcesWithVersionHistoryQueryElement; 577 } 578 579 585 public void setWorkspaceProperty( String rUri, NodeRevisionDescriptor rNrd ) { 586 UriHandler rUh = UriHandler.getUriHandler( rUri ); 587 String wsUri = rUh.getAssociatedWorkspaceUri(); 588 if( wsUri != null ) { 589 rNrd.setProperty( 590 new NodeProperty(P_WORKSPACE, pHelp.createHrefValue(wsUri)) ); 591 } 592 else { 593 rNrd.removeProperty(P_WORKSPACE); 594 } 595 } 596 597 603 public void mkworkspace( String resourcePath ) throws SlideException { 604 Iterator i; 605 606 UriHandler rUh = UriHandler.getUriHandler( resourcePath ); 607 NodeRevisionDescriptor rNrd = null; 608 try { 609 NodeRevisionDescriptors rNrds = content.retrieve( sToken, resourcePath ); 610 rNrd = content.retrieve( sToken, rNrds ); 611 } 612 catch( ObjectNotFoundException e ) {}; 614 ResourceKind rRk = AbstractResourceKind.determineResourceKind( nsaToken, resourcePath, rNrd ); 615 616 if( !(rRk instanceof DeltavCompliantUnmappedUrl) ) { 617 throw new PreconditionViolationException( 618 new ViolatedPrecondition(C_RESOURCE_MUST_BE_NULL, WebdavStatus.SC_CONFLICT), resourcePath); 619 } 620 if( !rUh.isWorkspaceUri() ) { 621 throw new PreconditionViolationException( 622 new ViolatedPrecondition(C_WORKSPACE_LOCATION_OK, WebdavStatus.SC_FORBIDDEN), resourcePath); 623 } 624 if( !rRk.isSupportedMethod(req.getMethod()) ) { 625 throw new MethodNotAllowedException( rRk ); 626 } 627 628 String wsUri = String.valueOf(rUh); 630 NodeRevisionDescriptor wsNrd = 631 new NodeRevisionDescriptor(0); 632 i = pHelp.createInitialProperties(WorkspaceImpl.getInstance(), resourcePath).iterator(); 633 while( i.hasNext() ) 634 wsNrd.setProperty( (NodeProperty)i.next() ); 635 636 wsNrd.setProperty( 638 new NodeProperty(P_WORKSPACE, pHelp.createHrefValue(wsUri)) ); 639 wsNrd.setLastModified( new Date () ); wsNrd.setContentLength( 0 ); wsNrd.setETag( PropertyHelper.computeEtag(wsUri, wsNrd) ); if (!Configuration.useBinding(nsaToken.getUri(sToken, wsUri).getStore())) { 643 wsNrd.setName( rUh.getWorkspaceName() ); } 645 wsNrd.setCreationDate( new Date () ); setCreationUser(wsNrd); 647 648 SubjectNode wsNode = new SubjectNode(); 650 structure.create( sToken, wsNode, wsUri ); 651 content.create( sToken, wsUri, wsNrd, null ); 653 resp.setStatus( WebdavStatus.SC_CREATED ); 655 } 656 657 668 public String checkout( String resourcePath, boolean forkOk, boolean applyToVersion ) 669 throws SlideException, JDOMException, IOException , PreconditionViolationException { 670 return checkout(resourcePath, forkOk, applyToVersion, false); 671 } 672 673 685 public String checkout( String resourcePath, boolean forkOk, boolean applyToVersion, boolean isAutoVersionCheckout ) 686 throws SlideException, JDOMException, IOException , PreconditionViolationException { 687 688 UriHandler rUh = UriHandler.getUriHandler( resourcePath ); 689 NodeRevisionDescriptors rNrds = content.retrieve( sToken, resourcePath ); 690 NodeRevisionDescriptor rNrd = content.retrieve( sToken, rNrds ); 691 692 if( rUh.isVersionUri() ) { 693 NodeRevisionContent rNrc = content.retrieve( sToken, rNrds, rNrd ); 694 return checkout( rNrds, rNrd, rNrc, forkOk, null ); } 696 else { 697 return checkout( rNrds, rNrd, forkOk, applyToVersion, isAutoVersionCheckout); 698 } 699 } 700 701 713 public String checkout( NodeRevisionDescriptors rNrds, 714 NodeRevisionDescriptor rNrd, boolean forkOk, boolean applyToVersion ) 715 throws SlideException, JDOMException, IOException , PreconditionViolationException { 716 return checkout(rNrds, rNrd, forkOk, applyToVersion, false); 717 } 718 719 733 public String checkout( NodeRevisionDescriptors rNrds, 734 NodeRevisionDescriptor rNrd, boolean forkOk, boolean applyToVersion, boolean isAutoVersionCheckout ) 735 throws SlideException, JDOMException, IOException , PreconditionViolationException { 736 737 String rUri = getUri( rNrds, rNrd ); 739 ResourceKind rRk = AbstractResourceKind.determineResourceKind( nsaToken, rNrds, rNrd ); 740 741 if( !rRk.isSupportedMethod(req.getMethod()) ) { 742 if( rRk instanceof CheckedOut ) { 744 throw new PreconditionViolationException(new ViolatedPrecondition(C_MUST_BE_CHECKED_IN, WebdavStatus.SC_CONFLICT), rNrds.getUri()); 745 } 746 throw new MethodNotAllowedException( rRk ); 747 } 748 749 if( rRk instanceof CheckedInVersionControlled ) { 750 NodeProperty cinProp = rNrd.getProperty( P_CHECKED_IN ); 752 String cinHref = getElementValue((String )cinProp.getValue()); 753 UriHandler cinUriHandler = UriHandler.getUriHandler(cinHref); 754 String cinhUri = cinUriHandler.getAssociatedHistoryUri(); 755 NodeRevisionNumber cinNrn = new NodeRevisionNumber(cinUriHandler.getVersionName()); 756 NodeRevisionDescriptors cinNrds = content.retrieve(sToken, cinhUri); 757 NodeRevisionDescriptor cinNrd = content.retrieve(sToken, cinNrds, cinNrn); 758 759 if( applyToVersion ) { 761 NodeRevisionContent cinNrc = content.retrieve( sToken, cinNrds, cinNrd ); 762 return checkout( cinNrds, cinNrd, cinNrc, forkOk, rUri ); } 764 765 ViolatedPrecondition violatedPrecondition = getCheckoutPreconditionViolation(cinNrds, cinNrd, forkOk); 766 if (violatedPrecondition != null) { 767 throw new PreconditionViolationException(violatedPrecondition, rNrds.getUri()); 768 } 769 770 772 backupSpecificLiveProperties(rNrds, rNrd); 774 rNrd.removeProperty( cinProp ); 775 rNrd.setProperty( 776 new NodeProperty(P_CHECKED_OUT, cinProp.getValue()) ); 777 rNrd.setProperty( 778 new NodeProperty(P_PREDECESSOR_SET, cinProp.getValue()) ); 779 NodeProperty property = cinNrd.getProperty(P_CHECKOUT_FORK); 780 if (property != null) { 781 rNrd.setProperty(property); 782 } 783 property = cinNrd.getProperty(P_CHECKIN_FORK); 784 if (property != null) { 785 rNrd.setProperty(property); 786 } 787 788 if (isAutoVersionCheckout && 789 !(E_CHECKOUT_IGNORE_UNLOCK.equals(getAutoVersionElementName(rNrd)))) { 790 NodeLock writeLock = getWriteLock(sToken, rNrds); 791 if (writeLock != null) { 792 NodeProperty p = 793 new NodeProperty(I_CHECKIN_LOCKTOKEN, 794 writeLock.getLockId(), 795 NamespaceCache.SLIDE_URI); 796 p.setKind( NodeProperty.Kind.PROTECTED ); 797 rNrd.setProperty( p ); 798 } 799 } 800 801 PropertyHelper.addHrefToProperty(cinNrd, P_CHECKOUT_SET, rUri); 803 804 content.store( sToken, rNrds.getUri(), rNrd, null ); content.store( sToken, cinNrds.getUri(), cinNrd, null ); 807 return null; 808 } 809 else { 810 Domain.warn( 811 "Do not know how to checkout a '"+rRk+"' resource" ); 812 resp.setStatus(WebdavStatus.SC_CONFLICT); 813 throw new WebdavException( WebdavStatus.SC_CONFLICT ); 814 } 815 } 816 817 830 public String checkout( NodeRevisionDescriptors rNrds, NodeRevisionDescriptor rNrd, NodeRevisionContent rNrc, 831 boolean forkOk, String autoUpdateUri ) 832 throws SlideException, JDOMException, IOException , PreconditionViolationException { 833 834 Iterator i; 835 Enumeration j; 836 String rUri = getUri( rNrds, rNrd ); 837 ResourceKind rRk = AbstractResourceKind.determineResourceKind( nsaToken, rNrds, rNrd ); 838 839 if( !rRk.isSupportedMethod(req.getMethod()) ) { 840 if( rRk instanceof CheckedOut ) { 842 throw new PreconditionViolationException(new ViolatedPrecondition(C_MUST_BE_CHECKED_IN, WebdavStatus.SC_CONFLICT), rNrds.getUri()); 843 } 844 throw new MethodNotAllowedException( rRk ); 845 } 846 847 if( rRk instanceof Version ) { 848 849 UriHandler rUh = UriHandler.getUriHandler( rUri ); 850 852 ViolatedPrecondition violatedPrecondition = getCheckoutPreconditionViolation(rNrds, rNrd, forkOk); 853 if (violatedPrecondition != null) { 854 throw new PreconditionViolationException(violatedPrecondition, rNrds.getUri()); 855 856 857 } 858 859 861 UriHandler wrUh = UriHandler.createNextWorkingresourceUri( sToken, nsaToken, rUh ); 863 String wrUri = String.valueOf( wrUh ); 864 SubjectNode wrNode = new SubjectNode(); 865 structure.create( sToken, wrNode, String.valueOf(wrUh) ); 866 867 NodeRevisionDescriptor wrNrd = new NodeRevisionDescriptor(); 869 i = pHelp.createInitialProperties(WorkingImpl.getInstance(), wrUri).iterator(); 870 while( i.hasNext() ) 871 wrNrd.setProperty( (NodeProperty)i.next() ); 872 874 wrNrd.setProperty( 876 new NodeProperty(P_CHECKED_OUT, pHelp.createHrefValue(rUri)) ); 877 wrNrd.setProperty( 878 new NodeProperty(P_PREDECESSOR_SET, pHelp.createHrefValue(rUri)) ); 879 NodeProperty coutfProp = rNrd.getProperty(P_CHECKOUT_FORK); 880 if( coutfProp != null ) 881 wrNrd.setProperty( coutfProp ); 882 NodeProperty cinfProp = rNrd.getProperty(P_CHECKIN_FORK); 883 if( cinfProp != null ) 884 wrNrd.setProperty( cinfProp ); 885 wrNrd.setContentType(rNrd.getContentType()); wrNrd.setContentLength( rNrd.getContentLength() ); wrNrd.setContentLanguage(rNrd.getContentLanguage()); wrNrd.setLastModified( new Date () ); wrNrd.setCreationDate( new Date () ); setCreationUser(wrNrd); 891 wrNrd.setETag( PropertyHelper.computeEtag(wrUri, wrNrd) ); 893 if( autoUpdateUri != null && autoUpdateUri.length() > 0 ) { 895 UriHandler autoUpdateUh = new UriHandler( autoUpdateUri ); 896 wrNrd.setProperty( 897 new NodeProperty(P_AUTO_UPDATE, pHelp.createHrefValue(autoUpdateUri)) ); 898 wrNrd.setName( autoUpdateUh.getName() ); 899 } 900 else { 901 wrNrd.removeProperty( P_AUTO_UPDATE ); 902 wrNrd.setName( rNrd.getName() ); 903 } 904 905 j = rNrd.enumerateProperties(); 907 while( j.hasMoreElements() ) { 908 NodeProperty p = (NodeProperty)j.nextElement(); 909 if( p.isLiveProperty() ) 910 continue; 911 wrNrd.setProperty( p ); 912 } 913 914 PropertyHelper.addHrefToProperty(rNrd, P_CHECKOUT_SET, wrUri); 916 content.store( sToken, rNrds.getUri(), rNrd, null); 917 918 content.create( sToken, wrUri, wrNrd, rNrc ); 920 content.store( sToken, wrUri, wrNrd, null ); 921 922 resp.setStatus( WebdavStatus.SC_CREATED ); 924 return wrUri; 925 } 926 else { 927 Domain.warn( 928 "Do not know how to checkout a '"+rRk+"' resource" ); 929 resp.setStatus(WebdavStatus.SC_CONFLICT); 930 throw new WebdavException( WebdavStatus.SC_CONFLICT ); 931 } 932 } 933 934 946 protected ViolatedPrecondition getCheckoutPreconditionViolation(NodeRevisionDescriptors cinNrds, NodeRevisionDescriptor cinNrd, boolean isForkOk) throws IllegalArgumentException , IOException , JDOMException, SlideException { 947 SlideToken stok = sToken; 948 949 ViolatedPrecondition violatedPrecondition = null; 950 951 NodeProperty checkoutForkProperty =cinNrd.getProperty(P_CHECKOUT_FORK); 952 if (checkoutForkProperty != null 953 && !checkoutForkProperty.getValue().toString().equals("")) 954 { 955 Element checkoutForkElement = pHelp.parsePropertyValue(checkoutForkProperty.getValue().toString()); 956 if (checkoutForkElement != null) { 957 958 Enumeration successors = cinNrds.getSuccessors(cinNrd.getRevisionNumber()); 960 if ( (successors != null) && successors.hasMoreElements()) { 961 962 if (E_FORBIDDEN.equals(checkoutForkElement.getName())) { 964 return new ViolatedPrecondition(C_CHECKOUT_OF_VERSION_WITH_DESCENDANT_IS_FORBIDDEN, WebdavStatus.SC_FORBIDDEN); 965 } 966 967 else if (E_DISCOURAGED.equals(checkoutForkElement.getName()) && !isForkOk) { 969 return new ViolatedPrecondition(C_CHECKOUT_OF_VERSION_WITH_DESCENDANT_IS_DISCOURAGED, WebdavStatus.SC_CONFLICT); 970 } 971 } 972 973 PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(stok, nsaToken, sConf); 975 976 NodeProperty checkoutSetProp = propertyHelper.getProperty(P_CHECKOUT_SET, cinNrds, cinNrd, slideContextPath); 977 if( checkoutSetProp != null && checkoutSetProp.getValue() != null ) { 978 XMLValue checkoutSetValue = new XMLValue( checkoutSetProp.getValue().toString() ); 979 if (checkoutSetValue.iterator().hasNext()) { 980 981 if (E_FORBIDDEN.equals(checkoutForkElement.getName())) { 983 return new ViolatedPrecondition(C_CHECKOUT_OF_CHECKED_OUT_VERSION_IS_FORBIDDEN, WebdavStatus.SC_FORBIDDEN); 984 } 985 986 else if (E_DISCOURAGED.equals(checkoutForkElement.getName()) && !isForkOk) { 988 return new ViolatedPrecondition(C_CHECKOUT_OF_CHECKED_OUT_VERSION_IS_DISCOURAGED, WebdavStatus.SC_CONFLICT); 989 } 990 } 991 } 992 } 993 } 994 995 return violatedPrecondition; 996 } 997 998 1003 public void uncheckout(String resourcePath) throws SlideException, JDOMException, IOException , PreconditionViolationException { 1004 1005 NodeRevisionDescriptors rNrds = content.retrieve( sToken, resourcePath ); 1006 NodeRevisionDescriptor rNrd = content.retrieve( sToken, rNrds ); 1007 uncheckout( rNrds, rNrd); 1008 } 1009 1010 1016 public void uncheckout( NodeRevisionDescriptors rNrds, NodeRevisionDescriptor rNrd) 1017 throws SlideException, JDOMException, IOException , PreconditionViolationException { 1018 1019 String rUri = getUri( rNrds, rNrd ); 1021 ResourceKind rRk = AbstractResourceKind.determineResourceKind( nsaToken, rNrds, rNrd ); 1022 1023 if ( ! (rRk instanceof CheckedOutVersionControlled) ) { 1025 throw new PreconditionViolationException(new ViolatedPrecondition(C_MUST_BE_CHECKED_OUT_VERSION_CONTROLLED_RESOURCE, 1026 WebdavStatus.SC_CONFLICT), 1027 rNrds.getUri()); 1028 } 1029 1030 if( !rRk.isSupportedMethod(req.getMethod()) ) { 1031 throw new MethodNotAllowedException( rRk ); 1032 } 1033 1034 NodeProperty coutProp = rNrd.getProperty( P_CHECKED_OUT ); 1036 String coutHref = getElementValue((String )coutProp.getValue()); 1037 UriHandler coutUriHandler = UriHandler.getUriHandler(coutHref); 1038 String coutUri = coutUriHandler.getAssociatedHistoryUri(); 1039 NodeRevisionNumber coutNrn = new NodeRevisionNumber(coutUriHandler.getVersionName()); 1040 NodeRevisionDescriptors coutNrds = content.retrieve(sToken, coutUri); 1041 NodeRevisionDescriptor coutNrd = content.retrieve(sToken, coutNrds, coutNrn); 1042 1044 if (!PropertyHelper.removeHrefFromProperty(coutNrd, P_CHECKOUT_SET, rUri)) { 1046 StringBuffer b = new StringBuffer ("Invalid path"); 1047 PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(sToken, nsaToken, sConf); 1048 NodeProperty checkoutSetProp = propertyHelper.getProperty(P_CHECKOUT_SET, coutNrds, coutNrd, slideContextPath); 1049 if( checkoutSetProp != null && checkoutSetProp.getValue() != null ) { 1050 XMLValue checkoutSetValue = new XMLValue( checkoutSetProp.getValue().toString() ); 1051 if (checkoutSetValue.iterator().hasNext()) { 1052 b.append(" - please use "+checkoutSetValue.getTextValue()+" instead"); 1053 } 1054 } 1055 throw new ConflictException( 1056 rUri, new SlideException(b.toString())); 1057 } 1058 content.store(sToken, coutNrds.getUri(), coutNrd, null); 1059 1060 rNrd.removeProperty( P_CHECKED_OUT ); 1062 update( rNrds, rNrd, coutNrds, coutNrd ); 1063 1064 restoreSpecificLiveProperties( rNrds, rNrd ); 1066 1067 content.store( sToken, rNrds.getUri(), rNrd, null ); content.remove( sToken, rNrds.getUri(), NodeRevisionNumber.HIDDEN_0_0 ); 1071 } 1072 1073 1085 public String checkin( String resourcePath, boolean forkOk, boolean keepCheckedOut, boolean autoVersion ) 1086 throws SlideException, JDOMException, IOException , PreconditionViolationException { 1087 1088 NodeRevisionDescriptors rNrds = content.retrieve( sToken, resourcePath ); 1089 NodeRevisionDescriptor rNrd = content.retrieve( sToken, rNrds ); 1090 return checkin( rNrds, rNrd, forkOk, keepCheckedOut, autoVersion ); 1091 } 1092 1093 1106 public String checkin( NodeRevisionDescriptors rNrds, NodeRevisionDescriptor rNrd, 1107 boolean forkOk, boolean keepCheckedOut, boolean autoVersion ) 1108 throws SlideException, JDOMException, IOException , PreconditionViolationException { 1109 1110 Iterator i; 1111 Enumeration j; 1112 String rUri = getUri( rNrds, rNrd ); 1113 ResourceKind rRk = AbstractResourceKind.determineResourceKind( nsaToken, rNrds, rNrd ); 1114 1115 if( !rRk.isSupportedMethod(req.getMethod()) ) { 1116 if( (rRk instanceof CheckedInVersionControlled) ) { 1118 throw new PreconditionViolationException( 1119 new ViolatedPrecondition(C_MUST_BE_CHECKED_OUT, WebdavStatus.SC_CONFLICT), rUri); 1120 } 1121 throw new MethodNotAllowedException( rRk ); 1122 } 1123 1124 if( rRk instanceof CheckedOutVersionControlled || rRk instanceof Working ) { 1125 1126 boolean isWorkingResource = (rRk instanceof Working); 1127 1128 NodeProperty coutProp = rNrd.getProperty( P_CHECKED_OUT ); 1129 NodeProperty predSetProp = rNrd.getProperty( P_PREDECESSOR_SET ); 1130 NodeProperty autoUpdProp = rNrd.getProperty( P_AUTO_UPDATE ); 1131 1132 NodeRevisionDescriptors autoUpdNrds = null; 1134 NodeRevisionDescriptor autoUpdNrd = null; 1135 if( autoUpdProp != null ) { 1136 Element autoUpdElm = pHelp.parsePropertyValue( (String )autoUpdProp.getValue() ); 1137 String autoUpdUri = autoUpdElm.getTextTrim(); 1138 autoUpdNrds = content.retrieve( sToken, autoUpdUri ); 1139 autoUpdNrd = content.retrieve( sToken, autoUpdNrds ); 1140 } 1141 1142 Element coutElm = pHelp.parsePropertyValue( (String )coutProp.getValue() ); 1144 String vrUriOld = coutElm.getTextTrim(); 1145 UriHandler vrUhOld = UriHandler.getUriHandler( vrUriOld ); 1146 NodeRevisionNumber vrNrnOld = new NodeRevisionNumber( vrUhOld.getVersionName() ); 1147 String vhrUri = vrUhOld.getAssociatedHistoryUri(); 1148 NodeRevisionDescriptors vhrNrds = content.retrieve( sToken, vhrUri ); 1149 NodeRevisionDescriptor vhrNrd = content.retrieve( sToken, vhrNrds ); NodeProperty vSetProp = vhrNrd.getProperty( P_VERSION_SET ); 1151 1152 NodeRevisionDescriptor vrNrdOld = 1154 content.retrieve( sToken, vhrNrds, vrNrnOld ); 1156 if (!PropertyHelper.removeHrefFromProperty(vrNrdOld, P_CHECKOUT_SET, rUri)) { 1158 StringBuffer b = new StringBuffer ("Invalid path"); 1159 PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(sToken, nsaToken, sConf); 1160 NodeProperty checkoutSetProp = propertyHelper.getProperty(P_CHECKOUT_SET, vhrNrds, vrNrdOld, slideContextPath); 1161 if( checkoutSetProp != null && checkoutSetProp.getValue() != null ) { 1162 XMLValue checkoutSetValue = new XMLValue( checkoutSetProp.getValue().toString() ); 1163 if (checkoutSetValue.iterator().hasNext()) { 1164 b.append(" - please use "+checkoutSetValue.getTextValue()+" instead"); 1165 } 1166 } 1167 throw new ConflictException( 1168 rUri, new SlideException(b.toString())); 1169 } 1170 content.store(sToken, vhrNrds.getUri(), vrNrdOld, null); 1171 1172 ViolatedPrecondition violatedPrecondition = 1174 getCheckinPreconditionViolation( predSetProp, vhrNrds, forkOk, autoUpdNrd ); 1175 if (violatedPrecondition != null) { 1176 throw new PreconditionViolationException(violatedPrecondition, rUri); 1177 } 1178 1179 String forkBranch = getForkBranch(predSetProp, vhrNrds, forkOk); 1181 NodeRevisionDescriptor vrNrdNew = null; 1182 if (forkBranch != null) { 1183 NodeRevisionNumber branchedRevisionNumber = 1185 content.fork(sToken, vhrNrds.getUri(), forkBranch, vrNrdOld); 1186 vhrNrds = content.retrieve( sToken, vhrUri ); 1187 vrNrdNew = content.retrieve(sToken, vhrNrds, branchedRevisionNumber); 1188 vrNrdNew.setContentLength(rNrd.getContentLength()); 1189 } 1190 else { 1191 vrNrdNew = new NodeRevisionDescriptor( rNrd.getContentLength() ); 1193 } 1194 1195 i = pHelp.createInitialProperties(VersionImpl.getInstance(), vhrUri).iterator(); 1196 while( i.hasNext() ) 1197 vrNrdNew.setProperty( (NodeProperty)i.next() ); 1198 1199 j = rNrd.enumerateProperties(); 1201 while( j.hasMoreElements() ) { 1202 NodeProperty p = (NodeProperty)j.nextElement(); 1203 if( p.isLiveProperty() ) 1204 continue; 1205 if( !vrNrdNew.exists(p.getName()) ) 1206 vrNrdNew.setProperty( p ); 1207 } 1208 vrNrdNew.setContentType(rNrd.getContentType()); vrNrdNew.setContentLength(rNrd.getContentLength()); vrNrdNew.setContentLanguage( rNrd.getContentLanguage() ); String comment = (autoVersion ? "CREATED BY AUTO-VERSIONING. " : ""); 1213 if( rNrd.exists(P_COMMENT) ) 1214 comment = (String )rNrd.getProperty(P_COMMENT).getValue(); 1215 vrNrdNew.setProperty( 1216 new NodeProperty(P_COMMENT, comment) ); 1217 1218 vrNrdNew.setProperty( rNrd.getProperty(P_CHECKOUT_FORK) ); 1219 vrNrdNew.setProperty( rNrd.getProperty(P_CHECKIN_FORK) ); 1220 1221 NodeRevisionContent rNrc = content.retrieve( sToken, rNrds, rNrd ); 1222 1223 if (forkBranch != null) { 1224 content.store(sToken, vhrUri, vrNrdNew, rNrc); 1225 } 1226 else { 1227 String branch = vrNrdOld.getBranchName(); 1228 content.create( sToken, vhrUri, branch, vrNrdNew, rNrc ); 1229 } 1230 1231 String vrUriNew = vhrUri+"/"+vrNrdNew.getRevisionNumber().toString(); 1233 UriHandler vrUhNew = UriHandler.getUriHandler( vrUriNew ); 1234 SubjectNode vrNodeNew = new SubjectNode(); 1235 structure.create( sToken, vrNodeNew, vrUriNew ); 1236 1237 if( keepCheckedOut ) { 1239 rNrd.setProperty( 1240 new NodeProperty(P_CHECKED_OUT, pHelp.createHrefValue(vrUriNew)) ); 1241 rNrd.setProperty( 1242 new NodeProperty(P_PREDECESSOR_SET, "") ); 1243 PropertyHelper.addHrefToProperty(rNrd, P_PREDECESSOR_SET, vrUriNew); 1244 PropertyHelper.addHrefToProperty(vrNrdNew, P_CHECKOUT_SET, rUri); 1245 } 1246 else { 1247 if( !isWorkingResource ) { 1248 rNrd.removeProperty( coutProp ); 1249 rNrd.setProperty( 1250 new NodeProperty(P_CHECKED_IN, pHelp.createHrefValue(vrUriNew)) ); 1251 rNrd.removeProperty( I_CHECKIN_LOCKTOKEN , NamespaceCache.SLIDE_URI); 1252 rNrd.removeProperty( I_CHECKIN_LOCKTOKEN ); 1255 rNrd.removeProperty(P_PREDECESSOR_SET); 1256 rNrd.removeProperty(P_CHECKOUT_FORK); 1257 rNrd.removeProperty(P_CHECKIN_FORK); 1258 } 1259 } 1260 1261 vhrNrd.setLastModified( new Date () ); vhrNrd.setProperty( new NodeProperty( 1263 P_VERSION_SET, ((String )vSetProp.getValue())+pHelp.createHrefValue(vrUriNew)) ); 1264 1265 vrNrdNew.setName( rNrd.getName() ); vrNrdNew.setCreationDate( new Date () ); vrNrdNew.setLastModified( new Date () ); vrNrdNew.setETag( PropertyHelper.computeEtag(vrUriNew, vrNrdNew) ); vrNrdNew.setProperty( 1270 new NodeProperty(P_VERSION_NAME, vrUhNew.getVersionName()) ); 1271 vrNrdNew.setProperty( 1272 new NodeProperty(P_PREDECESSOR_SET, predSetProp.getValue()) ); 1273 1274 if( keepCheckedOut || !isWorkingResource ) { 1276 content.store( sToken, rUri, rNrd, null ); try { 1278 content.remove( sToken, rUri, NodeRevisionNumber.HIDDEN_0_0 ); 1280 } 1281 catch( RevisionDescriptorNotFoundException x ) { 1282 Domain.info( "Checkin: no backup descriptor found at "+rUri ); 1285 } 1286 if( keepCheckedOut ) 1287 backupSpecificLiveProperties( rNrds, rNrd ); 1288 } 1289 else { 1290 macro.delete( sToken, rUri ); 1292 } 1293 content.store( sToken, vhrUri, vhrNrd, null ); content.store( sToken, vhrUri, vrNrdNew, null ); 1296 if( autoUpdNrd != null ) { 1298 update( autoUpdNrds, autoUpdNrd, vhrNrds, vrNrdNew ); 1299 } 1300 1301 resp.setStatus( WebdavStatus.SC_CREATED ); 1303 return vrUriNew; 1304 } 1305 else { 1306 Domain.warn( 1307 "Do not know how to checkout a '"+rRk+"' resource" ); 1308 resp.setStatus(WebdavStatus.SC_CONFLICT); 1309 return null; 1310 } 1311 } 1312 1313 private void setCreationUser(NodeRevisionDescriptor nrd) throws ServiceAccessException, ObjectNotFoundException { 1314 String creationUser = ((SubjectNode)nsaToken.getSecurityHelper().getPrincipal(sToken)).getPath().lastSegment(); 1316 nrd.setCreationUser(creationUser); 1317 nrd.setOwner(creationUser); 1318 } 1319 1320 1336 protected ViolatedPrecondition getCheckinPreconditionViolation(NodeProperty predSetProp, NodeRevisionDescriptors vhrNrds, boolean isForkOk, NodeRevisionDescriptor autoUpdNrd ) throws LinkedObjectNotFoundException, ServiceAccessException, ObjectLockedException, RevisionDescriptorNotFoundException, JDOMException, IllegalArgumentException , ObjectNotFoundException, AccessDeniedException, IOException , VetoException { 1337 SlideToken stok = sToken; 1338 1339 ViolatedPrecondition violatedPrecondition = null; 1340 1341 if ( (predSetProp != null) && (predSetProp.getValue() != null) ) { 1342 XMLValue predecessors = new XMLValue( (String )predSetProp.getValue() ); 1343 1344 Iterator iterator = predecessors.iterator(); 1345 while (iterator.hasNext()) { 1346 String href = ((Element)iterator.next()).getTextTrim(); 1347 if (href != null) { 1348 1349 UriHandler predecessorUriHandler = UriHandler.getUriHandler( href); 1350 1351 if ( !predecessorUriHandler.isVersionUri() || 1353 !vhrNrds.getUri().equals(predecessorUriHandler.getAssociatedHistoryUri()) ) { 1354 return new ViolatedPrecondition(C_VERSION_HISTORY_IS_TREE, WebdavStatus.SC_FORBIDDEN); 1355 } 1356 1357 NodeRevisionNumber predecessorNrn = new NodeRevisionNumber(predecessorUriHandler.getVersionName()); 1359 NodeRevisionDescriptor predecessorNrd = content.retrieve(stok, 1360 vhrNrds, 1361 predecessorNrn); 1362 NodeProperty predecessorCheckinForkProperty = predecessorNrd.getProperty(P_CHECKIN_FORK); 1363 if (predecessorCheckinForkProperty != null 1364 && !predecessorCheckinForkProperty.getValue().toString().equals("")) 1365 { 1366 Enumeration predecessorSuccessors = vhrNrds.getSuccessors(predecessorNrn); 1367 if ( (predecessorSuccessors != null) && 1368 (predecessorSuccessors.hasMoreElements()) && 1369 (predecessorCheckinForkProperty.getValue() != null) ) { 1370 1371 String checkinFork = getElementName(predecessorCheckinForkProperty.getValue().toString()); 1372 1373 if (E_FORBIDDEN.equals(checkinFork)) { 1374 return new ViolatedPrecondition(C_CHECKIN_FORK_FORBIDDEN, WebdavStatus.SC_FORBIDDEN); 1375 } 1376 1377 else if (E_DISCOURAGED.equals(checkinFork) && !isForkOk ) { 1379 return new ViolatedPrecondition(C_CHECKIN_FORK_DISCOURAGED, WebdavStatus.SC_CONFLICT); 1380 } 1381 } 1382 } 1383 1384 if( autoUpdNrd != null ) { 1386 NodeProperty cinProp = autoUpdNrd.getProperty( P_CHECKED_IN ); 1387 if( cinProp != null ) { 1388 Element cinHrefElm = pHelp.parsePropertyValue( (String )cinProp.getValue() ); 1389 UriHandler cinUh = new UriHandler( cinHrefElm.getTextTrim() ); 1390 NodeRevisionNumber cinNrn = new NodeRevisionNumber( cinUh.getVersionName() ); 1391 if( !vhrNrds.getUri().equals(cinUh.getAssociatedHistoryUri()) ) { 1392 return new ViolatedPrecondition(C_NO_OVERWRITE_BY_AUTO_UPDATE, WebdavStatus.SC_CONFLICT); 1394 } 1395 if( !vhrNrds.isAncestorDescendant(cinNrn, predecessorNrn) ) { 1396 return new ViolatedPrecondition(C_NO_OVERWRITE_BY_AUTO_UPDATE, WebdavStatus.SC_CONFLICT); 1398 } 1399 } 1400 } 1401 } 1402 } 1403 } 1404 return violatedPrecondition; 1405 } 1406 1407 1420 protected String getForkBranch(NodeProperty predSetProp, NodeRevisionDescriptors vhrNrds, boolean isForkOk) throws LinkedObjectNotFoundException, ServiceAccessException, ObjectLockedException, RevisionDescriptorNotFoundException, JDOMException, IllegalArgumentException , ObjectNotFoundException, AccessDeniedException, IOException , VetoException { 1421 1422 String forkBranch = null; 1423 1424 if ( (predSetProp != null) && (predSetProp.getValue() != null) ) { 1425 XMLValue predecessors = new XMLValue( (String )predSetProp.getValue() ); 1426 1427 Iterator iterator = predecessors.iterator(); 1428 if (iterator.hasNext()) { 1429 String href = ((Element)iterator.next()).getTextTrim(); 1430 if (href != null) { 1431 1432 UriHandler predecessorUriHandler = UriHandler.getUriHandler( href); 1433 1434 NodeRevisionNumber predecessorNrn = new NodeRevisionNumber(predecessorUriHandler.getVersionName()); 1435 NodeRevisionDescriptor predecessorNrd = content.retrieve(sToken, 1436 vhrNrds, 1437 predecessorNrn); 1438 NodeProperty predecessorCheckinForkProperty = predecessorNrd.getProperty(P_CHECKIN_FORK); 1439 if (predecessorCheckinForkProperty != null) { 1440 1441 Enumeration predecessorSuccessors = vhrNrds.getSuccessors(predecessorNrn); 1442 if ( (predecessorSuccessors != null) && 1443 predecessorSuccessors.hasMoreElements() ) { 1444 forkBranch = "branch_" + predecessorNrn.toString(); 1445 } 1446 } 1447 1448 } 1449 } 1450 } 1451 return forkBranch; 1452 } 1453 1454 1465 public String getUriOfAssociatedVR(String resourceUri) throws SlideException { 1466 return getUriOfAssociatedVR(nsaToken, sToken, content, resourceUri); 1467 } 1468 1469 1479 public String getUri(NodeRevisionDescriptors revisionDescriptors, 1480 NodeRevisionDescriptor revisionDescriptor) throws SlideException { 1481 return getUri(nsaToken, sToken, content, revisionDescriptors, revisionDescriptor); 1482 } 1483 1484 1493 public void update(String vcrUri, String vrUri) throws SlideException { 1494 1495 NodeRevisionDescriptors vcrRevisionDescriptors = content.retrieve( sToken,vcrUri ); 1496 NodeRevisionDescriptor vcrRevisionDescriptor = content.retrieve( sToken, vcrRevisionDescriptors); 1497 1498 NodeRevisionDescriptors vrRevisionDescriptors = content.retrieve( sToken, vrUri ); 1499 NodeRevisionDescriptor vrRevisionDescriptor = content.retrieve( sToken, vrRevisionDescriptors); 1501 update(vcrRevisionDescriptors, vcrRevisionDescriptor, vrRevisionDescriptors, vrRevisionDescriptor); 1502 } 1503 1504 1521 public void update(NodeRevisionDescriptors vcrRevisionDescriptors, NodeRevisionDescriptor vcrRevisionDescriptor, NodeRevisionDescriptors vrRevisionDescriptors, NodeRevisionDescriptor vrRevisionDescriptor) throws SlideException { 1522 1523 1528 String vcrUri = getUri(vcrRevisionDescriptors, vcrRevisionDescriptor); 1531 Enumeration propertyEnum; 1532 1533 propertyEnum = vcrRevisionDescriptor.enumerateProperties(); 1535 while (propertyEnum.hasMoreElements()) { 1536 NodeProperty p = (NodeProperty)propertyEnum.nextElement(); 1537 if( p.isLiveProperty() ) 1538 continue; 1539 vcrRevisionDescriptor.removeProperty(p); 1540 } 1541 1542 propertyEnum = vrRevisionDescriptor.enumerateProperties(); 1544 while (propertyEnum.hasMoreElements()) { 1545 NodeProperty p = (NodeProperty)propertyEnum.nextElement(); 1546 if( !p.isLiveProperty() ) { 1547 vcrRevisionDescriptor.setProperty(p); 1548 } 1549 } 1550 1551 String vrUri = getUri(vrRevisionDescriptors, vrRevisionDescriptor); 1553 vcrRevisionDescriptor.setProperty(new NodeProperty(P_CHECKED_IN, 1554 pHelp.createHrefValue(vrUri)) ); 1555 vcrRevisionDescriptor.setLastModified(new Date ()); 1556 vcrRevisionDescriptor.setContentLength(vrRevisionDescriptor.getContentLength()); 1557 vcrRevisionDescriptor.setContentType(vrRevisionDescriptor.getContentType()); 1558 vcrRevisionDescriptor.setContentLanguage(vrRevisionDescriptor.getContentLanguage()); 1559 vcrRevisionDescriptor.setETag(PropertyHelper.computeEtag(vcrRevisionDescriptors.getUri(), vcrRevisionDescriptor) ); 1560 1561 setWorkspaceProperty( vcrUri, vcrRevisionDescriptor ); 1563 1564 NodeRevisionContent vrContent = content.retrieve(sToken, vrRevisionDescriptors, vrRevisionDescriptor); 1566 1567 content.store( sToken, vcrUri, vcrRevisionDescriptor, vrContent ); 1569 } 1570 1571 1583 protected void backupSpecificLiveProperties(NodeRevisionDescriptors rNrds, NodeRevisionDescriptor rNrd) throws SlideException { 1584 1585 NodeRevisionDescriptor backupNrd = 1586 new NodeRevisionDescriptor( NodeRevisionNumber.HIDDEN_0_0, "backup", new Vector (), new Hashtable () ); 1587 1588 NodeProperty p; 1589 1590 p = rNrd.getProperty( P_AUTO_VERSION ); 1591 if( p != null ) 1592 backupNrd.setProperty( p ); 1593 1594 p = rNrd.getProperty( P_COMMENT ); 1595 if( p != null ) 1596 backupNrd.setProperty( p ); 1597 1598 p = rNrd.getProperty( P_DISPLAYNAME ); 1599 if( p != null ) 1600 backupNrd.setProperty( p ); 1601 1602 p = rNrd.getProperty( P_CREATOR_DISPLAYNAME ); 1603 if( p != null ) 1604 backupNrd.setProperty( p ); 1605 1606 try { 1607 content.retrieve( sToken, rNrds, NodeRevisionNumber.HIDDEN_0_0 ); 1608 content.store( sToken, rNrds.getUri(), backupNrd, null ); 1609 } 1610 catch (RevisionDescriptorNotFoundException e) { 1611 content.create( sToken, rNrds.getUri(), null, backupNrd, null ); } 1613 } 1614 1615 1626 protected void restoreSpecificLiveProperties(NodeRevisionDescriptors rNrds, NodeRevisionDescriptor rNrd) throws SlideException { 1627 1628 NodeRevisionDescriptor backupNrd = 1629 content.retrieve(sToken, rNrds, NodeRevisionNumber.HIDDEN_0_0); 1630 1631 NodeProperty p; 1632 1633 p = backupNrd.getProperty( P_AUTO_VERSION ); 1634 if( p != null ) 1635 rNrd.setProperty( p ); 1636 1637 p = backupNrd.getProperty( P_COMMENT ); 1638 if( p != null ) 1639 rNrd.setProperty( p ); 1640 1641 p = backupNrd.getProperty( P_DISPLAYNAME ); 1642 if( p != null ) 1643 rNrd.setProperty( p ); 1644 1645 p = backupNrd.getProperty( P_CREATOR_DISPLAYNAME ); 1646 if( p != null ) 1647 rNrd.setProperty( p ); 1648 1649 content.store(sToken, rNrds.getUri(), rNrd, null); 1650 } 1651 1652 1664 public String getAutoVersionElementName(NodeRevisionDescriptor revisionDescriptor) { 1665 1666 String autoVersionValue = null; 1667 NodeProperty autoVersionProperty = revisionDescriptor.getProperty(DeltavConstants.P_AUTO_VERSION); 1668 if ( (autoVersionProperty != null) && (autoVersionProperty.getValue() != null) ) { 1669 if (autoVersionProperty.getValue().toString().length() > 0) { 1670 autoVersionValue = getElementName(autoVersionProperty.getValue().toString()); 1671 } 1672 else { 1673 autoVersionValue = ""; 1674 } 1675 } 1676 return autoVersionValue; 1677 } 1678 1679 1690 public boolean mustCheckoutAutoVersionedVCR(String resourceUri) throws SlideException { 1691 NodeRevisionDescriptors vcrRevisionDescriptors = content.retrieve(sToken,resourceUri); 1692 NodeRevisionDescriptor vcrRevisionDescriptor = content.retrieve( sToken, vcrRevisionDescriptors); 1693 return mustCheckoutAutoVersionedVCR(vcrRevisionDescriptors, vcrRevisionDescriptor); 1694 } 1695 1696 1706 public boolean mustCheckoutAutoVersionedVCR(NodeRevisionDescriptors revisionDescriptors, NodeRevisionDescriptor revisionDescriptor) { 1707 1708 String autoVersionValue = getAutoVersionElementName(revisionDescriptor); 1709 return ( (autoVersionValue != null) && 1710 ( DeltavConstants.E_CHECKOUT_CHECKIN.equals(autoVersionValue) || 1711 DeltavConstants.E_CHECKOUT_UNLOCKED_CHECKIN.equals(autoVersionValue) || 1712 DeltavConstants.E_CHECKOUT.equals(autoVersionValue) || 1713 DeltavConstants.E_CHECKOUT_IGNORE_UNLOCK.equals(autoVersionValue) || 1714 DeltavConstants.E_LOCKED_CHECKOUT.equals(autoVersionValue) ) ); 1715 } 1716 1717 1729 public boolean mustCheckinAutoVersionedVCR(SlideToken slideToken, String resourceUri) throws SlideException { 1730 NodeRevisionDescriptors vcrRevisionDescriptors = content.retrieve(sToken,resourceUri); 1731 NodeRevisionDescriptor vcrRevisionDescriptor = content.retrieve( sToken, vcrRevisionDescriptors); 1732 return mustCheckinAutoVersionedVCR(slideToken, vcrRevisionDescriptors, vcrRevisionDescriptor); 1733 } 1734 1735 1746 public boolean mustCheckinAutoVersionedVCR(SlideToken slideToken, NodeRevisionDescriptors revisionDescriptors, NodeRevisionDescriptor revisionDescriptor) 1747 throws ServiceAccessException { 1748 1749 boolean checkin = false; 1750 String autoVersionValue = getAutoVersionElementName(revisionDescriptor); 1751 if (autoVersionValue != null) { 1752 checkin = DeltavConstants.E_CHECKOUT_CHECKIN.equals(autoVersionValue); 1753 if ( !checkin && DeltavConstants.E_CHECKOUT_UNLOCKED_CHECKIN.equals(autoVersionValue)) { 1754 checkin = ! isWriteLocked(slideToken, revisionDescriptors); 1755 } 1756 } 1757 return checkin; 1758 } 1759 1760 1769 public boolean isWriteLocked(SlideToken slideToken, NodeRevisionDescriptors revisionDescriptors) 1770 throws ServiceAccessException { 1771 return (getWriteLock(slideToken, revisionDescriptors) != null); 1772 } 1773 1774 1783 private NodeLock getWriteLock(SlideToken slideToken, NodeRevisionDescriptors revisionDescriptors) 1784 throws ServiceAccessException { 1785 1786 NodeLock writeLock = null; 1787 try { 1788 Enumeration lockEnum = lock.enumerateLocks(slideToken, revisionDescriptors.getUri()); 1789 if (lockEnum != null && lockEnum.hasMoreElements()) { 1790 writeLock = (NodeLock)lockEnum.nextElement(); 1792 } 1793 } 1794 catch (ObjectNotFoundException e) {} 1795 catch (LockTokenNotFoundException e) {} 1796 1797 return writeLock; 1798 } 1799 1800 1801 1815 public static String getElementValue(String elementString) { 1816 1817 String text = null; 1818 Element element = getElement(elementString); 1819 if (element != null) { 1820 text = element.getText(); 1821 } 1822 return text; 1823 } 1824 1825 1838 public static String getElementName(String elementString) { 1839 1840 String name = null; 1841 Element element = getElement(elementString); 1842 if (element != null) { 1843 name = element.getName(); 1844 } 1845 return name; 1846 } 1847 1848 1859 public static Element getElement(String elementString) { 1860 1861 Element element = null; 1862 try { 1863 Document document = getSAXBuilder().build(new StringReader (elementString)); 1864 element = document.getRootElement(); 1865 } 1866 catch (JDOMException e) {} 1867 catch (Exception e) { 1868 e.printStackTrace(); 1869 } 1870 return element; 1871 } 1872 1873 1878 protected static SAXBuilder getSAXBuilder() { 1879 if (saxBuilder == null) { 1880 saxBuilder = new SAXBuilder(); 1881 } 1882 return saxBuilder; 1883 } 1884 1885 1908 private static String getLabeledResourceUri(NamespaceAccessToken nsaToken, SlideToken sToken, Content content, String resourcePath, String label) throws SlideException, LabeledRevisionNotFoundException { 1909 1910 NodeRevisionDescriptors revisionDescriptors = 1911 content.retrieve( sToken, resourcePath ); 1912 NodeRevisionDescriptor revisionDescriptor = 1913 content.retrieve( sToken, revisionDescriptors); 1914 ResourceKind resourceKind = AbstractResourceKind.determineResourceKind( nsaToken, resourcePath, revisionDescriptor); 1915 1916 if ( (resourceKind instanceof VersionControlled) && (label != null) ) { 1917 String vrUri = getUriOfAssociatedVR(nsaToken, sToken, content, revisionDescriptors.getUri()); 1918 UriHandler vrUriHandler = UriHandler.getUriHandler(vrUri); 1919 String historyUri = vrUriHandler.getAssociatedHistoryUri(); 1920 revisionDescriptors = content.retrieve(sToken, historyUri); 1921 revisionDescriptor = retrieveLabeledRevision(nsaToken, sToken, content, historyUri, label); 1922 } 1923 return getUri(nsaToken, sToken, content, revisionDescriptors, revisionDescriptor); 1924 } 1925 1926 1927 1945 public static NodeRevisionDescriptor retrieveLabeledRevision(NamespaceAccessToken nsaToken, SlideToken sToken, Content content, String historyUri, String label) throws SlideException, LabeledRevisionNotFoundException { 1946 1947 NodeRevisionDescriptor labeledRevision = null; 1948 1949 UriHandler historyUriHandler = UriHandler.getUriHandler(historyUri); 1950 if (historyUriHandler.isHistoryUri()) { 1951 NodeRevisionDescriptors historyNrds = content.retrieve(sToken, historyUri); 1952 NodeRevisionDescriptor historyNrd = 1953 content.retrieve(sToken, historyNrds, NodeRevisionNumber.HIDDEN_0_0); 1954 NodeProperty versionSet = historyNrd.getProperty(P_VERSION_SET); 1955 try { 1956 XMLValue versionSetValue = new XMLValue(versionSet.getValue().toString()); 1957 NodeRevisionDescriptor vrNrd = null; 1958 NodeProperty labelNameSetProperty = null; 1959 String labelNameSetString = null; 1960 Iterator versionSetIterator = versionSetValue.iterator(); 1961 String vrUri = null; 1962 UriHandler vrUriHandler = null; 1963 boolean found = false; 1964 while ( !found && versionSetIterator.hasNext() ) { 1965 vrUri = ((Element)versionSetIterator.next()).getText(); 1966 vrUriHandler = UriHandler.getUriHandler(vrUri); 1967 NodeRevisionNumber vrRevisionNumber = new NodeRevisionNumber(vrUriHandler.getVersionName()); 1968 vrNrd = content.retrieve(sToken, historyNrds, vrRevisionNumber); 1969 labelNameSetProperty = vrNrd.getProperty(P_LABEL_NAME_SET); 1970 if ( (labelNameSetProperty != null) && (labelNameSetProperty.getValue() != null) ) { 1971 labelNameSetString = labelNameSetProperty.getValue().toString(); 1972 if (labelNameSetString != null) { 1973 XMLValue labelNameSet = new XMLValue(labelNameSetString); 1974 Iterator labelNameSetIterator = labelNameSet.iterator(); 1975 while ( !found && labelNameSetIterator.hasNext() ) { 1976 found = label.equals(((Element)labelNameSetIterator.next()).getText()); 1977 } 1978 } 1979 } 1980 } 1981 if (found) { 1982 labeledRevision = vrNrd; 1983 } 1984 else { 1985 throw new LabeledRevisionNotFoundException(historyUri, label); 1986 } 1987 } 1988 catch (JDOMException e) {} 1989 catch (IllegalArgumentException e) {} 1990 } 1991 return labeledRevision; 1992 } 1993 1994 1995 2009 public static String getUriOfAssociatedVR(NamespaceAccessToken nsaToken, 2010 SlideToken sToken, 2011 Content content, 2012 String resourceUri) throws SlideException { 2013 2014 String vrUri = null; 2015 2016 NodeRevisionDescriptors revisionDescriptors = content.retrieve(sToken, resourceUri); 2017 if (!revisionDescriptors.isVersioned()) { 2018 NodeRevisionDescriptor revisionDescriptor = 2019 content.retrieve( sToken, revisionDescriptors); 2020 NodeProperty property = revisionDescriptor.getProperty(P_CHECKED_OUT); 2021 if ( (property == null) || (property.getValue() == null) ) { 2022 property = revisionDescriptor.getProperty(P_CHECKED_IN); 2023 } 2024 if ( (property != null) && (property.getValue() != null) ) { 2025 2026 try { 2027 XMLValue xmlValue = new XMLValue(property.getValue().toString()); 2028 Iterator iterator = xmlValue.iterator(); 2029 if (iterator.hasNext()) { 2030 Element element = (Element)iterator.next(); 2031 vrUri = element.getText(); 2032 } 2033 } 2034 catch (JDOMException e) {} 2035 catch (IllegalArgumentException e) {} 2036 } 2037 } 2038 2039 return vrUri; 2040 } 2041 2042 2043 2057 public static String getUri(NamespaceAccessToken nsaToken, 2058 SlideToken sToken, 2059 Content content, 2060 NodeRevisionDescriptors revisionDescriptors, 2061 NodeRevisionDescriptor revisionDescriptor) throws SlideException { 2062 2063 StringBuffer uri = new StringBuffer (); 2064 UriHandler uriHandler = UriHandler.getUriHandler(revisionDescriptors.getUri()); 2065 if ( ! uriHandler.isHistoryUri() ) { 2066 uri.append(revisionDescriptors.getUri()); 2068 } 2069 else { 2070 if (revisionDescriptor.getRevisionNumber().equals(NodeRevisionNumber.HIDDEN_0_0)) { 2071 uri.append(revisionDescriptors.getUri()); 2073 } 2074 else { 2075 uri.append(revisionDescriptors.getUri()); 2077 if ( ! revisionDescriptors.getUri().endsWith("/") ) { 2078 uri.append("/"); 2079 } 2080 uri.append(revisionDescriptor.getRevisionNumber().toString()); 2081 } 2082 } 2083 return uri.toString(); 2084 } 2085} 2086 2087 2088 2089 2090 2091 2092 2093 2094 | Popular Tags |