From: Aron Roberts Date: Mon, 17 May 2010 23:27:40 +0000 (+0000) Subject: CSPACE-144: Basic infrastructure for the Movement (aka Location & Movement) service... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=6f8630f176bbc99b0d60158eb54005ad59f9cc07;p=tmp%2Fjakarta-migration.git CSPACE-144: Basic infrastructure for the Movement (aka Location & Movement) service is in place in the Services Layer. Introduces a new Nuxeo document type, and requires an 'ant deploy' and restarting the two JBoss servers. Data modeling may possibly need some future attention. --- diff --git a/pom.xml b/pom.xml index bb21b85f7..c8fd7e8d7 100644 --- a/pom.xml +++ b/pom.xml @@ -281,12 +281,12 @@ org.slf4j slf4j-api - 1.5.2 + 1.5.8 org.slf4j slf4j-log4j12 - 1.5.2 + 1.5.8 + + + + nuxeo-java + + + org.collectionspace.services.movement.nuxeo.MovementDocumentModelHandler + + + org.collectionspace.services.movement.nuxeo.MovementValidatorHandler + + + + + + + + + + + + + + authRefmovementContact + + + + + + + + + diff --git a/services/movement/.settings/org.maven.ide.eclipse.prefs b/services/movement/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 000000000..3dc0a0d5e --- /dev/null +++ b/services/movement/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Tue Apr 27 21:36:39 PDT 2010 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/services/movement/3rdparty/.settings/org.maven.ide.eclipse.prefs b/services/movement/3rdparty/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 000000000..3dc0a0d5e --- /dev/null +++ b/services/movement/3rdparty/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Tue Apr 27 21:36:39 PDT 2010 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/services/movement/3rdparty/build.xml b/services/movement/3rdparty/build.xml new file mode 100644 index 000000000..9f9da0488 --- /dev/null +++ b/services/movement/3rdparty/build.xml @@ -0,0 +1,127 @@ + + + + movement service 3rdparty + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/movement/3rdparty/nuxeo-platform-cs-movement/.settings/org.eclipse.jdt.core.prefs b/services/movement/3rdparty/nuxeo-platform-cs-movement/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..466b77bf4 --- /dev/null +++ b/services/movement/3rdparty/nuxeo-platform-cs-movement/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,6 @@ +#Tue Apr 27 21:36:41 PDT 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/services/movement/3rdparty/nuxeo-platform-cs-movement/.settings/org.maven.ide.eclipse.prefs b/services/movement/3rdparty/nuxeo-platform-cs-movement/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 000000000..3dc0a0d5e --- /dev/null +++ b/services/movement/3rdparty/nuxeo-platform-cs-movement/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Tue Apr 27 21:36:39 PDT 2010 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/services/movement/3rdparty/nuxeo-platform-cs-movement/build.xml b/services/movement/3rdparty/nuxeo-platform-cs-movement/build.xml new file mode 100644 index 000000000..a37c3c06a --- /dev/null +++ b/services/movement/3rdparty/nuxeo-platform-cs-movement/build.xml @@ -0,0 +1,143 @@ + + + + movement nuxeo document type + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/movement/3rdparty/nuxeo-platform-cs-movement/pom.xml b/services/movement/3rdparty/nuxeo-platform-cs-movement/pom.xml new file mode 100644 index 000000000..77a1bb14c --- /dev/null +++ b/services/movement/3rdparty/nuxeo-platform-cs-movement/pom.xml @@ -0,0 +1,38 @@ + + + + org.collectionspace.services + org.collectionspace.services.movement.3rdparty + 0.7-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.movement.3rdparty.nuxeo + services.movement.3rdparty.nuxeo + jar + + Movement Nuxeo Document Type + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + src/main/resources/META-INF/MANIFEST.MF + + ${eclipseVersion} + 2 + + + + + + + + diff --git a/services/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/META-INF/MANIFEST.MF b/services/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 000000000..f7e87c289 --- /dev/null +++ b/services/movement/3rdparty/nuxeo-platform-cs-movement/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.movement;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.publishing.api, + org.nuxeo.ecm.platform.ws, + org.collectionspace.collectionspace_core +Provide-Package: org.collectionspace.movement +Nuxeo-Component: OSGI-INF/core-types-contrib.xml, + OSGI-INF/ecm-types-contrib.xml, + OSGI-INF/layouts-contrib.xml + diff --git a/services/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/OSGI-INF/core-types-contrib.xml b/services/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/OSGI-INF/core-types-contrib.xml new file mode 100644 index 000000000..de3673017 --- /dev/null +++ b/services/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/OSGI-INF/core-types-contrib.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/services/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/OSGI-INF/deployment-fragment.xml b/services/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/OSGI-INF/deployment-fragment.xml new file mode 100644 index 000000000..88b94ffd1 --- /dev/null +++ b/services/movement/3rdparty/nuxeo-platform-cs-movement/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.vocabularies + + + + 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_vocabularies + /view_vocabularies.xhtml + + + + + view_vocabulary + /view_vocabulary.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/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/OSGI-INF/ecm-types-contrib.xml b/services/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/OSGI-INF/ecm-types-contrib.xml new file mode 100644 index 000000000..caab383ce --- /dev/null +++ b/services/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/OSGI-INF/ecm-types-contrib.xml @@ -0,0 +1,29 @@ + + + + + + + view_documents + + + heading + collectionspace_core + movement + + + + + + Movement + + + + + + Movement + + + + + diff --git a/services/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/OSGI-INF/layouts-contrib.xml b/services/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/OSGI-INF/layouts-contrib.xml new file mode 100644 index 000000000..c2ed33446 --- /dev/null +++ b/services/movement/3rdparty/nuxeo-platform-cs-movement/src/main/resources/OSGI-INF/layouts-contrib.xml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + currentLocation + currentLocationFitness + currentLocationNote + locationDate + normalLocation + movementContact + + + movementNote + movementReferenceNumber + plannedRemovalDate + removalDate + reasonForMove + + + + + + + true + + currentLocation + + + dataInputText + + + + + + + + true + + currentLocationFitness + + + dataInputText + + + + + + + + true + + currentLocationNote + + + dataInputText + + + + + + + + true + + locationDate + + + dataInputText + + + + + + + + true + + normalLocation + + + dataInputText + + + + + + + + true + + movementContact + + + dataInputText + + + + + + + + + + + true + + movementNote + + + dataInputText + + + + + + + + true + + movementReferenceNumber + + + dataInputText + + + + + + + + true + + plannedRemovalDate + + + dataInputText + + + + + + + + true + + removalDate + + + dataInputText + + + + + + + + true + + reasonForMove + + + dataInputText + + + + + + diff --git a/services/movement/3rdparty/pom.xml b/services/movement/3rdparty/pom.xml new file mode 100644 index 000000000..3e7742276 --- /dev/null +++ b/services/movement/3rdparty/pom.xml @@ -0,0 +1,24 @@ + + + + org.collectionspace.services.movement + org.collectionspace.services + 0.7-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.movement.3rdparty + services.movement.3rdparty + pom + + + 3rd party build for movement service + + + + nuxeo-platform-cs-movement + + diff --git a/services/movement/build.xml b/services/movement/build.xml new file mode 100644 index 000000000..5d6d504c2 --- /dev/null +++ b/services/movement/build.xml @@ -0,0 +1,124 @@ + + + + movement service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/movement/client/.settings/org.eclipse.jdt.core.prefs b/services/movement/client/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..dc6091efb --- /dev/null +++ b/services/movement/client/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,6 @@ +#Tue Apr 27 21:36:42 PDT 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/services/movement/client/.settings/org.maven.ide.eclipse.prefs b/services/movement/client/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 000000000..3dc0a0d5e --- /dev/null +++ b/services/movement/client/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Tue Apr 27 21:36:39 PDT 2010 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/services/movement/client/pom.xml b/services/movement/client/pom.xml new file mode 100644 index 000000000..73f18ad4e --- /dev/null +++ b/services/movement/client/pom.xml @@ -0,0 +1,91 @@ + + + + org.collectionspace.services + org.collectionspace.services.movement + 0.7-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.movement.client + services.movement.client + + + + + org.slf4j + slf4j-api + test + + + org.slf4j + slf4j-log4j12 + test + + + + 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.client + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.movement.jaxb + ${project.version} + + + + org.collectionspace.services + org.collectionspace.services.person.client + ${project.version} + + + + org.testng + testng + 5.6 + + + 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-movement-client + + diff --git a/services/movement/client/src/main/java/org/collectionspace/services/client/MovementClient.java b/services/movement/client/src/main/java/org/collectionspace/services/client/MovementClient.java new file mode 100644 index 000000000..cd747aef6 --- /dev/null +++ b/services/movement/client/src/main/java/org/collectionspace/services/client/MovementClient.java @@ -0,0 +1,150 @@ +/** + * 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 + */ +package org.collectionspace.services.client; + +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Response; + +import org.collectionspace.services.common.authorityref.AuthorityRefList; +//import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.movement.MovementsCommonList; + +import org.jboss.resteasy.client.ProxyFactory; +import org.jboss.resteasy.plugins.providers.RegisterBuiltin; +import org.jboss.resteasy.client.ClientResponse; +import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; +import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; +import org.jboss.resteasy.spi.ResteasyProviderFactory; + +/** + * MovementClient.java + * + * $LastChangedRevision: $ + * $LastChangedDate: $ + * + */ +public class MovementClient extends AbstractServiceClientImpl { + + /* (non-Javadoc) + * @see org.collectionspace.services.client.AbstractServiceClientImpl#getServicePathComponent() + */ + public String getServicePathComponent() { + return "movements"; + } + /** + * + */ +// private static final MovementClient instance = new MovementClient(); + /** + * + */ + private MovementProxy movementProxy; + + /** + * + * Default constructor for MovementClient class. + * + */ + public MovementClient() { + ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance(); + RegisterBuiltin.register(factory); + setProxy(); + } + + @Override + public CollectionSpaceProxy getProxy() { + return this.movementProxy; + } + + /** + * allow to reset proxy as per security needs + */ + public void setProxy() { + if (useAuth()) { + movementProxy = ProxyFactory.create(MovementProxy.class, + getBaseURL(), getHttpClient()); + } else { + movementProxy = ProxyFactory.create(MovementProxy.class, + getBaseURL()); + } + } + + /** + * FIXME Comment this + * + * @return + */ +// public static MovementClient getInstance() { +// return instance; +// } + + /** + * @return + * @see org.collectionspace.services.client.MovementProxy#getMovement() + */ + public ClientResponse readList() { + return movementProxy.readList(); + } + + /** + * @param csid + * @return + * @see org.collectionspace.services.client.MovementProxy#getAuthorityRefs(java.lang.String) + */ + public ClientResponse getAuthorityRefs(String csid) { + return movementProxy.getAuthorityRefs(csid); + } + + + /** + * @param csid + * @return + * @see org.collectionspace.services.client.MovementProxy#getMovement(java.lang.String) + */ + public ClientResponse read(String csid) { + return movementProxy.read(csid); + } + + /** + * @param movement + * @return + * @see org.collectionspace.services.client.MovementProxy#createMovement(org.collectionspace.hello.Movement) + */ + public ClientResponse create(MultipartOutput multipart) { + return movementProxy.create(multipart); + } + + /** + * @param csid + * @param movement + * @return + * @see org.collectionspace.services.client.MovementProxy#updateMovement(java.lang.Long, org.collectionspace.hello.Movement) + */ + public ClientResponse update(String csid, MultipartOutput multipart) { + return movementProxy.update(csid, multipart); + + } + + /** + * @param csid + * @return + * @see org.collectionspace.services.client.MovementProxy#deleteMovement(java.lang.Long) + */ + public ClientResponse delete(String csid) { + return movementProxy.delete(csid); + } +} diff --git a/services/movement/client/src/main/java/org/collectionspace/services/client/MovementProxy.java b/services/movement/client/src/main/java/org/collectionspace/services/client/MovementProxy.java new file mode 100644 index 000000000..9e0d53d76 --- /dev/null +++ b/services/movement/client/src/main/java/org/collectionspace/services/client/MovementProxy.java @@ -0,0 +1,57 @@ +package org.collectionspace.services.client; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; + +import org.collectionspace.services.common.authorityref.AuthorityRefList; +import org.collectionspace.services.movement.MovementsCommonList; +import org.jboss.resteasy.client.ClientResponse; +import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; +import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; + +/** + * @version $Revision:$ + */ +@Path("/movements/") +@Produces({"multipart/mixed"}) +@Consumes({"multipart/mixed"}) +public interface MovementProxy extends CollectionSpaceProxy { + + //(C)reate + @POST + ClientResponse create(MultipartOutput multipart); + + //(R)ead + @GET + @Path("/{csid}") + ClientResponse read(@PathParam("csid") String csid); + + //(U)pdate + @PUT + @Path("/{csid}") + ClientResponse update(@PathParam("csid") String csid, MultipartOutput multipart); + + //(D)elete + @DELETE + @Path("/{csid}") + ClientResponse delete(@PathParam("csid") String csid); + + // List + @GET + @Produces({"application/xml"}) + ClientResponse readList(); + + // List Authority References + @GET + @Produces({"application/xml"}) + @Path("/{csid}/authorityrefs/") + ClientResponse getAuthorityRefs(@PathParam("csid") String csid); + +} diff --git a/services/movement/client/src/test/java/org/collectionspace/services/client/test/MovementAuthRefsTest.java b/services/movement/client/src/test/java/org/collectionspace/services/client/test/MovementAuthRefsTest.java new file mode 100644 index 000000000..91301208c --- /dev/null +++ b/services/movement/client/src/test/java/org/collectionspace/services/client/test/MovementAuthRefsTest.java @@ -0,0 +1,334 @@ +/** + * 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 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.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.collectionspace.services.PersonJAXBSchema; +import org.collectionspace.services.client.CollectionSpaceClient; +import org.collectionspace.services.client.MovementClient; +import org.collectionspace.services.client.PersonAuthorityClient; +import org.collectionspace.services.client.PersonAuthorityClientUtils; +import org.collectionspace.services.common.authorityref.AuthorityRefList; +//import org.collectionspace.services.common.authorityref.AuthorityRefList.AuthorityRefItem; +import org.collectionspace.services.jaxb.AbstractCommonList; +import org.collectionspace.services.movement.MovementsCommon; +//import org.collectionspace.services.movement.MovementsCommonList; + +import org.jboss.resteasy.client.ClientResponse; + +import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; +import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; +import org.jboss.resteasy.plugins.providers.multipart.OutputPart; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * MovementAuthRefsTest, carries out Authority References tests against a + * deployed and running Movement Service. + * + * $LastChangedRevision: 1327 $ + * $LastChangedDate: 2010-02-12 10:35:11 -0800 (Fri, 12 Feb 2010) $ + */ +public class MovementAuthRefsTest extends BaseServiceTest { + + private final Logger logger = + LoggerFactory.getLogger(MovementAuthRefsTest.class); + + // Instance variables specific to this test. + final String SERVICE_PATH_COMPONENT = "movements"; + final String PERSON_AUTHORITY_NAME = "TestPersonAuth"; + private String knownResourceId = null; + private List movementIdsCreated = new ArrayList(); + private List personIdsCreated = new ArrayList(); + private int CREATED_STATUS = Response.Status.CREATED.getStatusCode(); + private int OK_STATUS = Response.Status.OK.getStatusCode(); + private String personAuthCSID = null; + private String movementContactRefName = null; + + // FIXME: Can add 'current location' and 'normal location' + // as authRefs to tests below, and increase the + // number of expected authRefs to 3. + private final int NUM_AUTH_REFS_EXPECTED = 1; + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance() + */ + @Override + protected CollectionSpaceClient getClientInstance() { + throw new UnsupportedOperationException(); //method not supported (or needed) in this test class + } + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse) + */ + @Override + protected AbstractCommonList getAbstractCommonList( + ClientResponse response) { + throw new UnsupportedOperationException(); //method not supported (or needed) in this test class + } + + // --------------------------------------------------------------- + // CRUD tests : CREATE tests + // --------------------------------------------------------------- + // Success outcomes + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class) + public void createWithAuthRefs(String testName) throws Exception { + + testSetup(CREATED_STATUS, ServiceRequestType.CREATE,testName); + + // Submit the request to the service and store the response. + String identifier = createIdentifier(); + + // Create all the person refs and entities + createPersonRefs(); + + // Create a new Movement resource. + // + // One or more fields in this resource will be PersonAuthority + // references, and will refer to Person resources by their refNames. + MovementClient movementClient = new MovementClient(); + MultipartOutput multipart = createMovementInstance( + "movementReferenceNumber-" + identifier, + "locationDate-" + identifier, + movementContactRefName); + ClientResponse res = movementClient.create(multipart); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + // + // Specifically: + // Does it fall within the set of valid status codes? + // Does it exactly match the expected status code? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + // Store the ID returned from the first resource created + // for additional tests below. + if (knownResourceId == null){ + knownResourceId = extractId(res); + if (logger.isDebugEnabled()) { + logger.debug(testName + ": knownResourceId=" + knownResourceId); + } + } + + // Store the IDs from every resource created by tests, + // so they can be deleted after tests have been run. + movementIdsCreated.add(extractId(res)); + } + + protected void createPersonRefs(){ + + PersonAuthorityClient personAuthClient = new PersonAuthorityClient(); + // Create a temporary PersonAuthority resource, and its corresponding + // refName by which it can be identified. + String authRefName = + PersonAuthorityClientUtils.createPersonAuthRefName(PERSON_AUTHORITY_NAME, false); + MultipartOutput multipart = PersonAuthorityClientUtils.createPersonAuthorityInstance( + PERSON_AUTHORITY_NAME, authRefName, personAuthClient.getCommonPartName()); + ClientResponse res = personAuthClient.create(multipart); + int statusCode = res.getStatus(); + + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, CREATED_STATUS); + personAuthCSID = extractId(res); + + // Create temporary Person resources, and their corresponding refNames + // by which they can be identified. + movementContactRefName = + PersonAuthorityClientUtils.createPersonRefName(authRefName, "Melvin MovementContact", true); + personIdsCreated.add(createPerson("Melvin", "MovementContact", movementContactRefName)); + } + + protected String createPerson(String firstName, String surName, String refName ) { + PersonAuthorityClient personAuthClient = new PersonAuthorityClient(); + Map personInfo = new HashMap(); + personInfo.put(PersonJAXBSchema.FORE_NAME, firstName); + personInfo.put(PersonJAXBSchema.SUR_NAME, surName); + MultipartOutput multipart = + PersonAuthorityClientUtils.createPersonInstance(personAuthCSID, + refName, personInfo, personAuthClient.getItemCommonPartName()); + ClientResponse res = personAuthClient.createItem(personAuthCSID, multipart); + int statusCode = res.getStatus(); + + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, CREATED_STATUS); + return extractId(res); + } + + // Success outcomes + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"createWithAuthRefs"}) + public void readAndCheckAuthRefs(String testName) throws Exception { + + // Perform setup. + testSetup(OK_STATUS, ServiceRequestType.READ,testName); + + // Submit the request to the service and store the response. + MovementClient movementClient = new MovementClient(); + ClientResponse res = movementClient.read(knownResourceId); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ".read: status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + MultipartInput input = (MultipartInput) res.getEntity(); + MovementsCommon movement = (MovementsCommon) extractPart(input, + movementClient.getCommonPartName(), MovementsCommon.class); + Assert.assertNotNull(movement); + if(logger.isDebugEnabled()){ + logger.debug(objectAsXmlString(movement, MovementsCommon.class)); + } + // Check a couple of fields + // FIXME + Assert.assertEquals(movement.getMovementContact(), movementContactRefName); + + // Get the auth refs and check them + ClientResponse res2 = + movementClient.getAuthorityRefs(knownResourceId); + statusCode = res2.getStatus(); + + if(logger.isDebugEnabled()){ + logger.debug(testName + ".getAuthorityRefs: status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + AuthorityRefList list = res2.getEntity(); + + // Optionally output additional data about list members for debugging. + boolean iterateThroughList = true; + if(iterateThroughList && logger.isDebugEnabled()){ + List items = + list.getAuthorityRefItem(); + int i = 0; + for(AuthorityRefList.AuthorityRefItem item : items){ + logger.debug(testName + ": list-item[" + i + "] Field:" + + item.getSourceField() + "= " + + item.getAuthDisplayName() + + item.getItemDisplayName()); + logger.debug(testName + ": list-item[" + i + "] refName=" + + item.getRefName()); + logger.debug(testName + ": list-item[" + i + "] URI=" + + item.getUri()); + i++; + } + Assert.assertEquals(i, NUM_AUTH_REFS_EXPECTED, "Did not find all authrefs!"); + } + } + + + // --------------------------------------------------------------- + // 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 ..."); + } + PersonAuthorityClient personAuthClient = new PersonAuthorityClient(); + // Delete Person resource(s) (before PersonAuthority resources). + for (String resourceId : personIdsCreated) { + // Note: Any non-success responses are ignored and not reported. + personAuthClient.deleteItem(personAuthCSID, resourceId); + } + // Delete PersonAuthority resource(s). + // Note: Any non-success response is ignored and not reported. + if (personAuthCSID != null) { + personAuthClient.delete(personAuthCSID); + } + // Delete Movement resource(s). + MovementClient movementClient = new MovementClient(); + for (String resourceId : movementIdsCreated) { + // Note: Any non-success responses are ignored and not reported. + movementClient.delete(resourceId); + } + } + + // --------------------------------------------------------------- + // Utility methods used by tests above + // --------------------------------------------------------------- + @Override + public String getServicePathComponent() { + return SERVICE_PATH_COMPONENT; + } + + private MultipartOutput createMovementInstance(String movementReferenceNumber, + String locationDate, + String movementContact) { + MovementsCommon movement = new MovementsCommon(); + movement.setMovementReferenceNumber(movementReferenceNumber); + movement.setLocationDate(locationDate); + movement.setMovementContact(movementContact); + MultipartOutput multipart = new MultipartOutput(); + OutputPart commonPart = + multipart.addPart(movement, MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", new MovementClient().getCommonPartName()); + + if(logger.isDebugEnabled()){ + logger.debug("to be created, movement common"); + logger.debug(objectAsXmlString(movement, MovementsCommon.class)); + } + + return multipart; + } +} diff --git a/services/movement/client/src/test/java/org/collectionspace/services/client/test/MovementServiceTest.java b/services/movement/client/src/test/java/org/collectionspace/services/client/test/MovementServiceTest.java new file mode 100644 index 000000000..3aa5e43cf --- /dev/null +++ b/services/movement/client/src/test/java/org/collectionspace/services/client/test/MovementServiceTest.java @@ -0,0 +1,702 @@ +/** + * 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 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.List; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.collectionspace.services.client.CollectionSpaceClient; +import org.collectionspace.services.client.MovementClient; +import org.collectionspace.services.jaxb.AbstractCommonList; +import org.collectionspace.services.movement.MovementsCommon; +import org.collectionspace.services.movement.MovementsCommonList; + +import org.jboss.resteasy.client.ClientResponse; + +import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; +import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; +import org.jboss.resteasy.plugins.providers.multipart.OutputPart; +import org.testng.Assert; +import org.testng.annotations.Test; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * MovementServiceTest, carries out tests against a + * deployed and running Movement Service. + * + * $LastChangedRevision: 1327 $ + * $LastChangedDate: 2010-02-12 10:35:11 -0800 (Fri, 12 Feb 2010) $ + */ +public class MovementServiceTest extends AbstractServiceTestImpl { + + /** The logger. */ + private final Logger logger = + LoggerFactory.getLogger(MovementServiceTest.class); + + // Instance variables specific to this test. + /** The service path component. */ + final String SERVICE_PATH_COMPONENT = "movements"; + + /** The known resource id. */ + private String knownResourceId = null; + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance() + */ + @Override + protected CollectionSpaceClient getClientInstance() { + return new MovementClient(); + } + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse) + */ + @Override + protected AbstractCommonList getAbstractCommonList( + ClientResponse response) { + return response.getEntity(MovementsCommonList.class); + } + + // --------------------------------------------------------------- + // CRUD tests : CREATE tests + // --------------------------------------------------------------- + // Success outcomes + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.ServiceTest#create(java.lang.String) + */ + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class) + public void create(String testName) throws Exception { + + // Perform setup, such as initializing the type of service request + // (e.g. CREATE, DELETE), its valid and expected status codes, and + // its associated HTTP method name (e.g. POST, DELETE). + setupCreate(testName); + + // Submit the request to the service and store the response. + MovementClient client = new MovementClient(); + String identifier = createIdentifier(); + MultipartOutput multipart = createMovementInstance(identifier); + ClientResponse res = client.create(multipart); + + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + // + // Specifically: + // Does it fall within the set of valid status codes? + // Does it exactly match the expected status code? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + // Store the ID returned from the first resource created + // for additional tests below. + if (knownResourceId == null){ + knownResourceId = extractId(res); + if (logger.isDebugEnabled()) { + logger.debug(testName + ": knownResourceId=" + knownResourceId); + } + } + + // Store the IDs from every resource created by tests, + // so they can be deleted after tests have been run. + allResourceIdsCreated.add(extractId(res)); + } + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createList(java.lang.String) + */ + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"create"}) + public void createList(String testName) throws Exception { + for(int i = 0; i < 3; i++){ + create(testName); + } + } + + // Failure outcomes + // Placeholders until the three tests below can be uncommented. + // See Issue CSPACE-401. + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithEmptyEntityBody(java.lang.String) + */ + @Override + public void createWithEmptyEntityBody(String testName) throws Exception { + //Should this really be empty? + } + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithMalformedXml(java.lang.String) + */ + @Override + public void createWithMalformedXml(String testName) throws Exception { + //Should this really be empty? + } + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithWrongXmlSchema(java.lang.String) + */ + @Override + public void createWithWrongXmlSchema(String testName) throws Exception { + //Should this really be empty? + } + + /* + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class, + dependsOnMethods = {"create", "testSubmitRequest"}) + public void createWithEmptyEntityBody(String testName) throws Exception { + + // Perform setup. + setupCreateWithEmptyEntityBody(testName); + + // Submit the request to the service and store the response. + String method = REQUEST_TYPE.httpMethodName(); + String url = getServiceRootURL(); + String mediaType = MediaType.APPLICATION_XML; + final String entity = ""; + int statusCode = submitRequest(method, url, mediaType, entity); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug("createWithEmptyEntityBody url=" + url + + " status=" + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class, + dependsOnMethods = {"create", "testSubmitRequest"}) + public void createWithMalformedXml(String testName) throws Exception { + + // Perform setup. + setupCreateWithMalformedXml(testName); + + // Submit the request to the service and store the response. + String method = REQUEST_TYPE.httpMethodName(); + String url = getServiceRootURL(); + String mediaType = MediaType.APPLICATION_XML; + final String entity = MALFORMED_XML_DATA; // Constant from base class. + int statusCode = submitRequest(method, url, mediaType, entity); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": url=" + url + + " status=" + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class, + dependsOnMethods = {"create", "testSubmitRequest"}) + public void createWithWrongXmlSchema(String testName) throws Exception { + + // Perform setup. + setupCreateWithWrongXmlSchema(testName); + + // Submit the request to the service and store the response. + String method = REQUEST_TYPE.httpMethodName(); + String url = getServiceRootURL(); + String mediaType = MediaType.APPLICATION_XML; + final String entity = WRONG_XML_SCHEMA_DATA; + int statusCode = submitRequest(method, url, mediaType, entity); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": url=" + url + + " status=" + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + */ + + // --------------------------------------------------------------- + // CRUD tests : READ tests + // --------------------------------------------------------------- + // Success outcomes + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#read(java.lang.String) + */ + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"create"}) + public void read(String testName) throws Exception { + + // Perform setup. + setupRead(testName); + + // Submit the request to the service and store the response. + MovementClient client = new MovementClient(); + ClientResponse res = client.read(knownResourceId); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + MultipartInput input = (MultipartInput) res.getEntity(); + MovementsCommon movement = (MovementsCommon) extractPart(input, + client.getCommonPartName(), MovementsCommon.class); + Assert.assertNotNull(movement); + } + + // Failure outcomes + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readNonExistent(java.lang.String) + */ + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"read"}) + public void readNonExistent(String testName) throws Exception { + + // Perform setup. + setupReadNonExistent(testName); + + // Submit the request to the service and store the response. + MovementClient client = new MovementClient(); + ClientResponse res = client.read(NON_EXISTENT_ID); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + + // --------------------------------------------------------------- + // CRUD tests : READ_LIST tests + // --------------------------------------------------------------- + // Success outcomes + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readList(java.lang.String) + */ + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"createList", "read"}) + public void readList(String testName) throws Exception { + + // Perform setup. + setupReadList(testName); + + // Submit the request to the service and store the response. + MovementClient client = new MovementClient(); + ClientResponse res = client.readList(); + MovementsCommonList list = res.getEntity(); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + // Optionally output additional data about list members for debugging. + boolean iterateThroughList = false; + if(iterateThroughList && logger.isDebugEnabled()){ + List items = + list.getMovementListItem(); + int i = 0; + for(MovementsCommonList.MovementListItem item : items){ + logger.debug(testName + ": list-item[" + i + "] csid=" + + item.getCsid()); + logger.debug(testName + ": list-item[" + i + "] movementReferenceNumber=" + + item.getMovementReferenceNumber()); + logger.debug(testName + ": list-item[" + i + "] URI=" + + item.getUri()); + i++; + } + } + + } + + // Failure outcomes + // None at present. + // --------------------------------------------------------------- + // CRUD tests : UPDATE tests + // --------------------------------------------------------------- + // Success outcomes + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#update(java.lang.String) + */ + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"read"}) + public void update(String testName) throws Exception { + + // Perform setup. + setupUpdate(testName); + + // Retrieve the contents of a resource to update. + MovementClient client = new MovementClient(); + ClientResponse res = + client.read(knownResourceId); + if(logger.isDebugEnabled()){ + logger.debug(testName + ": read status = " + res.getStatus()); + } + Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE); + + if(logger.isDebugEnabled()){ + logger.debug("got object to update with ID: " + knownResourceId); + } + MultipartInput input = (MultipartInput) res.getEntity(); + MovementsCommon movement = (MovementsCommon) extractPart(input, + client.getCommonPartName(), MovementsCommon.class); + Assert.assertNotNull(movement); + + // Update the content of this resource. + movement.setMovementReferenceNumber("updated-" + movement.getMovementReferenceNumber()); + movement.setLocationDate("updated-" + movement.getLocationDate()); + if(logger.isDebugEnabled()){ + logger.debug("to be updated object"); + logger.debug(objectAsXmlString(movement, MovementsCommon.class)); + } + // Submit the request to the service and store the response. + MultipartOutput output = new MultipartOutput(); + OutputPart commonPart = output.addPart(movement, MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", client.getCommonPartName()); + + res = client.update(knownResourceId, output); + int statusCode = res.getStatus(); + // Check the status code of the response: does it match the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + + input = (MultipartInput) res.getEntity(); + MovementsCommon updatedMovement = + (MovementsCommon) extractPart(input, + client.getCommonPartName(), MovementsCommon.class); + Assert.assertNotNull(updatedMovement); + + Assert.assertEquals(updatedMovement.getLocationDate(), + movement.getLocationDate(), + "Data in updated object did not match submitted data."); + + } + + // Failure outcomes + // Placeholders until the three tests below can be uncommented. + // See Issue CSPACE-401. + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithEmptyEntityBody(java.lang.String) + */ + @Override + public void updateWithEmptyEntityBody(String testName) throws Exception{ + //Should this really be empty? + } + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithMalformedXml(java.lang.String) + */ + @Override + public void updateWithMalformedXml(String testName) throws Exception { + //Should this really be empty? + } + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithWrongXmlSchema(java.lang.String) + */ + @Override + public void updateWithWrongXmlSchema(String testName) throws Exception { + //Should this really be empty? + } + + /* + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class, + dependsOnMethods = {"create", "update", "testSubmitRequest"}) + public void updateWithEmptyEntityBody(String testName) throws Exception { + + // Perform setup. + setupUpdateWithEmptyEntityBody(testName); + + // Submit the request to the service and store the response. + String method = REQUEST_TYPE.httpMethodName(); + String url = getResourceURL(knownResourceId); + String mediaType = MediaType.APPLICATION_XML; + final String entity = ""; + int statusCode = submitRequest(method, url, mediaType, entity); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": url=" + url + + " status=" + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class, + dependsOnMethods = {"create", "update", "testSubmitRequest"}) + public void updateWithMalformedXml(String testName) throws Exception { + + // Perform setup. + setupUpdateWithMalformedXml(testName); + + // Submit the request to the service and store the response. + String method = REQUEST_TYPE.httpMethodName(); + String url = getResourceURL(knownResourceId); + String mediaType = MediaType.APPLICATION_XML; + final String entity = MALFORMED_XML_DATA; + int statusCode = submitRequest(method, url, mediaType, entity); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": url=" + url + + " status=" + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class, + dependsOnMethods = {"create", "update", "testSubmitRequest"}) + public void updateWithWrongXmlSchema(String testName) throws Exception { + + // Perform setup. + setupUpdateWithWrongXmlSchema(testName); + + // Submit the request to the service and store the response. + String method = REQUEST_TYPE.httpMethodName(); + String url = getResourceURL(knownResourceId); + String mediaType = MediaType.APPLICATION_XML; + final String entity = WRONG_XML_SCHEMA_DATA; + int statusCode = submitRequest(method, url, mediaType, entity); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": url=" + url + + " status=" + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + */ + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateNonExistent(java.lang.String) + */ + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"update", "testSubmitRequest"}) + public void updateNonExistent(String testName) throws Exception { + + // Perform setup. + setupUpdateNonExistent(testName); + + // Submit the request to the service and store the response. + // Note: The ID used in this 'create' call may be arbitrary. + // The only relevant ID may be the one used in update(), below. + MovementClient client = new MovementClient(); + MultipartOutput multipart = createMovementInstance(NON_EXISTENT_ID); + ClientResponse res = + client.update(NON_EXISTENT_ID, multipart); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + + // --------------------------------------------------------------- + // CRUD tests : DELETE tests + // --------------------------------------------------------------- + // Success outcomes + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#delete(java.lang.String) + */ + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"}) + public void delete(String testName) throws Exception { + + // Perform setup. + setupDelete(testName); + + // Submit the request to the service and store the response. + MovementClient client = new MovementClient(); + ClientResponse res = client.delete(knownResourceId); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + + // Failure outcomes + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#deleteNonExistent(java.lang.String) + */ + @Override + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"delete"}) + public void deleteNonExistent(String testName) throws Exception { + + // Perform setup. + setupDeleteNonExistent(testName); + + // Submit the request to the service and store the response. + MovementClient client = new MovementClient(); + ClientResponse res = client.delete(NON_EXISTENT_ID); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + + // --------------------------------------------------------------- + // Utility tests : tests of code used in tests above + // --------------------------------------------------------------- + /** + * Tests the code for manually submitting data that is used by several + * of the methods above. + */ + @Test(dependsOnMethods = {"create", "read"}) + public void testSubmitRequest() { + + // Expected status code: 200 OK + final int EXPECTED_STATUS = Response.Status.OK.getStatusCode(); + + // Submit the request to the service and store the response. + String method = ServiceRequestType.READ.httpMethodName(); + String url = getResourceURL(knownResourceId); + int statusCode = submitRequest(method, url); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug("testSubmitRequest: url=" + url + + " status=" + statusCode); + } + Assert.assertEquals(statusCode, EXPECTED_STATUS); + + } + + // --------------------------------------------------------------- + // Utility methods used by tests above + // --------------------------------------------------------------- + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent() + */ + @Override + public String getServicePathComponent() { + return SERVICE_PATH_COMPONENT; + } + + /** + * Creates the movement instance. + * + * @param identifier the identifier + * @return the multipart output + */ + private MultipartOutput createMovementInstance(String identifier) { + return createMovementInstance( + "movementReferenceNumber-" + identifier, + "locationDate-" + identifier); + } + + /** + * Creates the movement instance. + * + * @param movementReferenceNumber the movement reference number + * @param locationDate the location date + * @return the multipart output + */ + private MultipartOutput createMovementInstance(String movementReferenceNumber, + String locationDate) { + MovementsCommon movement = new MovementsCommon(); + movement.setMovementReferenceNumber(movementReferenceNumber); + movement.setLocationDate(locationDate); + MultipartOutput multipart = new MultipartOutput(); + OutputPart commonPart = + multipart.addPart(movement, MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", new MovementClient().getCommonPartName()); + + if(logger.isDebugEnabled()){ + logger.debug("to be created, movement common"); + logger.debug(objectAsXmlString(movement, MovementsCommon.class)); + } + + return multipart; + } +} diff --git a/services/movement/client/src/test/resources/log4j.properties b/services/movement/client/src/test/resources/log4j.properties new file mode 100644 index 000000000..18c510350 --- /dev/null +++ b/services/movement/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/movement/jaxb/.settings/org.eclipse.jdt.core.prefs b/services/movement/jaxb/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..466b77bf4 --- /dev/null +++ b/services/movement/jaxb/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,6 @@ +#Tue Apr 27 21:36:41 PDT 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/services/movement/jaxb/.settings/org.maven.ide.eclipse.prefs b/services/movement/jaxb/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 000000000..3dc0a0d5e --- /dev/null +++ b/services/movement/jaxb/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Tue Apr 27 21:36:39 PDT 2010 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/services/movement/jaxb/pom.xml b/services/movement/jaxb/pom.xml new file mode 100644 index 000000000..5a5f9e674 --- /dev/null +++ b/services/movement/jaxb/pom.xml @@ -0,0 +1,47 @@ + + + + org.collectionspace.services.movement + org.collectionspace.services + 0.7-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.movement.jaxb + services.movement.jaxb + + + + com.sun.xml.bind + jaxb-impl + + + org.jvnet.jaxb2-commons + property-listener-injector + + + org.jvnet.jaxb2_commons + runtime + + + org.collectionspace.services + org.collectionspace.services.jaxb + ${project.version} + + + + + collectionspace-services-movement-jaxb + install + + + org.jvnet.jaxb2.maven2 + maven-jaxb2-plugin + + + + + diff --git a/services/movement/jaxb/src/main/java/org/collectionspace/services/MovementJAXBSchema.java b/services/movement/jaxb/src/main/java/org/collectionspace/services/MovementJAXBSchema.java new file mode 100644 index 000000000..fbd0fe828 --- /dev/null +++ b/services/movement/jaxb/src/main/java/org/collectionspace/services/MovementJAXBSchema.java @@ -0,0 +1,22 @@ +/** + * + */ +package org.collectionspace.services; + +public interface MovementJAXBSchema { + + final static String CURRENT_LOCATION = "currentLocation"; + final static String CURRENT_LOCATION_FITNESS = "currentLocationFitness"; + final static String CURRENT_LOCATION_NOTE = "currentLocationNote"; + final static String LOCATION_DATE = "locationDate"; + final static String NORMAL_LOCATION = "normalLocation"; + + final static String MOVEMENT_CONTACT = "movementContact"; + // MOVEMENT_METHODS + final static String MOVEMENT_NOTE = "movementNote"; + final static String MOVEMENT_REFERENCE_NUMBER = "movementReferenceNumber"; + final static String PLANNED_REMOVAL_DATE = "plannedRemovalDate"; + final static String REMOVAL_DATE = "removalDate"; + final static String REASON_FOR_MOVE = "reasonForMove"; + +} diff --git a/services/movement/jaxb/src/main/java/org/collectionspace/services/MovementListItemJAXBSchema.java b/services/movement/jaxb/src/main/java/org/collectionspace/services/MovementListItemJAXBSchema.java new file mode 100644 index 000000000..a9d7359cc --- /dev/null +++ b/services/movement/jaxb/src/main/java/org/collectionspace/services/MovementListItemJAXBSchema.java @@ -0,0 +1,8 @@ +package org.collectionspace.services; + +public interface MovementListItemJAXBSchema { + final static String MOVEMENT_REFERENCE_NUMBER = "movementReferenceNumber"; + final static String LOCATION_DATE = "locationDate"; + final static String CSID = "csid"; + final static String URI = "url"; +} diff --git a/services/movement/jaxb/src/main/resources/movements-common.xsd b/services/movement/jaxb/src/main/resources/movements-common.xsd new file mode 100644 index 000000000..e143713d4 --- /dev/null +++ b/services/movement/jaxb/src/main/resources/movements-common.xsd @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/movement/pom.xml b/services/movement/pom.xml new file mode 100644 index 000000000..f4963e0be --- /dev/null +++ b/services/movement/pom.xml @@ -0,0 +1,24 @@ + + + + + org.collectionspace.services + org.collectionspace.services.main + 0.7-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.movement + services.movement + pom + + + jaxb + service + 3rdparty + client + + + + diff --git a/services/movement/service/.settings/org.eclipse.jdt.core.prefs b/services/movement/service/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..466b77bf4 --- /dev/null +++ b/services/movement/service/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,6 @@ +#Tue Apr 27 21:36:41 PDT 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/services/movement/service/.settings/org.maven.ide.eclipse.prefs b/services/movement/service/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 000000000..3dc0a0d5e --- /dev/null +++ b/services/movement/service/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Tue Apr 27 21:36:39 PDT 2010 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/services/movement/service/pom.xml b/services/movement/service/pom.xml new file mode 100644 index 000000000..46eab9bff --- /dev/null +++ b/services/movement/service/pom.xml @@ -0,0 +1,117 @@ + + + + + org.collectionspace.services + org.collectionspace.services.movement + 0.7-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.movement.service + services.movement.service + jar + + + + org.collectionspace.services + org.collectionspace.services.common + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.movement.jaxb + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.collectionobject.jaxb + ${project.version} + + + + junit + junit + 4.1 + test + + + org.testng + testng + 5.6 + + + + + + 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 + 1.5.1-SNAPSHOT + + + 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-movement + + + diff --git a/services/movement/service/profiles.xml b/services/movement/service/profiles.xml new file mode 100644 index 000000000..347b9df22 --- /dev/null +++ b/services/movement/service/profiles.xml @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/services/movement/service/src/main/java/org/collectionspace/services/movement/MovementResource.java b/services/movement/service/src/main/java/org/collectionspace/services/movement/MovementResource.java new file mode 100644 index 000000000..51f171ad5 --- /dev/null +++ b/services/movement/service/src/main/java/org/collectionspace/services/movement/MovementResource.java @@ -0,0 +1,476 @@ +/** + * 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.movement; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; +import javax.ws.rs.core.UriInfo; + +import org.collectionspace.services.common.AbstractMultiPartCollectionSpaceResourceImpl; +import org.collectionspace.services.common.ClientType; +import org.collectionspace.services.common.ServiceMain; +import org.collectionspace.services.common.authorityref.AuthorityRefList; +import org.collectionspace.services.common.context.MultipartServiceContextImpl; +import org.collectionspace.services.common.context.ServiceBindingUtils; +import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.document.DocumentFilter; +import org.collectionspace.services.common.document.DocumentHandler; +import org.collectionspace.services.common.document.DocumentNotFoundException; +import org.collectionspace.services.common.document.DocumentWrapper; +import org.collectionspace.services.common.query.IQueryManager; +import org.collectionspace.services.common.query.QueryManager; +import org.collectionspace.services.common.security.UnauthorizedException; +import org.collectionspace.services.movement.MovementsCommon; +import org.collectionspace.services.movement.MovementsCommonList; +import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler; +import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl; +import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; +import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; +import org.jboss.resteasy.util.HttpResponseCodes; +import org.nuxeo.ecm.core.api.DocumentModel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class MovementResource. + */ +@Path("/movements") +@Consumes("multipart/mixed") +@Produces("multipart/mixed") +public class MovementResource extends + AbstractMultiPartCollectionSpaceResourceImpl { + + /** The Constant serviceName. */ + private final static String serviceName = "movements"; + + /** The logger. */ + final Logger logger = LoggerFactory.getLogger(MovementResource.class); + //FIXME retrieve client type from configuration + /** The Constant CLIENT_TYPE. */ + final static ClientType CLIENT_TYPE = ServiceMain.getInstance().getClientType(); + + /** + * Instantiates a new movement resource. + */ + public MovementResource() { + // do nothing + } + + /* (non-Javadoc) + * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString() + */ + @Override + protected String getVersionString() { + /** The last change revision. */ + final String lastChangeRevision = "$LastChangedRevision: 1627 $"; + return lastChangeRevision; + } + + /* (non-Javadoc) + * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getServiceName() + */ + @Override + public String getServiceName() { + return serviceName; + } + + /* (non-Javadoc) + * @see org.collectionspace.services.common.CollectionSpaceResource#getCommonPartClass() + */ + @Override + public Class getCommonPartClass() { + return MovementsCommon.class; + } + + /* (non-Javadoc) + * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#createDocumentHandler(org.collectionspace.services.common.context.ServiceContext) + */ +// @Override +// public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception { +// DocumentHandler docHandler = ctx.getDocumentHandler(); +// if (ctx.getInput() != null) { +// Object obj = ((MultipartServiceContext) ctx).getInputPart(ctx.getCommonPartLabel(), MovementsCommon.class); +// if (obj != null) { +// docHandler.setCommonPart((MovementsCommon) obj); +// } +// } +// return docHandler; +// } + + /** + * Creates the movement. + * + * @param input the input + * + * @return the response + */ + @POST + public Response createMovement(MultipartInput input) { + try { + ServiceContext ctx = createServiceContext(input); + DocumentHandler handler = createDocumentHandler(ctx); + String csid = getRepositoryClient(ctx).create(ctx, handler); + //movementObject.setCsid(csid); + UriBuilder path = UriBuilder.fromResource(MovementResource.class); + path.path("" + csid); + Response response = Response.created(path.build()).build(); + return response; + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Create failed reason " + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception in createMovement", e); + } + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity("Create failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + } + + /** + * Gets the movement. + * + * @param csid the csid + * + * @return the movement + */ + @GET + @Path("{csid}") + public MultipartOutput getMovement( + @PathParam("csid") String csid) { + if (logger.isDebugEnabled()) { + logger.debug("getMovement with csid=" + csid); + } + if (csid == null || "".equals(csid)) { + logger.error("getMovement: missing csid!"); + Response response = Response.status(Response.Status.BAD_REQUEST).entity( + "get failed on Movement csid=" + csid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } + MultipartOutput result = null; + try { + ServiceContext ctx = createServiceContext(); + DocumentHandler handler = createDocumentHandler(ctx); + getRepositoryClient(ctx).get(ctx, csid, handler); + result = (MultipartOutput) ctx.getOutput(); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Get failed reason " + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (DocumentNotFoundException dnfe) { + if (logger.isDebugEnabled()) { + logger.debug("getMovement", dnfe); + } + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Get failed on Movement csid=" + csid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("getMovement", e); + } + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + if (result == null) { + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Get failed, the requested Movement CSID:" + csid + ": was not found.").type( + "text/plain").build(); + throw new WebApplicationException(response); + } + return result; + } + + /** + * Gets the movement list. + * + * @param ui the ui + * @param keywords the keywords + * + * @return the movement list + */ + @GET + @Produces("application/xml") + public MovementsCommonList getMovementList(@Context UriInfo ui, + @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS_KW) String keywords) { + MovementsCommonList result = null; + MultivaluedMap queryParams = ui.getQueryParameters(); + if (keywords != null) { + result = searchMovements(queryParams, keywords); + } else { + result = getMovementList(queryParams); + } + + return result; + } + + /** + * Gets the movement list. + * + * @return the movement list + */ + private MovementsCommonList getMovementList(MultivaluedMap queryParams) { + MovementsCommonList movementObjectList; + try { + ServiceContext ctx = createServiceContext(queryParams); + DocumentHandler handler = createDocumentHandler(ctx); + getRepositoryClient(ctx).getFiltered(ctx, handler); + movementObjectList = (MovementsCommonList) handler.getCommonPartList(); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception in getMovementList", e); + } + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + return movementObjectList; + } + + /** + * Gets the authority refs. + * + * @param csid the csid + * @param ui the ui + * + * @return the authority refs + */ + @GET + @Path("{csid}/authorityrefs") + @Produces("application/xml") + public AuthorityRefList getAuthorityRefs( + @PathParam("csid") String csid, + @Context UriInfo ui) { + AuthorityRefList authRefList = null; + try { + MultivaluedMap queryParams = ui.getQueryParameters(); + ServiceContext ctx = createServiceContext(queryParams); + DocumentWrapper docWrapper = + getRepositoryClient(ctx).getDoc(ctx, csid); + DocumentModelHandler handler + = (DocumentModelHandler)createDocumentHandler(ctx); + List authRefFields = + ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues( + ServiceBindingUtils.AUTH_REF_PROP, ServiceBindingUtils.QUALIFIED_PROP_NAMES); + authRefList = handler.getAuthorityRefs(docWrapper, authRefFields); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Failed to retrieve authority references: reason " + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception in getAuthorityRefs", e); + } + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity("Failed to retrieve authority references").type("text/plain").build(); + throw new WebApplicationException(response); + } + return authRefList; + } + + /** + * Gets the movement list. + * + * @param csidList the csid list + * + * @return the movement list + */ + @Deprecated + public MovementsCommonList getMovementList(List csidList) { + MovementsCommonList movementObjectList = new MovementsCommonList(); + try { + ServiceContext ctx = createServiceContext(); + DocumentHandler handler = createDocumentHandler(ctx); + getRepositoryClient(ctx).get(ctx, csidList, handler); + movementObjectList = (MovementsCommonList) handler.getCommonPartList(); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception in getMovementList", e); + } + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + return movementObjectList; + } + + /** + * Update movement. + * + * @param csid the csid + * @param theUpdate the the update + * + * @return the multipart output + */ + @PUT + @Path("{csid}") + public MultipartOutput updateMovement( + @PathParam("csid") String csid, + MultipartInput theUpdate) { + if (logger.isDebugEnabled()) { + logger.debug("updateMovement with csid=" + csid); + } + if (csid == null || "".equals(csid)) { + logger.error("updateMovement: missing csid!"); + Response response = Response.status(Response.Status.BAD_REQUEST).entity( + "update failed on Movement csid=" + csid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } + MultipartOutput result = null; + try { + ServiceContext ctx = createServiceContext(theUpdate); + DocumentHandler handler = createDocumentHandler(ctx); + getRepositoryClient(ctx).update(ctx, csid, handler); + result = (MultipartOutput) ctx.getOutput(); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Update failed reason " + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (DocumentNotFoundException dnfe) { + if (logger.isDebugEnabled()) { + logger.debug("caught exception in updateMovement", dnfe); + } + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Update failed on Movement csid=" + csid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + return result; + } + + /** + * Delete movement. + * + * @param csid the csid + * + * @return the response + */ + @DELETE + @Path("{csid}") + public Response deleteMovement(@PathParam("csid") String csid) { + + if (logger.isDebugEnabled()) { + logger.debug("deleteMovement with csid=" + csid); + } + if (csid == null || "".equals(csid)) { + logger.error("deleteMovement: missing csid!"); + Response response = Response.status(Response.Status.BAD_REQUEST).entity( + "delete failed on Movement csid=" + csid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } + try { + ServiceContext ctx = createServiceContext(); + getRepositoryClient(ctx).delete(ctx, csid); + return Response.status(HttpResponseCodes.SC_OK).build(); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Delete failed reason " + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (DocumentNotFoundException dnfe) { + if (logger.isDebugEnabled()) { + logger.debug("caught exception in deleteMovement", dnfe); + } + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Delete failed on Movement csid=" + csid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + } + + /** + * Search movements. + * + * @param keywords the keywords + * + * @return the movements common list + */ + private MovementsCommonList searchMovements(MultivaluedMap queryParams, + String keywords) { + MovementsCommonList movementsObjectList; + try { + ServiceContext ctx = createServiceContext(queryParams); + DocumentHandler handler = createDocumentHandler(ctx); + + // perform a keyword search + if (keywords != null && !keywords.isEmpty()) { + String whereClause = QueryManager.createWhereClauseFromKeywords(keywords); + DocumentFilter documentFilter = handler.getDocumentFilter(); + documentFilter.setWhereClause(whereClause); + if (logger.isDebugEnabled()) { + logger.debug("The WHERE clause is: " + documentFilter.getWhereClause()); + } + } + getRepositoryClient(ctx).getFiltered(ctx, handler); + movementsObjectList = (MovementsCommonList) handler.getCommonPartList(); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception in search for Movements", e); + } + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + return movementsObjectList; + } +} diff --git a/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementConstants.java b/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementConstants.java new file mode 100644 index 000000000..84554cbb3 --- /dev/null +++ b/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementConstants.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.movement.nuxeo; + +/** + * MovementConstants specifies constants for the Movement service + * + */ +public class MovementConstants { + + public final static String NUXEO_DOCTYPE = "Movement"; + public final static String NUXEO_SCHEMA_NAME = "movement"; + public final static String NUXEO_DC_TITLE = "CollectionSpace-Movement"; +} diff --git a/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementDocumentModelHandler.java b/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementDocumentModelHandler.java new file mode 100644 index 000000000..c7cf06b04 --- /dev/null +++ b/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementDocumentModelHandler.java @@ -0,0 +1,162 @@ +/** + * 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.movement.nuxeo; + +import java.util.Iterator; +import java.util.List; + +import org.collectionspace.services.MovementJAXBSchema; +import org.collectionspace.services.common.document.DocumentWrapper; +import org.collectionspace.services.movement.MovementsCommon; +import org.collectionspace.services.movement.MovementsCommonList; +import org.collectionspace.services.movement.MovementsCommonList.MovementListItem; +import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl; +import org.collectionspace.services.nuxeo.util.NuxeoUtils; +import org.nuxeo.ecm.core.api.DocumentModel; +import org.nuxeo.ecm.core.api.DocumentModelList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class MovementDocumentModelHandler. + */ +public class MovementDocumentModelHandler + extends RemoteDocumentModelHandlerImpl { + + /** The logger. */ + private final Logger logger = LoggerFactory.getLogger(MovementDocumentModelHandler.class); + + /** The Movement. */ + private MovementsCommon Movement; + + /** The Movement list. */ + private MovementsCommonList MovementList; + + + /** + * Gets the common part. + * + * @return the common part + */ + @Override + public MovementsCommon getCommonPart() { + return Movement; + } + + /** + * Sets the common part. + * + * @param Movement the new common part + */ + @Override + public void setCommonPart(MovementsCommon Movement) { + this.Movement = Movement; + } + + /** + * Gets the common part list. + * + * @return the common part list + */ + @Override + public MovementsCommonList getCommonPartList() { + return MovementList; + } + + /** + * Sets the common part list. + * + * @param MovementList the new common part list + */ + @Override + public void setCommonPartList(MovementsCommonList MovementList) { + this.MovementList = MovementList; + } + + /** + * Extract common part. + * + * @param wrapDoc the wrap doc + * @return the Movements common + * @throws Exception the exception + */ + @Override + public MovementsCommon extractCommonPart(DocumentWrapper wrapDoc) + throws Exception { + throw new UnsupportedOperationException(); + } + + /** + * Fill common part. + * + * @param MovementObject the Movement object + * @param wrapDoc the wrap doc + * @throws Exception the exception + */ + @Override + public void fillCommonPart(MovementsCommon MovementObject, DocumentWrapper wrapDoc) throws Exception { + throw new UnsupportedOperationException(); + } + + /** + * Extract common part list. + * + * @param wrapDoc the wrap doc + * @return the Movements common list + * @throws Exception the exception + */ + @Override + public MovementsCommonList extractCommonPartList(DocumentWrapper wrapDoc) throws Exception { + MovementsCommonList coList = extractPagingInfo(new MovementsCommonList(), wrapDoc); + List list = coList.getMovementListItem(); + Iterator iter = wrapDoc.getWrappedObject().iterator(); + while(iter.hasNext()){ + DocumentModel docModel = iter.next(); + MovementListItem ilistItem = new MovementListItem(); + ilistItem.setMovementReferenceNumber((String) docModel.getProperty(getServiceContext().getCommonPartLabel(), + MovementJAXBSchema.MOVEMENT_REFERENCE_NUMBER)); + ilistItem.setLocationDate((String) docModel.getProperty(getServiceContext().getCommonPartLabel(), + MovementJAXBSchema.LOCATION_DATE)); + String id = NuxeoUtils.extractId(docModel.getPathAsString()); + ilistItem.setUri(getServiceContextPath() + id); + ilistItem.setCsid(id); + list.add(ilistItem); + } + + return coList; + } + + /** + * Gets the q property. + * + * @param prop the prop + * @return the q property + */ + @Override + public String getQProperty(String prop) { + return MovementConstants.NUXEO_SCHEMA_NAME + ":" + prop; + } + +} + diff --git a/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementValidatorHandler.java b/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementValidatorHandler.java new file mode 100644 index 000000000..5b29958e4 --- /dev/null +++ b/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementValidatorHandler.java @@ -0,0 +1,18 @@ +package org.collectionspace.services.movement.nuxeo; + +import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.document.InvalidDocumentException; +import org.collectionspace.services.common.document.ValidatorHandler; +import org.collectionspace.services.common.document.DocumentHandler.Action; + +public class MovementValidatorHandler implements ValidatorHandler { + + @Override + public void validate(Action action, ServiceContext ctx) + throws InvalidDocumentException { + // TODO Auto-generated method stub + System.out.println("movementValidatorHandler executed."); + + } + +} diff --git a/services/movement/service/src/test/java/org/collectionspace/services/test/MovementServiceTest.java b/services/movement/service/src/test/java/org/collectionspace/services/test/MovementServiceTest.java new file mode 100644 index 000000000..cdb446aa8 --- /dev/null +++ b/services/movement/service/src/test/java/org/collectionspace/services/test/MovementServiceTest.java @@ -0,0 +1,10 @@ +package org.collectionspace.services.test; + +/** + * Placeholder for server-side testing of Movement service code. + * + * @version $Revision:$ + */ +public class MovementServiceTest { + //empty +} diff --git a/services/movement/service/src/test/resources/log4j.xml b/services/movement/service/src/test/resources/log4j.xml new file mode 100644 index 000000000..52121cb83 --- /dev/null +++ b/services/movement/service/src/test/resources/log4j.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/pom.xml b/services/pom.xml index 58a77a9b5..86f43b02b 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -31,6 +31,7 @@ intake loanin loanout + movement dimension contact JaxRsServiceProvider