Changeset 5549 for ComponentRegistry/trunk/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestService.java
- Timestamp:
- 08/11/14 16:07:55 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
ComponentRegistry/trunk/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestService.java
r4681 r5549 2 2 3 3 import clarin.cmdi.componentregistry.AllowedAttributetypesXML; 4 import clarin.cmdi.componentregistry.AuthenticationFailException; 4 5 import clarin.cmdi.componentregistry.ComponentRegistry; 5 6 import clarin.cmdi.componentregistry.ComponentRegistryException; 6 7 import clarin.cmdi.componentregistry.ComponentRegistryFactory; 7 import clarin.cmdi.componentregistry.ComponentStatus;8 8 import clarin.cmdi.componentregistry.DeleteFailedException; 9 import clarin.cmdi.componentregistry.ItemNotFoundException; 9 10 import clarin.cmdi.componentregistry.MDMarshaller; 10 import clarin.cmdi.componentregistry. Owner;11 import clarin.cmdi.componentregistry.RegistrySpace; 11 12 import clarin.cmdi.componentregistry.UserCredentials; 12 13 import clarin.cmdi.componentregistry.UserUnauthorizedException; … … 45 46 import javax.servlet.ServletContext; 46 47 import javax.servlet.http.HttpServletRequest; 48 import javax.servlet.http.HttpServletResponse; 47 49 import javax.ws.rs.Consumes; 48 50 import javax.ws.rs.DELETE; … … 72 74 73 75 /** 74 * Handles CRUD operations on {@link ComponentDescription}, {@link ProfileDescription} and {@link Comment}s 76 * Handles CRUD operations on 77 * {@link ComponentDescription}, {@link ProfileDescription} and {@link Comment}s 78 * 75 79 * @author twago@mpi.nl 76 80 * @author olsha@mpi.nl … … 80 84 @Path("/registry") 81 85 @Service 82 @Transactional(rollbackFor = {Exception.class, ValidationException.class})86 @Transactional(rollbackFor = {Exception.class, ValidationException.class}) 83 87 public class ComponentRegistryRestService implements 84 IComponentRegistryRestService { 85 86 private final static Logger LOG = LoggerFactory 87 .getLogger(IComponentRegistryRestService.class); 88 @Context 89 private UriInfo uriInfo; 90 @Context 91 private SecurityContext security; 92 @Context 93 private HttpServletRequest request; 94 @Context 95 private ServletContext servletContext; 96 @InjectParam(value = "componentRegistryFactory") 97 private ComponentRegistryFactory componentRegistryFactory; 98 @InjectParam(value = "mdMarshaller") 99 private MDMarshaller marshaller; 100 101 @Autowired 102 private GroupService groupService; 103 104 /** 105 * Converts userspace boolean to component status. Temporary solution!!! 106 * 107 * TODO: Replace all calls to getRegistry that use this by calls using 108 * ComponentStatus 109 * 110 * 111 * 112 * @param userSpace 113 * @return 114 * @deprecated All calls should go directly to 115 * {@link #getRegistry(clarin.cmdi.componentregistry.ComponentStatus)} 116 */ 117 @Deprecated 118 private static ComponentStatus getStatus(boolean userSpace) { 119 if (userSpace) { 120 return ComponentStatus.PRIVATE; 121 } else { 122 return ComponentStatus.PUBLISHED; 123 } 124 } 125 126 private ComponentRegistry getRegistry(ComponentStatus status) { 127 Principal userPrincipal = security.getUserPrincipal(); 128 UserCredentials userCredentials = getUserCredentials(userPrincipal); 129 return getRegistry(status, null, userCredentials); 130 } 131 132 private ComponentRegistry getRegistry(ComponentStatus status, Owner owner, 133 UserCredentials userCredentials) { 134 try { 135 return componentRegistryFactory.getComponentRegistry(status, owner, 136 userCredentials); 137 } catch (UserUnauthorizedException uuEx) { 138 LOG.warn("Unauthorized access to {} registry by user {}", status, 139 userCredentials); 140 LOG.debug("Details for unauthorized access", uuEx); 141 throw new WebApplicationException(uuEx, Status.UNAUTHORIZED); 142 } 143 } 144 145 /** 146 * 147 * @return Principal of current request 148 * @throws IllegalArgumentException 149 * If no user principal found 150 */ 151 private Principal checkAndGetUserPrincipal() 152 throws UserUnauthorizedException { 153 Principal principal = security.getUserPrincipal(); 154 if (principal == null) { 155 throw new UserUnauthorizedException("no user principal found."); 156 } 157 return principal; 158 } 159 160 private UserCredentials getUserCredentials(Principal userPrincipal) { 161 UserCredentials userCredentials = null; 162 if (userPrincipal != null) { 163 userCredentials = new UserCredentials(userPrincipal); 164 } 165 return userCredentials; 166 } 167 168 @Override 169 @GET 170 @Path("/components") 171 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 172 MediaType.APPLICATION_JSON }) 173 public List<ComponentDescription> getRegisteredComponents( 174 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace, 175 @QueryParam(GROUPID_PARAM) String groupId) 176 throws ComponentRegistryException { 177 long start = System.currentTimeMillis(); 178 179 List<ComponentDescription> components = null; 180 ComponentRegistry cr = getRegistry(getStatus(userspace)); 181 if (groupId == null||groupId.isEmpty()) 182 components = cr.getComponentDescriptions(); 183 else { 184 Principal principal = security.getUserPrincipal(); 185 UserCredentials credentials = getUserCredentials(principal); 186 components = cr.getComponentDescriptionsInGroup(principal.getName(), groupId); 187 188 } 189 LOG.debug( 190 "Releasing {} registered components into the world ({} millisecs)", 191 components.size(), (System.currentTimeMillis() - start)); 192 return components; 193 } 194 195 @Override 196 @GET 197 @Path("/profiles") 198 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 199 MediaType.APPLICATION_JSON }) 200 public List<ProfileDescription> getRegisteredProfiles( 201 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace, 202 @QueryParam(METADATA_EDITOR_PARAM) @DefaultValue("false") boolean metadataEditor, 203 @QueryParam(GROUPID_PARAM) String groupId 204 ) 205 throws ComponentRegistryException { 206 long start = System.currentTimeMillis(); 207 208 List<ProfileDescription> profiles; 209 ComponentRegistry cr = getRegistry(getStatus(userspace)); 210 if (metadataEditor) { 211 if (groupId == null || groupId.isEmpty()) 212 profiles = cr.getProfileDescriptionsForMetadaEditor(); 213 else 214 profiles = cr.getProfileDescriptionsForMetadaEditor(groupId); 215 } else { 216 if (groupId == null || groupId.isEmpty()) 217 profiles = cr.getProfileDescriptions(); 218 else 219 profiles = cr.getProfileDescriptionsInGroup(groupId); 220 } 221 222 LOG.debug( 223 "Releasing {} registered profiles into the world ({} millisecs)", 224 profiles.size(), (System.currentTimeMillis() - start)); 225 return profiles; 226 } 227 228 @Override 229 @GET 230 @Path("/components/{componentId}") 231 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 232 MediaType.APPLICATION_JSON }) 233 public Response getRegisteredComponent( 234 @PathParam("componentId") String componentId, 235 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace 236 ) 237 throws ComponentRegistryException { 238 LOG.debug("Component with id: {} is requested.", componentId); 239 CMDComponentSpec mdComponent = getRegistry(getStatus(userspace)) 240 .getMDComponent(componentId); 241 if (mdComponent == null) { 242 return Response.status(Status.NOT_FOUND).build(); 243 } else { 244 return Response.ok(mdComponent).build(); 245 } 246 } 247 248 @Override 249 @GET 250 @Path("/components/{componentId}/{rawType}") 251 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML }) 252 public Response getRegisteredComponentRawType( 253 @PathParam("componentId") final String componentId, 254 @PathParam("rawType") String rawType) { 255 LOG.debug("Component with id: {} and rawType: {} is requested.", 256 componentId, rawType); 257 StreamingOutput result = null; 258 try { 259 final ComponentRegistry registry = findRegistry(componentId, 260 new ComponentClosure()); 261 if (registry == null) { 262 return Response 263 .status(Status.NOT_FOUND) 264 .entity("Id: " + componentId 265 + " is not registered, cannot create data.") 266 .build(); 267 } 268 ComponentDescription desc = registry 269 .getComponentDescription(componentId); 270 checkAndThrowDescription(desc, componentId); 271 String fileName = desc.getName() + "." + rawType; 272 if ("xml".equalsIgnoreCase(rawType)) { 273 result = new StreamingOutput() { 274 @Override 275 public void write(OutputStream output) throws IOException, 276 WebApplicationException { 277 try { 278 registry.getMDComponentAsXml(componentId, output); 279 } catch (ComponentRegistryException e) { 280 LOG.warn("Could not retrieve component {}", 281 componentId); 282 LOG.debug("Details", e); 283 throw new WebApplicationException(e, Response 284 .serverError() 285 .status(Status.INTERNAL_SERVER_ERROR) 286 .build()); 287 } 288 } 289 }; 290 } else if ("xsd".equalsIgnoreCase(rawType)) { 291 result = new StreamingOutput() { 292 @Override 293 public void write(OutputStream output) throws IOException, 294 WebApplicationException { 295 try { 296 registry.getMDComponentAsXsd(componentId, output); 297 } catch (ComponentRegistryException e) { 298 LOG.warn("Could not retrieve component {}", 299 componentId); 300 LOG.debug("Details", e); 301 throw new WebApplicationException(e, Response 302 .serverError() 303 .status(Status.INTERNAL_SERVER_ERROR) 304 .build()); 305 } 306 307 } 308 }; 309 } else { 310 throw new WebApplicationException(Response 311 .serverError() 312 .entity("unsupported rawType: " + rawType 313 + " (only xml or xsd are supported)").build()); 314 } 315 return createDownloadResponse(result, fileName); 316 } catch (ComponentRegistryException e) { 317 LOG.warn("Could not retrieve component {}", componentId); 318 LOG.debug("Details", e); 319 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 320 .build(); 321 } 322 } 323 324 @Override 325 public ComponentRegistry findRegistry(String id, 326 RegistryClosure<? extends BaseDescription> clos) 327 throws ComponentRegistryException { 328 BaseDescription desc = null; 329 ComponentRegistry result = getRegistry(getStatus(false)); 330 desc = clos.getDescription(result, id); 331 if (desc == null) { 332 List<ComponentRegistry> userRegs = componentRegistryFactory 333 .getAllUserRegistries(); 334 for (ComponentRegistry reg : userRegs) { 335 desc = clos.getDescription(reg, id); 336 if (desc != null) { 337 result = reg; 338 break; 339 } 340 } 341 } 342 return result; 343 } 344 345 @Override 346 @GET 347 @Path("/profiles/{profileId}") 348 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 349 MediaType.APPLICATION_JSON }) 350 public Response getRegisteredProfile( 351 @PathParam("profileId") String profileId, 352 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) 353 throws ComponentRegistryException { 354 LOG.debug("Profile with id {} is requested.", profileId); 355 CMDComponentSpec mdProfile = getRegistry(getStatus(userspace)) 356 .getMDProfile(profileId); 357 if (mdProfile == null) { 358 return Response.status(Status.NOT_FOUND).build(); 359 } else { 360 return Response.ok(mdProfile).build(); 361 } 362 } 363 364 @Override 365 @GET 366 @Path("/components/usage/{componentId}") 367 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 368 MediaType.APPLICATION_JSON }) 369 public List<BaseDescription> getComponentUsage( 370 @PathParam("componentId") String componentId, 371 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) 372 throws ComponentRegistryException { 373 try { 374 final long start = System.currentTimeMillis(); 375 ComponentRegistry registry = getRegistry(getStatus(userspace)); 376 List<ComponentDescription> components = registry 377 .getUsageInComponents(componentId); 378 List<ProfileDescription> profiles = registry 379 .getUsageInProfiles(componentId); 380 381 LOG.debug( 382 "Found {} components and {} profiles that use component {} ({} millisecs)", 383 components.size(), profiles.size(), componentId, 384 (System.currentTimeMillis() - start)); 385 386 List<BaseDescription> usages = new ArrayList<BaseDescription>( 387 components.size() + profiles.size()); 388 usages.addAll(components); 389 usages.addAll(profiles); 390 391 return usages; 392 } catch (ComponentRegistryException e) { 393 LOG.warn("Could not retrieve profile usage {}", componentId); 394 LOG.debug("Details", e); 395 throw e; 396 } 397 } 398 399 @Override 400 @GET 401 @Path("/profiles/{profileId}/comments") 402 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 403 MediaType.APPLICATION_JSON }) 404 public List<Comment> getCommentsFromProfile( 405 @PathParam("profileId") String profileId, 406 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) 407 throws ComponentRegistryException { 408 long start = System.currentTimeMillis(); 409 final Principal principal = security.getUserPrincipal(); 410 List<Comment> comments = getRegistry(getStatus(userspace)) 411 .getCommentsInProfile(profileId, principal); 412 LOG.debug( 413 "Releasing {} registered comments in profile into the world ({} millisecs)", 414 comments.size(), (System.currentTimeMillis() - start)); 415 return comments; 416 } 417 418 @Override 419 @GET 420 @Path("/components/{componentId}/comments") 421 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 422 MediaType.APPLICATION_JSON }) 423 public List<Comment> getCommentsFromComponent( 424 @PathParam("componentId") String componentId, 425 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) 426 throws ComponentRegistryException { 427 long start = System.currentTimeMillis(); 428 final Principal principal = security.getUserPrincipal(); 429 List<Comment> comments = getRegistry(getStatus(userspace)) 430 .getCommentsInComponent(componentId, principal); 431 LOG.debug( 432 "Releasing {} registered comments in Component into the world ({} millisecs)", 433 comments.size(), (System.currentTimeMillis() - start)); 434 return comments; 435 } 436 437 @Override 438 @GET 439 @Path("/profiles/{profileId}/comments/{commentId}") 440 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 441 MediaType.APPLICATION_JSON }) 442 public Comment getSpecifiedCommentFromProfile( 443 @PathParam("profileId") String profileId, 444 @PathParam("commentId") String commentId, 445 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) 446 throws ComponentRegistryException { 447 LOG.debug("Comments of profile with id {} are requested.", commentId); 448 final Principal principal = security.getUserPrincipal(); 449 return getRegistry(getStatus(userspace)).getSpecifiedCommentInProfile( 450 profileId, commentId, principal); 451 } 452 453 @Override 454 @GET 455 @Path("/components/{componentId}/comments/{commentId}") 456 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 457 MediaType.APPLICATION_JSON }) 458 public Comment getSpecifiedCommentFromComponent( 459 @PathParam("componentId") String componentId, 460 @PathParam("commentId") String commentId, 461 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) 462 throws ComponentRegistryException { 463 LOG.debug("Comments of component with id {} are requested.", commentId); 464 final Principal principal = security.getUserPrincipal(); 465 return getRegistry(getStatus(userspace)) 466 .getSpecifiedCommentInComponent(componentId, commentId, 467 principal); 468 } 469 470 /** 471 * 472 * Purely helper method for my front-end (FLEX) which only does post/get 473 * requests. The query param is checked and the "proper" method is called. 474 * 475 * @param profileId 476 * @param method 477 * @return 478 */ 479 @Override 480 @POST 481 @Path("/profiles/{profileId}") 482 public Response manipulateRegisteredProfile( 483 @PathParam("profileId") String profileId, 484 @FormParam("method") String method, 485 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) { 486 if ("delete".equalsIgnoreCase(method)) { 487 return deleteRegisteredProfile(profileId, userspace); 488 } else { 489 return Response.ok().build(); 490 } 491 } 492 493 @Override 494 @POST 495 @Path("/profiles/{profileId}/comments/{commentId}") 496 public Response manipulateCommentFromProfile( 497 @PathParam("profileId") String profileId, 498 @PathParam("commentId") String commentId, 499 @FormParam("method") String method, 500 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) { 501 if ("delete".equalsIgnoreCase(method)) { 502 return deleteCommentFromProfile(profileId, commentId, userspace); 503 } else { 504 return Response.ok().build(); 505 } 506 } 507 508 @Override 509 @POST 510 @Path("/components/{componentId}/comments/{commentId}") 511 public Response manipulateCommentFromComponent( 512 @PathParam("componentId") String componentId, 513 @PathParam("commentId") String commentId, 514 @FormParam("method") String method, 515 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) { 516 if ("delete".equalsIgnoreCase(method)) { 517 return deleteCommentFromComponent(componentId, commentId, userspace); 518 } else { 519 return Response.ok().build(); 520 } 521 } 522 523 @Override 524 @POST 525 @Path("/profiles/{profileId}/publish") 526 @Consumes("multipart/form-data") 527 public Response publishRegisteredProfile( 528 @PathParam("profileId") String profileId, 529 @FormDataParam(DATA_FORM_FIELD) InputStream input, 530 @FormDataParam(NAME_FORM_FIELD) String name, 531 @FormDataParam(DESCRIPTION_FORM_FIELD) String description, 532 @FormDataParam(GROUP_FORM_FIELD) String group, 533 @FormDataParam(DOMAIN_FORM_FIELD) String domainName) { 534 try { 535 Principal principal = checkAndGetUserPrincipal(); 536 ProfileDescription desc = getRegistry(getStatus(true)) 537 .getProfileDescription(profileId); 538 if (desc != null) { 539 updateDescription(desc, name, description, domainName, group); 540 return register(input, desc, getUserCredentials(principal), 541 true, new PublishAction(principal)); 542 } else { 543 LOG.error("Update of nonexistent profile {} failed.", profileId); 544 return Response 545 .serverError() 546 .entity("Invalid id, cannot update nonexistent profile") 547 .build(); 548 } 549 } catch (ComponentRegistryException e) { 550 LOG.warn("Could not retrieve profile {}", profileId); 551 LOG.debug("Details", e); 552 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 553 .build(); 554 } catch (UserUnauthorizedException ex) { 555 return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()) 556 .build(); 557 } 558 } 559 560 @Override 561 @POST 562 @Path("/profiles/{profileId}/update") 563 @Consumes("multipart/form-data") 564 public Response updateRegisteredProfile( 565 @PathParam("profileId") String profileId, 566 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace, 567 @FormDataParam(DATA_FORM_FIELD) InputStream input, 568 @FormDataParam(NAME_FORM_FIELD) String name, 569 @FormDataParam(DESCRIPTION_FORM_FIELD) String description, 570 @FormDataParam(GROUP_FORM_FIELD) String group, 571 @FormDataParam(DOMAIN_FORM_FIELD) String domainName) { 572 try { 573 Principal principal = checkAndGetUserPrincipal(); 574 UserCredentials userCredentials = getUserCredentials(principal); 575 ProfileDescription desc = getRegistry(getStatus(userspace)) 576 .getProfileDescription(profileId); 577 if (desc != null) { 578 updateDescription(desc, name, description, domainName, group); 579 return register(input, desc, userCredentials, userspace, 580 new UpdateAction(principal)); 581 } else { 582 LOG.error("Update of nonexistent id (" + profileId 583 + ") failed."); 584 return Response 585 .serverError() 586 .entity("Invalid id, cannot update nonexistent profile") 587 .build(); 588 } 589 } catch (ComponentRegistryException e) { 590 LOG.warn("Could not retrieve profile {}", profileId); 591 LOG.debug("Details", e); 592 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 593 .build(); 594 } catch (UserUnauthorizedException ex) { 595 return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()) 596 .build(); 597 } 598 599 } 600 601 /** 602 * 603 * Purely helper method for my front-end (FLEX) which van only do post/get 604 * requests. The query param is checked and the "proper" method is called. 605 * 606 * @param componentId 607 * @param method 608 * @return 609 */ 610 @Override 611 @POST 612 @Path("/components/{componentId}") 613 public Response manipulateRegisteredComponent( 614 @PathParam("componentId") String componentId, 615 @FormParam("method") String method, 616 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) { 617 if ("delete".equalsIgnoreCase(method)) { 618 return deleteRegisteredComponent(componentId, userspace); 619 } else { 620 return Response.ok().build(); 621 } 622 } 623 624 @Override 625 @POST 626 @Path("/components/{componentId}/publish") 627 @Consumes("multipart/form-data") 628 public Response publishRegisteredComponent( 629 @PathParam("componentId") String componentId, 630 @FormDataParam(DATA_FORM_FIELD) InputStream input, 631 @FormDataParam(NAME_FORM_FIELD) String name, 632 @FormDataParam(DESCRIPTION_FORM_FIELD) String description, 633 @FormDataParam(GROUP_FORM_FIELD) String group, 634 @FormDataParam(DOMAIN_FORM_FIELD) String domainName) { 635 try { 636 Principal principal = checkAndGetUserPrincipal(); 637 // TODO: Get status from parameter 638 ComponentDescription desc = getRegistry(getStatus(true)) 639 .getComponentDescription(componentId); 640 if (desc != null) { 641 updateDescription(desc, name, description, domainName, group); 642 return register(input, desc, getUserCredentials(principal), 643 true, new PublishAction(principal)); 644 } else { 645 LOG.error("Update of nonexistent id (" + componentId 646 + ") failed."); 647 return Response 648 .serverError() 649 .entity("Invalid id, cannot update nonexistent profile") 650 .build(); 651 } 652 } catch (ComponentRegistryException e) { 653 LOG.warn("Could not retrieve component {}", componentId); 654 LOG.debug("Details", e); 655 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 656 .build(); 657 } catch (UserUnauthorizedException ex) { 658 return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()) 659 .build(); 660 } 661 } 662 663 @Override 664 @POST 665 @Path("/components/{componentId}/update") 666 @Consumes("multipart/form-data") 667 public Response updateRegisteredComponent( 668 @PathParam("componentId") String componentId, 669 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace, 670 @FormDataParam(DATA_FORM_FIELD) InputStream input, 671 @FormDataParam(NAME_FORM_FIELD) String name, 672 @FormDataParam(DESCRIPTION_FORM_FIELD) String description, 673 @FormDataParam(GROUP_FORM_FIELD) String group, 674 @FormDataParam(DOMAIN_FORM_FIELD) String domainName) { 675 try { 676 Principal principal = checkAndGetUserPrincipal(); 677 ComponentDescription desc = getRegistry(getStatus(userspace)) 678 .getComponentDescription(componentId); 679 if (desc != null) { 680 updateDescription(desc, name, description, domainName, group); 681 return register(input, desc, getUserCredentials(principal), 682 userspace, new UpdateAction(principal)); 683 } else { 684 LOG.error("Update of nonexistent id (" + componentId 685 + ") failed."); 686 return Response 687 .serverError() 688 .entity("Invalid id, cannot update nonexistent component") 689 .build(); 690 } 691 } catch (ComponentRegistryException e) { 692 LOG.warn("Could not retrieve component {}", componentId); 693 LOG.debug("Details", e); 694 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 695 .build(); 696 } catch (UserUnauthorizedException ex) { 697 return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()) 698 .build(); 699 } 700 } 701 702 private void updateDescription(BaseDescription desc, String name, 703 String description, String domainName, String group) { 704 desc.setName(name); 705 desc.setDescription(description); 706 desc.setDomainName(domainName); 707 desc.setGroupName(group); 708 desc.setRegistrationDate(new Date()); 709 } 710 711 @Override 712 @DELETE 713 @Path("/components/{componentId}") 714 public Response deleteRegisteredComponent( 715 @PathParam("componentId") String componentId, 716 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) { 717 try { 718 Principal principal = checkAndGetUserPrincipal(); 719 ComponentRegistry registry = getRegistry(getStatus(userspace)); 720 LOG.debug("Component with id {} set for deletion.", componentId); 721 registry.deleteMDComponent(componentId, principal, false); 722 } catch (DeleteFailedException e) { 723 LOG.info("Component with id {} deletion failed. Reason: {}", 724 componentId, e.getMessage()); 725 LOG.debug("Deletion failure details:", e); 726 return Response.status(Status.FORBIDDEN) 727 .entity("" + e.getMessage()).build(); 728 } catch (ComponentRegistryException e) { 729 LOG.warn("Component with id " + componentId + " deletion failed.", 730 e); 731 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 732 .build(); 733 } catch (IOException e) { 734 LOG.error("Component with id " + componentId + " deletion failed.", 735 e); 736 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 737 .build(); 738 } catch (UserUnauthorizedException e) { 739 LOG.info("Component with id {} deletion failed: {}", componentId, 740 e.getMessage()); 741 LOG.debug("Deletion failure details:", e); 742 return Response.serverError().status(Status.UNAUTHORIZED) 743 .entity("" + e.getMessage()).build(); 744 } 745 LOG.info("Component with id: {} deleted.", componentId); 746 return Response.ok().build(); 747 } 748 749 @Override 750 @DELETE 751 @Path("/profiles/{profileId}") 752 public Response deleteRegisteredProfile( 753 @PathParam("profileId") String profileId, 754 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) { 755 try { 756 Principal principal = checkAndGetUserPrincipal(); 757 LOG.debug("Profile with id: {} set for deletion.", profileId); 758 getRegistry(getStatus(userspace)).deleteMDProfile(profileId, 759 principal); 760 } catch (DeleteFailedException e) { 761 LOG.info("Profile with id: {} deletion failed: {}", profileId, 762 e.getMessage()); 763 LOG.debug("Deletion failure details:", e); 764 return Response.serverError().status(Status.FORBIDDEN) 765 .entity("" + e.getMessage()).build(); 766 } catch (ComponentRegistryException e) { 767 LOG.warn("Could not retrieve component", e); 768 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 769 .build(); 770 } catch (IOException e) { 771 LOG.error("Profile with id: " + profileId + " deletion failed.", e); 772 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 773 .build(); 774 } catch (UserUnauthorizedException e) { 775 LOG.info("Profile with id: {} deletion failed: {}", profileId, 776 e.getMessage()); 777 LOG.debug("Deletion failure details:", e); 778 return Response.serverError().status(Status.UNAUTHORIZED) 779 .entity("" + e.getMessage()).build(); 780 } 781 LOG.info("Profile with id: {} deleted.", profileId); 782 return Response.ok().build(); 783 } 784 785 @Override 786 @DELETE 787 @Path("/profiles/{profileId}/comments/{commentId}") 788 public Response deleteCommentFromProfile( 789 @PathParam("profileId") String profileId, 790 @PathParam("commentId") String commentId, 791 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) { 792 try { 793 final Principal principal = checkAndGetUserPrincipal(); 794 final ComponentRegistry registry = getRegistry(getStatus(userspace)); 795 final Comment comment = registry.getSpecifiedCommentInProfile( 796 profileId, commentId, principal); 797 if (comment != null 798 && profileId.equals(comment.getComponentId())) { 799 LOG.debug("Comment with id: {} set for deletion.", commentId); 800 registry.deleteComment(commentId, principal); 801 } else { 802 throw new ComponentRegistryException( 803 "Comment not found for specified profile"); 804 } 805 } catch (DeleteFailedException e) { 806 LOG.info("Comment with id: {} deletion failed: {}", commentId, 807 e.getMessage()); 808 LOG.debug("Deletion failure details:", e); 809 return Response.serverError().status(Status.FORBIDDEN) 810 .entity("" + e.getMessage()).build(); 811 } catch (ComponentRegistryException e) { 812 LOG.info("Could not retrieve component", e); 813 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 814 .build(); 815 } catch (IOException e) { 816 LOG.error("Comment with id: " + commentId + " deletion failed.", e); 817 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 818 .build(); 819 } catch (UserUnauthorizedException e) { 820 LOG.info("Comment with id: {} deletion failed: {}", commentId, 821 e.getMessage()); 822 LOG.debug("Deletion failure details:", e); 823 return Response.serverError().status(Status.UNAUTHORIZED) 824 .entity("" + e.getMessage()).build(); 825 } 826 LOG.info("Comment with id: {} deleted.", commentId); 827 return Response.ok().build(); 828 } 829 830 @Override 831 @DELETE 832 @Path("/components/{componentId}/comments/{commentId}") 833 public Response deleteCommentFromComponent( 834 @PathParam("componentId") String componentId, 835 @PathParam("commentId") String commentId, 836 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) { 837 try { 838 final Principal principal = checkAndGetUserPrincipal(); 839 final ComponentRegistry registry = getRegistry(getStatus(userspace)); 840 final Comment comment = registry.getSpecifiedCommentInComponent( 841 componentId, commentId, principal); 842 if (comment != null 843 && componentId.equals(comment.getComponentId())) { 844 LOG.debug("Comment with id: {} set for deletion.", commentId); 845 registry.deleteComment(commentId, principal); 846 } else { 847 throw new ComponentRegistryException( 848 "Comment not found for specified component"); 849 } 850 } catch (DeleteFailedException e) { 851 LOG.info("Comment with id: {} deletion failed: {}", commentId, 852 e.getMessage()); 853 LOG.debug("Deletion failure details:", e); 854 return Response.serverError().status(Status.FORBIDDEN) 855 .entity("" + e.getMessage()).build(); 856 } catch (ComponentRegistryException e) { 857 LOG.info("Could not retrieve component", e); 858 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 859 .build(); 860 } catch (IOException e) { 861 LOG.error("Comment with id: " + commentId + " deletion failed.", e); 862 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 863 .build(); 864 } catch (UserUnauthorizedException e) { 865 LOG.info("Comment with id: {} deletion failed: {}", commentId, 866 e.getMessage()); 867 LOG.debug("Deletion failure details:", e); 868 return Response.serverError().status(Status.UNAUTHORIZED) 869 .entity("" + e.getMessage()).build(); 870 } 871 LOG.info("Comment with id: {} deleted.", commentId); 872 return Response.ok().build(); 873 } 874 875 @Override 876 @GET 877 @Path("/profiles/{profileId}/{rawType}") 878 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML }) 879 public Response getRegisteredProfileRawType( 880 @PathParam("profileId") final String profileId, 881 @PathParam("rawType") String rawType) { 882 LOG.debug("Profile with id {} and rawType {} is requested.", profileId, 883 rawType); 884 StreamingOutput result = null; 885 try { 886 final ComponentRegistry registry = findRegistry(profileId, 887 new ProfileClosure()); 888 if (registry == null) { 889 return Response 890 .status(Status.NOT_FOUND) 891 .entity("Id: " + profileId 892 + " is not registered, cannot create data.") 893 .build(); 894 } 895 ProfileDescription desc = registry.getProfileDescription(profileId); 896 checkAndThrowDescription(desc, profileId); 897 String fileName = desc.getName() + "." + rawType; 898 899 if ("xml".equalsIgnoreCase(rawType)) { 900 result = new StreamingOutput() { 901 @Override 902 public void write(OutputStream output) throws IOException, 903 WebApplicationException { 904 try { 905 registry.getMDProfileAsXml(profileId, output); 906 } catch (ComponentRegistryException e) { 907 LOG.warn("Could not retrieve component {}", 908 profileId); 909 LOG.debug("Details", e); 910 throw new WebApplicationException(e, Response 911 .serverError() 912 .status(Status.INTERNAL_SERVER_ERROR) 913 .build()); 914 } 915 } 916 }; 917 } else if ("xsd".equalsIgnoreCase(rawType)) { 918 result = new StreamingOutput() { 919 @Override 920 public void write(OutputStream output) throws IOException, 921 WebApplicationException { 922 try { 923 registry.getMDProfileAsXsd(profileId, output); 924 } catch (ComponentRegistryException e) { 925 LOG.warn("Could not retrieve component {}", 926 profileId); 927 LOG.debug("Details", e); 928 throw new WebApplicationException(e, Response 929 .serverError() 930 .status(Status.INTERNAL_SERVER_ERROR) 931 .build()); 932 } 933 } 934 }; 935 } else { 936 throw new WebApplicationException(Response 937 .serverError() 938 .entity("unsupported rawType: " + rawType 939 + " (only xml or xsd are supported)").build()); 940 } 941 return createDownloadResponse(result, fileName); 942 } catch (ComponentRegistryException e) { 943 LOG.warn("Could not retrieve component {}", profileId); 944 LOG.debug("Details", e); 945 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 946 .build(); 947 } 948 } 949 950 private void checkAndThrowDescription(BaseDescription desc, String id) { 951 if (desc == null) { 952 throw new WebApplicationException(Response.serverError() 953 .entity("Incorrect id:" + id + "cannot handle request") 954 .build()); 955 } 956 } 957 958 private Response createDownloadResponse(StreamingOutput result, 959 String fileName) { 960 // Making response so it triggers browsers native save as dialog. 961 Response response = Response 962 .ok() 963 .type("application/x-download") 964 .header("Content-Disposition", 965 "attachment; filename=\"" + fileName + "\"") 966 .entity(result).build(); 967 return response; 968 969 } 970 971 @Override 972 @POST 973 @Path("/profiles") 974 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 975 MediaType.APPLICATION_JSON }) 976 @Consumes("multipart/form-data") 977 public Response registerProfile( 978 @FormDataParam(DATA_FORM_FIELD) InputStream input, 979 @FormDataParam(NAME_FORM_FIELD) String name, 980 @FormDataParam(DESCRIPTION_FORM_FIELD) String description, 981 @FormDataParam(GROUP_FORM_FIELD) String group, 982 @FormDataParam(DOMAIN_FORM_FIELD) String domainName, 983 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) { 984 try { 985 Principal principal = checkAndGetUserPrincipal(); 986 UserCredentials userCredentials = getUserCredentials(principal); 987 ProfileDescription desc = createNewProfileDescription(); 988 desc.setCreatorName(userCredentials.getDisplayName()); 989 desc.setUserId(userCredentials.getPrincipalName()); // Hash used to 990 // be created 991 // here, now Id 992 // is 993 // constructed 994 // by impl 995 desc.setName(name); 996 desc.setDescription(description); 997 desc.setGroupName(group); 998 desc.setDomainName(domainName); 999 LOG.debug("Trying to register Profile: {}", desc); 1000 return register(input, desc, userCredentials, userspace, 1001 new NewAction()); 1002 } catch (UserUnauthorizedException ex) { 1003 return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()) 1004 .build(); 1005 } 1006 } 1007 1008 @Override 1009 @POST 1010 @Path("/components") 1011 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1012 MediaType.APPLICATION_JSON }) 1013 @Consumes("multipart/form-data") 1014 public Response registerComponent( 1015 @FormDataParam(DATA_FORM_FIELD) InputStream input, 1016 @FormDataParam(NAME_FORM_FIELD) String name, 1017 @FormDataParam(DESCRIPTION_FORM_FIELD) String description, 1018 @FormDataParam(GROUP_FORM_FIELD) String group, 1019 @FormDataParam(DOMAIN_FORM_FIELD) String domainName, 1020 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) { 1021 try { 1022 Principal principal = checkAndGetUserPrincipal(); 1023 UserCredentials userCredentials = getUserCredentials(principal); 1024 ComponentDescription desc = createNewComponentDescription(); 1025 desc.setCreatorName(userCredentials.getDisplayName()); 1026 desc.setUserId(userCredentials.getPrincipalName()); // Hash used to 1027 // be created 1028 // here, now Id 1029 // is 1030 // constructed 1031 // by impl 1032 desc.setName(name); 1033 desc.setDescription(description); 1034 desc.setGroupName(group); 1035 desc.setDomainName(domainName); 1036 LOG.debug("Trying to register Component: {}", desc); 1037 return register(input, desc, userCredentials, userspace, 1038 new NewAction()); 1039 } catch (UserUnauthorizedException ex) { 1040 return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()) 1041 .build(); 1042 } 1043 } 1044 1045 @Override 1046 @POST 1047 @Path("/components/{componentId}/comments") 1048 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1049 MediaType.APPLICATION_JSON }) 1050 @Consumes("multipart/form-data") 1051 public Response registerCommentInComponent( 1052 @FormDataParam(DATA_FORM_FIELD) InputStream input, 1053 @PathParam("componentId") String componentId, 1054 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) 1055 throws ComponentRegistryException { 1056 try { 1057 Principal principal = checkAndGetUserPrincipal(); 1058 UserCredentials userCredentials = getUserCredentials(principal); 1059 if (null == componentRegistryFactory 1060 .getOrCreateUser(userCredentials)) { 1061 throw new UserUnauthorizedException( 1062 "Cannot materialize authenticated user"); 1063 } 1064 // TODO: Add user/group param 1065 ComponentRegistry registry = getRegistry(getStatus(userspace), 1066 null, userCredentials); 1067 ComponentDescription description = registry 1068 .getComponentDescription(componentId); 1069 if (description != null) { 1070 LOG.debug("Trying to register comment to {}", componentId); 1071 return registerComment(input, registry, userspace, description, 1072 principal, userCredentials); 1073 } else { 1074 LOG.warn( 1075 "Attempt to post comment on nonexistent component id {} failed.", 1076 componentId); 1077 return Response 1078 .serverError() 1079 .entity("Invalid id, cannot comment on nonexistent component") 1080 .build(); 1081 } 1082 } catch (UserUnauthorizedException ex) { 1083 return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()) 1084 .build(); 1085 } 1086 } 1087 1088 @Override 1089 @POST 1090 @Path("/profiles/{profileId}/comments") 1091 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1092 MediaType.APPLICATION_JSON }) 1093 @Consumes("multipart/form-data") 1094 public Response registerCommentInProfile( 1095 @FormDataParam(DATA_FORM_FIELD) InputStream input, 1096 @PathParam("profileId") String profileId, 1097 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) 1098 throws ComponentRegistryException { 1099 try { 1100 Principal principal = checkAndGetUserPrincipal(); 1101 UserCredentials userCredentials = getUserCredentials(principal); 1102 if (null == componentRegistryFactory 1103 .getOrCreateUser(userCredentials)) { 1104 throw new UserUnauthorizedException( 1105 "Cannot materialize authenticated user"); 1106 } 1107 // TODO: Add user/group param 1108 ComponentRegistry registry = getRegistry(getStatus(userspace), 1109 null, userCredentials); 1110 ProfileDescription description = registry 1111 .getProfileDescription(profileId); 1112 if (description != null) { 1113 LOG.debug("Trying to register comment to {}", profileId); 1114 return registerComment(input, registry, userspace, description, 1115 principal, userCredentials); 1116 } else { 1117 LOG.warn( 1118 "Attempt to post comment on nonexistent profile id {} failed.", 1119 profileId); 1120 return Response 1121 .serverError() 1122 .entity("Invalid id, cannot comment on nonexistent profile") 1123 .build(); 1124 } 1125 } catch (UserUnauthorizedException ex) { 1126 return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()) 1127 .build(); 1128 } 1129 } 1130 1131 @Override 1132 @GET 1133 @Path("/pingSession") 1134 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1135 MediaType.APPLICATION_JSON }) 1136 public Response pingSession() { 1137 boolean stillActive = false; 1138 Principal userPrincipal = security.getUserPrincipal(); 1139 if (LOG.isInfoEnabled()) { 1140 LOG.debug("ping by <{}>", 1141 (userPrincipal == null ? "unauthorized user" 1142 : userPrincipal.getName())); 1143 } 1144 if (request != null) { 1145 if (userPrincipal != null 1146 && !ComponentRegistryFactory.ANONYMOUS_USER 1147 .equals(userPrincipal.getName())) { 1148 stillActive = !((HttpServletRequest) request).getSession() 1149 .isNew(); 1150 } 1151 } 1152 return Response 1153 .ok() 1154 .entity(String.format("<session stillActive=\"%s\"/>", 1155 stillActive)).build(); 1156 } 1157 1158 private Response register(InputStream input, BaseDescription desc, 1159 UserCredentials userCredentials, boolean userspace, 1160 RegisterAction action) { 1161 try { 1162 // TODO: Add user/group param 1163 ComponentRegistry registry = getRegistry(getStatus(userspace), 1164 null, userCredentials); 1165 DescriptionValidator descriptionValidator = new DescriptionValidator( 1166 desc); 1167 MDValidator validator = new MDValidator(input, desc, registry, 1168 getRegistry(getStatus(true)), 1169 componentRegistryFactory.getPublicRegistry(), marshaller); 1170 RegisterResponse response = new RegisterResponse(); 1171 response.setIsInUserSpace(userspace); 1172 validate(response, descriptionValidator, validator); 1173 if (response.getErrors().isEmpty()) { 1174 1175 CMDComponentSpec spec = validator.getCMDComponentSpec(); 1176 1177 // removing filename from spec before it gets extended. 1178 // recursion over all the components 1179 setFileNamesFromListToNull(Collections.singletonList(spec.getCMDComponent())); 1180 1181 try { 1182 checkForRecursion(validator, registry, desc); 1183 1184 // Add profile 1185 int returnCode = action.execute(desc, spec, response, 1186 registry); 1187 if (returnCode == 0) { 1188 response.setRegistered(true); 1189 response.setDescription(desc); 1190 } else { 1191 response.setRegistered(false); 1192 response.addError("Unable to register at this moment. Internal server error."); 1193 } 1194 } catch (ComponentRegistryException ex) { 1195 // Recursion detected 1196 response.setRegistered(false); 1197 response.addError("Error while expanding specification. " 1198 + ex.getMessage()); 1199 } 1200 } else { 1201 LOG.warn("Registration failed with validation errors: {}", 1202 Arrays.toString(response.getErrors().toArray())); 1203 response.setRegistered(false); 1204 } 1205 LOG.info("Registered new {} {}", desc.isProfile() ? "profile" 1206 : "component", desc); 1207 response.setIsProfile(desc.isProfile()); 1208 return Response.ok(response).build(); 1209 } finally { 1210 try { 1211 input.close();// either we read the input or there was an 1212 // exception, we need to close it. 1213 } catch (IOException e) { 1214 LOG.error("Error when closing inputstream: ", e); 1215 } 1216 } 1217 } 1218 1219 /** 1220 * 1221 * @param validator 1222 * @param registry 1223 * @param desc 1224 * @throws ComponentRegistryException 1225 * if recursion is detected or something goes wrong while trying 1226 * to detect recursion 1227 */ 1228 private void checkForRecursion(MDValidator validator, 1229 ComponentRegistry registry, BaseDescription desc) 1230 throws ComponentRegistryException { 1231 try { 1232 // Expand to check for recursion. Operate on copy so that original 1233 // does not get expanded. 1234 final CMDComponentSpec specCopy = validator 1235 .getCopyOfCMDComponentSpec(); 1236 // In case of recursion, the following will throw a 1237 // ComponentRegistryException 1238 registry.getExpander().expandNestedComponent( 1239 Lists.newArrayList(specCopy.getCMDComponent()), desc.getId()); 1240 } catch (JAXBException ex) { 1241 throw new ComponentRegistryException( 1242 "Unmarshalling failed while preparing recursion detection", 1243 ex); 1244 } 1245 } 1246 1247 private Response registerComment(InputStream input, 1248 ComponentRegistry registry, boolean userspace, 1249 BaseDescription description, Principal principal, 1250 UserCredentials userCredentials) { 1251 try { 1252 CommentValidator validator = new CommentValidator(input, 1253 description, marshaller); 1254 CommentResponse response = new CommentResponse(); 1255 response.setIsInUserSpace(userspace); 1256 validateComment(response, validator); 1257 if (response.getErrors().isEmpty()) { 1258 Comment com = validator.getCommentSpec(); 1259 // int returnCode = action.executeComment(com, response, 1260 // registry, principal.getName()); 1261 1262 // If user name is left empty, fill it using the user's display 1263 // name 1264 if (null == com.getUserName() || "".equals(com.getUserName())) { 1265 if (userCredentials != null) { 1266 com.setUserName(userCredentials.getDisplayName()); 1267 } else { 1268 com.setUserName(principal.getName()); 1269 } 1270 } 1271 1272 int returnCode = registry.registerComment(com, 1273 principal.getName()); 1274 if (returnCode == 0) { 1275 response.setRegistered(true); 1276 response.setComment(com); 1277 } else { 1278 response.setRegistered(false); 1279 response.addError("Unable to post at this moment. Internal server error."); 1280 } 1281 if (com.getComponentId() != null) { 1282 LOG.info("Posted new comment on component {}", 1283 com.getComponentId()); 1284 } else { 1285 LOG.info("Posted new comment on profile {}", 1286 com.getComponentId()); 1287 } 1288 } else { 1289 LOG.warn( 1290 "Posting of comment failed with validation errors: {}", 1291 Arrays.toString(response.getErrors().toArray())); 1292 response.setRegistered(false); 1293 } 1294 return Response.ok(response).build(); 1295 } catch (ComponentRegistryException ex) { 1296 LOG.error("Error while inserting comment: ", ex); 1297 return Response.serverError().entity(ex.getMessage()).build(); 1298 } finally { 1299 try { 1300 input.close();// either we read the input or there was an 1301 // exception, we need to close it. 1302 } catch (IOException e) { 1303 LOG.error("Error when closing inputstream: ", e); 1304 return Response.serverError().build(); 1305 } 1306 } 1307 } 1308 1309 private ComponentDescription createNewComponentDescription() { 1310 ComponentDescription desc = ComponentDescription.createNewDescription(); 1311 desc.setHref(createXlink(desc.getId())); 1312 return desc; 1313 } 1314 1315 private ProfileDescription createNewProfileDescription() { 1316 ProfileDescription desc = ProfileDescription.createNewDescription(); 1317 desc.setHref(createXlink(desc.getId())); 1318 return desc; 1319 } 1320 1321 private String createXlink(String id) { 1322 URI uri = uriInfo.getRequestUriBuilder().path(id).build(); 1323 return uri.toString(); 1324 } 1325 1326 /** 1327 * 1328 * @return The application's base URI as configured in the 1329 * {@link #APPLICATION_BASE_URL_PARAM} context parameter. If 1330 * correctly configured, it should look something like 1331 * "http://catalog.clarin.eu/ds/ComponentRegistry". 1332 * <em>Be aware that this 1333 * can also be null if configured incorrectly!</em> 1334 * 1335 * @see #APPLICATION_BASE_URL_PARAM 1336 */ 1337 private String getApplicationBaseURI() { 1338 return servletContext.getInitParameter(APPLICATION_BASE_URL_PARAM); 1339 } 1340 1341 private void validate(RegisterResponse response, Validator... validators) { 1342 for (Validator validator : validators) { 1343 if (!validator.validate()) { 1344 for (String error : validator.getErrorMessages()) { 1345 response.addError(error); 1346 } 1347 } 1348 } 1349 } 1350 1351 private void validateComment(CommentResponse response, 1352 Validator... validators) { 1353 for (Validator validator : validators) { 1354 if (!validator.validate()) { 1355 for (String error : validator.getErrorMessages()) { 1356 response.addError(error); 1357 } 1358 } 1359 } 1360 } 1361 1362 /** 1363 * @param componentRegistryFactory 1364 * the componentRegistryFactory to set 1365 */ 1366 @Override 1367 public void setComponentRegistryFactory( 1368 ComponentRegistryFactory componentRegistryFactory) { 1369 this.componentRegistryFactory = componentRegistryFactory; 1370 } 1371 1372 /** 1373 * 1374 * @param listofcomponents 1375 * a list of components whose file-names and whose childrens' 1376 * filenames are to be set to null 1377 */ 1378 @Override 1379 public void setFileNamesFromListToNull( 1380 List<CMDComponentType> listofcomponents) { 1381 1382 for (CMDComponentType currentcomponent : listofcomponents) { 1383 setFileNamesToNullCurrent(currentcomponent); 1384 } 1385 1386 } 1387 1388 /** 1389 * 1390 * @param currentcomponent 1391 * a component whose file-name and whose children filenames are 1392 * to be set to null 1393 */ 1394 protected void setFileNamesToNullCurrent(CMDComponentType currentcomponent) { 1395 currentcomponent.setFilename(null); 1396 setFileNamesFromListToNull(currentcomponent.getCMDComponent()); 1397 } 1398 1399 /** 1400 * 1401 * @param userspace 1402 * if "true" then profiles and components from the user's 1403 * workspace, otherwise -- public 1404 * @param limit 1405 * the number of items to be displayed 1406 * @return rss for the components in the database to which we are currently 1407 * connected 1408 * @throws ComponentRegistryException 1409 * @throws ParseException 1410 */ 1411 @Override 1412 @GET 1413 @Path("/components/rss") 1414 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1415 MediaType.APPLICATION_JSON }) 1416 public Rss getRssComponent( 1417 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace, 1418 @QueryParam(NUMBER_OF_RSSITEMS) @DefaultValue("20") String limit) 1419 throws ComponentRegistryException, ParseException { 1420 final List<ComponentDescription> components = getRegistry( 1421 getStatus(userspace)).getComponentDescriptions(); 1422 final RssCreatorDescriptions instance = new RssCreatorDescriptions( 1423 userspace, getApplicationBaseURI(), "components", 1424 Integer.parseInt(limit), components, 1425 ComponentUtils.COMPARE_ON_DATE); 1426 final Rss rss = instance.getRss(); 1427 LOG.debug("Releasing RSS of {} most recently registered components", 1428 limit); 1429 return rss; 1430 } 1431 1432 /** 1433 * 1434 * @param userspace 1435 * if "true" then profiles and components from the user's 1436 * workspace, otherwise -- public 1437 * @param limit 1438 * the number of items to be displayed 1439 * @return rss for the profiles in the database to which we are currently 1440 * connected 1441 * @throws ComponentRegistryException 1442 * @throws ParseException 1443 */ 1444 @Override 1445 @GET 1446 @Path("/profiles/rss") 1447 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1448 MediaType.APPLICATION_JSON }) 1449 public Rss getRssProfile( 1450 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace, 1451 @QueryParam(NUMBER_OF_RSSITEMS) @DefaultValue("20") String limit) 1452 throws ComponentRegistryException, ParseException { 1453 final List<ProfileDescription> profiles = getRegistry( 1454 getStatus(userspace)).getProfileDescriptions(); 1455 final RssCreatorDescriptions instance = new RssCreatorDescriptions( 1456 userspace, getApplicationBaseURI(), "profiles", 1457 Integer.parseInt(limit), profiles, 1458 ComponentUtils.COMPARE_ON_DATE); 1459 final Rss rss = instance.getRss(); 1460 LOG.debug("Releasing RSS of {} most recently registered profiles", 1461 limit); 1462 return rss; 1463 } 1464 1465 /** 1466 * 1467 * @param profileId 1468 * the Id of a profile whose comments are to be rss-ed 1469 * @param userspace 1470 * if "true" then profiles and components from the user's 1471 * workspace, otherwise -- public 1472 * @param limit 1473 * the number of items to be displayed 1474 * @return rss of the comments for a chosen profile 1475 * @throws ComponentRegistryException 1476 * @throws IOException 1477 * @throws JAXBException 1478 * @throws ParseException 1479 */ 1480 @Override 1481 @GET 1482 @Path("/profiles/{profileId}/comments/rss") 1483 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1484 MediaType.APPLICATION_JSON }) 1485 public Rss getRssOfCommentsFromProfile( 1486 @PathParam("profileId") String profileId, 1487 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace, 1488 @QueryParam(NUMBER_OF_RSSITEMS) @DefaultValue("20") String limit) 1489 throws ComponentRegistryException, IOException, JAXBException, 1490 ParseException { 1491 final Principal principal = security.getUserPrincipal(); 1492 final List<Comment> comments = getRegistry(getStatus(userspace)) 1493 .getCommentsInProfile(profileId, principal); 1494 final String profileName = getRegistry(getStatus(userspace)) 1495 .getProfileDescription(profileId).getName(); 1496 final RssCreatorComments instance = new RssCreatorComments(userspace, 1497 getApplicationBaseURI(), Integer.parseInt(limit), profileId, 1498 profileName, "profile", comments, Comment.COMPARE_ON_DATE); 1499 final Rss rss = instance.getRss(); 1500 LOG.debug("Releasing RSS of {} most recent post on profile {}", limit, 1501 profileId); 1502 return rss; 1503 } 1504 1505 /** 1506 * 1507 * @param componentId 1508 * the Id of a component whose comments are to be rss-ed 1509 * @param userspace 1510 * if "true" then profiles and components from the user's 1511 * workspace, otherwise -- public 1512 * @param limit 1513 * the number of items to be displayed 1514 * @return rss of the comments for a chosen component 1515 * @throws ComponentRegistryException 1516 * @throws IOException 1517 * @throws JAXBException 1518 * @throws ParseException 1519 */ 1520 @Override 1521 @GET 1522 @Path("/components/{componentId}/comments/rss") 1523 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1524 MediaType.APPLICATION_JSON }) 1525 public Rss getRssOfCommentsFromComponent( 1526 @PathParam("componentId") String componentId, 1527 @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace, 1528 @QueryParam(NUMBER_OF_RSSITEMS) @DefaultValue("20") String limit) 1529 throws ComponentRegistryException, IOException, JAXBException, 1530 ParseException { 1531 final Principal principal = security.getUserPrincipal(); 1532 final List<Comment> comments = getRegistry(getStatus(userspace)) 1533 .getCommentsInComponent(componentId, principal); 1534 final String componentName = getRegistry(getStatus(userspace)) 1535 .getComponentDescription(componentId).getName(); 1536 final RssCreatorComments instance = new RssCreatorComments(userspace, 1537 getApplicationBaseURI(), Integer.parseInt(limit), componentId, 1538 componentName, "component", comments, Comment.COMPARE_ON_DATE); 1539 final Rss rss = instance.getRss(); 1540 LOG.debug("Releasing RSS of {} most recent post on component {}", 1541 limit, componentId); 1542 return rss; 1543 } 1544 1545 @Override 1546 @GET 1547 @Path("/AllowedTypes") 1548 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1549 MediaType.APPLICATION_JSON }) 1550 public AllowedAttributetypesXML getAllowedAttributeTypes() 1551 throws ComponentRegistryException, IOException, JAXBException, 1552 ParseException { 1553 return (new AllowedAttributetypesXML()); 1554 } 1555 1556 @Override 1557 @GET 1558 @Path("/groups/usermembership") 1559 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1560 MediaType.APPLICATION_JSON }) 1561 public List<Group> getGroupsTheCurrentUserIsAMemberOf() { 1562 Principal principal = security.getUserPrincipal(); 1563 if (principal == null) 1564 return new ArrayList<Group>(); 1565 List<Group> groups = groupService.getGroupsOfWhichUserIsAMember(principal.getName()); 1566 return groups; 1567 } 1568 1569 @Override 1570 @GET 1571 @Path("/items/{itemId}/groups") 1572 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1573 MediaType.APPLICATION_JSON }) 1574 public List<Group> getGroupsTheItemIsAMemberOf(@PathParam("itemId") String itemId) { 1575 return groupService.getGroupsTheItemIsAMemberOf(itemId); 1576 } 1577 1578 @Override 1579 @POST 1580 @Path("/items/{itemId}/transferownership") 1581 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1582 MediaType.APPLICATION_JSON }) 1583 public void transferItemOwnershipToGroup(@PathParam("itemId") String itemId, @QueryParam("groupId") long groupId) { 1584 Principal principal = security.getUserPrincipal(); 1585 groupService.transferItemOwnershipFromUserToGroupId(principal.getName(), groupId, itemId); 1586 } 1587 1588 @Override 1589 @GET 1590 @Path("/items/{itemId}") 1591 @Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1592 MediaType.APPLICATION_JSON }) 1593 public BaseDescription getComponentDescription(@PathParam("itemId") String itemId) throws ComponentRegistryException{ 1594 LOG.debug("Item with id: {} is requested.", itemId); 1595 BaseDescription description = getRegistry(getStatus(false)).getComponentDescription(itemId); 1596 if (description == null) 1597 description = getRegistry(getStatus(true)).getComponentDescription(itemId); 1598 if (description == null) 1599 description = getRegistry(getStatus(false)).getProfileDescription(itemId); 1600 if (description == null) 1601 description = getRegistry(getStatus(true)).getProfileDescription(itemId); 1602 return description; 1603 } 1604 88 IComponentRegistryRestService { 89 90 private final static Logger LOG = LoggerFactory 91 .getLogger(IComponentRegistryRestService.class); 92 @Context 93 private UriInfo uriInfo; 94 @Context 95 private SecurityContext security; 96 @Context 97 private HttpServletRequest request; 98 @Context 99 private HttpServletResponse response; 100 @Context 101 private ServletContext servletContext; 102 @InjectParam(value = "componentRegistryFactory") 103 private ComponentRegistryFactory componentRegistryFactory; 104 @InjectParam(value = "mdMarshaller") 105 private MDMarshaller marshaller; 106 @Autowired 107 private GroupService groupService; 108 109 private ComponentRegistry getBaseRegistry() throws AuthenticationFailException { 110 Principal userPrincipal = this.checkAndGetUserPrincipal(); 111 UserCredentials userCredentials = this.getUserCredentials(userPrincipal); 112 return componentRegistryFactory.getBaseRegistry(userCredentials); 113 } 114 115 private ComponentRegistry getRegistry(RegistrySpace space, Number groupId) { 116 Principal userPrincipal = security.getUserPrincipal(); 117 UserCredentials userCredentials = this.getUserCredentials(userPrincipal); 118 try { 119 return componentRegistryFactory.getComponentRegistry(space, null, userCredentials, groupId); 120 } catch (UserUnauthorizedException uuEx) { 121 LOG.warn("Unauthorized access to {} registry by user {}", space, 122 userCredentials); 123 LOG.debug("Details for unauthorized access", uuEx); 124 throw new WebApplicationException(uuEx, Status.FORBIDDEN); 125 } 126 } 127 128 /** 129 * 130 * @return Principal of current request 131 * @throws IllegalArgumentException If no user principal found 132 */ 133 private Principal checkAndGetUserPrincipal() 134 throws AuthenticationFailException { 135 Principal principal = security.getUserPrincipal(); 136 if (principal == null) { 137 throw new AuthenticationFailException("No user principal found."); 138 } 139 return principal; 140 } 141 142 private UserCredentials getUserCredentials(Principal userPrincipal) { 143 UserCredentials userCredentials = null; 144 if (userPrincipal != null) { 145 userCredentials = new UserCredentials(userPrincipal); 146 } 147 return userCredentials; 148 } 149 150 private ComponentRegistry initialiseRegistry(String space, String groupId) throws AuthenticationFailException { 151 //checking credentials 152 RegistrySpace regSpace = RegistrySpace.valueOf(space.toUpperCase()); 153 UserCredentials user = this.getUserCredentials(this.checkAndGetUserPrincipal()); 154 // initializing the registry 155 Number groupIdNumber = null; 156 if (groupId != null && !groupId.isEmpty()) { 157 groupIdNumber = Integer.parseInt(groupId); 158 } 159 160 return this.getRegistry(regSpace, groupIdNumber); 161 } 162 163 @Override 164 @GET 165 @Path("/components") 166 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 167 MediaType.APPLICATION_JSON}) 168 public List<ComponentDescription> getRegisteredComponents( 169 @QueryParam(REGISTRY_SPACE_PARAM) @DefaultValue("published") String registrySpace, 170 @QueryParam(GROUPID_PARAM) String groupId) 171 throws ComponentRegistryException, IOException { 172 long start = System.currentTimeMillis(); 173 174 try { 175 ComponentRegistry cr = this.initialiseRegistry(registrySpace, groupId); 176 List<ComponentDescription> result = cr.getComponentDescriptions(); 177 LOG.debug( 178 "Releasing {} registered components into the world ({} millisecs)", 179 result.size(), (System.currentTimeMillis() - start)); 180 return result; 181 } catch (AuthenticationFailException e) { 182 response.sendError(Status.UNAUTHORIZED.getStatusCode(), e.toString()); 183 return new ArrayList<ComponentDescription>(); 184 185 } catch (UserUnauthorizedException e) { 186 response.sendError(Status.FORBIDDEN.getStatusCode(), e.toString()); 187 return new ArrayList<ComponentDescription>(); 188 189 } 190 191 } 192 193 @Override 194 @GET 195 @Path("/profiles") 196 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 197 MediaType.APPLICATION_JSON}) 198 public List<ProfileDescription> getRegisteredProfiles( 199 @QueryParam(REGISTRY_SPACE_PARAM) @DefaultValue("published") String registrySpace, 200 @QueryParam(METADATA_EDITOR_PARAM) @DefaultValue("false") boolean metadataEditor, 201 @QueryParam(GROUPID_PARAM) String groupId) 202 throws ComponentRegistryException, IOException { 203 204 long start = System.currentTimeMillis(); 205 try { 206 ComponentRegistry cr = this.initialiseRegistry(registrySpace, groupId); 207 List<ProfileDescription> result = (metadataEditor) ? cr.getProfileDescriptionsForMetadaEditor() : cr.getProfileDescriptions(); 208 LOG.debug( 209 "Releasing {} registered components into the world ({} millisecs)", 210 result.size(), (System.currentTimeMillis() - start)); 211 return result; 212 } catch (AuthenticationFailException e) { 213 response.sendError(Status.UNAUTHORIZED.getStatusCode(), e.toString()); 214 return new ArrayList<ProfileDescription>(); 215 216 } catch (UserUnauthorizedException e) { 217 response.sendError(Status.FORBIDDEN.getStatusCode(), e.toString()); 218 return new ArrayList<ProfileDescription>(); 219 } 220 } 221 222 @Override 223 @GET 224 @Path("/components/{componentId}") 225 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 226 MediaType.APPLICATION_JSON}) 227 public Response getRegisteredComponent( 228 @PathParam("componentId") String componentId) throws IOException { 229 LOG.debug("Component with id: {} is requested.", componentId); 230 try { 231 CMDComponentSpec mdComponent = this.getBaseRegistry().getMDComponentAccessControlled(componentId); 232 return Response.ok(mdComponent).build(); 233 } catch (ItemNotFoundException e) { 234 return Response.status(Status.NOT_FOUND).build(); 235 } catch (ComponentRegistryException e1) { 236 return Response.serverError().status(Status.CONFLICT).build(); 237 } catch (AuthenticationFailException e) { 238 return Response.serverError().status(Status.UNAUTHORIZED).build(); 239 } catch (UserUnauthorizedException e) { 240 return Response.serverError().status(Status.FORBIDDEN).build(); 241 } 242 } 243 244 @Override 245 @GET 246 @Path("/profiles/{profileId}") 247 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 248 MediaType.APPLICATION_JSON}) 249 public Response getRegisteredProfile( 250 @PathParam("profileId") String profileId) throws IOException { 251 LOG.debug("Profile with id {} is requested.", profileId); 252 try { 253 CMDComponentSpec mdProfile = this.getBaseRegistry().getMDProfileAccessControled(profileId); 254 return Response.ok(mdProfile).build(); 255 } catch (ItemNotFoundException e) { 256 return Response.status(Status.NOT_FOUND).build(); 257 } catch (ComponentRegistryException e1) { 258 return Response.serverError().status(Status.CONFLICT).build(); 259 } catch (UserUnauthorizedException e) { 260 return Response.serverError().status(Status.FORBIDDEN).build(); 261 } catch (AuthenticationFailException e) { 262 return Response.serverError().status(Status.UNAUTHORIZED).build(); 263 } 264 } 265 266 @Override 267 @GET 268 @Path("/components/{componentId}/{rawType}") 269 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML}) 270 public Response getRegisteredComponentRawType( 271 @PathParam("componentId") final String componentId, @PathParam("rawType") String rawType) throws ComponentRegistryException { 272 273 LOG.debug("Component with id: {} and rawType: {} is requested.", componentId, rawType); 274 try { 275 final ComponentRegistry registry = this.getBaseRegistry(); 276 try { 277 ComponentDescription desc = registry.getComponentDescriptionAccessControlled(componentId); 278 StreamingOutput result = null; 279 String fileName = desc.getName() + "." + rawType; 280 if ("xml".equalsIgnoreCase(rawType)) { 281 result = new StreamingOutput() { 282 @Override 283 public void write(OutputStream output) throws IOException, 284 WebApplicationException { 285 try { 286 try { 287 try { 288 registry.getMDComponentAsXml(componentId, output); 289 } catch (ItemNotFoundException e1) { 290 LOG.warn("Could not retrieve component {}", 291 componentId); 292 LOG.debug("Details", e1); 293 throw new WebApplicationException(e1, Response 294 .serverError() 295 .status(Status.INTERNAL_SERVER_ERROR) 296 .build()); 297 } 298 } catch (ComponentRegistryException e) { 299 LOG.warn("Could not retrieve component {}", 300 componentId); 301 LOG.debug("Details", e); 302 throw new WebApplicationException(e, Response 303 .serverError() 304 .status(Status.INTERNAL_SERVER_ERROR) 305 .build()); 306 } 307 308 } catch (UserUnauthorizedException e2) { 309 LOG.error(e2.toString()); 310 } 311 } 312 }; 313 } else if ("xsd".equalsIgnoreCase(rawType)) { 314 result = new StreamingOutput() { 315 @Override 316 public void write(OutputStream output) throws IOException, 317 WebApplicationException { 318 try { 319 try { 320 try { 321 registry.getMDComponentAsXsd(componentId, output); 322 } catch (ItemNotFoundException e1) { 323 LOG.warn("Could not retrieve component {}", 324 componentId); 325 LOG.debug("Details", e1); 326 throw new WebApplicationException(e1, Response 327 .serverError() 328 .status(Status.INTERNAL_SERVER_ERROR) 329 .build()); 330 } 331 } catch (ComponentRegistryException e) { 332 LOG.warn("Could not retrieve component {}", 333 componentId); 334 LOG.debug("Details", e); 335 throw new WebApplicationException(e, Response 336 .serverError() 337 .status(Status.INTERNAL_SERVER_ERROR) 338 .build()); 339 } 340 } catch (UserUnauthorizedException e2) { 341 LOG.error(e2.toString()); 342 } 343 344 } 345 }; 346 } else { 347 throw new WebApplicationException(Response 348 .serverError() 349 .entity("unsupported rawType: " + rawType 350 + " (only xml or xsd are supported)").build()); 351 } 352 return createDownloadResponse(result, fileName); 353 354 } catch (UserUnauthorizedException e2) { 355 return Response.status(Status.FORBIDDEN).build(); 356 } 357 } catch (ItemNotFoundException e3) { 358 return Response.status(Status.NOT_FOUND).build(); 359 } catch (AuthenticationFailException e) { 360 return Response.serverError().status(Status.UNAUTHORIZED).build(); 361 } 362 } 363 364 @Override 365 @GET 366 @Path("/components/usage/{componentId}") 367 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 368 MediaType.APPLICATION_JSON}) 369 public List<BaseDescription> getComponentUsage( 370 @PathParam("componentId") String componentId) throws ComponentRegistryException, IOException { 371 372 final long start = System.currentTimeMillis(); 373 try { 374 ComponentRegistry registry = this.getBaseRegistry(); 375 List<ComponentDescription> components = registry.getUsageInComponents(componentId); 376 List<ProfileDescription> profiles = registry.getUsageInProfiles(componentId); 377 378 LOG.debug( 379 "Found {} components and {} profiles that use component {} ({} millisecs)", 380 components.size(), profiles.size(), componentId, 381 (System.currentTimeMillis() - start)); 382 383 List<BaseDescription> usages = new ArrayList<BaseDescription>(components.size() + profiles.size()); 384 usages.addAll(components); 385 usages.addAll(profiles); 386 387 return usages; 388 } catch (ComponentRegistryException e) { 389 LOG.warn("Could not retrieve profile usage {}", componentId); 390 LOG.debug("Details", e); 391 return new ArrayList<BaseDescription>(); 392 } catch (AuthenticationFailException e1) { 393 response.sendError(Status.UNAUTHORIZED.getStatusCode()); 394 return new ArrayList<BaseDescription>(); 395 } 396 } 397 398 @Override 399 @GET 400 @Path("/profiles/{profileId}/comments") 401 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 402 MediaType.APPLICATION_JSON}) 403 public List<Comment> getCommentsFromProfile( 404 @PathParam("profileId") String profileId) 405 throws ComponentRegistryException, IOException { 406 long start = System.currentTimeMillis(); 407 try { 408 List<Comment> comments = this.getBaseRegistry().getCommentsInProfile(profileId); 409 LOG.debug( 410 "Releasing {} registered comments in profile into the world ({} millisecs)", 411 comments.size(), (System.currentTimeMillis() - start)); 412 return comments; 413 } catch (ItemNotFoundException e) { 414 response.sendError(Status.NOT_FOUND.getStatusCode()); 415 return new ArrayList<Comment>(); 416 417 } catch (UserUnauthorizedException e) { 418 response.sendError(Status.FORBIDDEN.getStatusCode()); 419 return new ArrayList<Comment>(); 420 } catch (AuthenticationFailException e1) { 421 response.sendError(Status.UNAUTHORIZED.getStatusCode()); 422 return new ArrayList<Comment>(); 423 } 424 } 425 426 @Override 427 @GET 428 @Path("/components/{componentId}/comments") 429 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 430 MediaType.APPLICATION_JSON}) 431 public List<Comment> getCommentsFromComponent( 432 @PathParam("componentId") String componentId) 433 throws ComponentRegistryException, IOException { 434 long start = System.currentTimeMillis(); 435 try { 436 List<Comment> comments = this.getBaseRegistry().getCommentsInComponent(componentId); 437 LOG.debug( 438 "Releasing {} registered comments in Component into the world ({} millisecs)", 439 comments.size(), (System.currentTimeMillis() - start)); 440 return comments; 441 } catch (ItemNotFoundException e) { 442 response.sendError(Status.NOT_FOUND.getStatusCode()); 443 return new ArrayList<Comment>(); 444 } catch (UserUnauthorizedException e1) { 445 response.sendError(Status.FORBIDDEN.getStatusCode()); 446 return new ArrayList<Comment>(); 447 } catch (AuthenticationFailException e1) { 448 response.sendError(Status.UNAUTHORIZED.getStatusCode()); 449 return new ArrayList<Comment>(); 450 } 451 } 452 453 @Override 454 @GET 455 @Path("/profiles/{profileId}/comments/{commentId}") 456 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 457 MediaType.APPLICATION_JSON}) 458 public Comment getSpecifiedCommentFromProfile( 459 @PathParam("profileId") String profileId, 460 @PathParam("commentId") String commentId) 461 throws ComponentRegistryException, IOException { 462 463 LOG.debug("Comments of profile with id {} are requested.", commentId); 464 try { 465 466 return this.getBaseRegistry().getSpecifiedCommentInProfile(profileId, commentId); 467 } catch (ItemNotFoundException e) { 468 response.sendError(Status.NOT_FOUND.getStatusCode()); 469 return new Comment(); 470 } catch (UserUnauthorizedException e1) { 471 response.sendError(Status.FORBIDDEN.getStatusCode()); 472 return new Comment(); 473 } catch (AuthenticationFailException e1) { 474 response.sendError(Status.UNAUTHORIZED.getStatusCode()); 475 return new Comment(); 476 } 477 } 478 479 @Override 480 @GET 481 @Path("/components/{componentId}/comments/{commentId}") 482 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 483 MediaType.APPLICATION_JSON}) 484 public Comment getSpecifiedCommentFromComponent( 485 @PathParam("componentId") String componentId, 486 @PathParam("commentId") String commentId) 487 throws ComponentRegistryException, IOException { 488 LOG.debug("Comments of component with id {} are requested.", commentId); 489 try { 490 491 return this.getBaseRegistry().getSpecifiedCommentInComponent(componentId, commentId); 492 } catch (ItemNotFoundException e) { 493 response.sendError(Status.NOT_FOUND.getStatusCode()); 494 return new Comment(); 495 } catch (UserUnauthorizedException e1) { 496 response.sendError(Status.FORBIDDEN.getStatusCode()); 497 return new Comment(); 498 } catch (AuthenticationFailException e1) { 499 response.sendError(Status.UNAUTHORIZED.getStatusCode()); 500 return new Comment(); 501 } 502 } 503 504 /** 505 * 506 * Purely helper method for my front-end (FLEX) which only does post/get 507 * requests. The query param is checked and the "proper" method is called. 508 * 509 * @param profileId 510 * @param method 511 * @return 512 */ 513 // TODO: test via POSTMAN 514 @Override 515 @POST 516 @Path("/profiles/{profileId}") 517 public Response manipulateRegisteredProfile( 518 @PathParam("profileId") String profileId, 519 @FormParam("method") String method) { 520 if ("delete".equalsIgnoreCase(method)) { 521 return this.deleteRegisteredProfile(profileId); 522 } else { 523 return Response.ok().build(); 524 } 525 } 526 527 // TODO: test via POSTMAN 528 @Override 529 @POST 530 @Path("/profiles/{profileId}/comments/{commentId}") 531 public Response manipulateCommentFromProfile( 532 @PathParam("profileId") String profileId, 533 @PathParam("commentId") String commentId, 534 @FormParam("method") String method) { 535 if ("delete".equalsIgnoreCase(method)) { 536 return this.deleteCommentFromProfile(profileId, commentId); 537 } else { 538 return Response.ok().build(); 539 } 540 } 541 542 // TODO: test via POSTMAN 543 @Override 544 @POST 545 @Path("/components/{componentId}/comments/{commentId}") 546 public Response manipulateCommentFromComponent( 547 @PathParam("componentId") String componentId, 548 @PathParam("commentId") String commentId, 549 @FormParam("method") String method) { 550 if ("delete".equalsIgnoreCase(method)) { 551 return this.deleteCommentFromComponent(componentId, commentId); 552 } else { 553 return Response.ok().build(); 554 } 555 } 556 557 // TODO: test via POSTMAN 558 @Override 559 @POST 560 @Path("/profiles/{profileId}/publish") 561 @Consumes("multipart/form-data") 562 public Response publishRegisteredProfile( 563 @PathParam("profileId") String profileId, 564 @FormDataParam(DATA_FORM_FIELD) InputStream input, 565 @FormDataParam(NAME_FORM_FIELD) String name, 566 @FormDataParam(DESCRIPTION_FORM_FIELD) String description, 567 @FormDataParam(GROUP_FORM_FIELD) String group, 568 @FormDataParam(DOMAIN_FORM_FIELD) String domainName) { 569 570 try { 571 Principal principal = checkAndGetUserPrincipal(); 572 ComponentRegistry registry = this.getBaseRegistry(); 573 ProfileDescription desc = registry.getProfileDescriptionAccessControlled(profileId); 574 if (desc != null) { 575 if (desc.isPublic()) { 576 return Response.status(Status.CONFLICT).entity("Cannot publish already published profile.") 577 .build(); 578 } 579 desc.setPublic(true); 580 this.updateDescription(desc, name, description, domainName, group); 581 return this.register(input, desc, new PublishAction(principal), registry); 582 } else { 583 LOG.error("Update of nonexistent profile {} failed.", profileId); 584 return Response 585 .serverError() 586 .entity("Invalid id, cannot update nonexistent profile") 587 .build(); 588 } 589 590 } catch (AuthenticationFailException e) { 591 return Response.serverError().status(Status.UNAUTHORIZED) 592 .build(); 593 } catch (ItemNotFoundException e1) { 594 return Response.status(Status.NOT_FOUND).entity(e1.getMessage()).build(); 595 } catch (ComponentRegistryException e) { 596 LOG.warn("Could not retrieve profile {}", profileId); 597 LOG.debug("Details", e); 598 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 599 .build(); 600 } catch (UserUnauthorizedException ex) { 601 return Response.status(Status.FORBIDDEN).entity(ex.getMessage()) 602 .build(); 603 } 604 } 605 606 @Override 607 @POST 608 @Path("/profiles/{profileId}/update") 609 @Consumes("multipart/form-data") 610 public Response updateRegisteredProfile( 611 @PathParam("profileId") String profileId, 612 @FormDataParam(DATA_FORM_FIELD) InputStream input, 613 @FormDataParam(NAME_FORM_FIELD) String name, 614 @FormDataParam(DESCRIPTION_FORM_FIELD) String description, 615 @FormDataParam(GROUP_FORM_FIELD) String group, 616 @FormDataParam(DOMAIN_FORM_FIELD) String domainName) { 617 try { 618 ComponentRegistry br = this.getBaseRegistry(); 619 ProfileDescription desc = br.getProfileDescriptionAccessControlled(profileId); 620 if (desc != null) { 621 if (desc.isPublic()) { 622 return Response.status(Status.CONFLICT).entity("Cannot update already published profile.") 623 .build(); 624 625 } 626 Number groupId; 627 RegistrySpace space; 628 List<Number> groupIds = br.getItemGroups(profileId); 629 if (groupIds == null || groupIds.isEmpty()) { 630 groupId = null; 631 space = RegistrySpace.PRIVATE; 632 } else { 633 groupId = groupIds.get(0); 634 space = RegistrySpace.GROUP; 635 } 636 637 updateDescription(desc, name, description, domainName, group); 638 ComponentRegistry cr = this.getRegistry(space, groupId); 639 return register(input, desc, new UpdateAction(), cr); 640 } else { 641 LOG.error("Update of nonexistent id (" + profileId 642 + ") failed."); 643 return Response 644 .serverError() 645 .entity("Invalid id, cannot update nonexistent profile") 646 .build(); 647 } 648 } catch (ComponentRegistryException e) { 649 LOG.warn("Could not retrieve profile {}", profileId); 650 LOG.debug("Details", e); 651 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 652 .build(); 653 654 } catch (UserUnauthorizedException ex) { 655 return Response.status(Status.FORBIDDEN).entity(ex.getMessage()) 656 .build(); 657 658 } catch (ItemNotFoundException ex2) { 659 return Response.status(Status.NOT_FOUND).entity(ex2.getMessage()) 660 .build(); 661 } catch (AuthenticationFailException e1) { 662 return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage()) 663 .build(); 664 } 665 666 } 667 668 /** 669 * 670 * Purely helper method for my front-end (FLEX) which van only do post/get 671 * requests. The query param is checked and the "proper" method is called. 672 * 673 * @param componentId 674 * @param method 675 * @return 676 */ 677 // twan: why do we need it? 678 // TODO: test via POSTMAN 679 @Override 680 @POST 681 @Path("/components/{componentId}") 682 public Response manipulateRegisteredComponent( 683 @PathParam("componentId") String componentId, 684 @FormParam("method") String method) { 685 if ("delete".equalsIgnoreCase(method)) { 686 return this.deleteRegisteredComponent(componentId); 687 } else { 688 return Response.ok("Nothing to do, not 'delete' method").build(); 689 } 690 } 691 692 // TODO: test via POSTMAN 693 @Override 694 @POST 695 @Path("/components/{componentId}/publish") 696 @Consumes("multipart/form-data") 697 public Response publishRegisteredComponent( 698 @PathParam("componentId") String componentId, 699 @FormDataParam(DATA_FORM_FIELD) InputStream input, 700 @FormDataParam(NAME_FORM_FIELD) String name, 701 @FormDataParam(DESCRIPTION_FORM_FIELD) String description, 702 @FormDataParam(GROUP_FORM_FIELD) String group, 703 @FormDataParam(DOMAIN_FORM_FIELD) String domainName) { 704 705 try { 706 Principal principal = checkAndGetUserPrincipal(); 707 ComponentRegistry registry = this.getBaseRegistry(); 708 ComponentDescription desc = registry.getComponentDescriptionAccessControlled(componentId); 709 if (desc != null) { 710 if (desc.isPublic()) { 711 return Response.status(Status.CONFLICT).entity("Cannot publish already published omponent.") 712 .build(); 713 } 714 desc.setPublic(true); 715 this.updateDescription(desc, name, description, domainName, group); 716 return this.register(input, desc, new PublishAction(principal), registry); 717 } else { 718 LOG.error("Update of nonexistent id (" + componentId 719 + ") failed."); 720 return Response 721 .serverError() 722 .entity("Invalid id, cannot update nonexistent profile") 723 .build(); 724 } 725 } catch (AuthenticationFailException e) { 726 LOG.warn("Could not retrieve component {}", componentId); 727 LOG.debug("Details", e); 728 return Response.serverError().status(Status.UNAUTHORIZED) 729 .build(); 730 } catch (ComponentRegistryException e) { 731 LOG.warn("Could not retrieve component {}", componentId); 732 LOG.debug("Details", e); 733 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 734 .build(); 735 } catch (ItemNotFoundException e) { 736 LOG.warn("Could not retrieve component {}", componentId); 737 LOG.debug("Details", e); 738 return Response.serverError().status(Status.NOT_FOUND) 739 .build(); 740 } catch (UserUnauthorizedException ex) { 741 return Response.status(Status.FORBIDDEN).entity(ex.getMessage()) 742 .build(); 743 } 744 } 745 746 @Override 747 @POST 748 @Path("/components/{componentId}/update") 749 @Consumes("multipart/form-data") 750 public Response updateRegisteredComponent( 751 @PathParam("componentId") String componentId, 752 @FormDataParam(DATA_FORM_FIELD) InputStream input, 753 @FormDataParam(NAME_FORM_FIELD) String name, 754 @FormDataParam(DESCRIPTION_FORM_FIELD) String description, 755 @FormDataParam(GROUP_FORM_FIELD) String group, 756 @FormDataParam(DOMAIN_FORM_FIELD) String domainName) { 757 try { 758 ComponentRegistry br = this.getBaseRegistry(); 759 ComponentDescription desc =br.getComponentDescriptionAccessControlled(componentId); 760 if (desc != null) { 761 if (desc.isPublic()) { 762 return Response.status(Status.CONFLICT).entity("Cannot update already published component.") 763 .build(); 764 } 765 Number groupId; 766 RegistrySpace space; 767 List<Number> groupIds = br.getItemGroups(componentId); 768 if (groupIds == null || groupIds.isEmpty()) { 769 groupId = null; 770 space = RegistrySpace.PRIVATE; 771 } else { 772 groupId = groupIds.get(0); 773 space = RegistrySpace.GROUP; 774 } 775 776 this.updateDescription(desc, name, description, domainName, group); 777 ComponentRegistry cr = this.getRegistry(space, groupId); 778 return this.register(input, desc, new UpdateAction(), cr); 779 } else { 780 LOG.error("Update of nonexistent id (" + componentId 781 + ") failed."); 782 return Response 783 .serverError() 784 .entity("Invalid id, cannot update nonexistent component") 785 .build(); 786 } 787 } catch (ComponentRegistryException e) { 788 LOG.warn("Could not retrieve component {}", componentId); 789 LOG.debug("Details", e); 790 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 791 .build(); 792 } catch (UserUnauthorizedException ex) { 793 return Response.status(Status.FORBIDDEN).entity(ex.getMessage()) 794 .build(); 795 } catch (ItemNotFoundException ex2) { 796 return Response.status(Status.FORBIDDEN).entity(ex2.getMessage()) 797 .build(); 798 } catch (AuthenticationFailException e1) { 799 return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage()) 800 .build(); 801 } 802 803 } 804 805 private void updateDescription(BaseDescription desc, String name, 806 String description, String domainName, String group) { 807 desc.setName(name); 808 desc.setDescription(description); 809 desc.setDomainName(domainName); 810 desc.setGroupName(group); 811 desc.setRegistrationDate(new Date()); 812 } 813 814 @Override 815 @DELETE 816 @Path("/components/{componentId}") 817 public Response deleteRegisteredComponent( 818 @PathParam("componentId") String componentId) { 819 try { 820 ComponentRegistry registry = this.getBaseRegistry(); 821 LOG.debug("Component with id {} set for deletion.", componentId); 822 registry.deleteMDComponent(componentId, false); 823 } catch (DeleteFailedException e) { 824 LOG.info("Component with id {} deletion failed. Reason: {}", 825 componentId, e.getMessage()); 826 LOG.debug("Deletion failure details:", e); 827 return Response.status(Status.FORBIDDEN) 828 .entity("" + e.getMessage()).build(); 829 } catch (ComponentRegistryException e) { 830 LOG.warn("Component with id " + componentId + " deletion failed.", 831 e); 832 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 833 .build(); 834 } catch (ItemNotFoundException e) { 835 LOG.warn("Component with id " + componentId + " is not found.", 836 e); 837 return Response.serverError().status(Status.NOT_FOUND) 838 .build(); 839 } catch (IOException e) { 840 LOG.error("Component with id " + componentId + " deletion failed.", 841 e); 842 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 843 .build(); 844 } catch (UserUnauthorizedException e) { 845 LOG.info("Component with id {} deletion failed: {}", componentId, 846 e.getMessage()); 847 LOG.debug("Deletion failure details:", e); 848 return Response.serverError().status(Status.FORBIDDEN) 849 .entity("" + e.getMessage()).build(); 850 } catch (AuthenticationFailException e1) { 851 return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage()) 852 .build(); 853 } 854 855 LOG.info("Component with id: {} deleted.", componentId); 856 return Response.ok().build(); 857 } 858 859 @Override 860 @DELETE 861 @Path("/profiles/{profileId}") 862 public Response deleteRegisteredProfile( 863 @PathParam("profileId") String profileId) { 864 try { 865 LOG.debug("Profile with id: {} set for deletion.", profileId); 866 this.getBaseRegistry().deleteMDProfile(profileId); 867 } catch (DeleteFailedException e) { 868 LOG.info("Profile with id: {} deletion failed: {}", profileId, 869 e.getMessage()); 870 LOG.debug("Deletion failure details:", e); 871 return Response.serverError().status(Status.FORBIDDEN) 872 .entity("" + e.getMessage()).build(); 873 } catch (ComponentRegistryException e) { 874 LOG.warn("Could not retrieve component", e); 875 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 876 .build(); 877 } catch (ItemNotFoundException e) { 878 LOG.warn("Profile with id " + profileId + " is not found.", 879 e); 880 return Response.serverError().status(Status.NOT_FOUND) 881 .build(); 882 } catch (IOException e) { 883 LOG.error("Profile with id: " + profileId + " deletion failed.", e); 884 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 885 .build(); 886 } catch (UserUnauthorizedException e) { 887 LOG.info("Profile with id: {} deletion failed: {}", profileId, 888 e.getMessage()); 889 LOG.debug("Deletion failure details:", e); 890 return Response.serverError().status(Status.FORBIDDEN) 891 .entity("" + e.getMessage()).build(); 892 } catch (AuthenticationFailException e1) { 893 return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage()) 894 .build(); 895 } 896 897 LOG.info("Profile with id: {} deleted.", profileId); 898 return Response.ok().build(); 899 } 900 901 @Override 902 @DELETE 903 @Path("/profiles/{profileId}/comments/{commentId}") 904 public Response deleteCommentFromProfile( 905 @PathParam("profileId") String profileId, 906 @PathParam("commentId") String commentId) { 907 try { 908 final ComponentRegistry registry = this.getBaseRegistry(); 909 try { 910 final Comment comment = registry.getSpecifiedCommentInProfile(profileId, commentId); 911 if (comment != null 912 && profileId.equals(comment.getComponentId())) { 913 LOG.debug("Comment with id: {} set for deletion.", commentId); 914 registry.deleteComment(commentId); 915 } else { 916 throw new ComponentRegistryException( 917 "Comment not found for specified profile"); 918 } 919 } catch (ItemNotFoundException e1) { 920 LOG.info("Comment with id: {} deletion failed: {}", commentId, 921 e1.getMessage()); 922 LOG.debug("Deletion failure details:", e1); 923 return Response.serverError().status(Status.NOT_FOUND) 924 .entity("" + e1.getMessage()).build(); 925 } 926 927 } catch (DeleteFailedException e) { 928 LOG.info("Comment with id: {} deletion failed: {}", commentId, 929 e.getMessage()); 930 LOG.debug("Deletion failure details:", e); 931 return Response.serverError().status(Status.FORBIDDEN) 932 .entity("" + e.getMessage()).build(); 933 } catch (ComponentRegistryException e) { 934 LOG.info("Could not retrieve component", e); 935 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 936 .build(); 937 } catch (IOException e) { 938 LOG.error("Comment with id: " + commentId + " deletion failed.", e); 939 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 940 .build(); 941 } catch (UserUnauthorizedException e) { 942 LOG.info("Comment with id: {} deletion failed: {}", commentId, 943 e.getMessage()); 944 LOG.debug("Deletion failure details:", e); 945 return Response.serverError().status(Status.FORBIDDEN) 946 .entity("" + e.getMessage()).build(); 947 } catch (AuthenticationFailException e1) { 948 return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage()) 949 .build(); 950 } 951 952 LOG.info("Comment with id: {} deleted.", commentId); 953 return Response.ok("Comment with id " + commentId + " deleted.").build(); 954 } 955 956 @Override 957 @DELETE 958 @Path("/components/{componentId}/comments/{commentId}") 959 public Response deleteCommentFromComponent( 960 @PathParam("componentId") String componentId, 961 @PathParam("commentId") String commentId) { 962 try { 963 final ComponentRegistry registry = this.getBaseRegistry(); 964 final Comment comment = registry.getSpecifiedCommentInComponent(componentId, commentId); 965 if (comment != null 966 && componentId.equals(comment.getComponentId())) { 967 LOG.debug("Comment with id: {} set for deletion.", commentId); 968 registry.deleteComment(commentId); 969 } else { 970 throw new ComponentRegistryException( 971 "Comment not found for specified component"); 972 } 973 } catch (ItemNotFoundException e) { 974 LOG.info("Comment with id: {} deletion failed: {}", commentId, 975 e.getMessage()); 976 LOG.debug("Deletion failure details:", e); 977 return Response.serverError().status(Status.NOT_FOUND) 978 .entity("" + e.getMessage()).build(); 979 } catch (DeleteFailedException e) { 980 LOG.info("Comment with id: {} deletion failed: {}", commentId, 981 e.getMessage()); 982 LOG.debug("Deletion failure details:", e); 983 return Response.serverError().status(Status.FORBIDDEN) 984 .entity("" + e.getMessage()).build(); 985 } catch (ComponentRegistryException e) { 986 LOG.info("Could not retrieve component", e); 987 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 988 .build(); 989 } catch (IOException e) { 990 LOG.error("Comment with id: " + commentId + " deletion failed.", e); 991 return Response.serverError().status(Status.INTERNAL_SERVER_ERROR) 992 .build(); 993 } catch (UserUnauthorizedException e) { 994 LOG.info("Comment with id: {} deletion failed: {}", commentId, 995 e.getMessage()); 996 LOG.debug("Deletion failure details:", e); 997 return Response.serverError().status(Status.FORBIDDEN) 998 .entity("" + e.getMessage()).build(); 999 } catch (AuthenticationFailException e1) { 1000 return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage()) 1001 .build(); 1002 } 1003 1004 LOG.info("Comment with id: {} deleted.", commentId); 1005 return Response.ok("Comment with id " + commentId + " deleted.").build(); 1006 } 1007 1008 @Override 1009 @GET 1010 @Path("/profiles/{profileId}/{rawType}") 1011 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML}) 1012 public Response getRegisteredProfileRawType( 1013 @PathParam("profileId") final String profileId, 1014 @PathParam("rawType") String rawType) throws ComponentRegistryException { 1015 1016 1017 LOG.debug("Profile with id {} and rawType {} is requested.", profileId, 1018 rawType); 1019 try { 1020 final ComponentRegistry registry = this.getBaseRegistry(); 1021 1022 ProfileDescription desc = registry.getProfileDescriptionAccessControlled(profileId); 1023 if (desc == null) { 1024 return Response.status(Status.NOT_FOUND).build(); 1025 } 1026 1027 StreamingOutput result = null; 1028 String fileName = desc.getName() + "." + rawType; 1029 if ("xml".equalsIgnoreCase(rawType)) { 1030 result = new StreamingOutput() { 1031 @Override 1032 public void write(OutputStream output) throws IOException, 1033 WebApplicationException { 1034 try { 1035 registry.getMDProfileAsXml(profileId, output); 1036 } catch (Exception e) { 1037 LOG.warn("Could not retrieve component {}", 1038 profileId); 1039 LOG.debug("Details", e); 1040 throw new WebApplicationException(e, Response 1041 .serverError() 1042 .status(Status.INTERNAL_SERVER_ERROR) 1043 .build()); 1044 } 1045 } 1046 }; 1047 } else if ("xsd".equalsIgnoreCase(rawType)) { 1048 result = new StreamingOutput() { 1049 @Override 1050 public void write(OutputStream output) throws IOException, 1051 WebApplicationException { 1052 try { 1053 registry.getMDProfileAsXsd(profileId, output); 1054 } catch (Exception e) { 1055 LOG.warn("Could not retrieve component {}", 1056 profileId); 1057 LOG.debug("Details", e); 1058 throw new WebApplicationException(e, Response 1059 .serverError() 1060 .status(Status.INTERNAL_SERVER_ERROR) 1061 .build()); 1062 } 1063 } 1064 }; 1065 } else { 1066 throw new WebApplicationException(Response 1067 .serverError() 1068 .entity("unsupported rawType: " + rawType 1069 + " (only xml or xsd are supported)").build()); 1070 } 1071 return createDownloadResponse(result, fileName); 1072 } catch (UserUnauthorizedException ex) { 1073 return Response.status(Status.FORBIDDEN).build(); 1074 } catch (ItemNotFoundException e) { 1075 return Response.serverError().status(Status.NOT_FOUND) 1076 .entity("" + e.getMessage()).build(); 1077 } catch (AuthenticationFailException e1) { 1078 return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage()) 1079 .build(); 1080 } 1081 1082 } 1083 1084 private Response createDownloadResponse(StreamingOutput result, 1085 String fileName) { 1086 // Making response so it triggers browsers native save as dialog. 1087 Response response = Response 1088 .ok() 1089 .type("application/x-download") 1090 .header("Content-Disposition", 1091 "attachment; filename=\"" + fileName + "\"") 1092 .entity(result).build(); 1093 return response; 1094 1095 } 1096 1097 @Override 1098 @POST 1099 @Path("/profiles") 1100 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1101 MediaType.APPLICATION_JSON}) 1102 @Consumes("multipart/form-data") 1103 public Response registerProfile( 1104 @FormDataParam(DATA_FORM_FIELD) InputStream input, 1105 @FormDataParam(NAME_FORM_FIELD) String name, 1106 @FormDataParam(DESCRIPTION_FORM_FIELD) String description, 1107 @FormDataParam(GROUP_FORM_FIELD) String group, 1108 @FormDataParam(DOMAIN_FORM_FIELD) String domainName) { 1109 try { 1110 Principal principal = checkAndGetUserPrincipal(); 1111 UserCredentials userCredentials = getUserCredentials(principal); 1112 ProfileDescription desc = this.createNewProfileDescription(); 1113 desc.setCreatorName(userCredentials.getDisplayName()); 1114 desc.setUserId(userCredentials.getPrincipalName()); // Hash used to 1115 // be created 1116 // here, now Id 1117 // is 1118 // constructed 1119 // by impl 1120 desc.setName(name); 1121 desc.setDescription(description); 1122 desc.setGroupName(group); 1123 desc.setDomainName(domainName); 1124 desc.setPublic(false); 1125 LOG.debug("Trying to register Profile: {}", desc); 1126 ComponentRegistry cr = this.getRegistry(RegistrySpace.PRIVATE, null); 1127 return this.register(input, desc, new NewAction(), cr); 1128 } catch (AuthenticationFailException e) { 1129 LOG.debug("Details", e); 1130 return Response.serverError().status(Status.UNAUTHORIZED) 1131 .build(); 1132 } catch (UserUnauthorizedException ex) { 1133 return Response.status(Status.FORBIDDEN).entity(ex.getMessage()) 1134 .build(); 1135 } 1136 } 1137 1138 @Override 1139 @POST 1140 @Path("/components") 1141 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1142 MediaType.APPLICATION_JSON}) 1143 @Consumes("multipart/form-data") 1144 public Response registerComponent( 1145 @FormDataParam(DATA_FORM_FIELD) InputStream input, 1146 @FormDataParam(NAME_FORM_FIELD) String name, 1147 @FormDataParam(DESCRIPTION_FORM_FIELD) String description, 1148 @FormDataParam(GROUP_FORM_FIELD) String group, 1149 @FormDataParam(DOMAIN_FORM_FIELD) String domainName) { 1150 try { 1151 Principal principal = checkAndGetUserPrincipal(); 1152 UserCredentials userCredentials = getUserCredentials(principal); 1153 ComponentDescription desc = createNewComponentDescription(); 1154 desc.setCreatorName(userCredentials.getDisplayName()); 1155 desc.setUserId(userCredentials.getPrincipalName()); // Hash used to 1156 // be created 1157 // here, now Id 1158 // is 1159 // constructed 1160 // by impl 1161 desc.setName(name); 1162 desc.setDescription(description); 1163 desc.setGroupName(group); 1164 desc.setDomainName(domainName); 1165 desc.setPublic(false); 1166 LOG.debug("Trying to register Component: {}", desc); 1167 ComponentRegistry cr = this.getRegistry(RegistrySpace.PRIVATE, null); 1168 return this.register(input, desc, new NewAction(), cr); 1169 } catch (AuthenticationFailException e) { 1170 LOG.debug("Details", e); 1171 return Response.serverError().status(Status.UNAUTHORIZED) 1172 .build(); 1173 } catch (UserUnauthorizedException ex) { 1174 return Response.status(Status.FORBIDDEN).entity(ex.getMessage()) 1175 .build(); 1176 } 1177 } 1178 1179 @Override 1180 @POST 1181 @Path("/components/{componentId}/comments") 1182 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1183 MediaType.APPLICATION_JSON}) 1184 @Consumes("multipart/form-data") 1185 public Response registerCommentInComponent( 1186 @FormDataParam(DATA_FORM_FIELD) InputStream input, 1187 @PathParam("componentId") String componentId) throws ComponentRegistryException { 1188 try { 1189 ComponentRegistry registry = this.getBaseRegistry(); 1190 ComponentDescription description = registry.getComponentDescriptionAccessControlled(componentId); 1191 1192 LOG.debug("Trying to register comment to {}", componentId); 1193 1194 return this.registerComment(input, description, registry); 1195 } catch (AuthenticationFailException e) { 1196 LOG.debug("Details", e); 1197 return Response.serverError().status(Status.UNAUTHORIZED) 1198 .build(); 1199 } catch (UserUnauthorizedException ex) { 1200 return Response.status(Status.FORBIDDEN) 1201 .build(); 1202 } catch (ItemNotFoundException e) { 1203 return Response.serverError().status(Status.NOT_FOUND) 1204 .entity("" + e.getMessage()).build(); 1205 } 1206 } 1207 1208 // TODO test with the POSTMAN 1209 @Override 1210 @POST 1211 @Path("/profiles/{profileId}/comments") 1212 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1213 MediaType.APPLICATION_JSON}) 1214 @Consumes("multipart/form-data") 1215 public Response registerCommentInProfile( 1216 @FormDataParam(DATA_FORM_FIELD) InputStream input, 1217 @PathParam("profileId") String profileId) 1218 throws ComponentRegistryException { 1219 try { 1220 ComponentRegistry registry = this.getBaseRegistry(); 1221 ProfileDescription description = registry 1222 .getProfileDescriptionAccessControlled(profileId); 1223 1224 LOG.debug("Trying to register comment to {}", profileId); 1225 1226 return this.registerComment(input, description, registry); 1227 } catch (AuthenticationFailException e) { 1228 LOG.debug("Details", e); 1229 return Response.serverError().status(Status.UNAUTHORIZED) 1230 .build(); 1231 } catch (UserUnauthorizedException ex) { 1232 return Response.status(Status.FORBIDDEN) 1233 .build(); 1234 } catch (ItemNotFoundException e1) { 1235 return Response.serverError().status(Status.NOT_FOUND) 1236 .entity("" + e1.getMessage()).build(); 1237 } 1238 } 1239 1240 @Override 1241 @GET 1242 @Path("/pingSession") 1243 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1244 MediaType.APPLICATION_JSON}) 1245 public Response pingSession() { 1246 boolean stillActive = false; 1247 Principal userPrincipal = security.getUserPrincipal(); 1248 if (LOG.isInfoEnabled()) { 1249 LOG.debug("ping by <{}>", 1250 (userPrincipal == null ? "unauthorized user" 1251 : userPrincipal.getName())); 1252 } 1253 if (request != null) { 1254 if (userPrincipal != null 1255 && !ComponentRegistryFactory.ANONYMOUS_USER 1256 .equals(userPrincipal.getName())) { 1257 stillActive = !((HttpServletRequest) request).getSession() 1258 .isNew(); 1259 } 1260 } 1261 return Response 1262 .ok() 1263 .entity(String.format("<session stillActive=\"%s\"/>", 1264 stillActive)).build(); 1265 } 1266 1267 private Response register(InputStream input, BaseDescription desc, RegisterAction action, ComponentRegistry registry) throws UserUnauthorizedException { 1268 try { 1269 1270 1271 DescriptionValidator descriptionValidator = new DescriptionValidator( 1272 desc); 1273 MDValidator validator = new MDValidator(input, desc, registry, marshaller); 1274 RegisterResponse response = new RegisterResponse(); 1275 //obsolete. Make it setstatus 1276 response.setIsInUserSpace(!desc.isPublic()); 1277 this.validate(response, descriptionValidator, validator); 1278 if (response.getErrors().isEmpty()) { 1279 1280 CMDComponentSpec spec = validator.getCMDComponentSpec(); 1281 1282 // removing filename from spec before it gets extended. 1283 // recursion over all the components 1284 setFileNamesFromListToNull(Collections.singletonList(spec.getCMDComponent())); 1285 1286 try { 1287 checkForRecursion(validator, registry, desc); 1288 1289 // Add profile 1290 int returnCode = action.execute(desc, spec, response, 1291 registry); 1292 if (returnCode == 0) { 1293 response.setRegistered(true); 1294 response.setDescription(desc); 1295 } else { 1296 response.setRegistered(false); 1297 response.addError("Unable to register at this moment. Internal server error."); 1298 } 1299 } catch (ComponentRegistryException ex) { 1300 // Recursion detected 1301 response.setRegistered(false); 1302 response.addError("Error while expanding specification. " 1303 + ex.getMessage()); 1304 } catch (ItemNotFoundException ex) { 1305 // Recursion detected 1306 response.setRegistered(false); 1307 response.addError("Error while expanding specification. " 1308 + ex.getMessage()); 1309 } 1310 } else { 1311 LOG.warn("Registration failed with validation errors: {}", 1312 Arrays.toString(response.getErrors().toArray())); 1313 response.setRegistered(false); 1314 } 1315 LOG.info("Registered new {} {}", desc.isProfile() ? "profile" 1316 : "component", desc); 1317 response.setIsProfile(desc.isProfile()); 1318 return Response.ok(response).build(); 1319 } finally { 1320 try { 1321 input.close();// either we read the input or there was an 1322 // exception, we need to close it. 1323 } catch (IOException e) { 1324 LOG.error("Error when closing inputstream: ", e); 1325 } 1326 } 1327 } 1328 1329 /** 1330 * 1331 * @param validator 1332 * @param registry 1333 * @param desc 1334 * @throws ComponentRegistryException if recursion is detected or something 1335 * goes wrong while trying to detect recursion 1336 */ 1337 private void checkForRecursion(MDValidator validator, 1338 ComponentRegistry registry, BaseDescription desc) 1339 throws ComponentRegistryException { 1340 try { 1341 // Expand to check for recursion. Operate on copy so that original 1342 // does not get expanded. 1343 final CMDComponentSpec specCopy = validator 1344 .getCopyOfCMDComponentSpec(); 1345 // In case of recursion, the following will throw a 1346 // ComponentRegistryException 1347 registry.getExpander().expandNestedComponent( 1348 Lists.newArrayList(specCopy.getCMDComponent()), desc.getId()); 1349 } catch (JAXBException ex) { 1350 throw new ComponentRegistryException( 1351 "Unmarshalling failed while preparing recursion detection", 1352 ex); 1353 } 1354 } 1355 1356 private Response registerComment(InputStream input, BaseDescription description, ComponentRegistry registry) throws UserUnauthorizedException, AuthenticationFailException { 1357 try { 1358 CommentValidator validator = new CommentValidator(input, description, marshaller); 1359 CommentResponse responseLocal = new CommentResponse(); 1360 1361 responseLocal.setIsInUserSpace(!description.isPublic()); 1362 this.validateComment(responseLocal, validator); 1363 if (responseLocal.getErrors().isEmpty()) { 1364 Comment com = validator.getCommentSpec(); 1365 // int returnCode = action.executeComment(com, response, 1366 // registry, principal.getName()); 1367 1368 // If user name is left empty, fill it using the user's display 1369 // name 1370 1371 Principal principal = this.checkAndGetUserPrincipal(); 1372 UserCredentials userCredentials = this.getUserCredentials(principal); 1373 if (null == com.getUserName() || "".equals(com.getUserName())) { 1374 if (userCredentials != null) { 1375 com.setUserName(userCredentials.getDisplayName()); 1376 } else { 1377 com.setUserName(principal.getName()); 1378 } 1379 } 1380 try { 1381 int returnCode = registry.registerComment(com, 1382 principal.getName()); 1383 if (returnCode == 0) { 1384 responseLocal.setRegistered(true); 1385 responseLocal.setComment(com); 1386 } else { 1387 responseLocal.setRegistered(false); 1388 responseLocal.addError("Unable to post at this moment. Internal server error."); 1389 } 1390 if (com.getComponentId() != null) { 1391 LOG.info("Posted new comment on component {}", 1392 com.getComponentId()); 1393 } else { 1394 LOG.info("Posted new comment on profile {}", 1395 com.getComponentId()); 1396 } 1397 } catch (ItemNotFoundException e) { 1398 return Response.serverError().status(Status.NOT_FOUND) 1399 .entity("" + e.getMessage()).build(); 1400 } 1401 } else { 1402 LOG.warn( 1403 "Posting of comment failed with validation errors: {}", 1404 Arrays.toString(responseLocal.getErrors().toArray())); 1405 responseLocal.setRegistered(false); 1406 } 1407 return Response.ok(responseLocal).build(); 1408 } catch (ComponentRegistryException ex) { 1409 LOG.error("Error while inserting comment: ", ex); 1410 return Response.serverError().entity(ex.getMessage()).build(); 1411 } finally { 1412 try { 1413 input.close();// either we read the input or there was an 1414 // exception, we need to close it. 1415 } catch (IOException e) { 1416 LOG.error("Error when closing inputstream: ", e); 1417 return Response.serverError().build(); 1418 } 1419 } 1420 } 1421 1422 private ComponentDescription createNewComponentDescription() { 1423 ComponentDescription desc = ComponentDescription.createNewDescription(); 1424 desc.setHref(createXlink(desc.getId())); 1425 return desc; 1426 } 1427 1428 private ProfileDescription createNewProfileDescription() { 1429 ProfileDescription desc = ProfileDescription.createNewDescription(); 1430 desc.setHref(createXlink(desc.getId())); 1431 return desc; 1432 } 1433 1434 private String createXlink(String id) { 1435 URI uri = uriInfo.getRequestUriBuilder().path(id).build(); 1436 return uri.toString(); 1437 } 1438 1439 /** 1440 * 1441 * @return The application's base URI as configured in the 1442 * {@link #APPLICATION_BASE_URL_PARAM} context parameter. If correctly 1443 * configured, it should look something like 1444 * "http://catalog.clarin.eu/ds/ComponentRegistry". <em>Be aware that this 1445 * can also be null if configured incorrectly!</em> 1446 * 1447 * @see #APPLICATION_BASE_URL_PARAM 1448 */ 1449 private String getApplicationBaseURI() { 1450 return servletContext.getInitParameter(APPLICATION_BASE_URL_PARAM); 1451 } 1452 1453 private void validate(RegisterResponse response, Validator... validators) throws UserUnauthorizedException { 1454 for (Validator validator : validators) { 1455 if (!validator.validate()) { 1456 for (String error : validator.getErrorMessages()) { 1457 response.addError(error); 1458 } 1459 } 1460 } 1461 } 1462 1463 private void validateComment(CommentResponse response, 1464 Validator... validators) throws UserUnauthorizedException { 1465 for (Validator validator : validators) { 1466 if (!validator.validate()) { 1467 for (String error : validator.getErrorMessages()) { 1468 response.addError(error); 1469 } 1470 } 1471 } 1472 } 1473 1474 /** 1475 * @param componentRegistryFactory the componentRegistryFactory to set 1476 */ 1477 @Override 1478 public void setComponentRegistryFactory( 1479 ComponentRegistryFactory componentRegistryFactory) { 1480 this.componentRegistryFactory = componentRegistryFactory; 1481 } 1482 1483 /** 1484 * 1485 * @param listofcomponents a list of components whose file-names and whose 1486 * childrens' filenames are to be set to null 1487 */ 1488 @Override 1489 public void setFileNamesFromListToNull( 1490 List<CMDComponentType> listofcomponents) { 1491 1492 for (CMDComponentType currentcomponent : listofcomponents) { 1493 setFileNamesToNullCurrent(currentcomponent); 1494 } 1495 1496 } 1497 1498 /** 1499 * 1500 * @param currentcomponent a component whose file-name and whose children 1501 * filenames are to be set to null 1502 */ 1503 protected void setFileNamesToNullCurrent(CMDComponentType currentcomponent) { 1504 currentcomponent.setFilename(null); 1505 setFileNamesFromListToNull(currentcomponent.getCMDComponent()); 1506 } 1507 1508 /** 1509 * 1510 * @param isPublished if "true" then profiles and components from the user's 1511 * workspace, otherwise -- public 1512 * @param limit the number of items to be displayed 1513 * @return rss for the components in the database to which we are currently 1514 * connected 1515 * @throws ComponentRegistryException 1516 * @throws ParseException 1517 */ 1518 @Override 1519 @GET 1520 @Path("/components/rss") 1521 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1522 MediaType.APPLICATION_JSON}) 1523 public Rss getRssComponent(@QueryParam(GROUPID_PARAM) String groupId, 1524 @QueryParam(REGISTRY_SPACE_PARAM) @DefaultValue("published") String registrySpace, 1525 @QueryParam(NUMBER_OF_RSSITEMS) @DefaultValue("20") String limit) 1526 throws ComponentRegistryException, ParseException, IOException { 1527 List<ComponentDescription> components = null; 1528 try { 1529 ComponentRegistry cr = this.initialiseRegistry(registrySpace, groupId); 1530 components = cr.getComponentDescriptions(); 1531 } catch (AuthenticationFailException e) { 1532 response.sendError(Status.UNAUTHORIZED.getStatusCode(), e.toString()); 1533 return new Rss(); 1534 } catch (UserUnauthorizedException e) { 1535 response.sendError(Status.FORBIDDEN.getStatusCode(), e.toString()); 1536 return new Rss(); 1537 } 1538 // obsolete, add group Id 1539 final RssCreatorDescriptions instance = new RssCreatorDescriptions(!registrySpace.equalsIgnoreCase("published"), getApplicationBaseURI(), "components", 1540 Integer.parseInt(limit), components, 1541 ComponentUtils.COMPARE_ON_DATE); 1542 final Rss rss = instance.getRss(); 1543 LOG.debug("Releasing RSS of {} most recently registered components", 1544 limit); 1545 return rss; 1546 } 1547 1548 /** 1549 * 1550 * @param isPublished if "true" then profiles and components from the user's 1551 * workspace, otherwise -- public 1552 * @param limit the number of items to be displayed 1553 * @return rss for the profiles in the database to which we are currently 1554 * connected 1555 * @throws ComponentRegistryException 1556 * @throws ParseException 1557 */ 1558 @Override 1559 @GET 1560 @Path("/profiles/rss") 1561 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1562 MediaType.APPLICATION_JSON}) 1563 public Rss getRssProfile(@QueryParam(GROUPID_PARAM) String groupId, 1564 @QueryParam(REGISTRY_SPACE_PARAM) @DefaultValue("published") String registrySpace, 1565 @QueryParam(NUMBER_OF_RSSITEMS) @DefaultValue("20") String limit) 1566 throws ComponentRegistryException, ParseException, IOException { 1567 List<ProfileDescription> profiles = null; 1568 try { 1569 ComponentRegistry cr = this.initialiseRegistry(registrySpace, groupId); 1570 profiles = cr.getProfileDescriptions(); 1571 } catch (AuthenticationFailException e) { 1572 response.sendError(Status.UNAUTHORIZED.getStatusCode(), e.toString()); 1573 return new Rss(); 1574 } catch (UserUnauthorizedException e) { 1575 response.sendError(Status.FORBIDDEN.getStatusCode(), e.toString()); 1576 return new Rss(); 1577 } 1578 final RssCreatorDescriptions instance = new RssCreatorDescriptions( 1579 !registrySpace.equalsIgnoreCase("published"), getApplicationBaseURI(), "profiles", 1580 Integer.parseInt(limit), profiles, 1581 ComponentUtils.COMPARE_ON_DATE); 1582 final Rss rss = instance.getRss(); 1583 LOG.debug("Releasing RSS of {} most recently registered profiles", 1584 limit); 1585 return rss; 1586 } 1587 1588 /** 1589 * 1590 * @param profileId the Id of a profile whose comments are to be rss-ed 1591 * @param isPublished if "true" then profiles and components from the user's 1592 * workspace, otherwise -- public 1593 * @param limit the number of items to be displayed 1594 * @return rss of the comments for a chosen profile 1595 * @throws ComponentRegistryException 1596 * @throws IOException 1597 * @throws JAXBException 1598 * @throws ParseException 1599 */ 1600 @Override 1601 @GET 1602 @Path("/profiles/{profileId}/comments/rss") 1603 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1604 MediaType.APPLICATION_JSON}) 1605 public Rss getRssOfCommentsFromProfile( 1606 @PathParam("profileId") String profileId, 1607 @QueryParam(NUMBER_OF_RSSITEMS) @DefaultValue("20") String limit) 1608 throws ComponentRegistryException, IOException, JAXBException, 1609 ParseException { 1610 try { 1611 1612 ComponentRegistry cr = this.getBaseRegistry(); 1613 1614 final List<Comment> comments = cr.getCommentsInProfile(profileId); 1615 final ProfileDescription pd = cr.getProfileDescriptionAccessControlled(profileId); 1616 final String profileName = pd.getName(); 1617 boolean profileIsPrivate = !pd.isPublic(); 1618 // obsolete, status must be involved, not boolean profileIsPrivate 1619 final RssCreatorComments instance = new RssCreatorComments(profileIsPrivate, 1620 getApplicationBaseURI(), Integer.parseInt(limit), profileId, 1621 profileName, "profile", comments, Comment.COMPARE_ON_DATE); 1622 final Rss rss = instance.getRss(); 1623 LOG.debug("Releasing RSS of {} most recent post on profile {}", limit, 1624 profileId); 1625 return rss; 1626 } catch (UserUnauthorizedException ex) { 1627 response.sendError(Status.FORBIDDEN.getStatusCode()); 1628 return new Rss(); 1629 } catch (ItemNotFoundException e) { 1630 response.sendError(Status.NOT_FOUND.getStatusCode()); 1631 return new Rss(); 1632 } catch (AuthenticationFailException e) { 1633 response.sendError(Status.UNAUTHORIZED.getStatusCode(), e.toString()); 1634 return new Rss(); 1635 } 1636 } 1637 1638 /** 1639 * 1640 * @param componentId the Id of a component whose comments are to be rss-ed 1641 * @param isPublished if "true" then profiles and components from the user's 1642 * workspace, otherwise -- public 1643 * @param limit the number of items to be displayed 1644 * @return rss of the comments for a chosen component 1645 * @throws ComponentRegistryException 1646 * @throws IOException 1647 * @throws JAXBException 1648 * @throws ParseException 1649 */ 1650 @Override 1651 @GET 1652 @Path("/components/{componentId}/comments/rss") 1653 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1654 MediaType.APPLICATION_JSON}) 1655 public Rss getRssOfCommentsFromComponent( 1656 @PathParam("componentId") String componentId, 1657 @QueryParam(NUMBER_OF_RSSITEMS) 1658 @DefaultValue("20") String limit) 1659 throws ComponentRegistryException, IOException, JAXBException, 1660 ParseException { 1661 try { 1662 ComponentRegistry cr = this.getBaseRegistry(); 1663 final List<Comment> comments = cr.getCommentsInComponent(componentId); 1664 final ComponentDescription cd = cr.getComponentDescriptionAccessControlled(componentId); 1665 final String componentName = cd.getName(); 1666 final boolean isPrivate = !cd.isPublic(); 1667 //oboslete. status must be involved, not boolean isPrivate 1668 final RssCreatorComments instance = new RssCreatorComments(isPrivate, 1669 getApplicationBaseURI(), Integer.parseInt(limit), componentId, 1670 componentName, "component", comments, Comment.COMPARE_ON_DATE); 1671 final Rss rss = instance.getRss(); 1672 LOG.debug("Releasing RSS of {} most recent post on component {}", 1673 limit, componentId); 1674 return rss; 1675 } catch (UserUnauthorizedException e) { 1676 response.sendError(Status.FORBIDDEN.getStatusCode()); 1677 return new Rss(); 1678 } catch (ItemNotFoundException e) { 1679 response.sendError(Status.NOT_FOUND.getStatusCode()); 1680 return new Rss(); 1681 } catch (AuthenticationFailException e1) { 1682 response.sendError(Status.UNAUTHORIZED.getStatusCode()); 1683 return new Rss(); 1684 } 1685 1686 } 1687 1688 @Override 1689 @GET 1690 @Path("/AllowedTypes") 1691 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1692 MediaType.APPLICATION_JSON}) 1693 public AllowedAttributetypesXML getAllowedAttributeTypes() 1694 throws ComponentRegistryException, IOException, JAXBException, 1695 ParseException { 1696 return (new AllowedAttributetypesXML()); 1697 } 1698 1699 @Override 1700 @GET 1701 @Path("/groups/usermembership") 1702 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1703 MediaType.APPLICATION_JSON}) 1704 public List<Group> getGroupsTheCurrentUserIsAMemberOf() { 1705 Principal principal = security.getUserPrincipal(); 1706 if (principal == null) { 1707 return new ArrayList<Group>(); 1708 } 1709 List<Group> groups = groupService.getGroupsOfWhichUserIsAMember(principal.getName()); 1710 return groups; 1711 } 1712 1713 @Override 1714 @GET 1715 @Path("/items/{itemId}/groups") 1716 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1717 MediaType.APPLICATION_JSON}) 1718 public List<Group> getGroupsTheItemIsAMemberOf(@PathParam("itemId") String itemId) { 1719 return groupService.getGroupsTheItemIsAMemberOf(itemId); 1720 } 1721 1722 @Override 1723 @POST 1724 @Path("/items/{itemId}/transferownership") 1725 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1726 MediaType.APPLICATION_JSON}) 1727 public String transferItemOwnershipToGroup(@PathParam("itemId") String itemId, 1728 @QueryParam("groupId") long groupId) throws IOException { 1729 Principal principal = security.getUserPrincipal(); 1730 try { 1731 groupService.transferItemOwnershipFromUserToGroupId(principal.getName(), groupId, itemId); 1732 return "No exceptions happen, the item shoul be transferred"; 1733 } catch (UserUnauthorizedException e) { 1734 response.sendError(Status.FORBIDDEN.getStatusCode(), e.toString()); 1735 return e.toString(); 1736 } 1737 } 1738 1739 @Override 1740 @GET 1741 @Path("/items/{itemId}") 1742 @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, 1743 MediaType.APPLICATION_JSON}) 1744 public BaseDescription getBaseDescription(@PathParam("itemId") String itemId) throws ComponentRegistryException, IOException { 1745 LOG.debug("Item with id: {} is requested.", itemId); 1746 try { 1747 ComponentRegistry cr = this.getBaseRegistry(); 1748 try { 1749 BaseDescription description = cr.getComponentDescriptionAccessControlled(itemId); 1750 return description; 1751 } catch (UserUnauthorizedException ex1) { 1752 try { 1753 BaseDescription description = cr.getProfileDescriptionAccessControlled(itemId); 1754 return description; 1755 } catch (UserUnauthorizedException ex2) { 1756 response.sendError(Status.FORBIDDEN.getStatusCode(), "User \'" + security.getUserPrincipal().getName() + "\' does not have access to the item with the given id or the item with the given id does not exist."); 1757 return new BaseDescription(); 1758 } 1759 } 1760 } catch (ItemNotFoundException e) { 1761 response.sendError(Status.NOT_FOUND.getStatusCode()); 1762 return new BaseDescription(); 1763 } catch (AuthenticationFailException e) { 1764 response.sendError(Status.UNAUTHORIZED.getStatusCode(), e.toString()); 1765 return new BaseDescription(); 1766 } 1767 } 1605 1768 }
Note: See TracChangeset
for help on using the changeset viewer.