001/* 002 * (C) Copyright 2008 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Thierry Delprat 018 */ 019package org.nuxeo.ecm.platform.indexing.gateway.ws; 020 021import java.io.Serializable; 022import java.util.ArrayList; 023import java.util.List; 024import java.util.Map; 025import java.util.concurrent.ConcurrentHashMap; 026import java.util.concurrent.TimeUnit; 027import java.util.concurrent.locks.ReentrantLock; 028 029import javax.jws.WebMethod; 030import javax.jws.WebParam; 031import javax.jws.WebService; 032import javax.jws.soap.SOAPBinding; 033import javax.jws.soap.SOAPBinding.Style; 034 035import org.apache.commons.logging.Log; 036import org.apache.commons.logging.LogFactory; 037import org.nuxeo.common.utils.ExceptionUtils; 038import org.nuxeo.ecm.core.api.CoreSession; 039import org.nuxeo.ecm.core.api.DocumentModel; 040import org.nuxeo.ecm.core.api.IdRef; 041import org.nuxeo.ecm.core.api.IterableQueryResult; 042import org.nuxeo.ecm.core.api.PathRef; 043import org.nuxeo.ecm.core.api.security.ACL; 044import org.nuxeo.ecm.core.api.security.ACP; 045import org.nuxeo.ecm.core.query.sql.NXQL; 046import org.nuxeo.ecm.core.schema.DocumentType; 047import org.nuxeo.ecm.core.schema.SchemaManager; 048import org.nuxeo.ecm.platform.api.ws.DocumentBlob; 049import org.nuxeo.ecm.platform.api.ws.DocumentDescriptor; 050import org.nuxeo.ecm.platform.api.ws.DocumentProperty; 051import org.nuxeo.ecm.platform.api.ws.DocumentSnapshot; 052import org.nuxeo.ecm.platform.api.ws.NuxeoRemoting; 053import org.nuxeo.ecm.platform.api.ws.WsACE; 054import org.nuxeo.ecm.platform.api.ws.session.WSRemotingSession; 055import org.nuxeo.ecm.platform.audit.ws.EventDescriptorPage; 056import org.nuxeo.ecm.platform.audit.ws.ModifiedDocumentDescriptor; 057import org.nuxeo.ecm.platform.audit.ws.ModifiedDocumentDescriptorPage; 058import org.nuxeo.ecm.platform.audit.ws.WSAuditBean; 059import org.nuxeo.ecm.platform.audit.ws.api.WSAudit; 060import org.nuxeo.ecm.platform.indexing.gateway.adapter.IndexingAdapter; 061import org.nuxeo.ecm.platform.indexing.gateway.ws.api.WSIndexingGateway; 062import org.nuxeo.ecm.platform.ws.AbstractNuxeoWebService; 063import org.nuxeo.ecm.platform.ws.NuxeoRemotingBean; 064import org.nuxeo.runtime.api.Framework; 065 066/** 067 * Base class for WS beans used for external indexers. Implements most of NuxeoRemotingBean trying as hard as possible 068 * no to throw when a requested document is missing but returning empty descriptions instead so as to 069 * make external indexers not view recently deleted documents as applicative errors. 070 * 071 * @author tiry 072 */ 073@WebService(name = "WSIndexingGatewayInterface", serviceName = "WSIndexingGatewayService") 074@SOAPBinding(style = Style.DOCUMENT) 075public class WSIndexingGatewayBean extends AbstractNuxeoWebService implements WSIndexingGateway { 076 077 protected static final String ENFORCE_SYNC_PROP_NAME = "nuxeo.indexing.gateway.forceSync"; 078 079 protected static Log log = LogFactory.getLog(WSIndexingGatewayBean.class); 080 081 private static final long serialVersionUID = 4696352633818100451L; 082 083 protected transient WSAudit auditBean; 084 085 protected transient NuxeoRemoting platformRemoting; 086 087 protected IndexingAdapter adapter; 088 089 protected ConcurrentHashMap<String, ReentrantLock> sessionIdLocks = new ConcurrentHashMap<String, ReentrantLock>(); 090 091 protected Boolean enforceSync = null; 092 093 protected boolean forceSync() { 094 if (enforceSync == null) { 095 String value = Framework.getProperty(ENFORCE_SYNC_PROP_NAME, null); 096 enforceSync = false; 097 if (value != null) { 098 enforceSync = Boolean.parseBoolean(value); 099 } else { 100 enforceSync = false; 101 } 102 } 103 return enforceSync; 104 } 105 106 protected void lockSession(String sid) { 107 if (forceSync()) { 108 ReentrantLock lock = sessionIdLocks.putIfAbsent(sid, new ReentrantLock()); 109 boolean aquired = false; 110 if (lock == null) { 111 lock = sessionIdLocks.get(sid); 112 } 113 try { 114 aquired = lock.tryLock(10, TimeUnit.SECONDS); 115 } catch (InterruptedException e) { 116 ExceptionUtils.checkInterrupt(e); 117 } 118 if (!aquired) { 119 log.error("Failed to acquire lock (timeout) for sid " + sid); 120 } 121 } 122 } 123 124 protected void releaseSession(String sid) { 125 if (forceSync()) { 126 ReentrantLock lock = sessionIdLocks.get(sid); 127 if (lock != null) { 128 lock.unlock(); 129 } 130 } 131 } 132 133 protected WSAudit getWSAudit() { 134 if (auditBean == null) { 135 auditBean = new WSAuditBean(); 136 } 137 return auditBean; 138 } 139 140 protected NuxeoRemoting getWSNuxeoRemoting() { 141 if (platformRemoting == null) { 142 platformRemoting = new NuxeoRemotingBean(); 143 } 144 return platformRemoting; 145 } 146 147 protected IndexingAdapter getAdapter() { 148 if (adapter == null) { 149 adapter = Framework.getLocalService(IndexingAdapter.class); 150 } 151 return adapter; 152 } 153 154 @WebMethod 155 public DocumentDescriptor[] getChildren(@WebParam(name = "sessionId") String sessionId, 156 @WebParam(name = "uuid") String uuid) { 157 try { 158 lockSession(sessionId); 159 CoreSession session = initSession(sessionId).getDocumentManager(); 160 if (session.exists(new IdRef(uuid))) { 161 return getWSNuxeoRemoting().getChildren(sessionId, uuid); 162 } else { 163 return new DocumentDescriptor[0]; 164 } 165 } finally { 166 releaseSession(sessionId); 167 } 168 } 169 170 @WebMethod 171 public DocumentDescriptor getCurrentVersion(@WebParam(name = "sessionId") String sid, 172 @WebParam(name = "uuid") String uid) { 173 try { 174 lockSession(sid); 175 CoreSession session = initSession(sid).getDocumentManager(); 176 if (session.exists(new IdRef(uid))) { 177 return getWSNuxeoRemoting().getCurrentVersion(sid, uid); 178 } else { 179 return missingDocumentDescriptor(uid); 180 } 181 } finally { 182 releaseSession(sid); 183 } 184 } 185 186 @WebMethod 187 public DocumentDescriptor getDocument(@WebParam(name = "sessionId") String sessionId, 188 @WebParam(name = "uuid") String uuid) { 189 try { 190 lockSession(sessionId); 191 CoreSession session = initSession(sessionId).getDocumentManager(); 192 DocumentDescriptor dd; 193 if (session.exists(new IdRef(uuid))) { 194 dd = getWSNuxeoRemoting().getDocument(sessionId, uuid); 195 } else { 196 dd = missingDocumentDescriptor(uuid); 197 } 198 return getAdapter().adaptDocumentDescriptor(session, uuid, dd); 199 } finally { 200 releaseSession(sessionId); 201 } 202 } 203 204 @WebMethod 205 public WsACE[] getDocumentACL(@WebParam(name = "sessionId") String sid, @WebParam(name = "uuid") String uuid) 206 { 207 try { 208 lockSession(sid); 209 CoreSession session = initSession(sid).getDocumentManager(); 210 WsACE[] aces; 211 if (session.exists(new IdRef(uuid))) { 212 aces = getWSNuxeoRemoting().getDocumentACL(sid, uuid); 213 } else { 214 aces = new WsACE[0]; 215 } 216 return getAdapter().adaptDocumentACL(session, uuid, aces); 217 } finally { 218 releaseSession(sid); 219 } 220 } 221 222 @WebMethod 223 public WsACE[] getDocumentLocalACL(@WebParam(name = "sessionId") String sid, @WebParam(name = "uuid") String uuid) 224 { 225 try { 226 lockSession(sid); 227 CoreSession session = initSession(sid).getDocumentManager(); 228 WsACE[] aces; 229 if (session.exists(new IdRef(uuid))) { 230 aces = getWSNuxeoRemoting().getDocumentLocalACL(sid, uuid); 231 } else { 232 aces = new WsACE[0]; 233 } 234 return getAdapter().adaptDocumentLocalACL(session, uuid, aces); 235 } finally { 236 releaseSession(sid); 237 } 238 } 239 240 public DocumentBlob[] getDocumentBlobsExt(@WebParam(name = "sessionId") String sid, 241 @WebParam(name = "uuid") String uuid, @WebParam(name = "useDownloadUrl") boolean useDownloadUrl) 242 { 243 try { 244 lockSession(sid); 245 CoreSession session = initSession(sid).getDocumentManager(); 246 DocumentBlob[] blobs; 247 if (session.exists(new IdRef(uuid))) { 248 blobs = getWSNuxeoRemoting().getDocumentBlobsExt(sid, uuid, useDownloadUrl); 249 } else { 250 blobs = new DocumentBlob[0]; 251 } 252 return getAdapter().adaptDocumentBlobs(session, uuid, blobs); 253 254 } finally { 255 releaseSession(sid); 256 } 257 } 258 259 @WebMethod 260 public DocumentBlob[] getDocumentBlobs(@WebParam(name = "sessionId") String sid, 261 @WebParam(name = "uuid") String uuid) { 262 return getDocumentBlobsExt(sid, uuid, getAdapter().useDownloadUrlForBlob()); 263 } 264 265 @WebMethod 266 public DocumentProperty[] getDocumentNoBlobProperties(@WebParam(name = "sessionId") String sid, 267 @WebParam(name = "uuid") String uuid) { 268 269 try { 270 lockSession(sid); 271 CoreSession session = initSession(sid).getDocumentManager(); 272 DocumentProperty[] properties; 273 if (session.exists(new IdRef(uuid))) { 274 properties = getWSNuxeoRemoting().getDocumentNoBlobProperties(sid, uuid); 275 } else { 276 properties = new DocumentProperty[0]; 277 } 278 return getAdapter().adaptDocumentNoBlobProperties(session, uuid, properties); 279 } finally { 280 releaseSession(sid); 281 } 282 283 } 284 285 @WebMethod 286 public DocumentProperty[] getDocumentProperties(@WebParam(name = "sessionId") String sid, 287 @WebParam(name = "uuid") String uuid) { 288 try { 289 lockSession(sid); 290 CoreSession session = initSession(sid).getDocumentManager(); 291 DocumentProperty[] properties; 292 if (session.exists(new IdRef(uuid))) { 293 properties = getWSNuxeoRemoting().getDocumentProperties(sid, uuid); 294 } else { 295 properties = new DocumentProperty[0]; 296 } 297 return getAdapter().adaptDocumentProperties(session, uuid, properties); 298 } finally { 299 releaseSession(sid); 300 } 301 } 302 303 @WebMethod 304 public String[] getGroups(@WebParam(name = "sessionId") String sid, 305 @WebParam(name = "parentGroup") String parentGroup) { 306 return getWSNuxeoRemoting().getGroups(sid, parentGroup); 307 } 308 309 @WebMethod 310 public String getRepositoryName(@WebParam(name = "sessionId") String sid) { 311 return getWSNuxeoRemoting().getRepositoryName(sid); 312 } 313 314 @WebMethod 315 public DocumentDescriptor getRootDocument(@WebParam(name = "sessionId") String sessionId) { 316 try { 317 lockSession(sessionId); 318 return getWSNuxeoRemoting().getRootDocument(sessionId); 319 } finally { 320 releaseSession(sessionId); 321 } 322 } 323 324 @WebMethod 325 public String resolvePathToUUID(@WebParam(name = "sessionId") String sessionId, @WebParam(name = "path") String path) 326 { 327 try { 328 lockSession(sessionId); 329 CoreSession session = initSession(sessionId).getDocumentManager(); 330 if (session != null) { 331 PathRef pathRef = new PathRef(path); 332 if (session.exists(pathRef)) { 333 return session.getDocument(pathRef).getId(); 334 } 335 } 336 return null; 337 } finally { 338 releaseSession(sessionId); 339 } 340 } 341 342 @WebMethod 343 public UUIDPage getRecursiveChildrenUUIDsByPage(@WebParam(name = "sessionId") String sid, 344 @WebParam(name = "uuid") String uuid, @WebParam(name = "page") int page, 345 @WebParam(name = "pageSize") int pageSize) { 346 347 try { 348 lockSession(sid); 349 CoreSession session = initSession(sid).getDocumentManager(); 350 351 List<String> uuids = new ArrayList<String>(); 352 IdRef parentRef = new IdRef(uuid); 353 DocumentModel parent = session.getDocument(parentRef); 354 String path = parent.getPathAsString(); 355 356 String query = "select ecm:uuid from Document where ecm:path startswith '" + path + "' order by ecm:uuid"; 357 358 IterableQueryResult result = session.queryAndFetch(query, "NXQL"); 359 boolean hasMore = false; 360 try { 361 if (page > 1) { 362 int skip = (page - 1) * pageSize; 363 result.skipTo(skip); 364 } 365 366 for (Map<String, Serializable> record : result) { 367 uuids.add((String) record.get(NXQL.ECM_UUID)); 368 if (uuids.size() == pageSize) { 369 hasMore = true; 370 break; 371 } 372 } 373 } finally { 374 result.close(); 375 } 376 return new UUIDPage(uuids.toArray(new String[uuids.size()]), page, hasMore); 377 } finally { 378 releaseSession(sid); 379 } 380 381 } 382 383 @WebMethod 384 public String[] getRecursiveChildrenUUIDs(@WebParam(name = "sessionId") String sid, 385 @WebParam(name = "uuid") String uuid) { 386 387 try { 388 lockSession(sid); 389 CoreSession session = initSession(sid).getDocumentManager(); 390 391 List<String> uuids = new ArrayList<String>(); 392 IdRef parentRef = new IdRef(uuid); 393 DocumentModel parent = session.getDocument(parentRef); 394 String path = parent.getPathAsString(); 395 396 String query = "select ecm:uuid from Document where ecm:path startswith '" + path + "' order by ecm:uuid"; 397 398 IterableQueryResult result = session.queryAndFetch(query, "NXQL"); 399 400 try { 401 for (Map<String, Serializable> record : result) { 402 uuids.add((String) record.get(NXQL.ECM_UUID)); 403 } 404 } finally { 405 result.close(); 406 } 407 408 return uuids.toArray(new String[uuids.size()]); 409 } finally { 410 releaseSession(sid); 411 } 412 413 } 414 415 @WebMethod 416 public DocumentTypeDescriptor[] getTypeDefinitions() { 417 418 List<DocumentTypeDescriptor> result = new ArrayList<DocumentTypeDescriptor>(); 419 SchemaManager sm = Framework.getService(SchemaManager.class); 420 421 for (DocumentType dt : sm.getDocumentTypes()) { 422 result.add(new DocumentTypeDescriptor(dt)); 423 } 424 425 return result.toArray(new DocumentTypeDescriptor[result.size()]); 426 } 427 428 @WebMethod 429 public DocumentDescriptor getDocumentFromPath(@WebParam(name = "sessionId") String sessionId, 430 @WebParam(name = "path") String path) { 431 try { 432 lockSession(sessionId); 433 String uuid = resolvePathToUUID(sessionId, path); 434 if (uuid != null) { 435 return getWSNuxeoRemoting().getDocument(sessionId, uuid); 436 } else { 437 // should we return a missing document with an null uuid 438 // instead? 439 return null; 440 } 441 } finally { 442 releaseSession(sessionId); 443 } 444 } 445 446 @WebMethod 447 public DocumentDescriptor getSourceDocument(@WebParam(name = "sessionId") String sid, 448 @WebParam(name = "uuid") String uid) { 449 try { 450 lockSession(sid); 451 CoreSession session = initSession(sid).getDocumentManager(); 452 if (session.exists(new IdRef(uid))) { 453 return getWSNuxeoRemoting().getSourceDocument(sid, uid); 454 } else { 455 return missingDocumentDescriptor(uid); 456 } 457 } finally { 458 releaseSession(sid); 459 } 460 } 461 462 @WebMethod 463 public String[] getUsers(@WebParam(name = "sessionId") String sid, 464 @WebParam(name = "parentGroup") String parentGroup) { 465 return getWSNuxeoRemoting().getUsers(sid, parentGroup); 466 } 467 468 @WebMethod 469 public DocumentDescriptor[] getVersions(@WebParam(name = "sessionId") String sid, 470 @WebParam(name = "uuid") String uid) { 471 try { 472 lockSession(sid); 473 CoreSession session = initSession(sid).getDocumentManager(); 474 if (session.exists(new IdRef(uid))) { 475 return getWSNuxeoRemoting().getVersions(sid, uid); 476 } else { 477 return new DocumentDescriptor[0]; 478 } 479 } finally { 480 releaseSession(sid); 481 } 482 } 483 484 @WebMethod 485 public String[] listGroups(@WebParam(name = "sessionId") String sid, @WebParam(name = "from") int from, 486 @WebParam(name = "to") int to) { 487 return getWSNuxeoRemoting().listGroups(sid, from, to); 488 } 489 490 @WebMethod 491 public String[] listUsers(@WebParam(name = "sessionId") String sid, @WebParam(name = "from") int from, 492 @WebParam(name = "to") int to) { 493 return getWSNuxeoRemoting().listUsers(sid, from, to); 494 } 495 496 @WebMethod 497 public ModifiedDocumentDescriptor[] listModifiedDocuments(@WebParam(name = "sessionId") String sessionId, 498 @WebParam(name = "dateRangeQuery") String dateRangeQuery) { 499 return getWSAudit().listModifiedDocuments(sessionId, dateRangeQuery); 500 } 501 502 @WebMethod 503 public ModifiedDocumentDescriptorPage listModifiedDocumentsByPage(@WebParam(name = "sessionId") String sessionId, 504 @WebParam(name = "dateRangeQuery") String dateRangeQuery, @WebParam(name = "path") String path, 505 @WebParam(name = "page") int page, @WebParam(name = "pageSize") int pageSize) { 506 return getWSAudit().listModifiedDocumentsByPage(sessionId, dateRangeQuery, path, page, pageSize); 507 } 508 509 @WebMethod 510 public EventDescriptorPage listEventsByPage(@WebParam(name = "sessionId") String sessionId, 511 @WebParam(name = "dateRangeQuery") String dateRangeQuery, @WebParam(name = "page") int page, 512 @WebParam(name = "pageSize") int pageSize) { 513 return getWSAudit().listEventsByPage(sessionId, dateRangeQuery, page, pageSize); 514 } 515 516 @WebMethod 517 public EventDescriptorPage listDocumentEventsByPage(@WebParam(name = "sessionId") String sessionId, 518 @WebParam(name = "dateRangeQuery") String dateRangeQuery, @WebParam(name = "startDate") String startDate, 519 @WebParam(name = "path") String path, @WebParam(name = "page") int page, 520 @WebParam(name = "pageSize") int pageSize) { 521 return getWSAudit().listDocumentEventsByPage(sessionId, dateRangeQuery, startDate, path, page, pageSize); 522 } 523 524 @WebMethod 525 public String getRelativePathAsString(@WebParam(name = "sessionId") String sessionId, 526 @WebParam(name = "uuid") String uuid) { 527 try { 528 lockSession(sessionId); 529 CoreSession session = initSession(sessionId).getDocumentManager(); 530 if (session.exists(new IdRef(uuid))) { 531 return getWSNuxeoRemoting().getRelativePathAsString(sessionId, uuid); 532 } else { 533 return null; 534 } 535 } finally { 536 releaseSession(sessionId); 537 } 538 } 539 540 @WebMethod 541 public boolean hasPermission(@WebParam(name = "sessionId") String sid, @WebParam(name = "uuid") String uuid, 542 @WebParam(name = "permission") String permission) { 543 try { 544 lockSession(sid); 545 CoreSession session = initSession(sid).getDocumentManager(); 546 if (session.exists(new IdRef(uuid))) { 547 return getWSNuxeoRemoting().hasPermission(sid, uuid, permission); 548 } else { 549 return false; 550 } 551 } finally { 552 releaseSession(sid); 553 } 554 } 555 556 @WebMethod 557 public String uploadDocument(@WebParam(name = "sessionId") String sid, String path, String type, String[] properties) 558 { 559 try { 560 lockSession(sid); 561 return getWSNuxeoRemoting().uploadDocument(sid, path, type, properties); 562 } finally { 563 releaseSession(sid); 564 } 565 } 566 567 @WebMethod 568 public String connect(@WebParam(name = "userName") String username, @WebParam(name = "password") String password) 569 { 570 return getWSNuxeoRemoting().connect(username, password); 571 } 572 573 @WebMethod 574 public void disconnect(@WebParam(name = "sessionId") String sid) { 575 getWSNuxeoRemoting().disconnect(sid); 576 if (forceSync()) { 577 ReentrantLock lock = sessionIdLocks.get(sid); 578 if (lock != null) { 579 if (lock.isLocked()) { 580 lock.unlock(); 581 } 582 sessionIdLocks.remove(sid); 583 } 584 } 585 } 586 587 @WebMethod 588 public EventDescriptorPage queryEventsByPage(@WebParam(name = "sessionId") String sessionId, 589 @WebParam(name = "whereClause") String whereClause, @WebParam(name = "pageIndex") int page, 590 @WebParam(name = "pageSize") int pageSize) { 591 return getWSAudit().queryEventsByPage(sessionId, whereClause, page, pageSize); 592 } 593 594 @WebMethod 595 public boolean validateUserPassword(@WebParam(name = "sessionId") String sessionId, 596 @WebParam(name = "username") String username, @WebParam(name = "password") String password) 597 { 598 WSRemotingSession rs = initSession(sessionId); 599 return rs.getUserManager().checkUsernamePassword(username, password); 600 } 601 602 @WebMethod 603 public String[] getUserGroups(@WebParam(name = "sessionId") String sessionId, 604 @WebParam(name = "username") String username) { 605 WSRemotingSession rs = initSession(sessionId); 606 List<String> groups = rs.getUserManager().getPrincipal(username).getAllGroups(); 607 String[] groupArray = new String[groups.size()]; 608 groups.toArray(groupArray); 609 return groupArray; 610 } 611 612 public DocumentSnapshot getDocumentSnapshotExt(@WebParam(name = "sessionId") String sessionId, 613 @WebParam(name = "uuid") String uuid, @WebParam(name = "useDownloadUrl") boolean useDownloadUrl) 614 { 615 616 try { 617 lockSession(sessionId); 618 WSRemotingSession rs = initSession(sessionId); 619 DocumentModel doc = rs.getDocumentManager().getDocument(new IdRef(uuid)); 620 621 DocumentProperty[] props = getDocumentNoBlobProperties(sessionId, uuid); 622 DocumentBlob[] blobs = getDocumentBlobs(sessionId, uuid); 623 624 WsACE[] resACP = null; 625 626 ACP acp = doc.getACP(); 627 if (acp != null && acp.getACLs().length > 0) { 628 ACL acl = acp.getMergedACLs("MergedACL"); 629 resACP = WsACE.wrap(acl.getACEs()); 630 } 631 DocumentSnapshot ds = new DocumentSnapshot(props, blobs, doc.getPathAsString(), resACP); 632 return ds; 633 } finally { 634 releaseSession(sessionId); 635 } 636 } 637 638 @WebMethod 639 public DocumentSnapshot getDocumentSnapshot(@WebParam(name = "sessionId") String sessionId, 640 @WebParam(name = "uuid") String uuid) { 641 return getDocumentSnapshotExt(sessionId, uuid, getAdapter().useDownloadUrlForBlob()); 642 } 643 644 public ModifiedDocumentDescriptorPage listDeletedDocumentsByPage(@WebParam(name = "sessionId") String sessionId, 645 @WebParam(name = "dataRangeQuery") String dateRangeQuery, @WebParam(name = "docPath") String path, 646 @WebParam(name = "pageIndex") int page, @WebParam(name = "pageSize") int pageSize) { 647 648 return getWSAudit().listDeletedDocumentsByPage(sessionId, dateRangeQuery, path, page, pageSize); 649 } 650 651 /** 652 * Utility method to build descriptor for a document that is non longer to be found in the repository. 653 * 654 * @param uuid 655 * @return 656 */ 657 protected DocumentDescriptor missingDocumentDescriptor(String uuid) { 658 // TODO: if we have to make the API / WSDL evolve it would be nice to 659 // include an explicit attribute in DocumentDescriptor to mark missing 660 // documents 661 DocumentDescriptor dd = new DocumentDescriptor(); 662 dd.setUUID(uuid); 663 return dd; 664 } 665 666}