--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src/main/java"/>
+ <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+ <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>javaee-addressbook-client</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+#Thu Feb 26 16:32:51 PST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.source=1.5
--- /dev/null
+#Thu Feb 26 16:30:28 PST 2009
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+version=1
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project-shared-configuration>\r
+ <!--
+This file contains additional configuration written by modules in the NetBeans IDE.
+The configuration is intended to be shared among all the users of project and
+therefore it is assumed to be part of version control checkout.
+Without this configuration present, some functionality in the IDE may be limited or fail altogether.
+-->\r
+ <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">\r
+ <!--
+Properties that influence various parts of the IDE, especially code formatting and the like.
+You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
+That way multiple projects can share the same settings (useful for formatting rules for example).
+Any value defined here will override the pom.xml file value but is only applicable to the current project.
+-->\r
+ <org-netbeans-modules-editor-indent.CodeStyle.usedProfile>default</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>\r
+ <org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>8</org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>\r
+ <org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>80</org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>\r
+ </properties>\r
+</project-shared-configuration>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<actions>
+ <action>
+ <actionName>rebuild</actionName>
+ <packagings>
+ <packaging>*</packaging>
+ </packagings>
+ <goals>
+ <goal>clean</goal>
+ <goal>install</goal>
+ </goals>
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ </properties>
+ </action>
+ </actions>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <parent>
+ <artifactId>helloworld</artifactId>
+ <groupId>org.collectionspace.hello.services</groupId>
+ <version>0.1</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.collectionspace.hello.services</groupId>
+ <artifactId>helloworld-client</artifactId>
+ <packaging>jar</packaging>
+ <version>0.1</version>
+ <name>Helloworld Client</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.collectionspace.hello.services</groupId>
+ <artifactId>helloworld-jaxb</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>5.6</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-jaxrs</artifactId>
+ <version>1.0.2.GA</version>
+ <!-- filter out unwanted jars -->
+ <exclusions>
+ <exclusion>
+ <groupId>tjws</groupId>
+ <artifactId>webserver</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-jaxb-provider</artifactId>
+ <version>1.0.2.GA</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package org.collectionspace.hello.client;
+
+import javax.ws.rs.core.Response;
+
+import org.collectionspace.hello.Identifier;
+import org.jboss.resteasy.client.ProxyFactory;
+import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
+import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+
+/**
+ * A IdentifierClient.
+
+ * @version $Revision:$
+ */
+public class IdentifierClient {
+
+ /**
+ *
+ */
+ private static final IdentifierClient instance = new IdentifierClient();
+ /**
+ *
+ */
+ private IdentifierProxy identifierProxy;
+
+ /**
+ *
+ * Create a new IdentifierClient.
+ *
+ */
+ private IdentifierClient() {
+ ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance();
+ RegisterBuiltin.register(factory);
+ identifierProxy = ProxyFactory.create(IdentifierProxy.class, "http://localhost:8080/helloworld/cspace");
+ }
+
+ /**
+ * FIXME Comment this
+ *
+ * @return
+ */
+ public static IdentifierClient getInstance() {
+ return instance;
+ }
+
+ /**
+ * @param id
+ * @return
+ * @see org.collectionspace.hello.client.IdentifierProxy#getIdentifier(java.lang.Long)
+ */
+ public ClientResponse<Identifier> getIdentifier(Long id) {
+ return identifierProxy.getIdentifier(id);
+ }
+
+ /**
+ * @param identifier
+ * @return
+ * @see org.collectionspace.hello.client.IdentifierProxy#createIdentifier(org.collectionspace.hello.client.entity.Identifier)
+ */
+ public ClientResponse<Response> createIdentifier(Identifier identifier) {
+ return identifierProxy.createIdentifier(identifier);
+ }
+}
--- /dev/null
+package org.collectionspace.hello.client;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+
+import org.collectionspace.hello.Identifier;
+import org.jboss.resteasy.client.ClientResponse;
+
+/**
+ * @version $Revision:$
+ */
+@Path("/identifiers/")
+@Produces({"application/xml"})
+@Consumes({"application/xml"})
+public interface IdentifierProxy {
+
+ /**
+ * @param id
+ * @return
+ */
+ @GET
+ @Path("/{id}")
+ ClientResponse<Identifier> getIdentifier(@PathParam("id") Long id);
+
+ @POST
+ ClientResponse<Response> createIdentifier(Identifier so);
+}
\ No newline at end of file
--- /dev/null
+package org.collectionspace.hello.client;
+
+import javax.ws.rs.core.Response;
+
+import org.collectionspace.hello.Person;
+import org.collectionspace.hello.Persons;
+import org.jboss.resteasy.client.ProxyFactory;
+import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
+import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+
+/**
+ * A PersonClient.
+
+ * @version $Revision:$
+ */
+public class PersonClient {
+
+ /**
+ *
+ */
+ private static final PersonClient instance = new PersonClient();
+ /**
+ *
+ */
+ private PersonProxy personProxy;
+
+ /**
+ *
+ * Create a new PersonClient.
+ *
+ */
+ private PersonClient() {
+ ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance();
+ RegisterBuiltin.register(factory);
+ personProxy = ProxyFactory.create(PersonProxy.class, "http://localhost:8080/helloworld/cspace");
+ }
+
+ /**
+ * FIXME Comment this
+ *
+ * @return
+ */
+ public static PersonClient getInstance() {
+ return instance;
+ }
+
+ /**
+ * @param id
+ * @return
+ * @see org.collectionspace.hello.client.PersonProxy#getPerson()
+ */
+ public ClientResponse<Persons> getPersons() {
+ return personProxy.getPersons();
+ }
+
+ /**
+ * @param id
+ * @return
+ * @see org.collectionspace.hello.client.PersonProxy#getPerson(java.lang.Long)
+ */
+ public ClientResponse<Person> getPerson(Long id) {
+ return personProxy.getPerson(id);
+ }
+
+ /**
+ * @param person
+ * @return
+ * @see org.collectionspace.hello.client.PersonProxy#createPerson(org.collectionspace.hello.client.entity.Person)
+ */
+ public ClientResponse<Response> createPerson(Person person) {
+ return personProxy.createPerson(person);
+ }
+
+ /**
+ * @param id
+ * @param person
+ * @return
+ * @see org.collectionspace.hello.client.PersonProxy#updatePerson(java.lang.Long, org.collectionspace.hello.client.entity.Person)
+ */
+ public ClientResponse<Person> updatePerson(Long id, Person person) {
+ return personProxy.updatePerson(id, person);
+ }
+
+ /**
+ * @param id
+ * @return
+ * @see org.collectionspace.hello.client.PersonProxy#deletePerson(java.lang.Long)
+ */
+ public ClientResponse<Response> deletePerson(Long id) {
+ return personProxy.deletePerson(id);
+ }
+}
--- /dev/null
+package org.collectionspace.hello.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.hello.Person;
+import org.collectionspace.hello.Persons;
+import org.jboss.resteasy.client.ClientResponse;
+
+/**
+ * @version $Revision:$
+ */
+@Path("/persons/")
+@Produces({"application/xml"})
+@Consumes({"application/xml"})
+public interface PersonProxy {
+
+ @GET
+ ClientResponse<Persons> getPersons();
+
+ @GET
+ @Path("/{id}")
+ ClientResponse<Person> getPerson(@PathParam("id") Long id);
+
+ @POST
+ ClientResponse<Response> createPerson(Person so);
+
+ @PUT
+ @Path("/{id}")
+ ClientResponse<Person> updatePerson(@PathParam("id") Long id, Person so);
+
+ @DELETE
+ @Path("/{id}")
+ ClientResponse<Response> deletePerson(@PathParam("id") Long id);
+}
\ No newline at end of file
--- /dev/null
+package org.collectionspace.hello.client.test;
+
+import org.collectionspace.hello.client.*;
+import java.util.ArrayList;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import org.collectionspace.hello.Identifier;
+import org.jboss.resteasy.client.ClientResponse;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * A IdentifierServiceTest.
+ *
+ * @version $Revision:$
+ */
+public class IdentifierServiceTest {
+
+ private IdentifierClient identifierClient = IdentifierClient.getInstance();
+ private Long id = 0L;
+
+ @Test
+ public void createIdentifier() {
+ Identifier identifier = new Identifier();
+ identifier.setNamespace("org.bnhm");
+ ClientResponse<Response> res = identifierClient.createIdentifier(identifier);
+ Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
+ id = extractId(res);
+ }
+
+ @Test(dependsOnMethods = {"createIdentifier"})
+ public void getIdentifier() {
+ Identifier i = identifierClient.getIdentifier(id).getEntity();
+ verbose("got Identifier", i);
+ }
+
+ private Long extractId(ClientResponse<Response> res) {
+ MultivaluedMap mvm = res.getMetadata();
+ String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
+ String[] segments = uri.split("/");
+ verbose("id=" + segments[segments.length - 1]);
+ return Long.valueOf(segments[segments.length - 1]);
+ }
+
+ private void verbose(String msg) {
+ System.out.println("IdentifierServiceTest : " + msg);
+ }
+
+ private void verbose(String msg, Identifier p) {
+ try {
+ verbose(msg);
+ JAXBContext jc = JAXBContext.newInstance(Identifier.class);
+ Marshaller m = jc.createMarshaller();
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
+ Boolean.TRUE);
+ m.marshal(p, System.out);
+ //m.marshal(new JAXBElement(new QName("uri", "local"), Identifier.class, p), System.out);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
--- /dev/null
+package org.collectionspace.hello.client.test;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import org.collectionspace.hello.Person;
+import org.collectionspace.hello.Persons;
+import org.collectionspace.hello.client.PersonClient;
+import org.jboss.resteasy.client.ClientResponse;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * A PersonServiceTest.
+ *
+ * @version $Revision:$
+ */
+public class PersonServiceTest {
+
+ private PersonClient personClient = PersonClient.getInstance();
+ private Long updateId = 0L;
+
+ @Test
+ public void createPerson() {
+ Person person = createPerson("Chris", "Hoffman");
+ ClientResponse<Response> res = personClient.createPerson(person);
+ Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
+ //store updateId locally
+ updateId = extractId(res);
+ }
+
+ @Test
+ public void createPersons() {
+ Person person = createPerson("Aron", "Roberts");
+ ClientResponse<Response> res = personClient.createPerson(person);
+ Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
+ person = createPerson("Dan", "Sheppard");
+ res = personClient.createPerson(person);
+ Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
+ }
+
+ @Test(dependsOnMethods = {"createPerson"})
+ public void updatePerson() {
+ Person touPerson = personClient.getPerson(updateId).getEntity();
+ verbose("got person to update", touPerson, Person.class);
+ touPerson.setFirstName("Richard");
+ touPerson.setLastName("Millet");
+ int initialVersion = touPerson.getVersion();
+ Person uPerson = personClient.updatePerson(updateId, touPerson).getEntity();
+ verbose("updated person", uPerson, Person.class);
+ Assert.assertNotSame(uPerson.getVersion(), initialVersion);
+ Assert.assertEquals(uPerson.getFirstName(), "Richard");
+ }
+
+ @Test(dependsOnMethods = {"createPerson"})
+ public void getPersons() {
+ //the resource method is expected to return at least an empty list
+ Persons persons = personClient.getPersons().getEntity();
+ List<Persons.PersonListItem> list = persons.getPersonListItem();
+ int i = 0;
+ for (Persons.PersonListItem pli : list) {
+ verbose("getPersons: list-item[" + i + "] firstName=" + pli.getFirstName());
+ verbose("getPersons: list-item[" + i + "] lastName=" + pli.getLastName());
+ verbose("getPersons: list-item[" + i + "] uri=" + pli.getUri());
+ i++;
+ }
+ }
+
+
+ @Test
+ public void getNonExistingPerson() {
+ ClientResponse<Person> res = personClient.getPerson(999L);
+
+ Response.Status status = res.getResponseStatus();
+ verbose(this.getClass().getName() + ": " +
+ "getNonExistingPerson: Status: code=" + status.getStatusCode() +
+ " message=" + status.toString());
+ verbose("getNonExistingPerson: Metadata:");
+ verboseMap(res.getMetadata());
+ verbose("getNonExistingPerson: Headers:");
+ verboseMap(res.getHeaders());
+ if (status.equals(Response.Status.NOT_FOUND)) {
+ String msg = res.getEntity(String.class, String.class);
+ verbose("getNonExistingPerson: error message=" + msg);
+ }
+ }
+
+ @Test(dependsOnMethods = {"updatePerson"})
+ public void updateWrongPerson() {
+ Person touPerson = personClient.getPerson(updateId).getEntity();
+ verbose("updateWrongPerson: got person to update", touPerson, Person.class);
+ touPerson.setFirstName("Richard");
+ touPerson.setLastName("Millet");
+ //use non existing person to update
+ ClientResponse<Person> res = personClient.updatePerson(9999L, touPerson);
+ if (res.getResponseStatus().equals(Response.Status.NOT_FOUND)) {
+ verbose("updateWrongPerson: Status=" + res.getResponseStatus().toString());
+ String msg = res.getEntity(String.class, String.class);
+ verbose("updateWrongPerson: application error message=" + msg);
+ }
+ }
+
+
+ @Test(dependsOnMethods = {"updateWrongPerson"})
+ public void deletePerson() {
+ ClientResponse<Response> res = personClient.deletePerson(updateId);
+ verbose("deletePerson: id=" + updateId);
+ verbose("deletePerson: status = " + res.getStatus());
+ Assert.assertEquals(res.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+ }
+
+ private Person createPerson(String firstName, String lastName) {
+ Person person = new Person();
+ person.setFirstName(firstName);
+ person.setLastName(lastName);
+ person.setStreet("2195 Hearst Ave.");
+ person.setCity("Berkeley");
+ person.setState("CA");
+ person.setZip("94704");
+ person.setCountry("US");
+ return person;
+ }
+
+ private Long extractId(ClientResponse<Response> res) {
+ MultivaluedMap mvm = res.getMetadata();
+ String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
+ String[] segments = uri.split("/");
+ verbose("id=" + segments[segments.length - 1]);
+ return Long.valueOf(segments[segments.length - 1]);
+ }
+
+ private void verbose(String msg) {
+ System.out.println("PersonServiceTest : " + msg);
+ }
+
+ private void verbose(String msg, Object o, Class clazz) {
+ try {
+ verbose(msg);
+ JAXBContext jc = JAXBContext.newInstance(clazz);
+ Marshaller m = jc.createMarshaller();
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
+ Boolean.TRUE);
+ m.marshal(o, System.out);
+ //m.marshal(new JAXBElement(new QName("uri", "local"), Person.class, p), System.out);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void verboseMap(MultivaluedMap map) {
+ for (Object entry : map.entrySet()) {
+ MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry;
+ verbose(" name=" + mentry.getKey() + " value=" + mentry.getValue());
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+ <appender name="console" class="org.apache.log4j.ConsoleAppender">
+ <param name="Target" value="System.out" />
+ <layout class="org.apache.log4j.TTCCLayout">
+ <param name="DateFormat" value="ISO8601" />
+ </layout>
+ </appender>
+
+
+ <appender name="unit-tests"
+ class="org.apache.log4j.RollingFileAppender">
+ <param name="File" value="./target/unit-tests.log" />
+ <param name="MaxFileSize" value="10240KB" />
+ <param name="MaxBackupIndex" value="6" />
+ <layout class="org.apache.log4j.TTCCLayout">
+ <param name="DateFormat" value="ISO8601" />
+ </layout>
+ </appender>
+
+ <logger name="org.apache.commons.httpclient" additivity="false">
+ <level value="warn" />
+ <appender-ref ref="console" />
+ <appender-ref ref="unit-tests" />
+ </logger>
+
+ <logger name="httpclient.wire" additivity="false">
+ <level value="info" />
+ <appender-ref ref="console" />
+ <appender-ref ref="unit-tests" />
+ </logger>
+
+ <root>
+ <priority value="debug" />
+ <appender-ref ref="console" />
+ <appender-ref ref="unit-tests" />
+ </root>
+
+</log4j:configuration>
+
+
+
+
--- /dev/null
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<suite name="javaee-addressbook-client">
+ <test verbose="2" name="org.jboss.resteasy.examples.addressbook.client.AddressBookTest" annotations="JDK">
+ <classes>
+ <class name="org.jboss.resteasy.examples.addressbook.client.AddressBookTest"/>
+ </classes>
+ </test>
+</suite>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src/main/java"/>
+ <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>javaee-addressbook-jaxb</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+#Thu Feb 26 16:32:52 PST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.source=1.5
--- /dev/null
+#Thu Feb 26 16:30:28 PST 2009
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+version=1
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project-shared-configuration>\r
+ <!--
+This file contains additional configuration written by modules in the NetBeans IDE.
+The configuration is intended to be shared among all the users of project and
+therefore it is assumed to be part of version control checkout.
+Without this configuration present, some functionality in the IDE may be limited or fail altogether.
+-->\r
+ <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">\r
+ <!--
+Properties that influence various parts of the IDE, especially code formatting and the like.
+You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
+That way multiple projects can share the same settings (useful for formatting rules for example).
+Any value defined here will override the pom.xml file value but is only applicable to the current project.
+-->\r
+ <org-netbeans-modules-editor-indent.CodeStyle.usedProfile>default</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>\r
+ <org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>8</org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>\r
+ <org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>80</org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>\r
+ </properties>\r
+</project-shared-configuration>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <parent>
+ <artifactId>helloworld</artifactId>
+ <groupId>org.collectionspace.hello.services</groupId>
+ <version>0.1</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.collectionspace.hello.services</groupId>
+ <artifactId>helloworld-jaxb</artifactId>
+ <version>0.1</version>
+ <name>Helloworld Client JAXB</name>
+ <dependencies>
+ <dependency>
+ <groupId>com.sun.xml.bind</groupId>
+ <artifactId>jaxb-impl</artifactId>
+ <version>2.0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jvnet.jaxb2-commons</groupId>
+ <artifactId>property-listener-injector</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jvnet.jaxb2_commons</groupId>
+ <artifactId>runtime</artifactId>
+ <version>0.4.1.4</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jvnet.jaxb2.maven2</groupId>
+ <artifactId>maven-jaxb2-plugin</artifactId>
+ <dependencies>
+ <!-- javax.activation.DataSource provider is required by spec -->
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.xml.bind</groupId>
+ <artifactId>jaxb-impl</artifactId>
+ <version>2.1.2</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<xs:schema
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:ns="http://collectionspace.org/hello"
+ xmlns="http://collectionspace.org/hello"
+ targetNamespace="http://collectionspace.org/hello"
+ version="0.1"
+>
+
+<!-- avoid XmlRootElement nightnmare, see http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html-->
+ <xs:element name="person">
+ <xs:complexType>
+
+ <xs:sequence>
+ <xs:element name="firstName" type="xs:string"
+ minOccurs="1" />
+ <xs:element name="lastName" type="xs:string"
+ minOccurs="1" />
+ <xs:element name="street" type="xs:string"
+ minOccurs="1" />
+ <xs:element name="city" type="xs:string"
+ minOccurs="1" />
+ <xs:element name="state" type="xs:string"
+ minOccurs="1" />
+ <xs:element name="zip" type="xs:string"
+ minOccurs="1" />
+ <xs:element name="country" type="xs:string"
+ minOccurs="1" />
+ </xs:sequence>
+ <xs:attribute name="id" type="xs:long" />
+ <xs:attribute name="version" type="xs:int" />
+
+ </xs:complexType>
+ </xs:element>
+
+
+ <!-- person short is returned by getPersons method -->
+ <xs:element name="persons">
+ <xs:complexType>
+ <xs:sequence>
+
+ <!-- person list item is returned by getPersons method -->
+ <xs:element name="person-list-item" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="firstName" type="xs:string"
+ minOccurs="1" />
+ <xs:element name="lastName" type="xs:string"
+ minOccurs="1" />
+ <!-- uri to retrive person details -->
+ <xs:element name="uri" type="xs:anyURI"
+ minOccurs="1" />
+ <xs:element name="id" type="xs:long"
+ minOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="identifier">
+ <xs:complexType>
+
+ <xs:sequence>
+ <xs:element name="namespace" type="xs:string"
+ minOccurs="1" />
+ <xs:element name="value" type="xs:string"
+ minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute name="id" type="xs:long" />
+ <xs:attribute name="version" type="xs:int" />
+
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
+
--- /dev/null
+
+This project is a simple example showing usage of @Path, @GET, PUT, POST, and @PathParam. It uses pure streaming
+output as well.
+
+System Requirements:
+====================
+- Maven 2.0.9 or higher
+
+Building the project:
+====================
+1. In root directoy
+
+mvn clean install
+
+This will build a WAR and run it with embedded Jetty
\ No newline at end of file
--- /dev/null
+jboss.dir=/usr/local/jboss
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project-shared-configuration>\r
+ <!--
+This file contains additional configuration written by modules in the NetBeans IDE.
+The configuration is intended to be shared among all the users of project and
+therefore it is assumed to be part of version control checkout.
+Without this configuration present, some functionality in the IDE may be limited or fail altogether.
+-->\r
+ <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">\r
+ <!--
+Properties that influence various parts of the IDE, especially code formatting and the like.
+You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
+That way multiple projects can share the same settings (useful for formatting rules for example).
+Any value defined here will override the pom.xml file value but is only applicable to the current project.
+-->\r
+ <org-netbeans-modules-editor-indent.CodeStyle.usedProfile>default</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>\r
+ <org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>8</org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>\r
+ <org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>80</org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>\r
+ <netbeans.hint.useExternalMaven>false</netbeans.hint.useExternalMaven>\r
+ </properties>\r
+</project-shared-configuration>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<actions>
+ <action>
+ <actionName>test</actionName>
+ <packagings>
+ <packaging>*</packaging>
+ </packagings>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ </action>
+ <action>
+ <actionName>build</actionName>
+ <packagings>
+ <packaging>*</packaging>
+ </packagings>
+ <goals>
+ <goal>install</goal>
+ </goals>
+ </action>
+ <action>
+ <actionName>clean</actionName>
+ <packagings>
+ <packaging>*</packaging>
+ </packagings>
+ <goals>
+ <goal>clean</goal>
+ </goals>
+ </action>
+ <action>
+ <actionName>rebuild</actionName>
+ <packagings>
+ <packaging>*</packaging>
+ </packagings>
+ <goals>
+ <goal>clean</goal>
+ <goal>install</goal>
+ </goals>
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ </properties>
+ </action>
+ <action>
+ <actionName>run</actionName>
+ <packagings>
+ <packaging>war</packaging>
+ <packaging>ear</packaging>
+ <packaging>ejb</packaging>
+ </packagings>
+ <goals>
+ <goal>package</goal>
+ </goals>
+ <properties>
+
+ <netbeans.deploy>true</netbeans.deploy>
+ </properties>
+ </action>
+ <action>
+ <actionName>debug</actionName>
+ <packagings>
+ <packaging>war</packaging>
+ <packaging>ear</packaging>
+ <packaging>ejb</packaging>
+ </packagings>
+ <goals>
+ <goal>package</goal>
+ </goals>
+ <properties>
+
+ <netbeans.deploy>true</netbeans.deploy>
+ <netbeans.deploy.debugmode>true</netbeans.deploy.debugmode>
+ </properties>
+ </action>
+ </actions>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>helloworld</artifactId>
+ <groupId>org.collectionspace.hello.services</groupId>
+ <version>0.1</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.collectionspace.hello.services</groupId>
+ <artifactId>helloworld-service</artifactId>
+ <packaging>war</packaging>
+ <version>0.1</version>
+ <name>Helloworld Service</name>
+
+ <repositories>
+ <repository>
+ <id>java.net</id>
+ <url>http://download.java.net/maven/1</url>
+ <layout>legacy</layout>
+ </repository>
+ <repository>
+ <id>maven repo</id>
+ <name>maven repo</name>
+ <url>http://repo1.maven.org/maven2/</url>
+ </repository>
+ <!-- For resteasy -->
+ <repository>
+ <id>jboss</id>
+ <name>jboss repo</name>
+ <url>http://repository.jboss.org/maven2</url>
+ </repository>
+ <repository>
+ <id>mojo</id>
+ <name>mojo repo</name>
+ <url>http://svn.codehaus.org/mojo/trunk/mojo/jboss-maven-plugin</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.collectionspace.hello.services</groupId>
+ <artifactId>helloworld-jaxb</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-jaxrs</artifactId>
+ <version>1.0.2.GA</version>
+ <!-- filter out unwanted jars -->
+ <exclusions>
+ <exclusion>
+ <groupId>tjws</groupId>
+ <artifactId>webserver</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-jaxb-provider</artifactId>
+ <version>1.0.2.GA</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>helloworld</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>jboss-maven-plugin</artifactId>
+ <configuration>
+ <jbossHome>${jboss.dir}</jbossHome>
+ </configuration>
+ <executions>
+ <execution>
+ <id>jboss-undeploy</id>
+ <phase>pre-integration-test</phase>
+ <goals>
+ <goal>undeploy</goal>
+ </goals>
+ <configuration>
+ <fileName>${basedir}/target/helloworld.war</fileName>
+ </configuration>
+ </execution>
+ <execution>
+ <id>jboss-deploy</id>
+ <phase>pre-integration-test</phase>
+ <goals>
+ <goal>deploy</goal>
+ </goals>
+ <configuration>
+ <fileName>${basedir}/target/helloworld.war</fileName>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+ <!--
+ <plugin>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>maven-jetty-plugin</artifactId>
+ <version>6.1.10</version>
+ <configuration>
+
+ <contextPath>/</contextPath>
+ <scanIntervalSeconds>2</scanIntervalSeconds>
+ <stopKey>foo</stopKey>
+ <stopPort>9999</stopPort>
+ <connectors>
+ <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
+ <port>9095</port>
+ <maxIdleTime>60000</maxIdleTime>
+ </connector>
+ </connectors>
+ </configuration>
+ <executions>
+ <execution>
+ <id>start-jetty</id>
+ <phase>pre-integration-test</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <scanIntervalSeconds>0</scanIntervalSeconds>
+ <daemon>true</daemon>
+ </configuration>
+ </execution>
+ <execution>
+ <id>stop-jetty</id>
+ <phase>post-integration-test</phase>
+ <goals>
+ <goal>stop</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ -->
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ </configuration>
+ <executions>
+ <execution>
+ <id>surefire-it</id>
+ <phase>integration-test</phase>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>2.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package org.collectionspace.hello.services;
+
+import javax.ws.rs.core.Application;
+import java.util.HashSet;
+import java.util.Set;
+
+public class HelloworldApplication extends Application {
+
+ private Set<Object> singletons = new HashSet<Object>();
+ private Set<Class<?>> empty = new HashSet<Class<?>>();
+
+ public HelloworldApplication() {
+ singletons.add(new PersonResource());
+ singletons.add(new IdentifierResource());
+ }
+
+ @Override
+ public Set<Class<?>> getClasses() {
+ return empty;
+ }
+
+ @Override
+ public Set<Object> getSingletons() {
+ return singletons;
+ }
+}
--- /dev/null
+package org.collectionspace.hello.services;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+import javax.ws.rs.core.UriBuilder;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import org.collectionspace.hello.Identifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Path("/identifiers")
+@Consumes("application/xml")
+@Produces("application/xml")
+public class IdentifierResource {
+
+ final Logger logger = LoggerFactory.getLogger(IdentifierResource.class);
+ private Map<Long, Identifier> idDB = new ConcurrentHashMap<Long, Identifier>();
+ private AtomicLong idCounter = new AtomicLong();
+
+ public IdentifierResource() {
+ }
+
+ @POST
+ public Response createIdentifier(Identifier id) {
+ if (id.getNamespace() == null) {
+ id.setNamespace("edu.berkeley");
+ }
+ id.setId(idCounter.incrementAndGet());
+ id.setVersion(1);
+ UUID uuid = UUID.nameUUIDFromBytes(id.getNamespace().getBytes());
+ id.setValue(uuid.toString());
+ idDB.put(id.getId(), id);
+ verbose("created Id", id);
+ UriBuilder path = UriBuilder.fromResource(IdentifierResource.class);
+ path.path("" + id.getId());
+ Response response = Response.created(path.build()).build();
+ return response;
+ }
+
+ @GET
+ @Path("{id}")
+ public Identifier getIdentifier(@PathParam("id") Long id) {
+ Identifier i = idDB.get(id);
+ if (i == null) {
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(
+ "The requested ID was not found.").type("text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ verbose("get Id", i);
+ return i;
+ }
+
+ private void verbose(String msg, Identifier id) {
+ try {
+ System.out.println("IdentifierResource : " + msg);
+ JAXBContext jc = JAXBContext.newInstance(Identifier.class);
+ Marshaller m = jc.createMarshaller();
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
+ Boolean.TRUE);
+ m.marshal(id, System.out);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
--- /dev/null
+package org.collectionspace.hello.services;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.Consumes;
+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.WebApplicationException;
+import javax.ws.rs.core.Response;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import org.collectionspace.hello.Person;
+import org.collectionspace.hello.Persons.PersonListItem;
+import org.collectionspace.hello.Persons;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Path("/persons")
+@Consumes("application/xml")
+@Produces("application/xml")
+public class PersonResource {
+
+ final Logger logger = LoggerFactory.getLogger(PersonResource.class);
+ private Map<Long, Person> personDB = new ConcurrentHashMap<Long, Person>();
+ private AtomicLong idCounter = new AtomicLong();
+
+ public PersonResource() {
+ }
+
+ @POST
+ public Response createPerson(Person p) {
+ p.setId(idCounter.incrementAndGet());
+ p.setVersion(1);
+ personDB.put(p.getId(), p);
+ verbose("created person", p);
+ UriBuilder path = UriBuilder.fromResource(PersonResource.class);
+ path.path("" + p.getId());
+ Response response = Response.created(path.build()).build();
+ return response;
+ }
+
+ @GET
+ @Path("{id}")
+ public Person getPerson(@PathParam("id") Long id) {
+ Person p = personDB.get(id);
+ if (p == null) {
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(
+ "Get failed, the requested person ID:" + id + ": was not found.").type("text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ verbose("get person", p);
+ return p;
+ }
+
+ @PUT
+ @Path("{id}")
+ public Person updatePerson(@PathParam("id") Long id, Person update) {
+ Person current = personDB.get(id);
+ if (current == null) {
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(
+ "Update failed, the person ID:" + id + ": was not found.").type("text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ verbose("update person input", update);
+ //todo: intelligent merge needed
+ current.setFirstName(update.getFirstName());
+ current.setLastName(update.getLastName());
+ current.setStreet(update.getStreet());
+ current.setState(update.getState());
+ current.setZip(update.getZip());
+ current.setCountry(update.getCountry());
+ current.setVersion(current.getVersion() + 1);
+ verbose("update person output", current);
+ return current;
+ }
+
+ @GET
+ public Persons getPersons(@Context UriInfo ui) {
+ Persons persons = new Persons();
+ List<Persons.PersonListItem> list = persons.getPersonListItem();
+ // builder starts with current URI and has appended path of getPerson method
+ UriBuilder ub = ui.getAbsolutePathBuilder().path(this.getClass(), "getPerson");
+ for (Person p : personDB.values()) {
+ PersonListItem pli = new PersonListItem();
+ pli.setFirstName(p.getFirstName());
+ pli.setLastName(p.getLastName());
+ pli.setId(p.getId());
+ // builder has {id} variable that must be filled in for each customer
+ URI uri = ub.build(p.getId());
+ pli.setUri(uri.toString());
+ list.add(pli);
+ }
+ return persons;
+ }
+
+ @DELETE
+ @Path("{id}")
+ public void deletePerson(@PathParam("id") Long id) {
+ Person removed = personDB.remove(id);
+ if (removed == null) {
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(
+ "Delete failed, the person ID:" + id + ": was not found.").type("text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ verbose("deleted person", removed);
+ }
+
+ private void verbose(String msg, Person p) {
+ try {
+ System.out.println("PersonResource : " + msg);
+ JAXBContext jc = JAXBContext.newInstance(Person.class);
+ Marshaller m = jc.createMarshaller();
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
+ Boolean.TRUE);
+ m.marshal(p, System.out);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+// @POST
+// @Consumes("application/xml")
+// public Response createPerson(InputStream is) {
+// Person p = readPerson(is);
+// p.setId(idCounter.incrementAndGet());
+// p.setVersion(1);
+// personDB.put(p.getId(), p);
+// try {
+// System.out.println("Created Person " + p.getId());
+// outputPerson(System.out, p);
+// } catch (IOException ioe) {
+// throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+// }
+// return Response.created(URI.create("/persons/" + p.getId())).build();
+//
+// }
+//
+// @GET
+// @Path("{id}")
+// @Produces("application/xml")
+// public StreamingOutput getPerson(@PathParam("id") int id) {
+// final Person p = personDB.get(id);
+// if (p == null) {
+// throw new WebApplicationException(Response.Status.NOT_FOUND);
+// }
+// return new StreamingOutput() {
+//
+// public void write(OutputStream outputStream) throws IOException, WebApplicationException {
+// outputPerson(outputStream, p);
+// }
+// };
+// }
+//
+// @PUT
+// @Path("{id}")
+// @Consumes("application/xml")
+// @Produces("application/xml")
+// public StreamingOutput updatePerson(@PathParam("id") int id, InputStream is) {
+// Person update = readPerson(is);
+// Person current = personDB.get(id);
+// if (current == null) {
+// throw new WebApplicationException(Response.Status.NOT_FOUND);
+// }
+//
+// current.setFirstName(update.getFirstName());
+// current.setLastName(update.getLastName());
+// current.setStreet(update.getStreet());
+// current.setState(update.getState());
+// current.setZip(update.getZip());
+// current.setCountry(update.getCountry());
+// current.setVersion(current.getVersion() + 1);
+// final Person scurrent = current;
+// return new StreamingOutput() {
+//
+// public void write(OutputStream outputStream) throws IOException, WebApplicationException {
+// outputPerson(outputStream, scurrent);
+// }
+// };
+// }
+//
+// protected void outputPerson(OutputStream os, Person p) throws IOException {
+// PrintStream writer = new PrintStream(os);
+// writer.println("<Person id=\"" + p.getId() + "\" version=\"" + p.getVersion() + "\">");
+// writer.println(" <first-name>" + p.getFirstName() + "</first-name>");
+// writer.println(" <last-name>" + p.getLastName() + "</last-name>");
+// writer.println(" <street>" + p.getStreet() + "</street>");
+// writer.println(" <city>" + p.getCity() + "</city>");
+// writer.println(" <state>" + p.getState() + "</state>");
+// writer.println(" <zip>" + p.getZip() + "</zip>");
+// writer.println(" <country>" + p.getCountry() + "</country>");
+// writer.println("</Person>");
+// }
+//
+// protected Person readPerson(InputStream is) {
+// try {
+// DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+// Document doc = builder.parse(is);
+// Element root = doc.getDocumentElement();
+// Person p = new Person();
+// if (root.getAttribute("id") != null && !root.getAttribute("id").trim().equals("")) {
+// p.setId(Integer.valueOf(root.getAttribute("id")));
+// }
+// if (root.getAttribute("version") != null && !root.getAttribute("version").trim().equals("")) {
+// p.setVersion(Integer.valueOf(root.getAttribute("version")));
+// }
+// NodeList nodes = root.getChildNodes();
+// for (int i = 0; i < nodes.getLength(); i++) {
+// Element element = (Element) nodes.item(i);
+// if (element.getTagName().equals("first-name")) {
+// p.setFirstName(element.getTextContent());
+// } else if (element.getTagName().equals("last-name")) {
+// p.setLastName(element.getTextContent());
+// } else if (element.getTagName().equals("street")) {
+// p.setStreet(element.getTextContent());
+// } else if (element.getTagName().equals("city")) {
+// p.setCity(element.getTextContent());
+// } else if (element.getTagName().equals("state")) {
+// p.setState(element.getTextContent());
+// } else if (element.getTagName().equals("zip")) {
+// p.setZip(element.getTextContent());
+// } else if (element.getTagName().equals("country")) {
+// p.setCountry(element.getTextContent());
+// }
+// }
+// return p;
+// } catch (Exception e) {
+// throw new WebApplicationException(e, Response.Status.BAD_REQUEST);
+// }
+// }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
+<web-app>
+ <display-name>Helloworld</display-name>
+
+ <context-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.collectionspace.hello.services.HelloworldApplication</param-value>
+ </context-param>
+
+ <context-param>
+ <param-name>resteasy.servlet.mapping.prefix</param-name>
+ <param-value>/cspace</param-value>
+ </context-param>
+
+ <listener>
+ <listener-class>
+ org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
+ </listener-class>
+ </listener>
+
+ <servlet>
+ <servlet-name>Resteasy</servlet-name>
+ <servlet-class>
+ org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
+ </servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Resteasy</servlet-name>
+ <url-pattern>/cspace/*</url-pattern>
+ </servlet-mapping>
+
+</web-app>
--- /dev/null
+package org.collectionspace.hello.test;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+/**
+ * @version $Revision: 1 $
+ */
+public class IdentifierServiceRawXmlTest {
+
+ @Test
+ public void testIdentifierResource() throws Exception {
+ verbose("create a new Identifier");
+ // Create a new object
+ String newIdentifier = "<ns2:identifier xmlns:ns2=\"http://collectionspace.org/hello\">" +
+ "<namespace>edu.stanford</namespace>" +
+ "</ns2:identifier>";
+
+ URL postUrl = new URL("http://localhost:8080/helloworld/cspace/identifiers");
+ HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
+ connection.setDoOutput(true);
+ connection.setInstanceFollowRedirects(false);
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/xml");
+ OutputStream os = connection.getOutputStream();
+ os.write(newIdentifier.getBytes());
+ os.flush();
+ Assert.assertEquals(HttpURLConnection.HTTP_CREATED, connection.getResponseCode());
+ String createdUrl = connection.getHeaderField("Location");
+ verbose("Location: " + createdUrl);
+ connection.disconnect();
+
+
+ // Get the new object
+ verbose("get created Identifier");
+ URL getUrl = new URL(createdUrl);
+ connection = (HttpURLConnection) getUrl.openConnection();
+ connection.setRequestMethod("GET");
+ verbose("Content-Type: " + connection.getContentType());
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+
+ String line = reader.readLine();
+ while (line != null) {
+ verbose(line);
+ line = reader.readLine();
+ }
+ Assert.assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());
+ connection.disconnect();
+
+ }
+
+ private void verbose(String msg) {
+ System.out.println("IdentifierServiceRawXmlTest : " + msg);
+ }
+}
--- /dev/null
+package org.collectionspace.hello.test;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+/**
+ * @version $Revision: 1 $
+ */
+public class PersonServiceRawXmlTest {
+
+ @Test
+ public void testPersonResource() throws Exception {
+ verbose("create a new Person");
+ // Create a new object
+ String newPerson = "<ns2:person xmlns:ns2=\"http://collectionspace.org/hello\">" + "<firstName>John</firstName>" + "<lastName>Doe</lastName>" + "<street>2195 Hearst Ave</street>" + "<city>Berkeley</city>" + "<state>CA</state>" + "<zip>94504</zip>" + "<country>USA</country>" + "</ns2:person>";
+
+ URL postUrl = new URL("http://localhost:8080/helloworld/cspace/persons");
+ HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
+ connection.setDoOutput(true);
+ connection.setInstanceFollowRedirects(false);
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/xml");
+ OutputStream os = connection.getOutputStream();
+ os.write(newPerson.getBytes());
+ os.flush();
+ Assert.assertEquals(HttpURLConnection.HTTP_CREATED, connection.getResponseCode());
+ String createdUrl = connection.getHeaderField("Location");
+ verbose("Location: " + createdUrl);
+ connection.disconnect();
+
+
+ // Get the new object
+ verbose("get created Person");
+ URL getUrl = new URL(createdUrl);
+ connection = (HttpURLConnection) getUrl.openConnection();
+ connection.setRequestMethod("GET");
+ verbose("Content-Type: " + connection.getContentType());
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+
+ String line = reader.readLine();
+ while (line != null) {
+ verbose(line);
+ line = reader.readLine();
+ }
+ Assert.assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());
+ connection.disconnect();
+
+ String updatePerson = "<ns2:person xmlns:ns2=\"http://collectionspace.org/hello\">" + "<firstName>Jane</firstName>" + "<lastName>Doe</lastName>" + "<street>1 University Ave</street>" + "<city>Berkeley</city>" + "<state>CA</state>" + "<zip>94504</zip>" + "<country>USA</country>" + "</ns2:person>";
+ connection = (HttpURLConnection) getUrl.openConnection();
+ connection.setDoOutput(true);
+ connection.setRequestMethod("PUT");
+ connection.setRequestProperty("Content-Type", "application/xml");
+ os = connection.getOutputStream();
+ os.write(updatePerson.getBytes());
+ os.flush();
+ Assert.assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());
+ connection.disconnect();
+
+ // Show the update
+ verbose("updated Person");
+ connection = (HttpURLConnection) getUrl.openConnection();
+ connection.setRequestMethod("GET");
+
+ verbose("Content-Type: " + connection.getContentType());
+ reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+
+ line = reader.readLine();
+ while (line != null) {
+ verbose(line);
+ line = reader.readLine();
+ }
+ Assert.assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());
+ connection.disconnect();
+ }
+
+ private void verbose(String msg) {
+ System.out.println("PersonServiceRawXmlTest : " + msg);
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.collectionspace.hello.services</groupId>
+ <version>0.1</version>
+ <artifactId>helloworld</artifactId>
+ <packaging>pom</packaging>
+ <name>HelloWorld</name>
+ <modules>
+ <module>HelloWorldJaxb</module>
+ <module>HelloWorldService</module>
+ <module>HelloWorldClient</module>
+ </modules>
+ <repositories>
+ <repository>
+ <id>jboss</id>
+ <url>http://repository.jboss.org/maven2</url>
+ </repository>
+ <repository>
+ <id>sun</id>
+ <url>http://download.java.net/maven/2</url>
+ </repository>
+ <repository>
+ <id>java.net</id>
+ <name>java.net Maven Repository</name>
+ <url>
+ https://maven-repository.dev.java.net/nonav/repository
+ </url>
+ <layout>legacy</layout>
+ </repository>
+ <repository>
+ <id>maven2-repository.dev.java.net</id>
+ <name>Java.net Maven 2 Repository</name>
+ <url>http://download.java.net/maven/2</url>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+
+ <pluginRepository>
+ <id>java.net</id>
+ <name>java.net Maven Repository</name>
+ <url>
+ https://maven-repository.dev.java.net/nonav/repository
+ </url>
+ <layout>legacy</layout>
+ </pluginRepository>
+ <pluginRepository>
+ <id>maven2-repository.dev.java.net</id>
+ <name>Java.net Maven 2 Repository</name>
+ <url>http://download.java.net/maven/2</url>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <configuration>
+ <unzipCommand>
+ /usr/bin/unzip -o > err.txt
+ </unzipCommand>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>2.0.1</version>
+ <configuration>
+
+ <warSourceExcludes>
+ WEB-INF/lib/*.jar
+ </warSourceExcludes>
+ <archive>
+ <manifest>
+ <addClasspath>true</addClasspath>
+
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.jvnet.jaxb2.maven2</groupId>
+ <artifactId>maven-jaxb2-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <args>
+ <arg>-XtoString</arg>
+ <arg>-Xinject-listener-code</arg>
+
+ <!-- <arg>-Xcollection-setter-injector</arg>
+ <arg>-Xfluent-api</arg> -->
+ </args>
+ <plugins>
+ <plugin>
+ <groupId>
+ org.jvnet.jaxb2_commons
+ </groupId>
+ <artifactId>basic</artifactId>
+ <version>0.4.1</version>
+ </plugin>
+ <plugin>
+ <groupId>
+ org.jvnet.jaxb2-commons
+ </groupId>
+ <artifactId>
+ property-listener-injector
+ </artifactId>
+ <version>1.0</version>
+ </plugin>
+ <!--
+ <plugin>
+ <groupId>
+ net.java.dev.jaxb2-commons
+ </groupId>
+ <artifactId>jaxb-fluent-api</artifactId>
+ <version>2.0.1</version>
+ </plugin>
+ -->
+ </plugins>
+ <generatePackage>
+ org.collectionspace.hello
+ </generatePackage>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>net.java.dev.jaxb2-commons</groupId>
+ <artifactId>jaxb-fluent-api</artifactId>
+ <version>2.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>5.6</version>
+ <scope>test</scope>
+ <classifier>jdk15</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>jaxrs-api</artifactId>
+ <version>1.0.2.GA</version>
+ </dependency>
+ <dependency>
+ <groupId>net.java.dev.jaxb2-commons</groupId>
+ <artifactId>jaxb-fluent-api</artifactId>
+ <version>2.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jvnet.jaxb2-commons</groupId>
+ <artifactId>property-listener-injector</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jvnet.jaxb2_commons</groupId>
+ <artifactId>runtime</artifactId>
+ <version>0.4.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-jaxrs</artifactId>
+ <version>1.0.2.GA</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.xml.bind</groupId>
+ <artifactId>jaxb-impl</artifactId>
+ <version>2.1.7</version>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>5.6</version>
+ <scope>test</scope>
+ <classifier>jdk15</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.5.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.5.2</version>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>5.1.5</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.jgoodies</groupId>
+ <artifactId>binding</artifactId>
+ <version>2.0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>com.jgoodies</groupId>
+ <artifactId>forms</artifactId>
+ <version>1.2.0</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>