KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > slide > webdav > util > VersioningHelper


1 /*
2  * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/util/VersioningHelper.java,v 1.107.2.3 2004/10/08 16:33:22 luetzkendorf Exp $
3  * $Revision: 1.107.2.3 $
4  * $Date: 2004/10/08 16:33:22 $
5  *
6  * ====================================================================
7  *
8  * Copyright 1999-2002 The Apache Software Foundation
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */

23
24 package org.apache.slide.webdav.util;
25 import java.io.IOException JavaDoc;
26 import java.io.StringReader JavaDoc;
27 import java.util.Date JavaDoc;
28 import java.util.Enumeration JavaDoc;
29 import java.util.Hashtable JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.Vector JavaDoc;
32
33 import javax.servlet.http.HttpServletRequest JavaDoc;
34 import javax.servlet.http.HttpServletResponse JavaDoc;
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 /**
95  * Helper class for versioning operations. Allows to execute the operation from
96  * within multiple methods.
97  *
98  */

99
100 public class VersioningHelper extends AbstractWebdavHelper {
101     
102     /**
103      * Factory method.
104      */

105     public static VersioningHelper
106         getVersioningHelper( SlideToken sToken, NamespaceAccessToken nsaToken,
107                             HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc resp, WebdavServletConfig sConf ) {
108         
109         return new VersioningHelper( sToken, nsaToken, req, resp, sConf );
110     }
111     
112     /**
113      ** The SAXBuilder used to create JDOM Documents.
114      **/

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 JavaDoc req = null;
122     private HttpServletResponse JavaDoc resp = null;
123     private WebdavServletConfig sConf = null;
124     private PropertyHelper pHelp = null;
125     //private String serverURL = null;
126
private String JavaDoc slideContextPath = null;
127     
128     /**
129      * The URI of the <code>modifyRevisionMetadataAction</code>.
130      */

131     protected final String JavaDoc modifyMetadataUri;
132     
133     /**
134      * The URI of the <code>modifyRevisionContentAction</code>.
135      */

136     protected final String JavaDoc modifyContentUri;
137     
138     
139     /**
140      * Protected contructor
141      */

142     protected VersioningHelper( SlideToken sToken, NamespaceAccessToken nsaToken,
143                                HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc 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         //serverURL = "http://" + req.getServerName()+ ":" + req.getServerPort();
173
}
174     
175     /**
176      * Returns slide Uri determinating the NodeRevisionDescriptors and
177      * NodeRevisionDescriptor associated with the given <code>resourcePath</code>.
178      * If the given <code>label</code> is not <code>null</code>, and the
179      * <code>resourcePath</code> identifies a VCR, the revision with that label
180      * of the associated history is returned.
181      *
182      * @param resourcePath the path of the resource for which to retrieve
183      * the SlideResource.
184      * @param label the label of the revision to return. May be
185      * <code>null</code>.
186      *
187      * @return slide Uri determinating the NodeRevisionDescriptors and
188      * NodeRevisionDescriptor associated with the given
189      * <code>resourcePath</code>.
190      *
191      * @throws SlideException
192      * @throws LabeledRevisionNotFoundException if no revision with the specified
193      * label was found.
194      */

195     public String JavaDoc getLabeledResourceUri(String JavaDoc resourcePath, String JavaDoc 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     /**
210      * If the <code>resourcePath</code> identifies a VHR, the associated revision
211      * with the given <code>label</code> is returned. If the <code>resourcePath</code>
212      * does not identify a VHR , <code>null</code> is returned.
213      *
214      * @param resourcePath the path of the resource for which to retrieve
215      * the NRD.
216      * @param label the label of the revision to return.
217      *
218      * @return the associated revision with the given <code>label</code>.
219      *
220      * @throws SlideException
221      * @throws LabeledRevisionNotFoundException if no revision with the specified
222      * label was found.
223      */

224     public NodeRevisionDescriptor retrieveLabeledRevision(String JavaDoc resourcePath, String JavaDoc label) throws SlideException, LabeledRevisionNotFoundException {
225         return retrieveLabeledRevision(nsaToken, sToken, content, resourcePath, label);
226     }
227     
228     /**
229      * Set the specified resource under version control
230      *
231      * @param resourcePath the URI of the resource to version-control
232      * @throws SlideException
233      */

234     public void versionControl( String JavaDoc resourcePath ) throws SlideException {
235         UriHandler rUh = UriHandler.getUriHandler( resourcePath );
236         Iterator JavaDoc i;
237         Enumeration JavaDoc 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         // Check for rRk = K_VERSION_CONTROLLED*
247
if( rRk instanceof VersionControlled ) {
248             // nothing to do
249
return;
250         }
251         
252         // Create new history URI
253
UriHandler vhrUh = UriHandler.createNextHistoryUri( sToken, nsaToken, rUh );
254         String JavaDoc vhrUri = String.valueOf(vhrUh);
255         
256         // Set initial VR properties
257
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         // Copy dead properties VCR -> VR
264
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         // Copy properties VCR->VR
274
NodeRevisionContent rNrc = content.retrieve( sToken, rNrds, rNrd );
275         vrNrd.setContentType(rNrd.getContentType()); // P_GETCONTENTTYPE
276
vrNrd.setContentLength(rNrd.getContentLength()); // P_GETCONTENTLENGTH
277
vrNrd.setContentLanguage(rNrd.getContentLanguage()); // P_GETCONTENTLANGUAGE
278
String JavaDoc comment = "INITIAL VERSION. ";
279         if( rNrd.exists(P_COMMENT) )
280             comment += (String JavaDoc)rNrd.getProperty(P_COMMENT).getValue();
281         vrNrd.setProperty(
282             new NodeProperty(P_COMMENT, comment) );
283         
284         // Set initial VHR properties
285
Vector JavaDoc vhrLabels = new Vector JavaDoc();
286         Hashtable JavaDoc vhrProps = new Hashtable JavaDoc();
287         String JavaDoc 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         // Set initial VCR properties (do not overwrite existing!!)
295
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         // Create VHR/VR
303
SubjectNode vhrNode = new SubjectNode();
304         structure.create( sToken, vhrNode, String.valueOf(vhrUh) );
305         content.create( sToken, vhrUri, true ); //isVersioned=true
306
content.create( sToken, vhrUri, vrNrd, rNrc );
307         //NodeRevisionDescriptors vhrNrds = content.retrieve( sToken, vhrUri );
308
content.create(
309             sToken, vhrUri, null, vhrNrd, null ); //branch=null, revisionContent=null
310

311         // Create VR node
312
NodeRevisionNumber vrVersion = vrNrd.getRevisionNumber();
313         SubjectNode vrNode = new SubjectNode();
314         UriHandler vrUh =
315             UriHandler.createVersionUri( vhrUh, String.valueOf(vrVersion) );
316         String JavaDoc vrUri = String.valueOf( vrUh );
317         structure.create( sToken, vrNode, String.valueOf(vrUh) );
318         
319         // Set specific properties
320
vrNrd.setName(rUh.getName()); // P_DISPLAYNAME
321
rNrd.setProperty(
322             new NodeProperty(P_CHECKED_IN, pHelp.createHrefValue(vrUri)) );
323         vhrNrd.setCreationDate( new Date JavaDoc() ); // P_CREATIONDATE
324
setCreationUser(vhrNrd);
325         vhrNrd.setLastModified( new Date JavaDoc() ); // P_GETLASTMODIFIED
326
vhrNrd.setContentLength( 0 ); // P_GETCONTENTLENGTH
327
vhrNrd.setETag( PropertyHelper.computeEtag(vhrUri, vhrNrd) ); // P_GETETAG
328
// vhrNrd.setName( vhrUh.getHistoryName() ); // P_DISPLAYNAME
329
vhrNrd.setName( rNrd.getName() ); // P_DISPLAYNAME
330
vhrNrd.setProperty(
331             new NodeProperty(P_VERSION_SET, pHelp.createHrefValue(vrUri)) );
332         vrNrd.setCreationDate( new Date JavaDoc() ); // P_CREATIONDATE
333
setCreationUser(vrNrd);
334         vrNrd.setLastModified( new Date JavaDoc() ); // P_GETLASTMODIFIED
335
vrNrd.setETag( PropertyHelper.computeEtag(vrUri, vrNrd)); // P_GETETAG
336
vrNrd.setProperty(
337             new NodeProperty(P_VERSION_NAME, vrUh.getVersionName()) );
338         
339         // Store changes
340
content.store( sToken, resourcePath, rNrd, null ); //revisionContent=null
341
content.store( sToken, vhrUri, vhrNrd, null ); //revisionContent=null
342
content.store( sToken, vhrUri, vrNrd, null ); //revisionContent=null
343
}
344     
345     /**
346      * Create new VCR for an existing version history.
347      * @pre existingVersionPath != null
348      *
349      * @param resourcePath the URI of the resource to version-control
350      * @param existingVersionPath the URI of the VR on which the new VCR will be based
351      * @throws SlideException
352      */

353     public void versionControl( String JavaDoc resourcePath, String JavaDoc existingVersionPath ) throws SlideException {
354         Iterator JavaDoc 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         //NodeRevisionNumber evNrn = new NodeRevisionNumber( evUh.getVersionName() );
363
NodeRevisionDescriptors rNrds = null;
364         NodeRevisionDescriptor rNrd = null;
365         //NodeRevisionDescriptors vcrNrds = null;
366
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 ) {}; // can be ignored here!
375
try {
376             evNrds = content.retrieve( sToken, existingVersionPath );
377             evNrd = content.retrieve( sToken, evNrds /*, evNrn*/ ); //existingVersionPath
378
//redirector should do the job
379
//s.t. evNrn is not required
380
}
381         catch( ObjectNotFoundException e ) {}; // can be ignored here!
382

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         // create the VCR
396
String JavaDoc vcrUri = String.valueOf(rUh);
397         String JavaDoc 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         // Set specific properties
405
vcrNrd.setLastModified( new Date JavaDoc() ); //P_GETLASTMODIFIED
406
vcrNrd.setContentLength( evNrd.getContentLength() ); // P_GETCONTENTLENGTH
407
vcrNrd.setETag( PropertyHelper.computeEtag(vcrUri, vcrNrd)); // P_GETETAG
408
vcrNrd.setContentType( evNrd.getContentType() ); // P_GETCONTENTTYPE
409
vcrNrd.setContentLanguage(evNrd.getContentLanguage()); // P_GETCONTENTLANGUAGE
410

411         String JavaDoc[] utok = vcrUh.getUriTokens();
412         
413         if (!Configuration.useBinding(nsaToken.getUri(sToken, vcrUri).getStore())) {
414             vcrNrd.setName( utok[utok.length - 1] ); // P_DISPLAYNAME
415
}
416         vcrNrd.setCreationDate( new Date JavaDoc() ); // P_CREATIONDATE
417
setCreationUser(vcrNrd);
418         vcrNrd.setProperty( new NodeProperty(P_CHECKED_IN,
419                                              pHelp.createHrefValue(evUri)) );
420         // set workspace
421
setWorkspaceProperty( vcrUri, vcrNrd );
422         
423         // store
424
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         // Set status created
431
resp.setStatus( WebdavStatus.SC_CREATED );
432     }
433     
434     /**
435      * Returns the precondition that might have been violated on an attempt to create
436      * a new VCR in a workspace for an existing version history.
437      * The following precondtions are checked:
438      * <ul>
439      * <li>&lt;DAV:cannot-add-to-existing-history&gt;</li>
440      * <li>&lt;DAV:must-be-version&gt;</li>
441      * <li>&lt;DAV:one-version-controlled-resource-per-history-per-workspace&gt;</li>
442      * </ul>
443      *
444      * @param resourcePath the path of the resource.
445      * @param resourceNrd the NodeRevisionDescriptor of the resource.
446      * @param resourceUriHandler the UriHandler of the resource.
447      * @param existingVersionPath the path of the existing version.
448      * @param existingVersionNrd the NodeRevisionDescriptor of the existing version.
449      * @param existingVersionUriHandler the UriHandler of the existing version.
450      *
451      * @return the precondition that has been violated (if any).
452      *
453      * @throws SlideException
454      */

455     public ViolatedPrecondition getVersionControlPreconditionViolation(String JavaDoc resourcePath,
456                                                                        NodeRevisionDescriptor resourceNrd,
457                                                                        UriHandler resourceUrihandler,
458                                                                        String JavaDoc 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 JavaDoc scope = resourceUrihandler.getAssociatedWorkspaceUri();
473         if( scope == null )
474             scope = UriHandler.bestMatchingScope(nsaToken.getName(), resourceUrihandler).toString();
475         String JavaDoc historyPath = existingVersionUrihandler.getAssociatedHistoryUri();
476         SearchQueryResult queryResult = searchResourcesWithGivenHistory(historyPath, scope, Integer.MAX_VALUE);
477         Iterator JavaDoc 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     /**
487      * Searches all resources in the given <code>scope</code> that have either a
488      * <code>&lt;checked-in&gt;</code> or <code>&lt;checked-in&gt;</code> property
489      * with a <code>&lt;href&gt;</code> element containing the given
490      * <code>historyPath</code>.
491      *
492      * @param historyPath the path of the history.
493      * @param scope the scope of the search.
494      *
495      * @return all matching resources.
496      *
497      * @throws ServiceAccessException
498      * @throws BadQueryException
499      */

500     protected SearchQueryResult searchResourcesWithGivenHistory(String JavaDoc historyPath, String JavaDoc scope, int maxDepth) throws ServiceAccessException, BadQueryException, VetoException {
501         
502         SlideUri slideUri = SlideUri.createWithRequestUri(
503                 this.slideContextPath, req.getRequestURI());
504         String JavaDoc absPath = slideUri.getContextPath (scope);
505         
506         Element basicSearch = getResourcesWithVersionHistoryQueryElement(absPath,
507                                                                          historyPath);
508         String JavaDoc 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     /**
522      * Returns the query document used to search all resources in the given
523      * <code>scope</code> that have either a &lt;checked-in&gt; or &lt;checked-out&gt;
524      * property with a &lt;href&gt; value containing the URI that identifies a
525      * version of the given history.
526      *
527      * @param scope the scope of the search.
528      * @param historyPath the Uri of the history.
529      *
530      * @return the query document.
531      */

532     protected Element getResourcesWithVersionHistoryQueryElement(String JavaDoc scope, String JavaDoc 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     /**
580      * Set the workspace property if needed.
581      *
582      * @param rUri the URI of the resource to set the workspace property
583      * @param rNrd the NodeRevisionDescriptor to set the workspace property
584      */

585     public void setWorkspaceProperty( String JavaDoc rUri, NodeRevisionDescriptor rNrd ) {
586         UriHandler rUh = UriHandler.getUriHandler( rUri );
587         String JavaDoc 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     /**
598      * Create the specified workspace.
599      *
600      * @param resourcePath the URI of the workspace to create
601      * @throws SlideException
602      */

603     public void mkworkspace( String JavaDoc resourcePath ) throws SlideException {
604         Iterator JavaDoc 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 ) {}; // can be ignored here!
613

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         // Set initial ws properties
629
String JavaDoc 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         // Set specific properties
637
wsNrd.setProperty(
638             new NodeProperty(P_WORKSPACE, pHelp.createHrefValue(wsUri)) );
639         wsNrd.setLastModified( new Date JavaDoc() ); //P_GETLASTMODIFIED
640
wsNrd.setContentLength( 0 ); // P_GETCONTENTLENGTH
641
wsNrd.setETag( PropertyHelper.computeEtag(wsUri, wsNrd) ); // P_GETETAG
642
if (!Configuration.useBinding(nsaToken.getUri(sToken, wsUri).getStore())) {
643             wsNrd.setName( rUh.getWorkspaceName() ); // P_DISPLAYNAME
644
}
645         wsNrd.setCreationDate( new Date JavaDoc() ); // P_CREATIONDATE
646
setCreationUser(wsNrd);
647         
648         // Create the ws resource
649
SubjectNode wsNode = new SubjectNode();
650         structure.create( sToken, wsNode, wsUri );
651         content.create( sToken, wsUri, wsNrd, null ); // revisionContent = null
652

653         // Set status created
654
resp.setStatus( WebdavStatus.SC_CREATED );
655     }
656     
657     /**
658      * Checkout a resource (for both: checkout-in-place and working-resource features).
659      * @param resourcePath the request URI
660      * @param forkOk true, if the request body contained a DAV:fork-ok element
661      * @param applyToVersion true, if the request body contained a DAV:apply-to-version element
662      * @return the URI of the created working resource, null if no resource was created
663      * @throws SlideException
664      * @throws JDOMException
665      * @throws IOException
666      * @throws PreconditionViolatedException
667      */

668     public String JavaDoc checkout( String JavaDoc resourcePath, boolean forkOk, boolean applyToVersion )
669         throws SlideException, JDOMException, IOException JavaDoc, PreconditionViolationException {
670         return checkout(resourcePath, forkOk, applyToVersion, false);
671     }
672     
673     /**
674      * Checkout a resource (for both: checkout-in-place and working-resource features).
675      * @param resourcePath the request URI
676      * @param forkOk true, if the request body contained a DAV:fork-ok element
677      * @param applyToVersion true, if the request body contained a DAV:apply-to-version element
678      * @param isAutoVersionCheckout true, if this is an implicit request due to auto-versioning
679      * @return the URI of the created working resource, null if no resource was created
680      * @throws SlideException
681      * @throws JDOMException
682      * @throws IOException
683      * @throws PreconditionViolatedException
684      */

685     public String JavaDoc checkout( String JavaDoc resourcePath, boolean forkOk, boolean applyToVersion, boolean isAutoVersionCheckout )
686         throws SlideException, JDOMException, IOException JavaDoc, 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 ); // autoUpdateUri=null
695
}
696         else {
697             return checkout( rNrds, rNrd, forkOk, applyToVersion, isAutoVersionCheckout);
698         }
699     }
700     
701     /**
702      * Checkout a resource (for both: checkout-in-place and working-resource features).
703      * @param rNrds the revision descriptors instance
704      * @param rNrd the revision descriptor instance
705      * @param forkOk true, if the request body contained a DAV:fork-ok element
706      * @param applyToVersion true, if the request body contained a DAV:apply-to-version element
707      * @return the URI of the created working resource, null if no resource was created
708      * @throws SlideException
709      * @throws JDOMException
710      * @throws IOException
711      * @throws PreconditionViolatedException
712      */

713     public String JavaDoc checkout( NodeRevisionDescriptors rNrds,
714                            NodeRevisionDescriptor rNrd, boolean forkOk, boolean applyToVersion )
715         throws SlideException, JDOMException, IOException JavaDoc, PreconditionViolationException {
716         return checkout(rNrds, rNrd, forkOk, applyToVersion, false);
717     }
718     
719     /**
720      * Checkout a resource (for both: checkout-in-place and working-resource features).
721      * Checkout a resource (for both: checkout-in-place and working-resource features).
722      * @param rNrds the revision descriptors instance
723      * @param rNrd the revision descriptor instance
724      * @param forkOk true, if the request body contained a DAV:fork-ok element
725      * @param applyToVersion true, if the request body contained a DAV:apply-to-version element
726      * @param isAutoVersionCheckout true, if this is an implicit request due to auto-versioning
727      * @return the URI of the created working resource, null if no resource was created
728      * @throws SlideException
729      * @throws JDOMException
730      * @throws IOException
731      * @throws PreconditionViolatedException
732      */

733     public String JavaDoc checkout( NodeRevisionDescriptors rNrds,
734                            NodeRevisionDescriptor rNrd, boolean forkOk, boolean applyToVersion, boolean isAutoVersionCheckout )
735         throws SlideException, JDOMException, IOException JavaDoc, PreconditionViolationException {
736         
737         //Iterator i;
738
String JavaDoc rUri = getUri( rNrds, rNrd );
739         ResourceKind rRk = AbstractResourceKind.determineResourceKind( nsaToken, rNrds, rNrd );
740         
741         if( !rRk.isSupportedMethod(req.getMethod()) ) {
742             // check precondition C_MUST_BE_CHECKED_IN
743
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             // get checked-in VR
751
NodeProperty cinProp = rNrd.getProperty( P_CHECKED_IN );
752             String JavaDoc cinHref = getElementValue((String JavaDoc)cinProp.getValue());
753             UriHandler cinUriHandler = UriHandler.getUriHandler(cinHref);
754             String JavaDoc 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             // working resource feature
760
if( applyToVersion ) {
761                 NodeRevisionContent cinNrc = content.retrieve( sToken, cinNrds, cinNrd );
762                 return checkout( cinNrds, cinNrd, cinNrc, forkOk, rUri ); // autoUpdateUri=rUri
763
}
764             
765             ViolatedPrecondition violatedPrecondition = getCheckoutPreconditionViolation(cinNrds, cinNrd, forkOk);
766             if (violatedPrecondition != null) {
767                 throw new PreconditionViolationException(violatedPrecondition, rNrds.getUri());
768             }
769             
770             //NodeRevisionDescriptors vhrNrds = content.retrieve(sToken, cinhUri);
771

772             // do the checkout
773
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             // update checked-in VR's DAV:checkout-set property
802
PropertyHelper.addHrefToProperty(cinNrd, P_CHECKOUT_SET, rUri);
803             
804             // Store changes
805
content.store( sToken, rNrds.getUri(), rNrd, null ); //revisionContent=null
806
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     /**
818      * Checkout a resource (working-resource features only).
819      * @param rNrds the revision descriptors instance associated to the version being checked-out
820      * @param rNrd the revision descriptor instance associated to the version being checked-out
821      * @param rNrc the revision content instance associated to the version being checked-out
822      * @param forkOk true, if the request body contained a DAV:fork-ok element
823      * @param autoUpdateUri the URI of the VCR that will be updated when the WR will be checked-in
824      * @return the URI of the created working resource
825      * @throws SlideException
826      * @throws JDOMException
827      * @throws IOException
828      * @throws PreconditionViolatedException
829      */

830     public String JavaDoc checkout( NodeRevisionDescriptors rNrds, NodeRevisionDescriptor rNrd, NodeRevisionContent rNrc,
831                            boolean forkOk, String JavaDoc autoUpdateUri )
832         throws SlideException, JDOMException, IOException JavaDoc, PreconditionViolationException {
833         
834         Iterator JavaDoc i;
835         Enumeration JavaDoc j;
836         String JavaDoc rUri = getUri( rNrds, rNrd );
837         ResourceKind rRk = AbstractResourceKind.determineResourceKind( nsaToken, rNrds, rNrd );
838         
839         if( !rRk.isSupportedMethod(req.getMethod()) ) {
840             // check precondition C_MUST_BE_CHECKED_IN
841
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             //String vhUri = rUh.getAssociatedHistoryUri();
851

852             ViolatedPrecondition violatedPrecondition = getCheckoutPreconditionViolation(rNrds, rNrd, forkOk);
853             if (violatedPrecondition != null) {
854                 throw new PreconditionViolationException(violatedPrecondition, rNrds.getUri());
855                 
856                 
857             }
858             
859             //NodeRevisionDescriptors vhrNrds = content.retrieve(sToken, vhUri);
860

861             // create the workingresource
862
UriHandler wrUh = UriHandler.createNextWorkingresourceUri( sToken, nsaToken, rUh );
863             String JavaDoc wrUri = String.valueOf( wrUh );
864             SubjectNode wrNode = new SubjectNode();
865             structure.create( sToken, wrNode, String.valueOf(wrUh) );
866             
867             // set WR props
868
NodeRevisionDescriptor wrNrd = new NodeRevisionDescriptor();
869             i = pHelp.createInitialProperties(WorkingImpl.getInstance(), wrUri).iterator();
870             while( i.hasNext() )
871                 wrNrd.setProperty( (NodeProperty)i.next() );
872             // content.create( sToken, wrUri, wrNrd, rNrc );
873

874             // set specific live props
875
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()); // P_GETCONTENTTYPE
886
wrNrd.setContentLength( rNrd.getContentLength() ); // P_GETCONTENTLENGTH
887
wrNrd.setContentLanguage(rNrd.getContentLanguage()); // P_GETCONTENTLANGUAGE
888
wrNrd.setLastModified( new Date JavaDoc() ); //P_GETLASTMODIFIED
889
wrNrd.setCreationDate( new Date JavaDoc() ); // P_CREATIONDATE
890
setCreationUser(wrNrd);
891             wrNrd.setETag( PropertyHelper.computeEtag(wrUri, wrNrd) ); // P_GETETAG
892

893             // set auto-update
894
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             // Copy dead properties VR -> WR
906
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             // update version's DAV:checkout-set property
915
PropertyHelper.addHrefToProperty(rNrd, P_CHECKOUT_SET, wrUri);
916             content.store( sToken, rNrds.getUri(), rNrd, null);
917             
918             // store changes
919
content.create( sToken, wrUri, wrNrd, rNrc );
920             content.store( sToken, wrUri, wrNrd, null );
921             
922             // Set status created
923
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     /**
935      * Returns the ViolatedPrecondition if one of the precondition defined for
936      * the <code>CHECKOUT</code> methods has been violated, otherwise
937      * <code>null</code>.
938      *
939      * @param cinNrds the NodeRevisionDescriptors of the VR to checkout.
940      * @param cinNrd the NodeRevisionDescriptor of the VR to checkout.
941      * @param isForkOk indicates if <code>&lt;fork-ok&gt;</code> is set in
942      * the request content.
943      *
944      * @return the ViolatedPrecondition (if any).
945      */

946     protected ViolatedPrecondition getCheckoutPreconditionViolation(NodeRevisionDescriptors cinNrds, NodeRevisionDescriptor cinNrd, boolean isForkOk) throws IllegalArgumentException JavaDoc, IOException JavaDoc, 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                 // check if the version has successors
959
Enumeration JavaDoc successors = cinNrds.getSuccessors(cinNrd.getRevisionNumber());
960                 if ( (successors != null) && successors.hasMoreElements()) {
961                     
962                     // check precondition C_CHECKOUT_OF_VERSION_WITH_DESCENDANT_IS_FORBIDDEN
963
if (E_FORBIDDEN.equals(checkoutForkElement.getName())) {
964                         return new ViolatedPrecondition(C_CHECKOUT_OF_VERSION_WITH_DESCENDANT_IS_FORBIDDEN, WebdavStatus.SC_FORBIDDEN);
965                     }
966                         
967                         // check precondition C_CHECKOUT_OF_VERSION_WITH_DESCENDANT_IS_DISCOURAGED
968
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                 // check if the version is already checked out
974
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                         // check precondition C_CHECKOUT_OF_CHECKED_OUT_VERSION_IS_FORBIDDEN
982
if (E_FORBIDDEN.equals(checkoutForkElement.getName())) {
983                             return new ViolatedPrecondition(C_CHECKOUT_OF_CHECKED_OUT_VERSION_IS_FORBIDDEN, WebdavStatus.SC_FORBIDDEN);
984                         }
985                             
986                             // check precondition C_CHECKOUT_OF_CHECKED_OUT_VERSION_IS_DISCOURAGED
987
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     /**
999      * Uncheckout the specified resource.
1000     *
1001     * @param resourcePath the path of the resource to uncheckout.
1002     */

1003    public void uncheckout(String JavaDoc resourcePath) throws SlideException, JDOMException, IOException JavaDoc, PreconditionViolationException {
1004        
1005        NodeRevisionDescriptors rNrds = content.retrieve( sToken, resourcePath );
1006        NodeRevisionDescriptor rNrd = content.retrieve( sToken, rNrds );
1007        uncheckout( rNrds, rNrd);
1008    }
1009    
1010    /**
1011     * Uncheckout the specified resource.
1012     *
1013     * @param rNrds the NodeRevisionDescriptors of the resource to uncheckout.
1014     * @param rNrd the NodeRevisionDescriptor of the resource to uncheckout.
1015     */

1016    public void uncheckout( NodeRevisionDescriptors rNrds, NodeRevisionDescriptor rNrd)
1017        throws SlideException, JDOMException, IOException JavaDoc, PreconditionViolationException {
1018        
1019        //Iterator i;
1020
String JavaDoc rUri = getUri( rNrds, rNrd );
1021        ResourceKind rRk = AbstractResourceKind.determineResourceKind( nsaToken, rNrds, rNrd );
1022        
1023        // check precondition C_MUST_BE_CHECKED_OUT_VERSION_CONTROLLED_RESOURCE
1024
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        // get checked-out VR
1035
NodeProperty coutProp = rNrd.getProperty( P_CHECKED_OUT );
1036        String JavaDoc coutHref = getElementValue((String JavaDoc)coutProp.getValue());
1037        UriHandler coutUriHandler = UriHandler.getUriHandler(coutHref);
1038        String JavaDoc 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        //NodeRevisionContent coutNrc = content.retrieve( sToken, coutNrds, coutNrd );
1043

1044        // update its DAV:checkout-set property
1045
if (!PropertyHelper.removeHrefFromProperty(coutNrd, P_CHECKOUT_SET, rUri)) {
1046            StringBuffer JavaDoc b = new StringBuffer JavaDoc("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        // update VCR to previous VR
1061
rNrd.removeProperty( P_CHECKED_OUT );
1062        update( rNrds, rNrd, coutNrds, coutNrd );
1063        
1064        // restore some live properties
1065
restoreSpecificLiveProperties( rNrds, rNrd );
1066        
1067        // Store changes
1068
content.store( sToken, rNrds.getUri(), rNrd, null ); // revisionContent=null
1069
// remove the hidden 0.0 revision
1070
content.remove( sToken, rNrds.getUri(), NodeRevisionNumber.HIDDEN_0_0 );
1071    }
1072    
1073    /**
1074     * Checkin the specified resource (for both: checkout-in-place and working-resource features).
1075     * @param resourcePath the request URI
1076     * @param forkOk true, if the request body contained a DAV:fork-ok element
1077     * @param keepCheckedOut true, if the request body contained a DAV:keep-checked-out element
1078     * @param autoVersion true, if the checkin is due to auto-versioning
1079     * @return the URI of the created version resource
1080     * @throws SlideException
1081     * @throws JDOMException
1082     * @throws IOException
1083     * @throws PreconditionViolatedException
1084     */

1085    public String JavaDoc checkin( String JavaDoc resourcePath, boolean forkOk, boolean keepCheckedOut, boolean autoVersion )
1086        throws SlideException, JDOMException, IOException JavaDoc, 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    /**
1094     * Checkin the specified resource (for both: checkout-in-place and working-resource features).
1095     * @param rNrds the revision descriptors instance
1096     * @param rNrd the revision descriptor instance
1097     * @param forkOk true, if the request body contained a DAV:fork-ok element
1098     * @param keepCheckedOut true, if the request body contained a DAV:keep-checked-out element
1099     * @param autoVersion true, if the checkin is due to auto-versioning
1100     * @return the URI of the created version resource
1101     * @throws SlideException
1102     * @throws JDOMException
1103     * @throws IOException
1104     * @throws PreconditionViolatedException
1105     */

1106    public String JavaDoc checkin( NodeRevisionDescriptors rNrds, NodeRevisionDescriptor rNrd,
1107                          boolean forkOk, boolean keepCheckedOut, boolean autoVersion )
1108        throws SlideException, JDOMException, IOException JavaDoc, PreconditionViolationException {
1109        
1110        Iterator JavaDoc i;
1111        Enumeration JavaDoc j;
1112        String JavaDoc rUri = getUri( rNrds, rNrd );
1113        ResourceKind rRk = AbstractResourceKind.determineResourceKind( nsaToken, rNrds, rNrd );
1114        
1115        if( !rRk.isSupportedMethod(req.getMethod()) ) {
1116            // check precondition C_MUST_BE_CHECKED_OUT
1117
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            // prepare auto-update
1133
NodeRevisionDescriptors autoUpdNrds = null;
1134            NodeRevisionDescriptor autoUpdNrd = null;
1135            if( autoUpdProp != null ) {
1136                Element autoUpdElm = pHelp.parsePropertyValue( (String JavaDoc)autoUpdProp.getValue() );
1137                String JavaDoc autoUpdUri = autoUpdElm.getTextTrim();
1138                autoUpdNrds = content.retrieve( sToken, autoUpdUri );
1139                autoUpdNrd = content.retrieve( sToken, autoUpdNrds );
1140            }
1141            
1142            // Retrieve VHR
1143
Element coutElm = pHelp.parsePropertyValue( (String JavaDoc)coutProp.getValue() );
1144            String JavaDoc vrUriOld = coutElm.getTextTrim();
1145            UriHandler vrUhOld = UriHandler.getUriHandler( vrUriOld );
1146            NodeRevisionNumber vrNrnOld = new NodeRevisionNumber( vrUhOld.getVersionName() );
1147            String JavaDoc vhrUri = vrUhOld.getAssociatedHistoryUri();
1148            NodeRevisionDescriptors vhrNrds = content.retrieve( sToken, vhrUri );
1149            NodeRevisionDescriptor vhrNrd = content.retrieve( sToken, vhrNrds ); //vhrUri
1150
NodeProperty vSetProp = vhrNrd.getProperty( P_VERSION_SET );
1151            
1152            // Retrieve old VR
1153
NodeRevisionDescriptor vrNrdOld =
1154                content.retrieve( sToken, vhrNrds, vrNrnOld ); // vrUriOld
1155

1156            // update the old VR's DAV:checkout-set property
1157
if (!PropertyHelper.removeHrefFromProperty(vrNrdOld, P_CHECKOUT_SET, rUri)) {
1158                StringBuffer JavaDoc b = new StringBuffer JavaDoc("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            // check preconditions
1173
ViolatedPrecondition violatedPrecondition =
1174                getCheckinPreconditionViolation( predSetProp, vhrNrds, forkOk, autoUpdNrd );
1175            if (violatedPrecondition != null) {
1176                throw new PreconditionViolationException(violatedPrecondition, rUri);
1177            }
1178            
1179            // check forking
1180
String JavaDoc forkBranch = getForkBranch(predSetProp, vhrNrds, forkOk);
1181            NodeRevisionDescriptor vrNrdNew = null;
1182            if (forkBranch != null) {
1183                // Create a new branch
1184
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                // Create new VR in the MAIN branch
1192
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            // Copy dead properties VCR --> VR-new
1200
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            // Copy specific live properties VCR/WR -> VR
1209
vrNrdNew.setContentType(rNrd.getContentType()); // P_GETCONTENTTYPE
1210
vrNrdNew.setContentLength(rNrd.getContentLength()); // P_GETCONTENTLENGTH
1211
vrNrdNew.setContentLanguage( rNrd.getContentLanguage() ); // P_GETCONTENTLANGUAGE
1212
String JavaDoc comment = (autoVersion ? "CREATED BY AUTO-VERSIONING. " : "");
1213            if( rNrd.exists(P_COMMENT) )
1214                comment = (String JavaDoc)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 JavaDoc branch = vrNrdOld.getBranchName();
1228                content.create( sToken, vhrUri, branch, vrNrdNew, rNrc );
1229            }
1230            
1231            // create new VR node
1232
String JavaDoc vrUriNew = vhrUri+"/"+vrNrdNew.getRevisionNumber().toString();
1233            UriHandler vrUhNew = UriHandler.getUriHandler( vrUriNew );
1234            SubjectNode vrNodeNew = new SubjectNode();
1235            structure.create( sToken, vrNodeNew, vrUriNew );
1236            
1237            // set specific properties
1238
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                    // retry with default (DAV:) namespace which was the
1253
// former namespace of this property
1254
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 JavaDoc() ); // P_GETLASTMODIFIED
1262
vhrNrd.setProperty( new NodeProperty(
1263                                   P_VERSION_SET, ((String JavaDoc)vSetProp.getValue())+pHelp.createHrefValue(vrUriNew)) );
1264            
1265            vrNrdNew.setName( rNrd.getName() ); // P_DISPLAYNAME
1266
vrNrdNew.setCreationDate( new Date JavaDoc() ); // P_CREATIONDATE
1267
vrNrdNew.setLastModified( new Date JavaDoc() ); // P_GETLASTMODIFIED
1268
vrNrdNew.setETag( PropertyHelper.computeEtag(vrUriNew, vrNrdNew) ); // P_GETETAG
1269
vrNrdNew.setProperty(
1270                new NodeProperty(P_VERSION_NAME, vrUhNew.getVersionName()) );
1271            vrNrdNew.setProperty(
1272                new NodeProperty(P_PREDECESSOR_SET, predSetProp.getValue()) );
1273
1274            // Store changes
1275
if( keepCheckedOut || !isWorkingResource ) {
1276                content.store( sToken, rUri, rNrd, null ); //revisionContent=null
1277
try {
1278                    // remove the hidden 0.0 revision and create new one if keepCheckedOut
1279
content.remove( sToken, rUri, NodeRevisionNumber.HIDDEN_0_0 );
1280                }
1281                catch( RevisionDescriptorNotFoundException x ) {
1282                    // the implicit CHECKOUT from COPY (auto-versioning) does not create a
1283
// backup descriptor.
1284
Domain.info( "Checkin: no backup descriptor found at "+rUri );
1285                }
1286                if( keepCheckedOut )
1287                    backupSpecificLiveProperties( rNrds, rNrd );
1288            }
1289            else {
1290                // remove the WR
1291
macro.delete( sToken, rUri );
1292            }
1293            content.store( sToken, vhrUri, vhrNrd, null ); //revisionContent=null
1294
content.store( sToken, vhrUri, vrNrdNew, null ); //revisionContent=null
1295

1296            // auto-update
1297
if( autoUpdNrd != null ) {
1298                update( autoUpdNrds, autoUpdNrd, vhrNrds, vrNrdNew );
1299            }
1300            
1301            // Set status created
1302
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        // Set the creation user
1315
String JavaDoc creationUser = ((SubjectNode)nsaToken.getSecurityHelper().getPrincipal(sToken)).getPath().lastSegment();
1316        nrd.setCreationUser(creationUser);
1317        nrd.setOwner(creationUser);
1318    }
1319    
1320    /**
1321     * Returns the ViolatedPrecondition if one of the precondition defined for
1322     * the <code>CHECKIN</code> methods has been violated, otherwise
1323     * <code>null</code>.
1324     *
1325     * @param predSetProp the <code>predecessor-set</code> NodeProperty
1326     * of the VCR to checkin.
1327     * @param vhrNrds the NodeRevisionDescriptors of the associated VHR.
1328     * @param isForkOk indicates if <code>&lt;fork-ok&gt;</code> is set in
1329     * the request content.
1330     * @param autoUpdNrd the NodeRevisionDescriptor of the VCR referenced via auto-update
1331     * if not null, indicates that a working resource is being checked-in
1332     * for which the auto-update property was set
1333     *
1334     * @return the ViolatedPrecondition (if any).
1335     */

1336    protected ViolatedPrecondition getCheckinPreconditionViolation(NodeProperty predSetProp, NodeRevisionDescriptors vhrNrds, boolean isForkOk, NodeRevisionDescriptor autoUpdNrd ) throws LinkedObjectNotFoundException, ServiceAccessException, ObjectLockedException, RevisionDescriptorNotFoundException, JDOMException, IllegalArgumentException JavaDoc, ObjectNotFoundException, AccessDeniedException, IOException JavaDoc, VetoException {
1337        SlideToken stok = sToken;
1338        
1339        ViolatedPrecondition violatedPrecondition = null;
1340        
1341        if ( (predSetProp != null) && (predSetProp.getValue() != null) ) {
1342            XMLValue predecessors = new XMLValue( (String JavaDoc)predSetProp.getValue() );
1343            
1344            Iterator JavaDoc iterator = predecessors.iterator();
1345            while (iterator.hasNext()) {
1346                String JavaDoc href = ((Element)iterator.next()).getTextTrim();
1347                if (href != null) {
1348                    
1349                    UriHandler predecessorUriHandler = UriHandler.getUriHandler( href);
1350                    
1351                    // check precondition C_VERSION_HISTORY_IS_TREE
1352
if ( !predecessorUriHandler.isVersionUri() ||
1353                        !vhrNrds.getUri().equals(predecessorUriHandler.getAssociatedHistoryUri()) ) {
1354                        return new ViolatedPrecondition(C_VERSION_HISTORY_IS_TREE, WebdavStatus.SC_FORBIDDEN);
1355                    }
1356                    
1357                    // check precondition C_CHECKIN_FORK_FORBIDDEN
1358
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 JavaDoc predecessorSuccessors = vhrNrds.getSuccessors(predecessorNrn);
1367                        if ( (predecessorSuccessors != null) &&
1368                                (predecessorSuccessors.hasMoreElements()) &&
1369                                (predecessorCheckinForkProperty.getValue() != null) ) {
1370                            
1371                            String JavaDoc 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                                // check precondition C_CHECKIN_FORK_DISCOURAGED
1378
else if (E_DISCOURAGED.equals(checkinFork) && !isForkOk ) {
1379                                return new ViolatedPrecondition(C_CHECKIN_FORK_DISCOURAGED, WebdavStatus.SC_CONFLICT);
1380                            }
1381                        }
1382                    }
1383                    
1384                    // check precondition C_NO_OVERWRITE_BY_AUTO_UPDATE
1385
if( autoUpdNrd != null ) {
1386                        NodeProperty cinProp = autoUpdNrd.getProperty( P_CHECKED_IN );
1387                        if( cinProp != null ) {
1388                            Element cinHrefElm = pHelp.parsePropertyValue( (String JavaDoc)cinProp.getValue() );
1389                            UriHandler cinUh = new UriHandler( cinHrefElm.getTextTrim() );
1390                            NodeRevisionNumber cinNrn = new NodeRevisionNumber( cinUh.getVersionName() );
1391                            if( !vhrNrds.getUri().equals(cinUh.getAssociatedHistoryUri()) ) {
1392                                // violation
1393
return new ViolatedPrecondition(C_NO_OVERWRITE_BY_AUTO_UPDATE, WebdavStatus.SC_CONFLICT);
1394                            }
1395                            if( !vhrNrds.isAncestorDescendant(cinNrn, predecessorNrn) ) {
1396                                // violation
1397
return new ViolatedPrecondition(C_NO_OVERWRITE_BY_AUTO_UPDATE, WebdavStatus.SC_CONFLICT);
1398                            }
1399                        }
1400                    }
1401                }
1402            }
1403        }
1404        return violatedPrecondition;
1405    }
1406    
1407    /**
1408     * Returns the ViolatedPrecondition if one of the precondition defined for
1409     * the <code>CHECKIN</code> methods has been violated, otherwise
1410     * <code>null</code>.
1411     *
1412     * @param predSetProp the <code>predecessor-set</code> NodeProperty
1413     * of the VCR to checkin.
1414     * @param vhrNrds the NodeRevisionDescriptors of the associated VHR.
1415     * @param isForkOk indicates if <code>&lt;fork-ok&gt;</code> is set in
1416     * the request content.
1417     *
1418     * @return the violated precondition.
1419     */

1420    protected String JavaDoc getForkBranch(NodeProperty predSetProp, NodeRevisionDescriptors vhrNrds, boolean isForkOk) throws LinkedObjectNotFoundException, ServiceAccessException, ObjectLockedException, RevisionDescriptorNotFoundException, JDOMException, IllegalArgumentException JavaDoc, ObjectNotFoundException, AccessDeniedException, IOException JavaDoc, VetoException {
1421        
1422        String JavaDoc forkBranch = null;
1423        
1424        if ( (predSetProp != null) && (predSetProp.getValue() != null) ) {
1425            XMLValue predecessors = new XMLValue( (String JavaDoc)predSetProp.getValue() );
1426            
1427            Iterator JavaDoc iterator = predecessors.iterator();
1428            if (iterator.hasNext()) {
1429                String JavaDoc 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 JavaDoc 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    /**
1455     * If the resource described by the given <code>resourceUri</code> is a
1456     * VCR this method returns the URI of the associated VR,
1457     * otherwise <code>null</code>
1458     *
1459     * @param resourceUri the URI of the resource.
1460     *
1461     * @return the URI of the associated VR.
1462     *
1463     * @throws SlideException
1464     */

1465    public String JavaDoc getUriOfAssociatedVR(String JavaDoc resourceUri) throws SlideException {
1466        return getUriOfAssociatedVR(nsaToken, sToken, content, resourceUri);
1467    }
1468    
1469    /**
1470     * Returns the URI of the resource defined by the given NodeRevisionDescriptor(s).
1471     *
1472     * @param revisionDescriptors the NodeRevisionDescriptors of the resource.
1473     * @param revisionDescriptor the NodeRevisionDescriptor of the resource.
1474     *
1475     * @return the URI of the resource.
1476     *
1477     * @throws SlideException
1478     */

1479    public String JavaDoc getUri(NodeRevisionDescriptors revisionDescriptors,
1480                         NodeRevisionDescriptor revisionDescriptor) throws SlideException {
1481        return getUri(nsaToken, sToken, content, revisionDescriptors, revisionDescriptor);
1482    }
1483    
1484    /**
1485     * Updates the VCR specified by <code>vcrPath</code> with the properties
1486     * and the content of the VR specified by the given <code>vrPath</code>.
1487     *
1488     * @param vcrUri the URI of the VCR to update.
1489     * @param vrUri the URI of the VR from which to update.
1490     *
1491     * @throws SlideException
1492     */

1493    public void update(String JavaDoc vcrUri, String JavaDoc 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); // vrUri
1500

1501        update(vcrRevisionDescriptors, vcrRevisionDescriptor, vrRevisionDescriptors, vrRevisionDescriptor);
1502    }
1503    
1504    /**
1505     * Updates the VCR specified by <code>vcrRevisionDescriptors</code> and
1506     * <code>vcrRevisionDescriptors</code> with the properties and the content
1507     * of the VR specified by the given <code>vrRevisionDescriptors</code>
1508     * and <code>vrRevisionDescriptor</code>.
1509     *
1510     * @pre (AbstractResourceKind.determineResourceKind(vrRevisionDescriptor) instanceof Version)
1511     *
1512     * @param vcrRevisionDescriptors the NodeRevisionDescriptors of the VCR to update.
1513     * @param vcrRevisionDescriptor the NodeRevisionDescriptor of the VCR to update.
1514     * @param vrRevisionDescriptors the NodeRevisionDescriptors of the VR from
1515     * which to update.
1516     * @param vrRevisionDescriptor the NodeRevisionDescriptor of the VR from
1517     * which to update.
1518     *
1519     * @throws SlideException
1520     */

1521    public void update(NodeRevisionDescriptors vcrRevisionDescriptors, NodeRevisionDescriptor vcrRevisionDescriptor, NodeRevisionDescriptors vrRevisionDescriptors, NodeRevisionDescriptor vrRevisionDescriptor) throws SlideException {
1522        
1523        // ***************************************
1524
// TODO:
1525
// 1) Preconditions; Problem: not specified formally.
1526
// ***************************************
1527

1528        //ResourceKind vrResourceKind = VersionImpl.getInstance();
1529
//ResourceKind cinvcrResourceKind = CheckedInVersionControlledImpl.getInstance();
1530
String JavaDoc vcrUri = getUri(vcrRevisionDescriptors, vcrRevisionDescriptor);
1531        Enumeration JavaDoc propertyEnum;
1532        
1533        // Remove all VCR dead properties first
1534
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        // Copy all dead properties of VR to VCR
1543
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        // update specific live properties
1552
String JavaDoc vrUri = getUri(vrRevisionDescriptors, vrRevisionDescriptor);
1553        vcrRevisionDescriptor.setProperty(new NodeProperty(P_CHECKED_IN,
1554                                                           pHelp.createHrefValue(vrUri)) );
1555        vcrRevisionDescriptor.setLastModified(new Date JavaDoc());
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        // set workspace
1562
setWorkspaceProperty( vcrUri, vcrRevisionDescriptor );
1563        
1564        // get the VR content
1565
NodeRevisionContent vrContent = content.retrieve(sToken, vrRevisionDescriptors, vrRevisionDescriptor);
1566        
1567        // store the content
1568
content.store( sToken, vcrUri, vcrRevisionDescriptor, vrContent );
1569    }
1570    
1571    /**
1572     * Backups specific live properties of the given <code>revisionDescriptor</code>
1573     * at the 0.0 revision of the NodeRevisionDescriptors of the VCR. A good idea seems to
1574     * be to backup the non-protected live properties.
1575     *
1576     * @param rNrds the NodeRevisionDescriptors of the
1577     * VCR to backup.
1578     * @param rNrd the NodeRevisionDescriptor of the
1579     * VCR to backup.
1580     *
1581     * @throws SlideException
1582     */

1583    protected void backupSpecificLiveProperties(NodeRevisionDescriptors rNrds, NodeRevisionDescriptor rNrd) throws SlideException {
1584        
1585        NodeRevisionDescriptor backupNrd =
1586            new NodeRevisionDescriptor( NodeRevisionNumber.HIDDEN_0_0, "backup", new Vector JavaDoc(), new Hashtable JavaDoc() );
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 ); // branch=null, revisionContent=null
1612
}
1613    }
1614    
1615    /**
1616     * Restores specific live properties of the given <code>revisionDescriptor</code>
1617     * from the hidden 0.0 revision of the NodeRevisionDescriptors of the VCR.
1618     *
1619     * @param rNrds the NodeRevisionDescriptors of the
1620     * VCR to restore.
1621     * @param rNrd the NodeRevisionDescriptor of the
1622     * VCR to restore.
1623     *
1624     * @throws SlideException
1625     */

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    /**
1653     * Returns the name of the element that represents the value of the
1654     * <code>&lt;auto-version&gt;</code> property of the given
1655     * <code>revisionDescriptor</code> (e.g. <code>checkout-checkin</code>).
1656     *
1657     * @param revisionDescriptor the NodeRevisionDescriptor for which to
1658     * return the value of the
1659     * <code>&lt;auto-version&gt;</code> property.
1660     *
1661     * @return the value of the <code>&lt;auto-version&gt;</code> property
1662     * of the given <code>revisionDescriptor</code>.
1663     */

1664    public String JavaDoc getAutoVersionElementName(NodeRevisionDescriptor revisionDescriptor) {
1665        
1666        String JavaDoc 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    /**
1680     * Indicates if the (VCR) reource be checked out prior to modifying it
1681     * depending on its <code>&lt;auto-version&gt;</code> property.
1682     *
1683     * @param resourceUri the URI of the resource.
1684     *
1685     * @return <code>true</code> if the resource must be checked out prior to
1686     * modifying it.
1687     *
1688     * @throws SlideException
1689     */

1690    public boolean mustCheckoutAutoVersionedVCR(String JavaDoc 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    /**
1697     * Indicates if the (VCR) reource be checked out prior to modifying it
1698     * depending on its <code>&lt;auto-version&gt;</code> property.
1699     *
1700     * @param revisionDescriptors the NodeRevisionDescriptors of the resource.
1701     * @param revisionDescriptor the NodeRevisionDescriptor of the resource.
1702     *
1703     * @return <code>true</code> if the resource must be checked out prior to
1704     * modifying it.
1705     */

1706    public boolean mustCheckoutAutoVersionedVCR(NodeRevisionDescriptors revisionDescriptors, NodeRevisionDescriptor revisionDescriptor) {
1707        
1708        String JavaDoc 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    /**
1718     * Indicates if the (VCR) reource be checked in after modifying it
1719     * depending on its <code>&lt;auto-version&gt;</code> property.
1720     *
1721     * @param slideToken the SlideToken to use.
1722     * @param resourceUri the URI of the resource.
1723     *
1724     * @return <code>true</code> if the resource must be checked in after
1725     * modifying it.
1726     *
1727     * @throws SlideException
1728     */

1729    public boolean mustCheckinAutoVersionedVCR(SlideToken slideToken, String JavaDoc 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    /**
1736     * Indicates if the (VCR) reource be checked in after modifying it
1737     * depending on its <code>&lt;auto-version&gt;</code> property.
1738     *
1739     * @param slideToken the SlideToken to use.
1740     * @param revisionDescriptors the NodeRevisionDescriptors of the resource.
1741     * @param revisionDescriptor the NodeRevisionDescriptor of the resource.
1742     *
1743     * @return <code>true</code> if the resource must be checked in after
1744     * modifying it.
1745     */

1746    public boolean mustCheckinAutoVersionedVCR(SlideToken slideToken, NodeRevisionDescriptors revisionDescriptors, NodeRevisionDescriptor revisionDescriptor)
1747        throws ServiceAccessException {
1748        
1749        boolean checkin = false;
1750        String JavaDoc 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    /**
1761     * Indicates if the resource specified by the given NodeRevisionDescriptors
1762     * is write locked. Reads all URLs in read only mode
1763     *
1764     * @param slideToken the SlideToken to use.
1765     * @param revisionDescriptors the NodeRevisionDescriptors of the resource.
1766     *
1767     * @return <code>true</code> if the resource is write locked.
1768     */

1769    public boolean isWriteLocked(SlideToken slideToken, NodeRevisionDescriptors revisionDescriptors)
1770        throws ServiceAccessException {
1771        return (getWriteLock(slideToken, revisionDescriptors) != null);
1772    }
1773    
1774    /**
1775     * Returns the write lock of the resource specified by the given
1776     * NodeRevisionDescriptors if one exists, otherwise <code>null</code>.
1777     *
1778     * @param slideToken the SlideToken to use.
1779     * @param revisionDescriptors the NodeRevisionDescriptors of the resource.
1780     *
1781     * @return the write lock of the resource.
1782     */

1783    private NodeLock getWriteLock(SlideToken slideToken, NodeRevisionDescriptors revisionDescriptors)
1784        throws ServiceAccessException {
1785        
1786        NodeLock writeLock = null;
1787        try {
1788            Enumeration JavaDoc lockEnum = lock.enumerateLocks(slideToken, revisionDescriptors.getUri());
1789            if (lockEnum != null && lockEnum.hasMoreElements()) {
1790                // there are no other types of locks beside write locks ... so take the first one if there
1791
writeLock = (NodeLock)lockEnum.nextElement();
1792            }
1793        }
1794        catch (ObjectNotFoundException e) {}
1795        catch (LockTokenNotFoundException e) {}
1796        
1797        return writeLock;
1798    }
1799    
1800    
1801    /**
1802     * Expects a String containing an XML Element like
1803     * <code>&lt;example&gt;value&lt;/example&gt;</code>
1804     * and returns the text <code>value</code> of this element.
1805     * If the String is not of the expected format, <code>null</code> is returned.
1806     *
1807     * @pre true
1808     * @post true
1809     *
1810     * @param elementString the String containing an XML Element like
1811     * <code>&lt;example&gt;value&lt;/example&gt;</code>.
1812     *
1813     * @return the text value of the Element given by the XML String.
1814     */

1815    public static String JavaDoc getElementValue(String JavaDoc elementString) {
1816        
1817        String JavaDoc text = null;
1818        Element element = getElement(elementString);
1819        if (element != null) {
1820            text = element.getText();
1821        }
1822        return text;
1823    }
1824    
1825    /**
1826     * Expects a String containing an XML Element and returns the
1827     * <code>name</code> of this element.
1828     * If the String is not of the expected format, <code>null</code> is returned.
1829     *
1830     * @pre true
1831     * @post true
1832     *
1833     * @param elementString the String containing an XML Element like
1834     * <code>&lt;example&gt;value&lt;/example&gt;</code>.
1835     *
1836     * @return the name of the Element given by the XML String.
1837     */

1838    public static String JavaDoc getElementName(String JavaDoc elementString) {
1839        
1840        String JavaDoc name = null;
1841        Element element = getElement(elementString);
1842        if (element != null) {
1843            name = element.getName();
1844        }
1845        return name;
1846    }
1847    
1848    /**
1849     * Expects a String containing at least one XML Element and returns this Element.
1850     * If the String is not of the expected format, <code>null</code> is returned.
1851     *
1852     * @pre true
1853     * @post true
1854     *
1855     * @param elementString the String containing an XML Element.
1856     *
1857     * @return the Element given by the XML String.
1858     */

1859    public static Element getElement(String JavaDoc elementString) {
1860        
1861        Element element = null;
1862        try {
1863            Document document = getSAXBuilder().build(new StringReader JavaDoc(elementString));
1864            element = document.getRootElement();
1865        }
1866        catch (JDOMException e) {}
1867        catch (Exception JavaDoc e) {
1868            e.printStackTrace();
1869        }
1870        return element;
1871    }
1872    
1873    /**
1874     * Returns the SAXBuilder used by various methods to create JDOM Documents.
1875     *
1876     * @return the SAXBuilder used to create JDOM Documents.
1877     */

1878    protected static SAXBuilder getSAXBuilder() {
1879        if (saxBuilder == null) {
1880            saxBuilder = new SAXBuilder();
1881        }
1882        return saxBuilder;
1883    }
1884    
1885    /**
1886     * Returns slide Uri determinating the NodeRevisionDescriptors and
1887     * NodeRevisionDescriptor associated with the given <code>resourcePath</code>.
1888     * If the given <code>label</code> is not <code>null</code>, and the
1889     * <code>resourcePath</code> identifies a VCR, the revision with that label
1890     * of the associated history is returned.
1891     *
1892     * @param nsaToken the NamespaceAccessToken to use.
1893     * @param sToken the SlideToken to use.
1894     * @param content the Content helper to use.
1895     * @param resourcePath the path of the resource for which to retrieve
1896     * the SlideResource.
1897     * @param label the label of the revision to return. May be
1898     * <code>null</code>.
1899     *
1900     * @return slide Uri determinating the NodeRevisionDescriptors and
1901     * NodeRevisionDescriptor associated with the given
1902     * <code>resourcePath</code>.
1903     *
1904     * @throws SlideException
1905     * @throws LabeledRevisionNotFoundException if no revision with the specified
1906     * label was found.
1907     */

1908    private static String JavaDoc getLabeledResourceUri(NamespaceAccessToken nsaToken, SlideToken sToken, Content content, String JavaDoc resourcePath, String JavaDoc 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 JavaDoc vrUri = getUriOfAssociatedVR(nsaToken, sToken, content, revisionDescriptors.getUri());
1918            UriHandler vrUriHandler = UriHandler.getUriHandler(vrUri);
1919            String JavaDoc 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    /**
1928     * If the <code>resourcePath</code> identifies a VHR, the associated revision
1929     * with the given <code>label</code> is returned. If the <code>resourcePath</code>
1930     * does not identify a VHR , <code>null</code> is returned.
1931     *
1932     * @param nsaToken the NamespaceAccessToken to use.
1933     * @param sToken the SlideToken to use.
1934     * @param content the Content helper to use.
1935     * @param historyUri the path of the resource for which to retrieve
1936     * the NRD.
1937     * @param label the label of the revision to return.
1938     *
1939     * @return the associated revision with the given <code>label</code>.
1940     *
1941     * @throws SlideException
1942     * @throws LabeledRevisionNotFoundException if no revision with the specified
1943     * label was found.
1944     */

1945    public static NodeRevisionDescriptor retrieveLabeledRevision(NamespaceAccessToken nsaToken, SlideToken sToken, Content content, String JavaDoc historyUri, String JavaDoc 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 JavaDoc labelNameSetString = null;
1960                Iterator JavaDoc versionSetIterator = versionSetValue.iterator();
1961                String JavaDoc 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 JavaDoc 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 JavaDoc e) {}
1990        }
1991        return labeledRevision;
1992    }
1993    
1994    
1995    /**
1996     * If the resource described by the given <code>resourceUri</code> is a
1997     * VCR this method returns the URI of the associated VR,
1998     * otherwise <code>null</code>
1999     *
2000     * @param nsaToken the NamespaceAccessToken to use.
2001     * @param sToken the SlideToken to use.
2002     * @param content the Content helper to use.
2003     * @param resourceUri the URI of the resource.
2004     *
2005     * @return the URI of the associated VR.
2006     *
2007     * @throws SlideException
2008     */

2009    public static String JavaDoc getUriOfAssociatedVR(NamespaceAccessToken nsaToken,
2010                                              SlideToken sToken,
2011                                              Content content,
2012                                              String JavaDoc resourceUri) throws SlideException {
2013        
2014        String JavaDoc 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 JavaDoc 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 JavaDoc e) {}
2036            }
2037        }
2038        
2039        return vrUri;
2040    }
2041    
2042    
2043    /**
2044     * Returns the URI of the resource defined by the given NodeRevisionDescriptor(s).
2045     *
2046     *
2047     * @param nsaToken the NamespaceAccessToken to use.
2048     * @param sToken the SlideToken to use.
2049     * @param content the Content helper to use.
2050     * @param revisionDescriptors the NodeRevisionDescriptors of the resource.
2051     * @param revisionDescriptor the NodeRevisionDescriptor of the resource.
2052     *
2053     * @return the URI of the resource.
2054     *
2055     * @throws SlideException
2056     */

2057    public static String JavaDoc getUri(NamespaceAccessToken nsaToken,
2058                                SlideToken sToken,
2059                                Content content,
2060                                NodeRevisionDescriptors revisionDescriptors,
2061                                NodeRevisionDescriptor revisionDescriptor) throws SlideException {
2062        
2063        StringBuffer JavaDoc uri = new StringBuffer JavaDoc();
2064        UriHandler uriHandler = UriHandler.getUriHandler(revisionDescriptors.getUri());
2065        if ( ! uriHandler.isHistoryUri() ) {
2066            // any resource
2067
uri.append(revisionDescriptors.getUri());
2068        }
2069        else {
2070            if (revisionDescriptor.getRevisionNumber().equals(NodeRevisionNumber.HIDDEN_0_0)) {
2071                // history resource
2072
uri.append(revisionDescriptors.getUri());
2073            }
2074            else {
2075                // version resource
2076
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