From: Rick Jaffe Date: Wed, 14 Mar 2012 05:09:27 +0000 (-0700) Subject: CSPACE-4391: Adding Place service (entire folder) X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=232ca0a722eca75699100917e759d8ac086de584;p=tmp%2Fjakarta-migration.git CSPACE-4391: Adding Place service (entire folder) --- diff --git a/services/place/3rdparty/build.xml b/services/place/3rdparty/build.xml new file mode 100644 index 000000000..22122c677 --- /dev/null +++ b/services/place/3rdparty/build.xml @@ -0,0 +1,131 @@ + + + + place service 3rdparty + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/place/3rdparty/nuxeo-platform-cs-place/build.xml b/services/place/3rdparty/nuxeo-platform-cs-place/build.xml new file mode 100644 index 000000000..8f3500132 --- /dev/null +++ b/services/place/3rdparty/nuxeo-platform-cs-place/build.xml @@ -0,0 +1,149 @@ + + + + place nuxeo document type + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/place/3rdparty/nuxeo-platform-cs-place/pom.xml b/services/place/3rdparty/nuxeo-platform-cs-place/pom.xml new file mode 100644 index 000000000..f3daccadf --- /dev/null +++ b/services/place/3rdparty/nuxeo-platform-cs-place/pom.xml @@ -0,0 +1,37 @@ + + + org.collectionspace.services + org.collectionspace.services.place.3rdparty + 2.2-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.place.3rdparty.nuxeo + services.place.3rdparty.nuxeo + jar + + Place Nuxeo Document Type + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + src/main/resources/META-INF/MANIFEST.MF + + ${eclipseVersion} + 2 + + + + + + + + diff --git a/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/META-INF/MANIFEST.MF b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 000000000..348b873b4 --- /dev/null +++ b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,23 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 1 +Bundle-Name: NuxeoCS +Bundle-SymbolicName: org.collectionspace.place;singleton:=true +Bundle-Version: 1.0.0 +Bundle-Localization: plugin +Bundle-Vendor: Nuxeo +Require-Bundle: org.nuxeo.runtime, + org.nuxeo.ecm.core.api, + org.nuxeo.ecm.core, + org.nuxeo.ecm.core.api, + org.nuxeo.ecm.platform.types.api, + org.nuxeo.ecm.platform.versioning.api, + org.nuxeo.ecm.platform.ui, + org.nuxeo.ecm.platform.forms.layout.client, + org.nuxeo.ecm.platform.ws, + org.collectionspace.collectionspace_core +Provide-Package: org.collectionspace.place +Nuxeo-Component: OSGI-INF/core-types-contrib.xml, + OSGI-INF/life-cycle-contrib.xml, + OSGI-INF/ecm-types-contrib.xml, + OSGI-INF/layouts-contrib.xml + diff --git a/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/core-types-contrib.xml b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/core-types-contrib.xml new file mode 100644 index 000000000..799d003b1 --- /dev/null +++ b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/core-types-contrib.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/deployment-fragment.xml b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/deployment-fragment.xml new file mode 100644 index 000000000..8bbdd72b6 --- /dev/null +++ b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/deployment-fragment.xml @@ -0,0 +1,408 @@ + + + + + + ${bundle.fileName} + + + + + nuxeo.war + /nuxeo + + + + + + + + + + + + Seam Context Filter + /ws/FileManageWS + + + + Seam Context Filter + /DocumentManagerWS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #{currentServerLocation.name}/#{currentTabAction.label} + + + + Create new document in #{currentDocument.name} + + + + Create new document in #{currentDocument.name} + + + + breadcrumb=command.user_dashboard + + + + breadcrumb=command.manageMembers + + + + breadcrumb=command.manageMembers + + + + breadcrumb=title.orgauthorities + + + + breadcrumb=command.advancedSearch + + + + + + en + en_GB + en_US + fr + de + es + it + ar + ru + ja + vn + + + messages + + + + config/addWorkspace.jpdl.xml + + + + + + generic_error_page + /generic_error_page.xhtml + + + + + generic_message_page + /generic_message_page.xhtml + + + + + home + /nxstartup.xhtml + + + + + user_login + /login.xhtml + + + + + user_logout + /logout.xhtml + + + + + view_servers + /view_servers.xhtml + + + + + + + view_domains + /view_domains.xhtml + + + + + select_document_type + /select_document_type.xhtml + + + + + create_document + /create_document.xhtml + + + + + edit_document + /edit_document.xhtml + + + + + view_documents + /view_documents.xhtml + + + + + create_file + /create_file.xhtml + + + + + create_workspace_wizard + /createWorkspaceWizard.xhtml + + + + + send_email + /document_email.xhtml + + + + + + view_workspaces + /view_workspaces.xhtml + + + + + + create_domain + /create_domain.xhtml + + + + + + edit_domain + /edit_domain.xhtml + + + + + + create_workspace + /create_workspace.xhtml + + + + + + edit_workspace + /edit_workspace.xhtml + + + + + + + members_management + /members_management.xhtml + + + + + view_users + /view_users.xhtml + + + + + view_many_users + /view_many_users.xhtml + + + + + edit_user + /edit_user.xhtml + + + + + edit_user_password + /edit_user_password.xhtml + + + + + view_user + /view_user.xhtml + + + + + create_user + /create_user.xhtml + + + + + view_groups + /view_groups.xhtml + + + + + view_group + /view_group.xhtml + + + + + edit_group + /edit_group.xhtml + + + + + create_group + /create_group.xhtml + + + + + view_orgauthorities + /view_orgauthorities.xhtml + + + + + view_orgauthority + /view_orgauthority.xhtml + + + + + + + search_form + /search/search_form.xhtml + + + + + search_results_nxql + /search/search_results_nxql.xhtml + + + + + search_results_advanced + + /search/search_results_advanced.xhtml + + + + + + search_results_simple + /search/search_results_simple.xhtml + + + + + + + clipboard + /incl/clipboard.xhtml + + + + + user_dashboard + /user_dashboard.xhtml + + + + + select_workspace_template + /select_workspace_template.xhtml + + + + + pdf_generation_error + /pdf_generation_error.xhtml + + + + + mass_edit + /massedit_documents.xhtml + + + + + mass_edit_confirm + /massedit_documents_preview.xhtml + + + + + + diff --git a/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/ecm-types-contrib.xml b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/ecm-types-contrib.xml new file mode 100644 index 000000000..304c85bca --- /dev/null +++ b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/ecm-types-contrib.xml @@ -0,0 +1,53 @@ + + + + + + + view_documents + + + heading + csplaceauthority + + + + + + Placeauthority + + + + + + Placeauthority + + + + + + + + + view_documents + + + heading + place + + + + + + Place + + + + + + Place + + + + + diff --git a/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/layouts-contrib.xml b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/layouts-contrib.xml new file mode 100644 index 000000000..e24523d79 --- /dev/null +++ b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/layouts-contrib.xml @@ -0,0 +1,240 @@ + + + + + + + + + + + + displayName + shortIdentifier + refName + vocabType + + + + + + + true + + displayName + + + dataInputText + + + + + + + + true + + shortIdentifier + + + dataInputText + + + + + + + + true + + refName + + + dataInputText + + + + + + + + true + + vocabType + + + dataInputText + + + + + + + + + + + + + inAuthority + shortIdentifier + refName + displayName + displayNameComputed + name + conditionNote + conditionNoteDate + securityNote + placeType + status + + + + + + + true + + inAuthority + + + dataInputText + + + + + + + + true + + shortIdentifier + + + dataInputText + + + + + + + + true + + refName + + + dataInputText + + + + + + + + true + + displayName + + + dataInputText + + + + + + + + + true + + displayNameComputed + + + dataInputText + + + + + + + + true + + name + + + dataInputText + + + + + + + + true + + conditionNote + + + dataInputText + + + + + + + + true + + conditionNoteDate + + + dataInputText + + + + + + + + true + + securityNote + + + dataInputText + + + + + + + + true + + placeType + + + dataInputText + + + + + + + + true + + status + + + dataInputText + + + + + + diff --git a/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/life-cycle-contrib.xml b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/life-cycle-contrib.xml new file mode 100644 index 000000000..8e05ab2fc --- /dev/null +++ b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/OSGI-INF/life-cycle-contrib.xml @@ -0,0 +1,12 @@ + + + + + + default + default + + + + diff --git a/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/schemas/placeauthorities_common.xsd b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/schemas/placeauthorities_common.xsd new file mode 100644 index 000000000..25603c1d8 --- /dev/null +++ b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/schemas/placeauthorities_common.xsd @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + diff --git a/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/schemas/places_common.xsd b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/schemas/places_common.xsd new file mode 100644 index 000000000..a59b671c7 --- /dev/null +++ b/services/place/3rdparty/nuxeo-platform-cs-place/src/main/resources/schemas/places_common.xsd @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/place/3rdparty/pom.xml b/services/place/3rdparty/pom.xml new file mode 100644 index 000000000..81773d467 --- /dev/null +++ b/services/place/3rdparty/pom.xml @@ -0,0 +1,23 @@ + + + + org.collectionspace.services + org.collectionspace.services.place + 2.2-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.place.3rdparty + services.place.3rdparty + pom + + 3rd party build for place service + + + + nuxeo-platform-cs-place + + diff --git a/services/place/build.xml b/services/place/build.xml new file mode 100644 index 000000000..2ddc143ce --- /dev/null +++ b/services/place/build.xml @@ -0,0 +1,131 @@ + + + Place Authority service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/place/client/pom.xml b/services/place/client/pom.xml new file mode 100644 index 000000000..9ad9daa5d --- /dev/null +++ b/services/place/client/pom.xml @@ -0,0 +1,91 @@ + + + + org.collectionspace.services + org.collectionspace.services.place + 2.2-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.place.client + services.place.client + + + + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-log4j12 + + + + org.collectionspace.services + org.collectionspace.services.jaxb + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.common + true + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.place.jaxb + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.client + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.authority.jaxb + true + ${project.version} + + + + org.testng + testng + + + org.jboss.resteasy + resteasy-jaxrs + + + + tjws + webserver + + + + + org.jboss.resteasy + resteasy-jaxb-provider + + + org.jboss.resteasy + resteasy-multipart-provider + + + commons-httpclient + commons-httpclient + 3.1 + + + + + collectionspace-services-place-client + + + + + diff --git a/services/place/client/src/main/java/org/collectionspace/services/client/PlaceAuthorityClient.java b/services/place/client/src/main/java/org/collectionspace/services/client/PlaceAuthorityClient.java new file mode 100644 index 000000000..981e6adde --- /dev/null +++ b/services/place/client/src/main/java/org/collectionspace/services/client/PlaceAuthorityClient.java @@ -0,0 +1,80 @@ +/** + * PlaceAuthorityClient.java + * + * {Purpose of This Class} + * + * {Other Notes Relating to This Class (Optional)} + * + * $LastChangedBy: $ + * $LastChangedRevision: $ + * $LastChangedDate: $ + * + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright © 2009 {Contributing Institution} + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + */ +package org.collectionspace.services.client; + +import org.collectionspace.services.place.PlacesCommon; +/** + * The Class PlaceAuthorityClient. + */ +public class PlaceAuthorityClient extends AuthorityClientImpl { + public static final String SERVICE_NAME = "placeauthorities"; + public static final String SERVICE_PATH_COMPONENT = SERVICE_NAME; + public static final String SERVICE_PATH = "/" + SERVICE_PATH_COMPONENT; + public static final String SERVICE_PAYLOAD_NAME = SERVICE_NAME; + // + // Subitem constants + // + public static final String SERVICE_ITEM_NAME = "places"; + public static final String SERVICE_ITEM_PAYLOAD_NAME = SERVICE_ITEM_NAME; + // + // Payload Part/Schema part names + // + public static final String SERVICE_COMMON_PART_NAME = SERVICE_NAME + + PART_LABEL_SEPARATOR + PART_COMMON_LABEL; + public static final String SERVICE_ITEM_COMMON_PART_NAME = SERVICE_ITEM_NAME + + PART_LABEL_SEPARATOR + PART_COMMON_LABEL; + + @Override + public String getServiceName() { + return SERVICE_NAME; + } + + @Override + public String getServicePathComponent() { + return SERVICE_PATH_COMPONENT; + } + + @Override + public String getItemCommonPartName() { + return getCommonPartName(SERVICE_ITEM_NAME); + } + + @Override + public Class getProxyClass() { + return PlaceAuthorityProxy.class; + } + + @Override + public String getInAuthority(PlacesCommon item) { + return item.getInAuthority(); + } + + @Override + public void setInAuthority(PlacesCommon item, String inAuthorityCsid) { + item.setInAuthority(inAuthorityCsid); + } +} diff --git a/services/place/client/src/main/java/org/collectionspace/services/client/PlaceAuthorityClientUtils.java b/services/place/client/src/main/java/org/collectionspace/services/client/PlaceAuthorityClientUtils.java new file mode 100644 index 000000000..b537e8c16 --- /dev/null +++ b/services/place/client/src/main/java/org/collectionspace/services/client/PlaceAuthorityClientUtils.java @@ -0,0 +1,310 @@ +package org.collectionspace.services.client; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; + +import org.apache.commons.io.FileUtils; +import org.collectionspace.services.PlaceJAXBSchema; +import org.collectionspace.services.client.test.ServiceRequestType; +import org.collectionspace.services.place.PlaceauthoritiesCommon; +import org.collectionspace.services.place.PlaceNameGroup; +import org.collectionspace.services.place.PlaceNameGroupList; +import org.collectionspace.services.place.PlacesCommon; +import org.dom4j.DocumentException; +import org.jboss.resteasy.client.ClientResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PlaceAuthorityClientUtils { + private static final Logger logger = + LoggerFactory.getLogger(PlaceAuthorityClientUtils.class); + + /** + * Creates a new Place Authority + * @param displayName The displayName used in UI, etc. + * @param refName The proper refName for this authority + * @param headerLabel The common part label + * @return The PoxPayloadOut payload for the create call + */ + public static PoxPayloadOut createPlaceAuthorityInstance( + String displayName, String shortIdentifier, String headerLabel ) { + PlaceauthoritiesCommon placeAuthority = new PlaceauthoritiesCommon(); + placeAuthority.setDisplayName(displayName); + placeAuthority.setShortIdentifier(shortIdentifier); + String refName = createPlaceAuthRefName(shortIdentifier, displayName); + placeAuthority.setRefName(refName); + placeAuthority.setVocabType("PlaceAuthority"); //FIXME: REM - Should this really be hard-coded? + PoxPayloadOut multipart = new PoxPayloadOut(PlaceAuthorityClient.SERVICE_PAYLOAD_NAME); + PayloadOutputPart commonPart = multipart.addPart(placeAuthority, MediaType.APPLICATION_XML_TYPE); + commonPart.setLabel(headerLabel); + + if(logger.isDebugEnabled()){ + logger.debug("to be created, placeAuthority common ", + placeAuthority, PlaceauthoritiesCommon.class); + } + + return multipart; + } + + /** + * @param placeRefName The proper refName for this authority + * @param placeInfo the properties for the new Place. Can pass in one condition + * note and date string. + * @param headerLabel The common part label + * @return The PoxPayloadOut payload for the create call + */ + public static PoxPayloadOut createPlaceInstance( + String placeAuthRefName, Map placeInfo, + String headerLabel){ + PlacesCommon place = new PlacesCommon(); + String shortId = placeInfo.get(PlaceJAXBSchema.SHORT_IDENTIFIER); + String displayName = placeInfo.get(PlaceJAXBSchema.DISPLAY_NAME); + place.setShortIdentifier(shortId); + String placeRefName = createPlaceRefName(placeAuthRefName, shortId, displayName); + place.setRefName(placeRefName); + String value = null; + value = placeInfo.get(PlaceJAXBSchema.DISPLAY_NAME_COMPUTED); + boolean displayNameComputed = (value==null) || value.equalsIgnoreCase("true"); + place.setDisplayNameComputed(displayNameComputed); + if((value = (String)placeInfo.get(PlaceJAXBSchema.DISPLAY_NAME))!=null) + place.setDisplayName(value); + value = placeInfo.get(PlaceJAXBSchema.DISPLAY_NAME_COMPUTED); + displayNameComputed = (value==null) || value.equalsIgnoreCase("true"); + place.setDisplayNameComputed(displayNameComputed); + /* TODO - think about how much to support. This approach to the client + * does not scale! We should really favor the document/payload approach. */ + if((value = (String)placeInfo.get(PlaceJAXBSchema.NAME))!=null) { + PlaceNameGroupList placeNameGroupList = new PlaceNameGroupList(); + List placeNameGroups = placeNameGroupList.getPlaceNameGroup(); + PlaceNameGroup placeNameGroup = new PlaceNameGroup(); + placeNameGroup.setName(value); + placeNameGroups.add(placeNameGroup); + place.setPlaceNameGroupList(placeNameGroupList); + } + + + if((value = (String)placeInfo.get(PlaceJAXBSchema.TERM_STATUS))!=null) + place.setTermStatus(value); + + PoxPayloadOut multipart = new PoxPayloadOut(PlaceAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME); + PayloadOutputPart commonPart = multipart.addPart(place, + MediaType.APPLICATION_XML_TYPE); + commonPart.setLabel(headerLabel); + + if(logger.isDebugEnabled()){ + logger.debug("to be created, place common ", place, PlacesCommon.class); + } + + return multipart; + } + + /** + * @param vcsid CSID of the authority to create a new placplace + * @param placeAuthorityRefName The refName for the authority + * @param placeMap the properties for the new Place + * @param client the service client + * @return the CSID of the new item + */ + public static String createItemInAuthority(String vcsid, + String placeAuthorityRefName, Map placeMap, + PlaceAuthorityClient client ) { + // Expected status code: 201 Created + int EXPECTED_STATUS_CODE = Response.Status.CREATED.getStatusCode(); + // Type of service request being tested + ServiceRequestType REQUEST_TYPE = ServiceRequestType.CREATE; + + String displayName = placeMap.get(PlaceJAXBSchema.DISPLAY_NAME); + String displayNameComputedStr = placeMap.get(PlaceJAXBSchema.DISPLAY_NAME_COMPUTED); + boolean displayNameComputed = (displayNameComputedStr==null) || displayNameComputedStr.equalsIgnoreCase("true"); + if( displayName == null ) { + if(!displayNameComputed) { + throw new RuntimeException( + "CreateItem: Must supply a displayName if displayNameComputed is set to false."); + } + /* Could try to pull name out of first placeNameGroup + displayName = + prepareDefaultDisplayName( + placeMap.get(PlaceJAXBSchema.NAME)); + */ + } + + if(logger.isDebugEnabled()){ + logger.debug("Import: Create Item: \""+displayName + +"\" in placeAuthority: \"" + placeAuthorityRefName +"\""); + } + PoxPayloadOut multipart = + createPlaceInstance( placeAuthorityRefName, + placeMap, client.getItemCommonPartName() ); + String newID = null; + ClientResponse res = client.createItem(vcsid, multipart); + try { + int statusCode = res.getStatus(); + + if(!REQUEST_TYPE.isValidStatusCode(statusCode)) { + throw new RuntimeException("Could not create Item: \"" + +placeMap.get(PlaceJAXBSchema.SHORT_IDENTIFIER) + +"\" in placeAuthority: \"" + placeAuthorityRefName + +"\" "+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + } + if(statusCode != EXPECTED_STATUS_CODE) { + throw new RuntimeException("Unexpected Status when creating Item: \"" + +placeMap.get(PlaceJAXBSchema.SHORT_IDENTIFIER) + +"\" in placeAuthority: \"" + placeAuthorityRefName +"\", Status:"+ statusCode); + } + newID = extractId(res); + } finally { + res.releaseConnection(); + } + + return newID; + } + + public static PoxPayloadOut createPlaceInstance( + String commonPartXML, String headerLabel) throws DocumentException { + PoxPayloadOut multipart = new PoxPayloadOut(PlaceAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME); + PayloadOutputPart commonPart = multipart.addPart(commonPartXML, + MediaType.APPLICATION_XML_TYPE); + commonPart.setLabel(headerLabel); + + if(logger.isDebugEnabled()){ + logger.debug("to be created, place common ", commonPartXML); + } + + return multipart; + } + + public static String createItemInAuthority(String vcsid, + String commonPartXML, + PlaceAuthorityClient client ) throws DocumentException { + // Expected status code: 201 Created + int EXPECTED_STATUS_CODE = Response.Status.CREATED.getStatusCode(); + // Type of service request being tested + ServiceRequestType REQUEST_TYPE = ServiceRequestType.CREATE; + + PoxPayloadOut multipart = + createPlaceInstance(commonPartXML, client.getItemCommonPartName()); + String newID = null; + ClientResponse res = client.createItem(vcsid, multipart); + try { + int statusCode = res.getStatus(); + + if(!REQUEST_TYPE.isValidStatusCode(statusCode)) { + throw new RuntimeException("Could not create Item: \""+commonPartXML + +"\" in placeAuthority: \"" + vcsid + +"\" "+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + } + if(statusCode != EXPECTED_STATUS_CODE) { + throw new RuntimeException("Unexpected Status when creating Item: \""+commonPartXML + +"\" in placeAuthority: \"" + vcsid +"\", Status:"+ statusCode); + } + newID = extractId(res); + } finally { + res.releaseConnection(); + } + + return newID; + } + + /** + * Creates the from xml file. + * + * @param fileName the file name + * @return new CSID as string + * @throws Exception the exception + */ + private String createItemInAuthorityFromXmlFile(String vcsid, String commonPartFileName, + PlaceAuthorityClient client) throws Exception { + byte[] b = FileUtils.readFileToByteArray(new File(commonPartFileName)); + String commonPartXML = new String(b); + return createItemInAuthority(vcsid, commonPartXML, client ); + } + + /** + * Creates the placeAuthority ref name. + * + * @param shortId the placeAuthority shortIdentifier + * @param displaySuffix displayName to be appended, if non-null + * @return the string + */ + public static String createPlaceAuthRefName(String shortId, String displaySuffix) { + String refName = "urn:cspace:org.collectionspace.demo:placeauthority:name(" + +shortId+")"; + if(displaySuffix!=null&&!displaySuffix.isEmpty()) + refName += "'"+displaySuffix+"'"; + return refName; + } + + /** + * Creates the place ref name. + * + * @param placeAuthRefName the placeAuthority ref name + * @param shortId the place shortIdentifier + * @param displaySuffix displayName to be appended, if non-null + * @return the string + */ + public static String createPlaceRefName( + String placeAuthRefName, String shortId, String displaySuffix) { + String refName = placeAuthRefName+":place:name("+shortId+")"; + if(displaySuffix!=null&&!displaySuffix.isEmpty()) + refName += "'"+displaySuffix+"'"; + return refName; + } + + public static String extractId(ClientResponse res) { + MultivaluedMap mvm = res.getMetadata(); + String uri = (String) ((ArrayList) mvm.get("Location")).get(0); + if(logger.isDebugEnabled()){ + logger.debug("extractId:uri=" + uri); + } + String[] segments = uri.split("/"); + String id = segments[segments.length - 1]; + if(logger.isDebugEnabled()){ + logger.debug("id=" + id); + } + return id; + } + + /** + * Returns an error message indicating that the status code returned by a + * specific call to a service does not fall within a set of valid status + * codes for that service. + * + * @param serviceRequestType A type of service request (e.g. CREATE, DELETE). + * + * @param statusCode The invalid status code that was returned in the response, + * from submitting that type of request to the service. + * + * @return An error message. + */ + public static String invalidStatusCodeMessage(ServiceRequestType requestType, int statusCode) { + return "Status code '" + statusCode + "' in response is NOT within the expected set: " + + requestType.validStatusCodesAsString(); + } + + + + /** + * Produces a default displayName from one or more supplied field(s). + * @see PlaceAuthorityDocumentModelHandler.prepareDefaultDisplayName() which + * duplicates this logic, until we define a service-general utils package + * that is neither client nor service specific. + * @param name + * @return a display name + */ + public static String prepareDefaultDisplayName( + String name ) { + StringBuilder newStr = new StringBuilder(); + newStr.append(name); + return newStr.toString(); + } + + + +} diff --git a/services/place/client/src/main/java/org/collectionspace/services/client/PlaceAuthorityProxy.java b/services/place/client/src/main/java/org/collectionspace/services/client/PlaceAuthorityProxy.java new file mode 100644 index 000000000..3b99e6d55 --- /dev/null +++ b/services/place/client/src/main/java/org/collectionspace/services/client/PlaceAuthorityProxy.java @@ -0,0 +1,14 @@ +package org.collectionspace.services.client; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +/** + * @version $Revision:$ + */ +@Path(PlaceAuthorityClient.SERVICE_PATH + "/") +@Produces("application/xml") +@Consumes("application/xml") +public interface PlaceAuthorityProxy extends AuthorityProxy { +} diff --git a/services/place/client/src/test/java/org/collectionspace/services/client/test/PlaceAuthorityServiceTest.java b/services/place/client/src/test/java/org/collectionspace/services/client/test/PlaceAuthorityServiceTest.java new file mode 100644 index 000000000..7186f79ba --- /dev/null +++ b/services/place/client/src/test/java/org/collectionspace/services/client/test/PlaceAuthorityServiceTest.java @@ -0,0 +1,658 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright (c)) 2009 Regents of the University of California + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.collectionspace.services.client.test; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.collectionspace.services.PlaceJAXBSchema; +import org.collectionspace.services.client.AbstractCommonListUtils; +import org.collectionspace.services.client.AuthorityClient; +import org.collectionspace.services.client.CollectionSpaceClient; +import org.collectionspace.services.client.PayloadOutputPart; +import org.collectionspace.services.client.PoxPayloadIn; +import org.collectionspace.services.client.PoxPayloadOut; +import org.collectionspace.services.client.PlaceAuthorityClient; +import org.collectionspace.services.client.PlaceAuthorityClientUtils; +import org.collectionspace.services.jaxb.AbstractCommonList; +import org.collectionspace.services.place.PlaceauthoritiesCommon; +import org.collectionspace.services.place.PlacesCommon; +import org.collectionspace.services.place.PlaceNameGroup; +import org.collectionspace.services.place.PlaceNameGroupList; + +import org.jboss.resteasy.client.ClientResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; + +/** + * PlaceAuthorityServiceTest, carries out tests against a + * deployed and running PlaceAuthority Service. + * + * $LastChangedRevision: 753 $ + * $LastChangedDate: 2009-09-23 11:03:36 -0700 (Wed, 23 Sep 2009) $ + */ +public class PlaceAuthorityServiceTest extends AbstractAuthorityServiceTest { + + /** The logger. */ + private final String CLASS_NAME = PlaceAuthorityServiceTest.class.getName(); + private final Logger logger = LoggerFactory.getLogger(PlaceAuthorityServiceTest.class); + private final String REFNAME = "refName"; + private final static String EMPTY_REFNAME = ""; + private final String DISPLAYNAME = "displayName"; + + @Override + public String getServicePathComponent() { + return PlaceAuthorityClient.SERVICE_PATH_COMPONENT; + } + + @Override + protected String getServiceName() { + return PlaceAuthorityClient.SERVICE_NAME; + } + + public String getItemServicePathComponent() { + return AuthorityClient.ITEMS; + } + + // Instance variables specific to this test. + +// /** The SERVICE path component. */ +// final String SERVICE_PATH_COMPONENT = "placeauthorities"; +// +// /** The ITEM service path component. */ +// final String ITEM_SERVICE_PATH_COMPONENT = "items"; +// + + final String TEST_DNAME = "San Jose, CA"; + final String TEST_NAME = "San Jose"; + final String TEST_SHORTID = "sanjose"; + // TODO Make place type be a controlled vocab term. + final String TEST_PLACE_TYPE = "City"; + // TODO Make status type be a controlled vocab term. + final String TEST_STATUS = "Approved"; + final String TEST_NOTE = "My hometown"; + final String TEST_SOURCE = "Peralta's Places of California"; + final String TEST_SOURCE_PAGE = "p.21"; + final String TEST_DISPLAY_DATE = "This year"; + final String TEST_EARLIEST_SINGLE_YEAR = "2012"; + + /** The known resource id. */ + private String knownResourceShortIdentifer = null; + private String knownResourceRefName = null; + + private String knownPlaceTypeRefName = null; + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance() + */ + @Override + protected CollectionSpaceClient getClientInstance() { + return new PlaceAuthorityClient(); + } + + /** + * Creates the item in authority. + * + * @param vcsid the vcsid + * @param authRefName the auth ref name + * @return the string + */ + private String createItemInAuthority(String vcsid, String authRefName) { + final String testName = "createItemInAuthority("+vcsid+","+authRefName+")"; + + // Submit the request to the service and store the response. + PlaceAuthorityClient client = new PlaceAuthorityClient(); + Map sanjoseMap = new HashMap(); + // TODO Make place type and status be controlled vocabs. + sanjoseMap.put(PlaceJAXBSchema.DISPLAY_NAME, TEST_DNAME); + sanjoseMap.put(PlaceJAXBSchema.SHORT_IDENTIFIER, TEST_SHORTID); + sanjoseMap.put(PlaceJAXBSchema.NAME, TEST_NAME); + sanjoseMap.put(PlaceJAXBSchema.NOTE, TEST_NOTE); + sanjoseMap.put(PlaceJAXBSchema.SOURCE, TEST_SOURCE); + sanjoseMap.put(PlaceJAXBSchema.SOURCE_PAGE, TEST_SOURCE_PAGE); + sanjoseMap.put(PlaceJAXBSchema.PLACE_TYPE, TEST_PLACE_TYPE); + sanjoseMap.put(PlaceJAXBSchema.TERM_STATUS, TEST_STATUS); + + String newID = PlaceAuthorityClientUtils.createItemInAuthority(vcsid, + authRefName, sanjoseMap, client ); + + // Store the ID returned from the first item resource created + // for additional tests below. + if (knownItemResourceId == null){ + setKnownItemResource(newID, TEST_SHORTID); + if (logger.isDebugEnabled()) { + logger.debug(testName + ": knownItemResourceId=" + newID); + } + } + + // Store the IDs from any item resources created + // by tests, along with the IDs of their parents, so these items + // can be deleted after all tests have been run. + allResourceItemIdsCreated.put(newID, vcsid); + + return newID; + } + + /** + * Verify item display name. + * + * @param testName the test name + * @throws Exception the exception + */ + @Test(dataProvider="testName", + dependsOnMethods = {"readItem", "updateItem"}) + public void verifyItemDisplayName(String testName) throws Exception { + // Perform setup. + setupRead(); + // + // First, read our known item resource + // + PlaceAuthorityClient client = new PlaceAuthorityClient(); + ClientResponse res = client.readItem(knownResourceId, knownItemResourceId); + PlacesCommon place = null; + try { + assertStatusCode(res, testName); + // Check whether place has expected displayName. + PoxPayloadIn input = new PoxPayloadIn(res.getEntity()); + place = (PlacesCommon) extractPart(input, + client.getItemCommonPartName(), PlacesCommon.class); + Assert.assertNotNull(place); + } finally { + if (res != null) { + res.releaseConnection(); + } + } + // + // Now prepare an updated payload. + // + String displayName = place.getDisplayName(); + // Make sure displayName matches computed form + String expectedDisplayName = + PlaceAuthorityClientUtils.prepareDefaultDisplayName(TEST_NAME); + Assert.assertNotNull(displayName, expectedDisplayName); + + // Update the shortName and verify the computed name is updated. + place.setCsid(null); + place.setDisplayNameComputed(true); + + // Verify the contents of this resource + PlaceNameGroupList placeNameGroupList = place.getPlaceNameGroupList(); + Assert.assertNotNull(placeNameGroupList); + List placeNameGroups = placeNameGroupList.getPlaceNameGroup(); + Assert.assertNotNull(placeNameGroups); + Assert.assertTrue(placeNameGroups.size() > 0); + String name = placeNameGroups.get(0).getName(); + Assert.assertNotNull(name); + + // Update the contents of this resource. + final String PLACE_NAME_ADDITION = "verify-item-place-name-updated"; + placeNameGroups.get(0).setName(PLACE_NAME_ADDITION + TEST_NAME); + place.setPlaceNameGroupList(placeNameGroupList); + if (logger.isDebugEnabled()) { + logger.debug("to be updated Place"); + logger.debug(objectAsXmlString(place, + PlacesCommon.class)); + } + expectedDisplayName = + PlaceAuthorityClientUtils.prepareDefaultDisplayName(PLACE_NAME_ADDITION + TEST_NAME); + + // Submit the updated resource to the service and store the response. + PoxPayloadOut output = new PoxPayloadOut(PlaceAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME); + PayloadOutputPart commonPart = output.addPart(client.getItemCommonPartName(), place); + + setupUpdate(); + res = client.updateItem(knownResourceId, knownItemResourceId, output); + PlacesCommon updatedPlace = null; + try { + assertStatusCode(res, testName); + // Retrieve the updated resource and verify that its contents exist. + PoxPayloadIn input = new PoxPayloadIn(res.getEntity()); + updatedPlace = (PlacesCommon) extractPart(input, + client.getItemCommonPartName(), PlacesCommon.class); + Assert.assertNotNull(updatedPlace); + } finally { + if (res != null) { + res.releaseConnection(); + } + } + + // Verify that the updated resource computes the right displayName. + Assert.assertEquals(updatedPlace.getDisplayName(), expectedDisplayName, + "Updated DisplayName in Place not reflected in computed DisplayName."); + // + // Now Update the displayName, not computed and verify the computed name is overriden. + // + place.setDisplayNameComputed(false); + expectedDisplayName = "TestName"; + place.setDisplayName(expectedDisplayName); + + // Submit the updated resource to the service and store the response. + output = new PoxPayloadOut(PlaceAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME); + commonPart = output.addPart(client.getItemCommonPartName(), place); + setupUpdate(); + res = client.updateItem(knownResourceId, knownItemResourceId, output); + try { + assertStatusCode(res, testName); + // Retrieve the updated resource and verify that its contents exist. + PoxPayloadIn input = new PoxPayloadIn(res.getEntity()); + updatedPlace = (PlacesCommon) extractPart(input, + client.getItemCommonPartName(), PlacesCommon.class); + Assert.assertNotNull(updatedPlace); + } finally { + if (res != null) { + res.releaseConnection(); + } + } + + // Verify that the updated resource received the correct data. + Assert.assertEquals(updatedPlace.isDisplayNameComputed(), false, + "Updated displayNameComputed in Place did not match submitted data."); + // Verify that the updated resource computes the right displayName. + Assert.assertEquals(updatedPlace.getDisplayName(), + expectedDisplayName, + "Updated DisplayName (not computed) in Place not stored."); + } + + /** + * Verify illegal item display name. + * + * @param testName the test name + * @throws Exception the exception + */ + @Test(dataProvider="testName", + dependsOnMethods = {"verifyItemDisplayName"}) + public void verifyIllegalItemDisplayName(String testName) throws Exception { + // Perform setup for read. + setupRead(); + + // Submit the request to the service and store the response. + PlaceAuthorityClient client = new PlaceAuthorityClient(); + ClientResponse res = client.readItem(knownResourceId, knownItemResourceId); + PlacesCommon place= null; + try { + assertStatusCode(res, testName); + PoxPayloadIn input = new PoxPayloadIn(res.getEntity()); + place = (PlacesCommon) extractPart(input, + client.getItemCommonPartName(), PlacesCommon.class); + Assert.assertNotNull(place); + } finally { + if (res != null) { + res.releaseConnection(); + } + } + + // Try to Update with computed false and no displayName + place.setDisplayNameComputed(false); + place.setDisplayName(null); + + // Submit the updated resource to the service and store the response. + PoxPayloadOut output = new PoxPayloadOut(PlaceAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME); + PayloadOutputPart commonPart = output.addPart(client.getItemCommonPartName(), place); + setupUpdateWithInvalidBody(); // we expected a failure here. + res = client.updateItem(knownResourceId, knownItemResourceId, output); + try { + assertStatusCode(res, testName); + } finally { + if (res != null) { + res.releaseConnection(); + } + } + } + + /** + * Read item list. + */ + @Test(dataProvider = "testName", groups = {"readList"}, + dependsOnMethods = {"readList"}) + public void readItemList(String testName) { + readItemList(knownAuthorityWithItems, null); + } + + /** + * Read item list by authority name. + */ + @Test(dataProvider = "testName", groups = {"readList"}, + dependsOnMethods = {"readItemList"}) + public void readItemListByAuthorityName(String testName) { + readItemList(null, READITEMS_SHORT_IDENTIFIER); + } + + /** + * Read item list. + * + * @param vcsid + * the vcsid + * @param name + * the name + */ + private void readItemList(String vcsid, String shortId) { + String testName = "readItemList"; + + // Perform setup. + setupReadList(); + + // Submit the request to the service and store the response. + PlaceAuthorityClient client = new PlaceAuthorityClient(); + ClientResponse res = null; + if (vcsid != null) { + res = client.readItemList(vcsid, null, null); + } else if (shortId != null) { + res = client.readItemListForNamedAuthority(shortId, null, null); + } else { + Assert.fail("readItemList passed null csid and name!"); + } + + AbstractCommonList list = null; + try { + assertStatusCode(res, testName); + list = res.getEntity(); + } finally { + if (res != null) { + res.releaseConnection(); + } + } + + List items = list.getListItem(); + int nItemsReturned = items.size(); + // There will be 'nItemsToCreateInList' + // items created by the createItemList test, + // all associated with the same parent resource. + int nExpectedItems = nItemsToCreateInList; + if (logger.isDebugEnabled()) { + logger.debug(testName + ": Expected " + nExpectedItems + + " items; got: " + nItemsReturned); + } + Assert.assertEquals(nItemsReturned, nExpectedItems); + + for (AbstractCommonList.ListItem item : items) { + String value = AbstractCommonListUtils.ListItemGetElementValue( + item, REFNAME); + Assert.assertTrue((null != value), "Item refName is null!"); + value = AbstractCommonListUtils.ListItemGetElementValue(item, + DISPLAYNAME); + Assert.assertTrue((null != value), "Item displayName is null!"); + } + if (logger.isTraceEnabled()) { + AbstractCommonListUtils.ListItemsInAbstractCommonList(list, logger, + testName); + } + } + + @Override + public void delete(String testName) throws Exception { + // Do nothing. See localDelete(). This ensure proper test order. + } + + @Test(dataProvider = "testName", dependsOnMethods = {"localDeleteItem"}) + public void localDelete(String testName) throws Exception { + super.delete(testName); + } + + @Override + public void deleteItem(String testName) throws Exception { + // Do nothing. We need to wait until after the test "localDelete" gets run. When it does, + // its dependencies will get run first and then we can call the base class' delete method. + } + + @Test(dataProvider = "testName", groups = {"delete"}, + dependsOnMethods = {"verifyIllegalItemDisplayName"}) + public void localDeleteItem(String testName) throws Exception { + super.deleteItem(testName); + } + + // --------------------------------------------------------------- + // Cleanup of resources created during testing + // --------------------------------------------------------------- + + /** + * Deletes all resources created by tests, after all tests have been run. + * + * This cleanup method will always be run, even if one or more tests fail. + * For this reason, it attempts to remove all resources created + * at any point during testing, even if some of those resources + * may be expected to be deleted by certain tests. + */ + + @AfterClass(alwaysRun=true) + public void cleanUp() { + String noTest = System.getProperty("noTestCleanup"); + if(Boolean.TRUE.toString().equalsIgnoreCase(noTest)) { + if (logger.isDebugEnabled()) { + logger.debug("Skipping Cleanup phase ..."); + } + return; + } + if (logger.isDebugEnabled()) { + logger.debug("Cleaning up temporary resources created for testing ..."); + } + String parentResourceId; + String itemResourceId; + // Clean up contact resources. + PlaceAuthorityClient client = new PlaceAuthorityClient(); + parentResourceId = knownResourceId; + // Clean up item resources. + for (Map.Entry entry : allResourceItemIdsCreated.entrySet()) { + itemResourceId = entry.getKey(); + parentResourceId = entry.getValue(); + // Note: Any non-success responses from the delete operation + // below are ignored and not reported. + client.deleteItem(parentResourceId, itemResourceId).releaseConnection(); + } + // Clean up parent resources. + for (String resourceId : allResourceIdsCreated) { + // Note: Any non-success responses from the delete operation + // below are ignored and not reported. + client.delete(resourceId).releaseConnection(); + } + } + + // --------------------------------------------------------------- + // Utility methods used by tests above + // --------------------------------------------------------------- + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent() + */ + + /** + * Returns the root URL for the item service. + * + * This URL consists of a base URL for all services, followed by + * a path component for the owning parent, followed by the + * path component for the items. + * + * @param parentResourceIdentifier An identifier (such as a UUID) for the + * parent authority resource of the relevant item resource. + * + * @return The root URL for the item service. + */ + protected String getItemServiceRootURL(String parentResourceIdentifier) { + return getResourceURL(parentResourceIdentifier) + "/" + getItemServicePathComponent(); + } + + /** + * Returns the URL of a specific item resource managed by a service, and + * designated by an identifier (such as a universally unique ID, or UUID). + * + * @param parentResourceIdentifier An identifier (such as a UUID) for the + * parent authority resource of the relevant item resource. + * + * @param itemResourceIdentifier An identifier (such as a UUID) for an + * item resource. + * + * @return The URL of a specific item resource managed by a service. + */ + protected String getItemResourceURL(String parentResourceIdentifier, String itemResourceIdentifier) { + return getItemServiceRootURL(parentResourceIdentifier) + "/" + itemResourceIdentifier; + } + + @Override + public void authorityTests(String testName) { + // TODO Auto-generated method stub + + } + + // + // Place specific overrides + // + + @Override + protected PoxPayloadOut createInstance(String commonPartName, + String identifier) { + // Submit the request to the service and store the response. + String shortId = identifier; + String displayName = "displayName-" + shortId; + // String baseRefName = PlaceAuthorityClientUtils.createPlaceAuthRefName(shortId, null); + PoxPayloadOut result = + PlaceAuthorityClientUtils.createPlaceAuthorityInstance( + displayName, shortId, commonPartName); + return result; + } + + @Override + protected PoxPayloadOut createNonExistenceInstance(String commonPartName, String identifier) { + String displayName = "displayName-NON_EXISTENT_ID"; + PoxPayloadOut result = PlaceAuthorityClientUtils.createPlaceAuthorityInstance( + displayName, "nonEx", commonPartName); + return result; + } + + @Override + protected PlaceauthoritiesCommon updateInstance(PlaceauthoritiesCommon placeauthoritiesCommon) { + PlaceauthoritiesCommon result = new PlaceauthoritiesCommon(); + + result.setDisplayName("updated-" + placeauthoritiesCommon.getDisplayName()); + result.setVocabType("updated-" + placeauthoritiesCommon.getVocabType()); + + return result; + } + + @Override + protected void compareUpdatedInstances(PlaceauthoritiesCommon original, + PlaceauthoritiesCommon updated) throws Exception { + Assert.assertEquals(updated.getDisplayName(), + original.getDisplayName(), + "Display name in updated object did not match submitted data."); + } + + protected void compareReadInstances(PlaceauthoritiesCommon original, + PlaceauthoritiesCommon fromRead) throws Exception { + Assert.assertNotNull(fromRead.getDisplayName()); + Assert.assertNotNull(fromRead.getShortIdentifier()); + Assert.assertNotNull(fromRead.getRefName()); + } + + // + // Authority item specific overrides + // + + @Override + protected String createItemInAuthority(String authorityId) { + return createItemInAuthority(authorityId, null /*refname*/); + } + + @Override + protected PlacesCommon updateItemInstance(PlacesCommon placesCommon) { + + // Get the Name field from the resource passed in + PlaceNameGroupList placeNameGroupList = placesCommon.getPlaceNameGroupList(); + Assert.assertNotNull(placeNameGroupList); + List placeNameGroups = placeNameGroupList.getPlaceNameGroup(); + Assert.assertNotNull(placeNameGroups); + Assert.assertTrue(placeNameGroups.size() > 0); + String originalName = placeNameGroups.get(0).getName(); + Assert.assertNotNull(originalName); + + // Update the contents of the new resource based on original value + PlaceNameGroupList updatedPlaceNameGroupList = new PlaceNameGroupList(); + List updatedPlaceNameGroups = updatedPlaceNameGroupList.getPlaceNameGroup(); + PlaceNameGroup updatedPlaceNameGroup = new PlaceNameGroup(); + updatedPlaceNameGroup.setName("updated-" + originalName); + updatedPlaceNameGroups.add(updatedPlaceNameGroup); + PlacesCommon result = new PlacesCommon(); + result.setPlaceNameGroupList(updatedPlaceNameGroupList); + + result.setDisplayName("updated-" + placesCommon.getDisplayName()); + + return result; + } + + @Override + protected void compareUpdatedItemInstances(PlacesCommon original, + PlacesCommon updated) throws Exception { + + // Get the Name fields each resource passed in + PlaceNameGroupList placeNameGroupList = original.getPlaceNameGroupList(); + Assert.assertNotNull(placeNameGroupList); + List placeNameGroups = placeNameGroupList.getPlaceNameGroup(); + Assert.assertNotNull(placeNameGroups); + Assert.assertTrue(placeNameGroups.size() > 0); + String originalName = placeNameGroups.get(0).getName(); + Assert.assertNotNull(originalName); + + PlaceNameGroupList updatedPlaceNameGroupList = updated.getPlaceNameGroupList(); + Assert.assertNotNull(updatedPlaceNameGroupList); + List updatedPlaceNameGroups = updatedPlaceNameGroupList.getPlaceNameGroup(); + Assert.assertNotNull(updatedPlaceNameGroups); + Assert.assertTrue(updatedPlaceNameGroups.size() > 0); + String updatedName = updatedPlaceNameGroups.get(0).getName(); + Assert.assertNotNull(updatedName); + + + + + Assert.assertEquals(updatedName, originalName, + "Data in updated Place did not match submitted data."); + } + + @Override + protected void verifyReadItemInstance(PlacesCommon item) + throws Exception { + // TODO Auto-generated method stub + + } + + @Override + protected PoxPayloadOut createNonExistenceItemInstance( + String commonPartName, String identifier) { + Map nonexMap = new HashMap(); + nonexMap.put(PlaceJAXBSchema.NAME, TEST_NAME); + nonexMap.put(PlaceJAXBSchema.SHORT_IDENTIFIER, "nonEx"); + nonexMap.put(PlaceJAXBSchema.PLACE_TYPE, TEST_PLACE_TYPE); + nonexMap.put(PlaceJAXBSchema.TERM_STATUS, TEST_STATUS); + // PoxPayloadOut multipart = + // PlaceAuthorityClientUtils.createPlaceInstance( + // PlaceAuthorityClientUtils.createPlaceRefName(knownResourceRefName, "nonEx", "Non Existent"), + // nonexMap, client.getItemCommonPartName() ); + final String EMPTY_REFNAME = ""; + PoxPayloadOut result = + PlaceAuthorityClientUtils.createPlaceInstance(EMPTY_REFNAME, + nonexMap, commonPartName); + return result; + } +} diff --git a/services/place/client/src/test/resources/log4j.properties b/services/place/client/src/test/resources/log4j.properties new file mode 100644 index 000000000..148a3e865 --- /dev/null +++ b/services/place/client/src/test/resources/log4j.properties @@ -0,0 +1,23 @@ +log4j.rootLogger=debug, stdout, R + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + +# Pattern to output the caller's file name and line number. +log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n + +log4j.appender.R=org.apache.log4j.RollingFileAppender +log4j.appender.R.File=target/test-client.log + +log4j.appender.R.MaxFileSize=100KB +# Keep one backup file +log4j.appender.R.MaxBackupIndex=1 + +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n + +#packages +log4j.logger.org.collectionspace=DEBUG +log4j.logger.org.apache=INFO +log4j.logger.httpclient=INFO +log4j.logger.org.jboss.resteasy=INFO diff --git a/services/place/installer/build.xml b/services/place/installer/build.xml new file mode 100644 index 000000000..5b1fe5366 --- /dev/null +++ b/services/place/installer/build.xml @@ -0,0 +1,61 @@ + + + + place service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/place/jaxb/pom.xml b/services/place/jaxb/pom.xml new file mode 100644 index 000000000..206f249ec --- /dev/null +++ b/services/place/jaxb/pom.xml @@ -0,0 +1,60 @@ + + + + org.collectionspace.services + org.collectionspace.services.place + 2.2-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.place.jaxb + services.place.jaxb + + + + org.collectionspace.services + org.collectionspace.services.common + ${project.version} + + + com.sun.xml.bind + jaxb-impl + + + + org.collectionspace.services + org.collectionspace.services.jaxb + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.authority.jaxb + true + ${project.version} + + + + + collectionspace-services-place-jaxb + install + + + org.jvnet.jaxb2.maven2 + maven-jaxb2-plugin + + + + + diff --git a/services/place/jaxb/src/main/java/org/collectionspace/services/PlaceJAXBSchema.java b/services/place/jaxb/src/main/java/org/collectionspace/services/PlaceJAXBSchema.java new file mode 100644 index 000000000..12fd66b2c --- /dev/null +++ b/services/place/jaxb/src/main/java/org/collectionspace/services/PlaceJAXBSchema.java @@ -0,0 +1,24 @@ +/** + * + */ +package org.collectionspace.services; +import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema; + +/** + * @author pschmitz + * + */ +public interface PlaceJAXBSchema extends AuthorityItemJAXBSchema { + final static String PLACES_COMMON = "places_common"; + final static String DISPLAY_NAME = "displayName"; + final static String DISPLAY_NAME_COMPUTED = "displayNameComputed"; + final static String SHORT_DISPLAY_NAME = "shortDisplayName"; + final static String SHORT_DISPLAY_NAME_COMPUTED = "shortDisplayNameComputed"; + final static String PLACE_NAME_GROUP_LIST = "placeNameGroupList"; + final static String NAME = "name"; + final static String NOTE = "note"; + final static String SOURCE = "source"; + final static String SOURCE_PAGE = "sourcePage"; + final static String PLACE_TYPE = "placeType"; +} + diff --git a/services/place/jaxb/src/main/resources/place_common.xsd b/services/place/jaxb/src/main/resources/place_common.xsd new file mode 100644 index 000000000..55a38cd20 --- /dev/null +++ b/services/place/jaxb/src/main/resources/place_common.xsd @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/place/jaxb/src/main/resources/placeauthority_common.xsd b/services/place/jaxb/src/main/resources/placeauthority_common.xsd new file mode 100644 index 000000000..458364bd0 --- /dev/null +++ b/services/place/jaxb/src/main/resources/placeauthority_common.xsd @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/place/pom.xml b/services/place/pom.xml new file mode 100644 index 000000000..babf26092 --- /dev/null +++ b/services/place/pom.xml @@ -0,0 +1,41 @@ + + + + org.collectionspace.services + org.collectionspace.services.main + 2.2-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.place + services.place + pom + + + + + + + jaxb + service + 3rdparty + client + + + + + samples + + + + + + + + diff --git a/services/place/service/pom.xml b/services/place/service/pom.xml new file mode 100644 index 000000000..570f23520 --- /dev/null +++ b/services/place/service/pom.xml @@ -0,0 +1,146 @@ + + + + org.collectionspace.services + org.collectionspace.services.place + 2.2-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.place.service + services.place.service + jar + + + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-log4j12 + + + + org.collectionspace.services + org.collectionspace.services.common + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.place.jaxb + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.place.client + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.authority.service + true + ${project.version} + + + + junit + junit + 4.1 + test + + + org.testng + testng + 5.6 + + + + + commons-beanutils + commons-beanutils + 1.6.1 + + + + commons-logging + commons-logging + 1.1 + + + + + + javax.security + jaas + 1.0.01 + provided + + + + dom4j + dom4j + 1.6.1 + provided + + + + + + org.jboss.resteasy + resteasy-jaxrs + + + tjws + webserver + + + + + org.jboss.resteasy + resteasy-jaxb-provider + + + org.jboss.resteasy + resteasy-multipart-provider + + + + + + org.nuxeo.ecm.core + nuxeo-core-api + + + jboss-remoting + jboss + + + + + + org.restlet + org.restlet + 1.0.7 + + + com.noelios.restlet + com.noelios.restlet.ext.httpclient + 1.0.7 + + + com.noelios.restlet + com.noelios.restlet + 1.0.7 + + + + + + collectionspace-services-place + + + + + diff --git a/services/place/service/src/main/java/org/collectionspace/services/place/PlaceAuthorityResource.java b/services/place/service/src/main/java/org/collectionspace/services/place/PlaceAuthorityResource.java new file mode 100644 index 000000000..0ca9ae7e6 --- /dev/null +++ b/services/place/service/src/main/java/org/collectionspace/services/place/PlaceAuthorityResource.java @@ -0,0 +1,69 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2009 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.collectionspace.services.place; + +import org.collectionspace.services.client.PlaceAuthorityClient; +import org.collectionspace.services.common.vocabulary.AuthorityResource; +import org.collectionspace.services.place.nuxeo.PlaceDocumentModelHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +@Path(PlaceAuthorityClient.SERVICE_PATH) +@Consumes("application/xml") +@Produces("application/xml") +public class PlaceAuthorityResource + extends AuthorityResource { + + private final static String placeAuthorityServiceName = "placeauthorities"; + private final static String PLACEAUTHORITIES_COMMON = "placeauthorities_common"; + + private final static String placeServiceName = "places"; + private final static String PLACES_COMMON = "places_common"; + + final Logger logger = LoggerFactory.getLogger(PlaceAuthorityResource.class); + + public PlaceAuthorityResource() { + super(PlaceauthoritiesCommon.class, PlaceAuthorityResource.class, + PLACEAUTHORITIES_COMMON, PLACES_COMMON); + } + + @Override + public String getServiceName() { + return placeAuthorityServiceName; + } + + public String getItemServiceName() { + return placeServiceName; + } + + @Override + public Class getCommonPartClass() { + return PlaceauthoritiesCommon.class; + } +} diff --git a/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceAuthorityConstants.java b/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceAuthorityConstants.java new file mode 100644 index 000000000..42993233a --- /dev/null +++ b/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceAuthorityConstants.java @@ -0,0 +1,35 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2009 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.collectionspace.services.place.nuxeo; + +/** + * PlaceAuthorityConstants processes CollectionObject document + * + */ +public class PlaceAuthorityConstants { + + public final static String NUXEO_DOCTYPE = "PlaceAuthority"; + public final static String NUXEO_SCHEMA_NAME = "placeauthority"; + public final static String NUXEO_DC_TITLE = "CollectionSpace-PlaceAuthority"; +} diff --git a/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceAuthorityDocumentModelHandler.java b/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceAuthorityDocumentModelHandler.java new file mode 100644 index 000000000..bd9459799 --- /dev/null +++ b/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceAuthorityDocumentModelHandler.java @@ -0,0 +1,57 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2009 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.collectionspace.services.place.nuxeo; + +import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityDocumentModelHandler; +import org.collectionspace.services.place.PlaceauthoritiesCommon; + +/** + * PlaceAuthorityDocumentModelHandler + * + * $LastChangedRevision: $ + * $LastChangedDate: $ + */ +public class PlaceAuthorityDocumentModelHandler + extends AuthorityDocumentModelHandler { + + /** + * Common part schema label + */ + private static final String COMMON_PART_LABEL = "placeauthorities_common"; + + public PlaceAuthorityDocumentModelHandler() { + super(COMMON_PART_LABEL); + } + + /** + * getQProperty converts the given property to qualified schema property + * @param prop + * @return + */ + @Override + public String getQProperty(String prop) { + return PlaceAuthorityConstants.NUXEO_SCHEMA_NAME + ":" + prop; + } +} + diff --git a/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceConstants.java b/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceConstants.java new file mode 100644 index 000000000..50ee2dac8 --- /dev/null +++ b/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceConstants.java @@ -0,0 +1,35 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2009 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.collectionspace.services.place.nuxeo; + +/** + * PlaceConstants processes CollectionObject document + * + */ +public class PlaceConstants { + + public final static String NUXEO_DOCTYPE = "Place"; + public final static String NUXEO_SCHEMA_NAME = "place"; + public final static String NUXEO_DC_TITLE = "CollectionSpace-Place"; +} diff --git a/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceDocumentModelHandler.java b/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceDocumentModelHandler.java new file mode 100644 index 000000000..4163faf9f --- /dev/null +++ b/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceDocumentModelHandler.java @@ -0,0 +1,120 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2009 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.collectionspace.services.place.nuxeo; + +import org.collectionspace.services.PlaceJAXBSchema; +import org.collectionspace.services.client.PlaceAuthorityClient; +import org.collectionspace.services.common.document.DocumentWrapper; +import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityItemDocumentModelHandler; +import org.collectionspace.services.place.PlacesCommon; +import org.nuxeo.ecm.core.api.DocumentModel; + +/** + * PlaceDocumentModelHandler + * + * $LastChangedRevision: $ + * $LastChangedDate: $ + */ +/** + * @author pschmitz + * + */ +public class PlaceDocumentModelHandler + extends AuthorityItemDocumentModelHandler { + + /** + * Common part schema label + */ + private static final String COMMON_PART_LABEL = "places_common"; + + public PlaceDocumentModelHandler() { + super(COMMON_PART_LABEL); + } + + @Override + public String getAuthorityServicePath(){ + return PlaceAuthorityClient.SERVICE_PATH_COMPONENT; // CSPACE-3932 + } + + /** + * Handle display name. + * + * @param docModel the doc model + * @throws Exception the exception + */ + @Override + protected void handleComputedDisplayNames(DocumentModel docModel) throws Exception { + String commonPartLabel = getServiceContext().getCommonPartLabel("places"); + Boolean displayNameComputed = (Boolean) docModel.getProperty(commonPartLabel, + PlaceJAXBSchema.DISPLAY_NAME_COMPUTED); + Boolean shortDisplayNameComputed = (Boolean) docModel.getProperty(commonPartLabel, + PlaceJAXBSchema.SHORT_DISPLAY_NAME_COMPUTED); + if(displayNameComputed==null) + displayNameComputed = true; + if(shortDisplayNameComputed==null) + shortDisplayNameComputed = true; + if (displayNameComputed || shortDisplayNameComputed) { + // Obtain the primary place name from the list of place names, for computing the display name. + String xpathToName = PlaceJAXBSchema.PLACE_NAME_GROUP_LIST + + "/[0]/" + PlaceJAXBSchema.NAME; + String name = getXPathStringValue(docModel, COMMON_PART_LABEL, xpathToName); + String displayName = prepareDefaultDisplayName(name); + if (displayNameComputed) { + docModel.setProperty(commonPartLabel, PlaceJAXBSchema.DISPLAY_NAME, + displayName); + } + if (shortDisplayNameComputed) { + docModel.setProperty(commonPartLabel, PlaceJAXBSchema.SHORT_DISPLAY_NAME, + displayName); + } + } + } + + /** + * Produces a default displayName from one or more supplied fields. + * @see PlaceAuthorityClientUtils.prepareDefaultDisplayName() which + * duplicates this logic, until we define a service-general utils package + * that is neither client nor service specific. + * @param name + * @return the default display name + * @throws Exception + */ + private static String prepareDefaultDisplayName( + String name ) throws Exception { + StringBuilder newStr = new StringBuilder(); + newStr.append(name); + return newStr.toString(); + } + + /** + * getQProperty converts the given property to qualified schema property + * @param prop + * @return + */ + @Override + public String getQProperty(String prop) { + return PlaceConstants.NUXEO_SCHEMA_NAME + ":" + prop; + } +} + diff --git a/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceValidatorHandler.java b/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceValidatorHandler.java new file mode 100644 index 000000000..feb798c1a --- /dev/null +++ b/services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceValidatorHandler.java @@ -0,0 +1,116 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2009 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2009 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.collectionspace.services.place.nuxeo; + +import java.util.regex.Pattern; + +import org.collectionspace.services.place.PlacesCommon; +import org.collectionspace.services.common.context.MultipartServiceContext; +import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.document.DocumentHandler.Action; +import org.collectionspace.services.common.document.InvalidDocumentException; +import org.collectionspace.services.common.document.ValidatorHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author + */ +public class PlaceValidatorHandler implements ValidatorHandler { + + final Logger logger = LoggerFactory.getLogger(PlaceValidatorHandler.class); + private static final Pattern shortIdBadPattern = Pattern.compile("[\\W]"); //.matcher(input).matches() + + @Override + public void validate(Action action, ServiceContext ctx) + throws InvalidDocumentException { + if(logger.isDebugEnabled()) { + logger.debug("validate() action=" + action.name()); + } + try { + MultipartServiceContext mctx = (MultipartServiceContext) ctx; + PlacesCommon place = (PlacesCommon) mctx.getInputPart(mctx.getCommonPartLabel(), + PlacesCommon.class); + String msg = ""; + boolean invalid = false; + + // Validation occurring on both creates and updates + String displayName = place.getDisplayName(); + if (!place.isDisplayNameComputed() && ((displayName == null) || displayName.trim().isEmpty())) { + invalid = true; + msg += "displayName must be non-null and non-blank if displayNameComputed is false"; + } + + // Validation specific to creates or updates + if (action.equals(Action.CREATE)) { + String shortId = place.getShortIdentifier(); + // Per CSPACE-2215, shortIdentifier values that are null (missing) + // oe the empty string are now legally accepted in create payloads. + // In either of those cases, a short identifier will be synthesized from + // a display name or supplied in another manner. + if ((shortId != null) && (shortIdBadPattern.matcher(shortId).find())) { + invalid = true; + msg += "shortIdentifier must only contain standard word characters"; + } + } else if (action.equals(Action.UPDATE)) { + } + + if (invalid) { + logger.error(msg); + throw new InvalidDocumentException(msg); + } + } catch (InvalidDocumentException ide) { + throw ide; + } catch (Exception e) { + throw new InvalidDocumentException(e); + } + } +}