1 23 24 package org.apache.slide.webdav.method; 25 26 import java.io.IOException ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 30 import org.apache.slide.common.NamespaceAccessToken; 31 import org.apache.slide.common.RequestedProperties; 32 import org.apache.slide.common.SlideException; 33 import org.apache.slide.event.EventDispatcher; 34 import org.apache.slide.search.BadGatewayException; 35 import org.apache.slide.search.BadQueryException; 36 import org.apache.slide.search.InvalidQueryException; 37 import org.apache.slide.search.InvalidScopeException; 38 import org.apache.slide.search.QueryScope; 39 import org.apache.slide.search.RequestedResource; 40 import org.apache.slide.search.Search; 41 import org.apache.slide.search.SearchQuery; 42 import org.apache.slide.search.SearchQueryResult; 43 import org.apache.slide.search.basic.IBasicQuery; 44 import org.apache.slide.security.AccessDeniedException; 45 import org.apache.slide.structure.ObjectNotFoundException; 46 import org.apache.slide.structure.StructureException; 47 import org.apache.slide.util.Configuration; 48 import org.apache.slide.webdav.WebdavException; 49 import org.apache.slide.webdav.WebdavServletConfig; 50 import org.apache.slide.webdav.event.WebdavEvent; 51 import org.apache.slide.webdav.util.ComputedPropertyProvider; 52 import org.apache.slide.webdav.util.PropertyRetriever; 53 import org.apache.slide.webdav.util.PropertyRetrieverImpl; 54 import org.apache.slide.webdav.util.WebdavConstants; 55 import org.apache.slide.webdav.util.WebdavStatus; 56 import org.apache.slide.webdav.util.WebdavUtils; 57 import org.jdom.Document; 58 import org.jdom.Element; 59 import org.jdom.JDOMException; 60 import org.jdom.output.XMLOutputter; 61 62 66 public class SearchMethod extends AbstractWebdavMethod implements WebdavConstants, ReadMethod { 67 68 69 71 private SearchQuery searchQuery = null; 72 private Search searchHelper = null; 73 74 private RequestedProperties requestedProperties = null; 75 private PropertyRetriever retriever; 76 77 78 protected boolean extendedAllprop = false; 79 80 82 83 89 public SearchMethod(NamespaceAccessToken token, 90 WebdavServletConfig config) { 91 super(token, config); 92 } 93 94 99 protected void parseRequest() throws WebdavException { 100 101 searchHelper = token.getSearchHelper(); 102 retriever = new PropertyRetrieverImpl(token, slideToken, getConfig()); 103 String slidePath = null; 104 105 extendedAllprop = getBooleanInitParameter( "extendedAllprop" ); 106 107 if (Configuration.useSearch ()) { 108 try { 109 Element queryElement = getQueryElement(); 110 String grammarNamespace = queryElement.getNamespaceURI(); 111 112 int maxDepth = getConfig().getDepthLimit(); 114 115 searchQuery = searchHelper.createSearchQuery 116 (grammarNamespace, queryElement, slideToken, maxDepth, 117 new ComputedPropertyProvider(token, slideToken, 118 getSlideContextPath(), getConfig()), 119 req.getRequestURI ()); 120 121 requestedProperties = searchQuery.requestedProperties (); 122 123 if (searchQuery instanceof IBasicQuery) 124 { 125 QueryScope scope = ((IBasicQuery)searchQuery).getScope(); 126 slidePath = ((IBasicQuery)searchQuery).getSlidePath(); 127 128 token.getContentHelper().retrieve(slideToken, slidePath); 130 131 scope.setIsCollection ( 132 WebdavUtils.isCollection (token, slideToken, slidePath)); 133 } 134 } 135 catch (JDOMException e) { 136 resp.setStatus(WebdavStatus.SC_BAD_REQUEST); 137 resp.setContentType (TEXT_XML_UTF_8); 138 createErrorResult (SearchQueryResult.STATUS_BAD_QUERY, 139 e.getMessage()); 140 throw new WebdavException(WebdavStatus.SC_BAD_REQUEST); 141 } 142 catch (InvalidQueryException e) { 143 resp.setStatus(WebdavStatus.SC_UNPROCESSABLE_ENTITY); 144 resp.setContentType (TEXT_XML_UTF_8); 145 createErrorResult (SearchQueryResult.STATUS_UNPROCESSABLE_ENTITY, 146 e.getMessage()); 147 throw new WebdavException(WebdavStatus.SC_UNPROCESSABLE_ENTITY); 148 } 149 catch (BadGatewayException e) { 150 resp.setStatus(WebdavStatus.SC_BAD_GATEWAY); 151 resp.setContentType (TEXT_XML_UTF_8); 152 createErrorResult (SearchQueryResult.STATUS_BAD_GATEWAY, 153 e.getMessage()); 154 throw new WebdavException(WebdavStatus.SC_BAD_GATEWAY); 155 } 156 catch (InvalidScopeException e) { 157 resp.setStatus(WebdavStatus.SC_BAD_REQUEST); 158 resp.setContentType (TEXT_XML_UTF_8); 159 createErrorResult (SearchQueryResult.STATUS_INVALID_SCOPE, 160 e.getMessage()); 161 162 throw new WebdavException (WebdavStatus.SC_BAD_REQUEST); 163 } 164 catch (BadQueryException e) { 165 resp.setStatus(WebdavStatus.SC_BAD_REQUEST); 166 resp.setContentType (TEXT_XML_UTF_8); 167 createErrorResult (SearchQueryResult.STATUS_BAD_QUERY, 168 e.getMessage()); 169 throw new WebdavException(WebdavStatus.SC_BAD_REQUEST); 170 } 171 catch (AccessDeniedException e) { 172 173 String contextPath = getSlideContextPath(); 174 AccessDeniedException ade = new AccessDeniedException 175 (contextPath + e.getObjectUri(), 176 contextPath + e.getSubjectUri(), 177 contextPath + e.getActionUri()); 178 179 String msg = ade.getMessage(); 180 resp.setStatus(WebdavStatus.SC_FORBIDDEN); 181 resp.setContentType (TEXT_XML_UTF_8); 182 createErrorResult (SearchQueryResult.STATUS_FORBIDDEN, msg); 183 throw new WebdavException(WebdavStatus.SC_FORBIDDEN); 184 } 185 catch (ObjectNotFoundException e) { 186 resp.setStatus(WebdavStatus.SC_BAD_REQUEST); 187 resp.setContentType (TEXT_XML_UTF_8); 188 createErrorResult (SearchQueryResult.STATUS_INVALID_SCOPE, 189 "scope " + slidePath + " is invalid"); 190 191 throw new WebdavException (WebdavStatus.SC_BAD_REQUEST); 192 } 193 catch (SlideException e) { 194 e.printStackTrace(); 195 } 196 } 197 else { 198 resp.setStatus(WebdavStatus.SC_BAD_REQUEST); 199 resp.setContentType (TEXT_XML_UTF_8); 200 createErrorResult (SearchQueryResult.STATUS_BAD_QUERY, "SEARCH not implemented on this server"); 201 throw new WebdavException(WebdavStatus.SC_BAD_REQUEST); 202 } 203 } 204 205 206 213 protected void executeRequest() throws WebdavException { 214 215 SearchQueryResult result = null; 216 217 try { 218 if ( WebdavEvent.SEARCH.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(WebdavEvent.SEARCH, new WebdavEvent(this)); 219 220 resp.setContentType (TEXT_XML_UTF_8); 221 222 result = searchHelper.search (slideToken, searchQuery); 223 WebdavResult webdavResult = new WebdavResult (result, retriever); 224 resp.setStatus (webdavResult.getWebdavStatus()); 225 org.jdom.Document responseDoc = webdavResult.getWebdavResultDocument(); 226 sendResult (responseDoc); 227 } 228 229 catch (StructureException e) { 230 try { 231 resp.sendError 232 (WebdavStatus.SC_NOT_FOUND, 233 WebdavStatus.getStatusText(WebdavStatus.SC_NOT_FOUND)); 234 } catch(IOException ex) { 235 ex.printStackTrace(); 236 } 237 throw new WebdavException(WebdavStatus.SC_NOT_FOUND); 238 } catch (RuntimeException e) { 239 e.printStackTrace(); 240 resp.setStatus(getErrorCode(e)); throw new WebdavException(WebdavStatus.SC_ACCEPTED, false); 243 } catch (Exception e) { 244 resp.setStatus(getErrorCode(e)); throw new WebdavException(WebdavStatus.SC_ACCEPTED, false); } 247 } 248 249 258 private Element getQueryElement() throws WebdavException, JDOMException { 259 Element queryElement = null; 260 try 261 { 262 Document document = parseRequestContent(); Element rootElement = document.getRootElement(); 264 List children = rootElement.getChildren(); 265 if (children.size() > 0) { 266 queryElement = (Element)children.get(0); 267 } 268 return queryElement; 269 270 271 } 272 catch (IOException e) { 273 System.err.println(e.getMessage()); 274 e.printStackTrace(); 275 resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR); 276 throw new WebdavException 277 (WebdavStatus.SC_INTERNAL_SERVER_ERROR); 278 } 279 } 280 281 290 private void sendResult (org.jdom.Document responseDoc) 291 throws org.jdom.JDOMException, IOException 292 { 293 org.jdom.output.Format format = org.jdom.output.Format.getPrettyFormat(); 294 format.setIndent(XML_RESPONSE_INDENT); 295 XMLOutputter xmlWriter = new XMLOutputter (format); 296 xmlWriter.output (responseDoc, resp.getWriter()); 297 } 298 299 306 private void createErrorResult (int queryStatus, String message) { 307 SearchQueryResult result = new SearchQueryResult (); 308 result.setStatus (queryStatus); 309 result.setDescription (message); 310 result.setHref (getSlideContextPath()); 311 312 try { 313 WebdavResult webdavResult = new WebdavResult (result, retriever); 314 org.jdom.Document responseDoc = webdavResult.getWebdavResultDocument(); 315 sendResult (responseDoc); 316 } 317 catch (Exception e) {} 318 } 319 320 326 class WebdavResult { 327 328 private SearchQueryResult queryResult; 329 private org.jdom.Document responseDoc; 330 private PropertyRetriever retriever; 331 332 333 private int webdavStatus = WebdavStatus.SC_MULTI_STATUS; 334 335 345 WebdavResult (SearchQueryResult queryResult, PropertyRetriever retriever) 346 throws org.jdom.JDOMException, SlideException 347 { 348 this.queryResult = queryResult; 349 this.retriever = retriever; 350 init(); 351 } 352 353 359 int getWebdavStatus () { 360 return webdavStatus; 361 } 362 363 369 org.jdom.Document getWebdavResultDocument () { 370 return responseDoc; 371 } 372 373 380 private void init () throws org.jdom.JDOMException, SlideException { 381 382 String href = null; 383 int errorStatus = webdavStatus; 384 385 org.jdom.Element rootElement = 386 new org.jdom.Element (E_MULTISTATUS, DNSP); 387 388 responseDoc = new org.jdom.Document (rootElement); 389 390 Iterator it = queryResult.iterator(); 391 while (it.hasNext()) { 392 393 org.jdom.Element responseElement = 394 new org.jdom.Element (E_RESPONSE, DNSP); 395 396 rootElement.addContent (responseElement); 397 org.jdom.Element hrefElement = 398 new org.jdom.Element (E_HREF, DNSP); 399 400 RequestedResource resource = (RequestedResource)it.next(); 401 String internalUri = resource.getUri(); 402 403 String absUri = WebdavUtils.getAbsolutePath (internalUri, req, getConfig()); 404 405 hrefElement.addContent(absUri); 406 407 responseElement.addContent (hrefElement); 408 List propstatList= retriever.getPropertiesOfObject (requestedProperties, 409 resource, 410 getSlideContextPath(), 411 extendedAllprop); 412 Iterator iterator = propstatList.iterator(); 413 while (iterator.hasNext()) { 414 responseElement.addContent((org.jdom.Element)iterator.next()); 415 } 416 } 417 418 int status = queryResult.getStatus(); 419 if (status != SearchQueryResult.STATUS_OK) { 420 421 423 switch (status) { 424 case SearchQueryResult.STATUS_BAD_QUERY: 425 webdavStatus = WebdavStatus.SC_BAD_REQUEST; 426 errorStatus = WebdavStatus.SC_BAD_REQUEST; 427 href = queryResult.getHref(); 428 break; 429 430 case SearchQueryResult.STATUS_INVALID_SCOPE: 431 webdavStatus = WebdavStatus.SC_BAD_REQUEST; 432 errorStatus = WebdavStatus.SC_NOT_FOUND; 433 href = queryResult.getHref(); 434 break; 435 436 case SearchQueryResult.STATUS_PARTIAL_RESULT: 437 errorStatus = WebdavStatus.SC_INSUFFICIENT_STORAGE; 438 href = getSlideContextPath(); 439 break; 440 441 case SearchQueryResult.STATUS_UNPROCESSABLE_ENTITY: 442 errorStatus = WebdavStatus.SC_UNPROCESSABLE_ENTITY; 443 href = getSlideContextPath(); 444 break; 445 446 case SearchQueryResult.STATUS_BAD_GATEWAY: 447 errorStatus = WebdavStatus.SC_BAD_GATEWAY; 448 href = queryResult.getHref(); 449 break; 450 451 case SearchQueryResult.STATUS_FORBIDDEN: 452 errorStatus = WebdavStatus.SC_FORBIDDEN; 453 href = queryResult.getHref(); 454 break; 455 456 default: 457 throw new WebdavException 458 (WebdavStatus.SC_INTERNAL_SERVER_ERROR); 459 460 } 461 org.jdom.Element responseElement = 462 new org.jdom.Element (E_RESPONSE, DNSP); 463 464 org.jdom.Element hrefElement = 465 new org.jdom.Element (E_HREF, DNSP); 466 467 hrefElement.addContent (href); 468 469 org.jdom.Element statusElement = 470 new org.jdom.Element (E_STATUS, DNSP); 471 472 statusElement.addContent (getStatusText (errorStatus)); 473 responseElement.addContent (hrefElement); 474 responseElement.addContent (statusElement); 475 476 String description = queryResult.getDescription(); 477 if (description != null) { 478 org.jdom.Element responseDescriptionElement = 479 new org.jdom.Element (E_RESPONSEDESCRIPTION, 480 DNSP); 481 482 responseDescriptionElement.addContent (description); 483 responseElement.addContent (responseDescriptionElement); 484 } 485 486 if (status == SearchQueryResult.STATUS_INVALID_SCOPE) { 487 responseElement.addContent ( 488 new org.jdom.Element ("scopeerror", 489 DNSP)); 490 } 491 rootElement.addContent (responseElement); 492 } 493 } 494 495 503 private String getStatusText (int status) { 504 return "HTTP/1.1 " + status + " " 505 + WebdavStatus.getStatusText (status); 506 } 507 } 508 } 509 510 511 | Popular Tags |