1 23 24 package org.apache.slide.webdav.method; 25 26 import java.io.IOException ; 27 import java.util.Enumeration ; 28 import java.util.Iterator ; 29 30 import org.apache.slide.common.NamespaceAccessToken; 31 import org.apache.slide.common.NestedSlideException; 32 import org.apache.slide.common.ServiceAccessException; 33 import org.apache.slide.common.SlideException; 34 import org.apache.slide.content.NodeProperty; 35 import org.apache.slide.content.NodeRevisionDescriptor; 36 import org.apache.slide.content.NodeRevisionDescriptors; 37 import org.apache.slide.event.EventDispatcher; 38 import org.apache.slide.structure.ObjectNode; 39 import org.apache.slide.util.XMLValue; 40 import org.apache.slide.webdav.WebdavException; 41 import org.apache.slide.webdav.WebdavServletConfig; 42 import org.apache.slide.webdav.event.WebdavEvent; 43 import org.apache.slide.webdav.util.DeltavConstants; 44 import org.apache.slide.webdav.util.LabeledRevisionNotFoundException; 45 import org.apache.slide.webdav.util.PreconditionViolationException; 46 import org.apache.slide.webdav.util.PropertyHelper; 47 import org.apache.slide.webdav.util.VersioningHelper; 48 import org.apache.slide.webdav.util.ViolatedPrecondition; 49 import org.apache.slide.webdav.util.WebdavStatus; 50 import org.apache.slide.webdav.util.WebdavUtils; 51 import org.apache.slide.webdav.util.resourcekind.AbstractResourceKind; 52 import org.apache.slide.webdav.util.resourcekind.CheckedInVersionControlled; 53 import org.apache.slide.webdav.util.resourcekind.ResourceKind; 54 import org.apache.slide.webdav.util.resourcekind.Version; 55 import org.apache.slide.webdav.util.resourcekind.VersionControlled; 56 import org.jdom.Element; 57 import org.jdom.JDOMException; 58 59 65 public class LabelMethod extends AbstractMultistatusResponseMethod implements DeltavConstants, WriteMethod { 66 69 public static final String LABEL_MISSING = "Label missing"; 70 71 75 public static final String LABEL_MUST_CONTAIN_EITHER_ADD_SET_OR_REMOVE = 76 "Request content <label> element must contain either <" + 77 E_ADD + ">, <" + E_SET + "> or <" + E_REMOVE + ">"; 78 79 80 81 82 85 private String resourcePath; 86 87 90 protected boolean isCollection = false; 91 92 95 protected VersioningHelper versioningHelper = null; 96 97 101 protected String operation = null; 102 103 106 protected String label = null; 107 108 111 protected String labelHeader = null; 112 113 114 116 117 123 public LabelMethod(NamespaceAccessToken token, 124 WebdavServletConfig config) { 125 super(token, config); 126 } 127 128 133 protected void parseRequest() throws WebdavException { 134 versioningHelper = VersioningHelper.getVersioningHelper(slideToken, 136 token, 137 req, 138 resp, 139 config); 140 resourcePath = requestUri; 141 if (resourcePath == null) { 142 resourcePath = "/"; 143 } 144 145 labelHeader = WebdavUtils.fixTomcatHeader(requestHeaders.getLabel(), "UTF-8"); 146 147 try{ 148 Element root = parseRequestContent(DeltavConstants.E_LABEL); 149 Element current = root.getChild(DeltavConstants.E_ADD, DNSP); 150 Element operationElement = null; 151 if (current != null) { 152 operationElement = current; 153 } 154 current = root.getChild(DeltavConstants.E_SET, DNSP); 155 if ( current != null) { 156 if (operationElement != null) { 157 throw new JDOMException(LABEL_MUST_CONTAIN_EITHER_ADD_SET_OR_REMOVE); 158 } 159 operationElement = current; 160 } 161 current = root.getChild(DeltavConstants.E_REMOVE, DNSP); 162 if ( current != null) { 163 if (operationElement != null) { 164 throw new JDOMException(LABEL_MUST_CONTAIN_EITHER_ADD_SET_OR_REMOVE); 165 } 166 operationElement = current; 167 } 168 if (operationElement == null) { 169 throw new JDOMException(LABEL_MUST_CONTAIN_EITHER_ADD_SET_OR_REMOVE); 170 } 171 operation = operationElement.getName(); 172 173 Element labelName = operationElement.getChild(DeltavConstants.E_LABEL_NAME, DNSP); 174 if ( (labelName == null) || 175 (labelName.getText() == null) || 176 (labelName.getText().length() == 0) ) { 177 throw new JDOMException(LABEL_MISSING); 178 } 179 label = labelName.getText(); 180 } 181 catch (IOException e){ 182 int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR; 183 sendError( statusCode, e ); 184 throw new WebdavException( statusCode ); 185 } 186 catch (JDOMException e){ 187 int statusCode = WebdavStatus.SC_BAD_REQUEST; 188 sendError( statusCode, e ); 189 throw new WebdavException( statusCode ); 190 } 191 } 192 193 199 protected void executeRequest() throws WebdavException, IOException { 200 201 slideToken.setForceStoreEnlistment(true); 203 204 try { 206 if (isLockNull(resourcePath)) { 207 int statusCode = WebdavStatus.SC_NOT_FOUND; 208 sendError( statusCode, "lock-null resource", new Object []{resourcePath} ); 209 throw new WebdavException( statusCode ); 210 } 211 } 212 catch (ServiceAccessException e) { 213 int statusCode = getErrorCode((Exception )e); 214 sendError( statusCode, e ); 215 throw new WebdavException( statusCode ); 216 } 217 218 isCollection = isCollection(resourcePath); 219 try { 220 if ( WebdavEvent.LABEL.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(WebdavEvent.LABEL, new WebdavEvent(this)); 221 222 labelResource(resourcePath); 223 } catch (NestedSlideException nestedSlideException) { 224 if (generateMultiStatusResponse(isCollection, nestedSlideException, requestUri)) { 228 String errorMessage = generateErrorMessage(nestedSlideException); 229 resp.setStatus(WebdavStatus.SC_MULTI_STATUS); 231 try { 232 resp.setContentType(TEXT_XML_UTF_8); 233 resp.getWriter().write(errorMessage); 234 } catch(IOException ex) { 235 int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR; 237 sendError( statusCode, ex ); 238 throw new WebdavException( statusCode ); 239 } 240 } else { 241 SlideException exception = (SlideException)nestedSlideException.enumerateExceptions().nextElement(); 245 if (exception instanceof PreconditionViolationException) { 246 try { 247 sendPreconditionViolation((PreconditionViolationException)exception); 248 } catch(IOException ex) { 249 int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR; 251 sendError( statusCode, ex ); 252 throw new WebdavException( statusCode ); 253 } 254 } 255 else { 256 int statusCode = getErrorCode( exception ); 257 sendError( statusCode, exception ); 258 throw new WebdavException( statusCode ); 259 } 260 } 261 throw new WebdavException(WebdavStatus.SC_ACCEPTED, false); 266 } catch( SlideException x ) { 267 int statusCode = getErrorCode((SlideException)x); 268 sendError( statusCode, x ); 269 throw new WebdavException( statusCode ); 270 } 271 finally { 272 resp.setHeader(H_CACHE_CONTROL, NO_CACHE); 273 } 274 } 275 276 287 protected void labelResource(String resourcePath) throws NestedSlideException { 288 NestedSlideException nestedSlideException = new NestedSlideException(null); 289 try { 290 labelResource(resourcePath, getDepth(), nestedSlideException); 291 } 292 catch (WebdavException e) { 293 nestedSlideException.addException(e); 294 } 295 if ( ! nestedSlideException.isEmpty() ) { 296 throw nestedSlideException; 297 } 298 } 299 300 312 protected void labelResource(String resourcePath, int depth, NestedSlideException nestedSlideException) { 313 314 try { 315 316 if ( ! isCollection(resourcePath) ) { 317 ViolatedPrecondition violatedPrecondition = getPreconditionViolation(resourcePath); 318 if (violatedPrecondition != null) { 319 throw new PreconditionViolationException(violatedPrecondition, resourcePath); 320 } 321 322 performLabelOperation(resourcePath); 323 } 324 else if (depth > 0) { 325 326 ObjectNode currentNode = structure.retrieve(slideToken, resourcePath); 328 Enumeration childrenEnum = structure.getChildren(slideToken, currentNode); 329 if (childrenEnum != null) { 330 while (childrenEnum.hasMoreElements()) { 331 labelResource(((ObjectNode)childrenEnum.nextElement()).getUri(), depth-1, nestedSlideException); 332 } 333 } 334 } 335 } 336 catch (SlideException e) { 337 nestedSlideException.addException(e); 338 } 339 catch (JDOMException e) { 340 nestedSlideException.addException(new SlideException(e.getMessage())); 341 } 342 } 343 344 352 private void performLabelOperation(String resourcePath) throws JDOMException, SlideException { 353 354 String labelHeader = WebdavUtils.fixTomcatHeader(requestHeaders.getLabel(), "UTF-8"); 355 String labeledResourceUri = getResourceUri(resourcePath, labelHeader); 356 NodeRevisionDescriptors revisionDescriptors = 357 content.retrieve( slideToken, labeledResourceUri); 358 NodeRevisionDescriptor revisionDescriptor = 359 content.retrieve( slideToken, revisionDescriptors); 360 ResourceKind resourceKind = AbstractResourceKind.determineResourceKind(token, revisionDescriptors, revisionDescriptor); 361 if (resourceKind instanceof Version) { 362 363 if (DeltavConstants.E_REMOVE.equals(operation)) { 364 PropertyHelper.removeElementFromProperty(revisionDescriptor, 365 P_LABEL_NAME_SET, 366 E_LABEL_NAME, 367 label); 368 content.store(slideToken, revisionDescriptors.getUri(), revisionDescriptor, null); 369 } 370 371 if (DeltavConstants.E_SET.equals(operation)) { 372 try { 373 NodeRevisionDescriptor alreadyLabeledDescriptor = 374 versioningHelper.retrieveLabeledRevision(revisionDescriptors.getUri(), 375 label); 376 PropertyHelper.removeElementFromProperty(alreadyLabeledDescriptor, 377 P_LABEL_NAME_SET, 378 E_LABEL_NAME, 379 label); 380 content.store(slideToken, revisionDescriptors.getUri(), alreadyLabeledDescriptor, null); 381 } 382 catch (LabeledRevisionNotFoundException e) { 383 } 386 } 387 388 if (DeltavConstants.E_ADD.equals(operation) || 389 DeltavConstants.E_SET.equals(operation) ) { 390 PropertyHelper.addElementToProperty(revisionDescriptor, 391 P_LABEL_NAME_SET, 392 E_LABEL_NAME, 393 label); 394 content.store(slideToken, revisionDescriptors.getUri(), revisionDescriptor, null); 395 } 396 } 397 } 398 399 414 protected ViolatedPrecondition getPreconditionViolation(String resourcePath) throws SlideException { 415 416 ViolatedPrecondition violatedPrecondition = null; 417 NodeRevisionDescriptors revisionDescriptors = 418 content.retrieve( slideToken, resourcePath); 419 NodeRevisionDescriptor revisionDescriptor = 420 content.retrieve( slideToken, revisionDescriptors); 421 ResourceKind resourceKind = AbstractResourceKind.determineResourceKind(token, revisionDescriptors, revisionDescriptor); 422 423 if ( (resourceKind instanceof VersionControlled) && 425 !(resourceKind instanceof CheckedInVersionControlled) ) { 426 return new ViolatedPrecondition(DeltavConstants.C_MUST_BE_CHECKED_IN, 427 WebdavStatus.SC_CONFLICT); 428 } 429 430 if ( (resourceKind instanceof VersionControlled) && 432 (labelHeader != null) ) { 433 try { 434 versioningHelper.getLabeledResourceUri(resourcePath, labelHeader); 435 } 436 catch (LabeledRevisionNotFoundException e) { 437 return new ViolatedPrecondition(DeltavConstants.C_MUST_SELECT_VERSION_IN_HISTORY, 438 WebdavStatus.SC_CONFLICT); 439 } 440 } 441 442 try { 443 String slideResourceUri = getResourceUri(resourcePath, labelHeader); 444 revisionDescriptors = 445 content.retrieve( slideToken, slideResourceUri); 446 revisionDescriptor = 447 content.retrieve( slideToken, revisionDescriptors); 448 resourceKind = AbstractResourceKind.determineResourceKind(token, revisionDescriptors, revisionDescriptor); 449 if (resourceKind instanceof Version) { 450 451 if (DeltavConstants.E_REMOVE.equals(operation)) { 453 if ( ! hasLabel(revisionDescriptor, label) ) { 454 return new ViolatedPrecondition(DeltavConstants.C_LABEL_MUST_EXIST, 455 WebdavStatus.SC_CONFLICT); 456 } 457 } 458 459 try { 460 versioningHelper.retrieveLabeledRevision(revisionDescriptors.getUri(), label); 461 if (DeltavConstants.E_ADD.equals(operation)) { 463 return new ViolatedPrecondition(DeltavConstants.C_MUST_BE_NEW_LABEL, 464 WebdavStatus.SC_CONFLICT); 465 } 466 } 467 catch (LabeledRevisionNotFoundException e) {} 468 } 469 } 470 catch (LabeledRevisionNotFoundException e) { 471 if (DeltavConstants.E_REMOVE.equals(operation)) { 473 return new ViolatedPrecondition(DeltavConstants.C_LABEL_MUST_EXIST, 474 WebdavStatus.SC_CONFLICT); 475 } 476 } 477 478 return violatedPrecondition; 479 } 480 481 482 488 private int getDepth() throws WebdavException { 489 return requestHeaders.getDepth(0); 490 } 491 492 502 protected boolean hasLabel(NodeRevisionDescriptor revisionDescriptor, String label) { 503 504 boolean containsLabel = false; 505 NodeProperty labelNameSetProperty = revisionDescriptor.getProperty(DeltavConstants.P_LABEL_NAME_SET); 506 if ( (labelNameSetProperty != null) && (labelNameSetProperty.getValue() != null) ) { 507 try { 508 XMLValue xmlValue = new XMLValue(labelNameSetProperty.getValue().toString()); 509 Iterator iterator = xmlValue.iterator(); 510 while ( !containsLabel && iterator.hasNext()) { 511 containsLabel = label.equals(((Element)iterator.next()).getText()); 512 } 513 } 514 catch (JDOMException e) {} 515 catch (IllegalArgumentException e) {} 516 } 517 518 return containsLabel; 519 } 520 521 534 protected String getResourceUri(String resourcePath, String label) throws SlideException { 535 536 String labeledResourceUri = versioningHelper.getLabeledResourceUri(resourcePath, 537 label); 538 NodeRevisionDescriptors revisionDescriptors = 539 content.retrieve( slideToken,labeledResourceUri); 540 NodeRevisionDescriptor revisionDescriptor = 541 content.retrieve( slideToken, revisionDescriptors); 542 ResourceKind resourceKind = AbstractResourceKind.determineResourceKind(token, revisionDescriptors, revisionDescriptor); 543 if (resourceKind instanceof VersionControlled) { 544 labeledResourceUri = versioningHelper.getUriOfAssociatedVR(resourcePath); 545 } 546 547 return labeledResourceUri; 548 } 549 550 } 551 552 553 | Popular Tags |