aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGul Onural2012-09-28 09:04:22 (EDT)
committertware2012-10-01 13:31:44 (EDT)
commitff1318d993f139763e8f03123a7711afc0dbdd23 (patch)
treeb06e6aa07b32b40f478f4e6061d49cef59fa0928
parent28b7071bdbaca1c2e6e06abef64333aba3dd3e4c (diff)
downloadeclipselink.runtime-ff1318d993f139763e8f03123a7711afc0dbdd23.zip
eclipselink.runtime-ff1318d993f139763e8f03123a7711afc0dbdd23.tar.gz
eclipselink.runtime-ff1318d993f139763e8f03123a7711afc0dbdd23.tar.bz2
JPA-RS changes
-rw-r--r--foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Attribute.java34
-rw-r--r--foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Descriptor.java49
-rw-r--r--foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Link.java46
-rw-r--r--foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/LinkTemplate.java46
-rw-r--r--foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Parameter.java26
-rw-r--r--foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/PersistenceUnit.java31
-rw-r--r--foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Query.java57
-rw-r--r--foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/SessionBeanCall.java49
-rw-r--r--jpa/eclipselink.jpars.test/resource/org/eclipse/persistence/jpars/test/restmessage/json/auction-bidsByRef.json25
-rw-r--r--jpa/eclipselink.jpars.test/resource/org/eclipse/persistence/jpars/test/restmessage/json/auction-bidsByValue.json26
-rw-r--r--jpa/eclipselink.jpars.test/src/org/eclipse/persistence/jpars/test/AllJavaSETests.java3
-rw-r--r--jpa/eclipselink.jpars.test/src/org/eclipse/persistence/jpars/test/server/UnmarshalTest.java219
-rw-r--r--jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java224
-rw-r--r--jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/ServiceBase.java1208
-rw-r--r--jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/ReferenceAdapter.java111
15 files changed, 1492 insertions, 662 deletions
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Attribute.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Attribute.java
new file mode 100644
index 0000000..3ec3a8a
--- /dev/null
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Attribute.java
@@ -0,0 +1,34 @@
+package org.eclipse.persistence.internal.jpa.rs.metadata.model;
+
+import javax.xml.bind.annotation.XmlType;
+
+@XmlType(propOrder = { "name", "type" })
+public class Attribute {
+
+ protected String name;
+ protected String type;
+
+ public Attribute() {
+ }
+
+ public Attribute(String name, String type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+} \ No newline at end of file
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Descriptor.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Descriptor.java
new file mode 100644
index 0000000..0f5c4fb
--- /dev/null
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Descriptor.java
@@ -0,0 +1,49 @@
+package org.eclipse.persistence.internal.jpa.rs.metadata.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement
+@XmlType(propOrder={"name", "type", "attributes", "linkTemplates", "queries"})
+public class Descriptor {
+
+ protected String name = null;
+ protected String type = null;
+ protected List<LinkTemplate> linkTemplates = new ArrayList<LinkTemplate>();
+ protected List<Attribute> attributes = new ArrayList<Attribute>();
+ protected List<Query> queries = new ArrayList<Query>();
+
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public String getType() {
+ return type;
+ }
+ public void setType(String type) {
+ this.type = type;
+ }
+ public List<LinkTemplate> getLinkTemplates() {
+ return linkTemplates;
+ }
+ public void setLinkTemplates(List<LinkTemplate> linkTemplates) {
+ this.linkTemplates = linkTemplates;
+ }
+ public List<Attribute> getAttributes() {
+ return attributes;
+ }
+ public void setAttributes(List<Attribute> attributes) {
+ this.attributes = attributes;
+ }
+ public List<Query> getQueries() {
+ return queries;
+ }
+ public void setQueries(List<Query> queries) {
+ this.queries = queries;
+ }
+} \ No newline at end of file
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Link.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Link.java
new file mode 100644
index 0000000..5f0a56b
--- /dev/null
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Link.java
@@ -0,0 +1,46 @@
+package org.eclipse.persistence.internal.jpa.rs.metadata.model;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement
+@XmlType(propOrder = { "method", "href", "rel" })
+public class Link {
+
+ public Link() {
+ }
+
+ public Link(String rel, String method, String href) {
+ this.rel = rel;
+ this.method = method;
+ this.href = href;
+ }
+
+ private String rel;
+ private String method;
+ private String href;
+
+ public String getRel() {
+ return rel;
+ }
+
+ public void setRel(String rel) {
+ this.rel = rel;
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public void setMethod(String method) {
+ this.method = method;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+} \ No newline at end of file
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/LinkTemplate.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/LinkTemplate.java
new file mode 100644
index 0000000..3f21abc
--- /dev/null
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/LinkTemplate.java
@@ -0,0 +1,46 @@
+package org.eclipse.persistence.internal.jpa.rs.metadata.model;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement
+@XmlType(propOrder = { "type", "href", "rel" })
+public class LinkTemplate {
+
+ private String rel;
+ private String type;
+ private String href;
+
+ public LinkTemplate() {
+ }
+
+ public LinkTemplate(String rel, String type, String href) {
+ this.rel = rel;
+ this.type = type;
+ this.href = href;
+ }
+
+ public String getRel() {
+ return rel;
+ }
+
+ public void setRel(String rel) {
+ this.rel = rel;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+} \ No newline at end of file
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Parameter.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Parameter.java
new file mode 100644
index 0000000..a6da569
--- /dev/null
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Parameter.java
@@ -0,0 +1,26 @@
+package org.eclipse.persistence.internal.jpa.rs.metadata.model;
+
+import javax.xml.bind.annotation.XmlType;
+
+@XmlType(propOrder = { "value", "typeName" })
+public class Parameter {
+
+ private String value = null;
+ private String typeName = null;
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public String getTypeName() {
+ return typeName;
+ }
+
+ public void setTypeName(String typeName) {
+ this.typeName = typeName;
+ }
+} \ No newline at end of file
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/PersistenceUnit.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/PersistenceUnit.java
new file mode 100644
index 0000000..534f8b5
--- /dev/null
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/PersistenceUnit.java
@@ -0,0 +1,31 @@
+package org.eclipse.persistence.internal.jpa.rs.metadata.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement
+@XmlType(propOrder = { "persistenceUnitName", "types" })
+public class PersistenceUnit {
+
+ protected String persistenceUnitName = null;
+ protected List<Link> types = new ArrayList<Link>();
+
+ public String getPersistenceUnitName() {
+ return persistenceUnitName;
+ }
+
+ public void setPersistenceUnitName(String persistenceUnitName) {
+ this.persistenceUnitName = persistenceUnitName;
+ }
+
+ public List<Link> getTypes() {
+ return types;
+ }
+
+ public void setTypes(List<Link> types) {
+ this.types = types;
+ }
+} \ No newline at end of file
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Query.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Query.java
new file mode 100644
index 0000000..e4b4f3f
--- /dev/null
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/Query.java
@@ -0,0 +1,57 @@
+package org.eclipse.persistence.internal.jpa.rs.metadata.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement
+@XmlType(propOrder = { "queryName", "returnTypes", "linkTemplate", "jpql" })
+public class Query {
+ protected String queryName;
+ protected String jpql;
+ protected LinkTemplate linkTemplate;
+ protected List<String> returnTypes = new ArrayList<String>();
+
+ public Query() {
+ }
+
+ public Query(String queryName, String jpql, LinkTemplate linkTemplate) {
+ this.queryName = queryName;
+ this.jpql = jpql;
+ this.linkTemplate = linkTemplate;
+ }
+
+ public String getQueryName() {
+ return queryName;
+ }
+
+ public void setQueryName(String queryName) {
+ this.queryName = queryName;
+ }
+
+ public String getJpql() {
+ return jpql;
+ }
+
+ public void setJpql(String jpql) {
+ this.jpql = jpql;
+ }
+
+ public LinkTemplate getLinkTemplate() {
+ return linkTemplate;
+ }
+
+ public void setLinkTemplate(LinkTemplate linkTemplate) {
+ this.linkTemplate = linkTemplate;
+ }
+
+ public List<String> getReturnTypes() {
+ return returnTypes;
+ }
+
+ public void setReturnTypes(List<String> returnTypes) {
+ this.returnTypes = returnTypes;
+ }
+} \ No newline at end of file
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/SessionBeanCall.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/SessionBeanCall.java
new file mode 100644
index 0000000..593dbd3
--- /dev/null
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/jpa/rs/metadata/model/SessionBeanCall.java
@@ -0,0 +1,49 @@
+package org.eclipse.persistence.internal.jpa.rs.metadata.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement
+@XmlType(propOrder = { "context", "jndiName", "methodName", "parameters" })
+public class SessionBeanCall {
+
+ private String jndiName = null;
+ private String methodName = null;
+ private String context = null;
+ private List<Parameter> parameters = new ArrayList<Parameter>();
+
+ public String getContext() {
+ return context;
+ }
+
+ public void setContext(String context) {
+ this.context = context;
+ }
+
+ public String getJndiName() {
+ return jndiName;
+ }
+
+ public void setJndiName(String jndiName) {
+ this.jndiName = jndiName;
+ }
+
+ public String getMethodName() {
+ return methodName;
+ }
+
+ public void setMethodName(String methodName) {
+ this.methodName = methodName;
+ }
+
+ public List<Parameter> getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(List<Parameter> parameters) {
+ this.parameters = parameters;
+ }
+} \ No newline at end of file
diff --git a/jpa/eclipselink.jpars.test/resource/org/eclipse/persistence/jpars/test/restmessage/json/auction-bidsByRef.json b/jpa/eclipselink.jpars.test/resource/org/eclipse/persistence/jpars/test/restmessage/json/auction-bidsByRef.json
new file mode 100644
index 0000000..791df5a
--- /dev/null
+++ b/jpa/eclipselink.jpars.test/resource/org/eclipse/persistence/jpars/test/restmessage/json/auction-bidsByRef.json
@@ -0,0 +1,25 @@
+{
+ "bids":[
+ {
+ "persistence_href":{
+ "method":"GET",
+ "href":"http://localhost:9090/JPA-RS/auction-static/entity/StaticBid/1234",
+ "rel":"self"
+ }
+ },
+ {
+ "persistence_href":{
+ "method":"GET",
+ "href":"http://localhost:9090/JPA-RS/auction-static/entity/StaticBid/5678",
+ "rel":"self"
+ }
+ }
+ ],
+ "description":"a famous Picasso paint",
+ "endPrice":1000000.0,
+ "id":12,
+ "image":"Dora_Maar_au_Chat.jpeg",
+ "name":"Dora Maar au Chat",
+ "sold":false,
+ "startPrice":10000.0
+} \ No newline at end of file
diff --git a/jpa/eclipselink.jpars.test/resource/org/eclipse/persistence/jpars/test/restmessage/json/auction-bidsByValue.json b/jpa/eclipselink.jpars.test/resource/org/eclipse/persistence/jpars/test/restmessage/json/auction-bidsByValue.json
new file mode 100644
index 0000000..9bca3dc
--- /dev/null
+++ b/jpa/eclipselink.jpars.test/resource/org/eclipse/persistence/jpars/test/restmessage/json/auction-bidsByValue.json
@@ -0,0 +1,26 @@
+{
+ "bids":[
+ {
+ "id":333,
+ "time":1234567,
+ "amount":500.0
+ },
+ {
+ "id":444,
+ "time":678910,
+ "amount":1000.0
+ },
+ {
+ "id":555,
+ "time":646464,
+ "amount":1500.0
+ }
+ ],
+ "description":"another famous Picasso paint",
+ "endPrice":1000000.0,
+ "id":111,
+ "image":"The_Old_Guitarist.jpeg",
+ "name":"The Old Guitarist",
+ "sold":false,
+ "startPrice":10000.0
+} \ No newline at end of file
diff --git a/jpa/eclipselink.jpars.test/src/org/eclipse/persistence/jpars/test/AllJavaSETests.java b/jpa/eclipselink.jpars.test/src/org/eclipse/persistence/jpars/test/AllJavaSETests.java
index cf04cfb..087c19b 100644
--- a/jpa/eclipselink.jpars.test/src/org/eclipse/persistence/jpars/test/AllJavaSETests.java
+++ b/jpa/eclipselink.jpars.test/src/org/eclipse/persistence/jpars/test/AllJavaSETests.java
@@ -13,13 +13,14 @@
package org.eclipse.persistence.jpars.test;
import org.eclipse.persistence.jpars.test.crud.StaticCrudTests;
+import org.eclipse.persistence.jpars.test.server.UnmarshalTest;
import org.eclipse.persistence.jpars.test.service.TestService;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
-@SuiteClasses({TestService.class, StaticCrudTests.class})
+@SuiteClasses({TestService.class, StaticCrudTests.class, UnmarshalTest.class})
public class AllJavaSETests {
}
diff --git a/jpa/eclipselink.jpars.test/src/org/eclipse/persistence/jpars/test/server/UnmarshalTest.java b/jpa/eclipselink.jpars.test/src/org/eclipse/persistence/jpars/test/server/UnmarshalTest.java
new file mode 100644
index 0000000..993e1b6
--- /dev/null
+++ b/jpa/eclipselink.jpars.test/src/org/eclipse/persistence/jpars/test/server/UnmarshalTest.java
@@ -0,0 +1,219 @@
+package org.eclipse.persistence.jpars.test.server;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.ws.rs.core.MediaType;
+import javax.xml.bind.JAXBException;
+
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+import org.eclipse.persistence.dynamic.DynamicClassLoader;
+import org.eclipse.persistence.exceptions.ConversionException;
+import org.eclipse.persistence.jpa.rs.PersistenceContext;
+import org.eclipse.persistence.jpa.rs.PersistenceFactoryBase;
+import org.eclipse.persistence.jpars.test.model.StaticAddress;
+import org.eclipse.persistence.jpars.test.model.StaticAuction;
+import org.eclipse.persistence.jpars.test.model.StaticBid;
+import org.eclipse.persistence.jpars.test.model.StaticUser;
+import org.eclipse.persistence.jpars.test.util.ExamplePropertiesLoader;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class UnmarshalTest {
+
+ private static final String DEFAULT_SERVER_URI_BASE = "http://localhost:8080";
+ private static final String DEFAULT_PU = "auction-static";
+ private static PersistenceContext context = null;
+ private static final String JSON_REST_MESSAGE_FOLDER = "org/eclipse/persistence/jpars/test/restmessage/json/";
+
+ /**
+ * Setup.
+ *
+ * @throws URISyntaxException the uRI syntax exception
+ */
+ @BeforeClass
+ public static void setup() throws URISyntaxException {
+ Map<String, Object> properties = new HashMap<String, Object>();
+ ExamplePropertiesLoader.loadProperties(properties);
+ properties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, null);
+ properties.put(PersistenceUnitProperties.JTA_DATASOURCE, null);
+ properties.put(PersistenceUnitProperties.DDL_GENERATION,
+ PersistenceUnitProperties.DROP_AND_CREATE);
+ properties.put(PersistenceUnitProperties.CLASSLOADER,
+ new DynamicClassLoader(Thread.currentThread()
+ .getContextClassLoader()));
+ PersistenceFactoryBase factory = new PersistenceFactoryBase();
+ EntityManagerFactory emf = Persistence.createEntityManagerFactory(
+ DEFAULT_PU, properties);
+ context = factory.bootstrapPersistenceContext("auction-static", emf,
+ new URI(DEFAULT_SERVER_URI_BASE + "/JPA-RS/"), false);
+ }
+
+ /**
+ * Test unmarshal by ref.
+ *
+ * @throws JAXBException the jAXB exception
+ */
+ @Test
+ public void testUnmarshalByRef() throws JAXBException {
+ EntityManager em = context.getEmf().createEntityManager();
+
+ // Create the bids referenced by hrefs, so that unmarshal can find them
+ // in PU
+ em.getTransaction().begin();
+
+ // "href":"http://localhost:9090/JPA-RS/auction-static/entity/StaticBid/1234",
+ StaticBid bid1 = new StaticBid();
+ bid1.setId(1234);
+ bid1.setAmount(110);
+ bid1.setTime(System.currentTimeMillis());
+ em.persist(bid1);
+
+ // "href":"http://localhost:9090/JPA-RS/auction-static/entity/StaticBid/5678",
+ StaticBid bid2 = new StaticBid();
+ bid1.setId(5678);
+ bid2.setAmount(111);
+ bid2.setTime(System.currentTimeMillis());
+ em.persist(bid2);
+ em.getTransaction().commit();
+
+ //
+ String jsonMessage = getJSONMessage("auction-bidsByRef.json");
+ assertTrue(jsonMessage != null);
+ StaticAuction auction = unmarshal(jsonMessage,
+ StaticAuction.class.getSimpleName());
+ assertTrue("Incorrectly unmarshalled auction.", auction.getName()
+ .equals("Dora Maar au Chat"));
+ List<StaticBid> bids = auction.getBids();
+ assertTrue("Incorrectly unmarshalled bids.", bids.size() > 0);
+
+ // cleanup
+ dbDelete(bid1);
+ dbDelete(bid2);
+ }
+
+ /**
+ * Test unmarshal by value.
+ *
+ * @throws JAXBException the jAXB exception
+ */
+ @Test
+ public void testUnmarshalByValue() throws JAXBException {
+ String jsonMessage = getJSONMessage("auction-bidsByValue.json");
+ StaticAuction auctionUnmarshalled = unmarshal(jsonMessage,
+ StaticAuction.class.getSimpleName());
+
+ assertTrue("Unmarshal returned a null object",
+ auctionUnmarshalled != null);
+ List<StaticBid> bidsUnmarshalled = auctionUnmarshalled.getBids();
+ assertTrue("Incorrectly unmarshalled bids.",
+ bidsUnmarshalled.size() > 0);
+ }
+
+ /**
+ * Test unmarshal by reference non existing nested object.
+ *
+ * @throws IOException Signals that an I/O exception has occurred.
+ * @throws JAXBException the jAXB exception
+ */
+ @Test(expected = ConversionException.class)
+ public void testUnmarshalByReferenceNonExistingNestedObject()
+ throws IOException, JAXBException {
+ // Send a JSON message with links where the links point to non-existing
+ // objects
+ String jsonMessage = getJSONMessage("auction-bidsByRef.json");
+ assertTrue(jsonMessage != null);
+ // unmarshall should raise ConversionException
+ unmarshal(jsonMessage, StaticAuction.class.getSimpleName());
+ }
+
+ /**
+ * Test marshal.
+ *
+ * @throws RestCallFailedException the rest call failed exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ * @throws JAXBException the jAXB exception
+ */
+ @Test
+ public void testMarshal() throws RestCallFailedException,
+ UnsupportedEncodingException, JAXBException {
+ StaticBid bid = new StaticBid();
+ bid.setId(20);
+ bid.setAmount(100.0);
+ bid.setTime(System.currentTimeMillis());
+
+ StaticUser user = new StaticUser();
+ user.setId(22);
+ user.setName("Brahms");
+
+ StaticAddress address = new StaticAddress();
+ address.setCity("Hamburg");
+ // set pk
+ address.setId(67);
+ address.setType("Home");
+
+ user.setAddress(address);
+ bid.setUser(user);
+
+ String marshalledBid = marshal(bid);
+ assertTrue("Marshalling bid returned null", marshalledBid != null);
+
+ String marshalledUser = marshal(user);
+ assertTrue("Marshalling user returned null", marshalledUser != null);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> T unmarshal(String msg, String type)
+ throws JAXBException {
+ T resultObject = null;
+ resultObject = (T) context.unmarshalEntity(type,
+ MediaType.APPLICATION_JSON_TYPE,
+ new ByteArrayInputStream(msg.getBytes()));
+ return resultObject;
+ }
+
+ private static <T> String marshal(Object object)
+ throws RestCallFailedException, JAXBException,
+ UnsupportedEncodingException {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ context.marshallEntity(object, MediaType.APPLICATION_JSON_TYPE, os,
+ false);
+ return os.toString("UTF-8");
+ }
+
+ private static String getJSONMessage(String inputFile) {
+ InputStream is = Thread.currentThread().getContextClassLoader()
+ .getResourceAsStream(JSON_REST_MESSAGE_FOLDER + inputFile);
+ String msg = convertStreamToString(is);
+ return msg;
+ }
+
+ private static String convertStreamToString(InputStream is) {
+ try {
+ return new java.util.Scanner(is).useDelimiter("\\A").next();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private static void dbDelete(Object object) {
+ EntityManager em = context.getEmf().createEntityManager();
+ em.getTransaction().begin();
+ Object merged = em.merge(object);
+ em.remove(merged);
+ em.getTransaction().commit();
+ }
+}
diff --git a/jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java b/jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java
index cc7d32e..ca1dd8a 100644
--- a/jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java
+++ b/jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java
@@ -16,6 +16,7 @@ import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.reflect.Constructor;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
@@ -31,16 +32,13 @@ import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.ws.rs.core.MediaType;
-
-import org.eclipse.persistence.jaxb.JAXBContext;
-import org.eclipse.persistence.jaxb.JAXBContextProperties;
-import org.eclipse.persistence.jaxb.MarshallerProperties;
-import org.eclipse.persistence.jaxb.UnmarshallerProperties;
-
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.ValidationEvent;
+import javax.xml.bind.ValidationEventHandler;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.stream.StreamSource;
@@ -53,8 +51,14 @@ import org.eclipse.persistence.internal.dynamic.DynamicEntityImpl;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.jpa.EJBQueryImpl;
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
+import org.eclipse.persistence.internal.jpa.weaving.RestAdapterClassWriter;
+import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.weaving.PersistenceWeavedRest;
import org.eclipse.persistence.internal.weaving.RelationshipInfo;
+import org.eclipse.persistence.jaxb.JAXBContext;
+import org.eclipse.persistence.jaxb.JAXBContextProperties;
+import org.eclipse.persistence.jaxb.MarshallerProperties;
+import org.eclipse.persistence.jaxb.UnmarshallerProperties;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;
import org.eclipse.persistence.jpa.JpaHelper;
import org.eclipse.persistence.jpa.PersistenceProvider;
@@ -96,18 +100,19 @@ import org.eclipse.persistence.sessions.server.ServerSession;
* @author douglas.clarke, tom.ware
*/
public class PersistenceContext {
-
+
/** A factory class that will provide listeners for events provided by the database
* Setting this provides a hook to allow applications that are capable of receiving
* events from the database to do so.
*/
public DatabaseEventListenerFactory eventListenerFactory = null;
-
+
/** This internal property is used to save a change listener on the session for later retreival.**/
public static final String CHANGE_NOTIFICATION_LISTENER = "jpars.change-notification-listener";
-
+
public static final String JPARS_CONTEXT = "eclipselink.jpars.context";
+ List<XmlAdapter> adapters = null;
/**
* Static setter for the EVENT_LISTENER_FACTORY
@@ -118,27 +123,27 @@ public class PersistenceContext {
DatabaseEventListenerFactory eventListenerFactory) {
this.eventListenerFactory = eventListenerFactory;
}
-
+
/**
* The name of the persistence context is used to look it up. By default it will be the
* persistence unit name of the JPA persistence unit.
*/
protected String name = null;
-
+
/** The EntityManagerFactory used to interact using JPA **/
protected EntityManagerFactory emf;
-
+
/** The JAXBConext used to produce JSON or XML **/
protected JAXBContext context = null;
-
+
/** The URI of the Persistence context. This is used to build Links in JSON and XML **/
protected URI baseURI = null;
-
+
protected TransactionWrapper transaction = null;
protected PersistenceContext() {
}
-
+
public PersistenceContext(String emfName, EntityManagerFactoryImpl emf, URI defaultURI) {
super();
this.emf = emf;
@@ -149,18 +154,19 @@ public class PersistenceContext {
transaction = new ResourceLocalTransactionWrapper();
}
try{
- JAXBContext jaxbContext = createDynamicJAXBContext(emf.getServerSession());
- this.context = jaxbContext;
+ this.context = createDynamicJAXBContext(emf.getServerSession());
} catch (JAXBException jaxbe){
+ jaxbe.printStackTrace();
JPARSLogger.fine("exception_creating_jaxb_context", new Object[]{emfName, jaxbe.toString()});
emf.close();
} catch (IOException e){
+ e.printStackTrace();
JPARSLogger.fine("exception_creating_jaxb_context", new Object[]{emfName, e.toString()});
emf.close();
}
setBaseURI(defaultURI);
}
-
+
/**
* This method is used to help construct a JAXBContext from an existing EntityManagerFactory.
*
@@ -184,12 +190,12 @@ public class PersistenceContext {
packages.add(packageName);
}
}
-
+
for(String packageName: packages){
metadataSources.add(new DynamicXMLMetadataSource(session, packageName));
}
}
-
+
/**
* A part of the facade over the JPA API
* Persist an entity in JPA and commit
@@ -206,7 +212,7 @@ public class PersistenceContext {
em.close();
}
}
-
+
/**
* Create a JAXBConext based on the EntityManagerFactory for this PersistenceContext
* @param session
@@ -222,12 +228,12 @@ public class PersistenceContext {
ClassLoader cl = session.getPlatform().getConversionManager().getLoader();
jaxbContext = DynamicJAXBContextFactory.createContextFromOXM(cl, properties);
-
+
session.setProperty(JAXBContext.class.getName(), jaxbContext);
return jaxbContext;
}
-
+
/**
* A part of the facade over the JPA API
* Create an EntityManagerFactory using the given PersistenceUnitInfo and properties
@@ -240,7 +246,7 @@ public class PersistenceContext {
EntityManagerFactory emf = provider.createContainerEntityManagerFactory(info, properties);
return (EntityManagerFactoryImpl)emf;
}
-
+
/**
* A part of the facade over the JPA API
* Create an EntityManager from the EntityManagerFactory wrapped by this persistence context
@@ -250,7 +256,7 @@ public class PersistenceContext {
protected EntityManager createEntityManager(String tenantId) {
return getEmf().createEntityManager();
}
-
+
/**
* Build the set of properties used to create the JAXBContext based on the EntityManagerFactory that
* this PersistenceContext wraps
@@ -277,16 +283,16 @@ public class PersistenceContext {
} else {
metadataLocations.add(passedOXMLocations);
}
-
+
}
-
+
metadataLocations.add(new LinkMetadataSource());
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataLocations);
-
- properties.put("eclipselink.session-event-listener", new PreLoginMappingAdapter());
+
+ properties.put("eclipselink.session-event-listener", new PreLoginMappingAdapter((AbstractSession)session));
return properties;
}
-
+
/**
* A part of the facade over the JPA API
* Delete the given entity in JPA and commit the changes
@@ -305,7 +311,7 @@ public class PersistenceContext {
em.close();
}
}
-
+
/**
* A part of the facade over the JPA API
* Find an entity with the given name and id in JPA
@@ -328,7 +334,7 @@ public class PersistenceContext {
public Object find(Map<String, String> tenantId, String entityName, Object id) {
return find(tenantId, entityName, id, null);
}
-
+
/**
* A part of the facade over the JPA API
* Find an entity with the given name and id in JPA
@@ -347,7 +353,7 @@ public class PersistenceContext {
em.close();
}
}
-
+
public Object findAttribute(Map<String, String> tenantId, String entityName, Object id, Map<String, Object> properties, String attribute) {
EntityManager em = getEmf().createEntityManager(tenantId);
@@ -363,7 +369,7 @@ public class PersistenceContext {
em.close();
}
}
-
+
public Object updateOrAddAttribute(Map<String, String> tenantId, String entityName, Object id, Map<String, Object> properties, String attribute, Object attributeValue, String partner) {
EntityManager em = getEmf().createEntityManager(tenantId);
@@ -404,7 +410,7 @@ public class PersistenceContext {
em.close();
}
}
-
+
public Object removeAttribute(Map<String, String> tenantId, String entityName, Object id, Map<String, Object> properties, String attribute, Object attributeValue, String partner) {
EntityManager em = getEmf().createEntityManager(tenantId);
@@ -440,7 +446,7 @@ public class PersistenceContext {
em.close();
}
}
-
+
protected void removeMappingValueFromObject(Object object, Object attributeValue, DatabaseMapping mapping, DatabaseMapping partner){
if (mapping.isObjectReferenceMapping()){
Object currentValue = mapping.getRealAttributeValueFromObject(object, getJpaSession());
@@ -457,11 +463,11 @@ public class PersistenceContext {
}
}
}
-
+
public URI getBaseURI() {
return baseURI;
}
-
+
/**
* Look-up the given entity name in the EntityManagerFactory and return the class
* is describes
@@ -475,11 +481,11 @@ public class PersistenceContext {
}
return descriptor.getJavaClass();
}
-
+
public ServerSession getJpaSession(){
return (ServerSession)JpaHelper.getServerSession(emf);
}
-
+
/**
* Lookup the descriptor for the given entity name.
* This method will look first in the EntityManagerFactory wrapped by this persistence context
@@ -501,21 +507,30 @@ public class PersistenceContext {
}
return descriptor;
}
-
+
+ @SuppressWarnings("rawtypes")
public ClassDescriptor getDescriptorForClass(Class clazz){
Server session = getJpaSession();
ClassDescriptor descriptor = session.getDescriptor(clazz);
if (descriptor == null){
- for (Object ajaxBSession:((JAXBContext)getJAXBContext()).getXMLContext().getSessions() ){
- descriptor = ((Session)ajaxBSession).getClassDescriptor(clazz);
- if (descriptor != null){
- break;
- }
+ return getJAXBDescriptorForClass(clazz);
+ }
+ return descriptor;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public ClassDescriptor getJAXBDescriptorForClass(Class clazz) {
+ ClassDescriptor descriptor = null;
+ for (Object ajaxBSession : ((JAXBContext) getJAXBContext())
+ .getXMLContext().getSessions()) {
+ descriptor = ((Session) ajaxBSession).getClassDescriptor(clazz);
+ if (descriptor != null) {
+ break;
}
}
return descriptor;
}
-
+
public EntityManagerFactory getEmf() {
return emf;
}
@@ -523,11 +538,11 @@ public class PersistenceContext {
public JAXBContext getJAXBContext() {
return context;
}
-
+
public String getName() {
return name;
}
-
+
/**
* A part of the facade over the JPA API
* Call jpa merge on the given object and commit
@@ -557,7 +572,7 @@ public class PersistenceContext {
em.close();
}
}
-
+
/**
* A convenience method to create a new dynamic entity of the given type
* @param type
@@ -566,7 +581,7 @@ public class PersistenceContext {
public DynamicEntity newEntity(String type) {
return newEntity(null, type);
}
-
+
/**
* A convenience method to create a new dynamic entity of the given type
* @param tenantId
@@ -591,7 +606,7 @@ public class PersistenceContext {
}
return entity;
}
-
+
/**
* A part of the facade over the JPA API
* Run a query with the given name in JPA and return the result
@@ -602,7 +617,7 @@ public class PersistenceContext {
public Object query(Map<String, String> tenantId, String name, Map<?, ?> parameters) {
return query(tenantId, name, parameters, null, false, false);
}
-
+
/**
* A part of the facade over the JPA API
* Run a query with the given name in JPA and return the result
@@ -653,7 +668,7 @@ public class PersistenceContext {
em.close();
}
}
-
+
/**
* Remove a given change listener. Used in interacting with an application-provided mechanism for listenig
* to database events.
@@ -665,11 +680,11 @@ public class PersistenceContext {
changeListener.removeChangeListener(listener);
}
}
-
+
public void setBaseURI(URI baseURI) {
this.baseURI = baseURI;
}
-
+
protected void setMappingValueInObject(Object object, Object attributeValue, DatabaseMapping mapping, DatabaseMapping partner){
if (mapping.isObjectReferenceMapping()){
@@ -684,7 +699,7 @@ public class PersistenceContext {
}
}
}
-
+
/**
* Stop the current application instance
*/
@@ -698,28 +713,58 @@ public class PersistenceContext {
public String toString() {
return "Application(" + getName() + ")::" + System.identityHashCode(this);
}
-
+
public Object unmarshalEntity(String type, MediaType acceptedMedia, InputStream in) throws JAXBException {
return unmarshalEntity(getClass(type), acceptedMedia, in);
}
-
+
public Object unmarshalEntity(Class type, MediaType acceptedMedia, InputStream in) throws JAXBException {
Unmarshaller unmarshaller = getJAXBContext().createUnmarshaller();
unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, Boolean.FALSE);
unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, acceptedMedia.toString());
unmarshaller.setAdapter(new LinkAdapter(getBaseURI().toString(), this));
+ unmarshaller.setEventHandler(new ValidationEventHandler() {
+ @Override
+ /*
+ * ReferenceAdaptor unmarshal throws exception if the object referred by a link
+ * doesn't exist, and this handler is required to interrupt the unmarshal
+ * operation under this condition.
+ * (non-Javadoc) @see javax.xml.bind.ValidationEventHandler#handleEvent(javax.xml.bind.ValidationEvent)
+ *
+ */
+ public boolean handleEvent(ValidationEvent event) {
+ if (event.getSeverity() != ValidationEvent.WARNING) {
+ // ValidationEventLocator eventLocator = event.getLocator();
+ // Throwable throwable = event.getLinkedException();
+ // nothing is really useful to check for us in eventLocator
+ // and linked exception, just return false;
+ return false;
+ }
+ return true;
+ }
+ });
+
+ try {
+ for (XmlAdapter adapter:getAdapters()) {
+ unmarshaller.setAdapter(adapter);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+
JAXBElement<?> element = unmarshaller.unmarshal(new StreamSource(in), type);
- if (element.getValue() instanceof List<?>){
+ /*if (element.getValue() instanceof List<?>){
for (Object object: (List<?>)element.getValue()){
wrap(object);
}
return element.getValue();
} else {
wrap(element.getValue());
- }
+ }*/
return element.getValue();
}
-
+
/**
* Make adjustements to an unmarshalled entity based on what is found in the weaved fields
*
@@ -747,7 +792,7 @@ public class PersistenceContext {
}
return entity;
}
-
+
/**
* Marshall an entity to either JSON or XML
* Calling this method, will treat relationships as unfetched in the XML/JSON and marshall them as links
@@ -778,8 +823,19 @@ public class PersistenceContext {
Marshaller marshaller = getJAXBContext().createMarshaller();
marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, mediaType.toString());
marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
+
marshaller.setAdapter(new LinkAdapter(getBaseURI().toString(), this));
marshaller.setAdapter(new RelationshipLinkAdapter(getBaseURI().toString(), this));
+
+ try {
+ for (XmlAdapter adapter:getAdapters()) {
+ marshaller.setAdapter(adapter);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+
marshaller.setListener(new Marshaller.Listener() {
@Override
public void beforeMarshal(Object source) {
@@ -792,7 +848,7 @@ public class PersistenceContext {
}
}
});
-
+
if (mediaType == MediaType.APPLICATION_XML_TYPE && object instanceof List){
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
@@ -816,7 +872,7 @@ public class PersistenceContext {
postMarshallEntity(object);
}
}
-
+
/**
* Process an entity and add any additional data that needs to be added prior to marshalling
* This method will both single entities and lists of entities
@@ -832,7 +888,7 @@ public class PersistenceContext {
preMarshallIndividualEntity(object);
}
}
-
+
/**
* Add any data required prior to marshalling an entity to XML or JSON
* In general, this will only affect fields that have been weaved into the object
@@ -855,14 +911,18 @@ public class PersistenceContext {
info.setOwningEntityAlias(descriptor.getAlias());
info.setPersistencePrimaryKey(descriptor.getObjectBuilder().extractPrimaryKeyFromObject(entity, getJpaSession()));
((PersistenceWeavedRest)entity)._persistence_getRelationships().add(info);
+
+ //String href = baseURI + this.name + "/entity/" + info.getOwningEntityAlias() + "/" +
+ // IdHelper.stringifyId(info.getOwningEntity(), info.getOwningEntityAlias(), this) + "/" + frMapping.getAttributeName();
+ // ((PersistenceWeavedRest)entity)._persistence_setHref(href);
}
}
}
}
-
+
}
}
-
+
protected void postMarshallEntity(Object object){
if (object instanceof List){
Iterator i = ((List)object).iterator();
@@ -878,7 +938,7 @@ public class PersistenceContext {
}
}
}
-
+
/**
* Check to see if our weaved list of relationships contains a particular attribute.
* This will tell us if an object that has been composed by unmarshalling XML or JSON
@@ -898,4 +958,30 @@ public class PersistenceContext {
}
return false;
}
+
+ protected List<XmlAdapter> getAdapters() throws Exception {
+ if (adapters == null) {
+ adapters = new ArrayList<XmlAdapter>();
+ for (ClassDescriptor desc : this.getJpaSession().getDescriptors()
+ .values()) {
+ Class clz = desc.getJavaClass();
+ String referenceAdapterName = clz.getName() + "."
+ + RestAdapterClassWriter.ADAPTER_INNER_CLASS_NAME;
+ ClassLoader cl = getJpaSession().getDatasourcePlatform()
+ .getConversionManager().getLoader();
+ Class referenceAdaptorClass = Class.forName(
+ referenceAdapterName, true, cl);
+
+ //adapters.add((XmlAdapter)referenceAdaptorClass.newInstance());
+
+ Class[] argTypes = { String.class, PersistenceContext.class };
+ Constructor referenceAdaptorConstructor = referenceAdaptorClass
+ .getDeclaredConstructor(argTypes);
+ Object[] args = new Object[] { getBaseURI().toString(), this };
+ adapters.add((XmlAdapter) referenceAdaptorConstructor
+ .newInstance(args));
+ }
+ }
+ return adapters;
+ }
}
diff --git a/jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/ServiceBase.java b/jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/ServiceBase.java
index ccb62a6..ed7541a 100644
--- a/jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/ServiceBase.java
+++ b/jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/ServiceBase.java
@@ -24,8 +24,8 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.Map.Entry;
+import java.util.Set;
import javax.naming.InitialContext;
import javax.naming.NamingException;
@@ -43,35 +43,34 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.UriInfo;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.persistence.descriptors.ClassDescriptor;
+import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.internal.expressions.ConstantExpression;
import org.eclipse.persistence.internal.expressions.MapEntryExpression;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.ConversionManager;
+import org.eclipse.persistence.internal.jpa.rs.metadata.model.Attribute;
+import org.eclipse.persistence.internal.jpa.rs.metadata.model.Descriptor;
+import org.eclipse.persistence.internal.jpa.rs.metadata.model.Link;
+import org.eclipse.persistence.internal.jpa.rs.metadata.model.LinkTemplate;
+import org.eclipse.persistence.internal.jpa.rs.metadata.model.Parameter;
+import org.eclipse.persistence.internal.jpa.rs.metadata.model.PersistenceUnit;
+import org.eclipse.persistence.internal.jpa.rs.metadata.model.Query;
+import org.eclipse.persistence.internal.jpa.rs.metadata.model.SessionBeanCall;
import org.eclipse.persistence.internal.queries.MapContainerPolicy;
import org.eclipse.persistence.internal.queries.ReportItem;
import org.eclipse.persistence.jaxb.JAXBContext;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.eclipse.persistence.jaxb.UnmarshallerProperties;
-import org.eclipse.persistence.jpa.rs.PersistenceContext;
-import org.eclipse.persistence.jpa.rs.ServiceBase;
-import org.eclipse.persistence.jpa.rs.metadata.model.Attribute;
-import org.eclipse.persistence.jpa.rs.metadata.model.Descriptor;
-import org.eclipse.persistence.jpa.rs.metadata.model.Link;
-import org.eclipse.persistence.jpa.rs.metadata.model.LinkTemplate;
-import org.eclipse.persistence.jpa.rs.metadata.model.Parameter;
-import org.eclipse.persistence.jpa.rs.metadata.model.PersistenceUnit;
-import org.eclipse.persistence.jpa.rs.metadata.model.Query;
-import org.eclipse.persistence.jpa.rs.metadata.model.SessionBeanCall;
import org.eclipse.persistence.jpa.rs.util.IdHelper;
import org.eclipse.persistence.jpa.rs.util.JPARSLogger;
import org.eclipse.persistence.jpa.rs.util.StreamingOutputMarshaller;
@@ -94,19 +93,19 @@ public class ServiceBase {
public static final String RELATIONSHIP_PARTNER = "partner";
protected PersistenceFactoryBase factory;
-
+
public PersistenceFactoryBase getPersistenceFactory() {
if (factory == null){
factory = new PersistenceFactoryBase();
}
return factory;
}
-
+
@GET
public Response getContexts(@Context HttpHeaders hh, @Context UriInfo uriInfo) throws JAXBException {
return getContexts(hh, uriInfo.getBaseUri());
}
-
+
public Response getContexts(HttpHeaders hh, URI baseURI) throws JAXBException {
Set<String> contexts = getPersistenceFactory().getPersistenceContextNames();
Iterator<String> contextIterator = contexts.iterator();
@@ -120,14 +119,15 @@ public class ServiceBase {
result = marshallMetadata(links, mediaType);
return Response.ok(new StreamingOutputMarshaller(null, result, hh.getAcceptableMediaTypes())).build();
}
-
-
+
+
@POST
@Produces(MediaType.WILDCARD)
public Response callSessionBean(@Context HttpHeaders hh, @Context UriInfo ui, @Context UriInfo uriInfo, InputStream is) throws JAXBException, ClassNotFoundException, NamingException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
return callSessionBean(hh, ui, ui.getBaseUri(), is);
}
+ @SuppressWarnings("rawtypes")
public Response callSessionBean(HttpHeaders hh, UriInfo ui, URI baseURI, InputStream is) throws JAXBException, ClassNotFoundException, NamingException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
SessionBeanCall call = null;
call = unmarshallSessionBeanCall(is);
@@ -139,7 +139,7 @@ public class ServiceBase {
JPARSLogger.fine("jpars_could_not_find_session_bean", new Object[]{jndiName});
return Response.status(Status.NOT_FOUND).build();
}
-
+
PersistenceContext context = null;
if (call.getContext() != null){
context = getPersistenceFactory().get(call.getContext(), baseURI, null);
@@ -148,7 +148,7 @@ public class ServiceBase {
return Response.status(Status.NOT_FOUND).build();
}
}
-
+
Class[] parameters = new Class[call.getParameters().size()];
Object[] args = new Object[call.getParameters().size()];
int i = 0;
@@ -172,578 +172,602 @@ public class ServiceBase {
Object returnValue = method.invoke(ans, args);
return Response.ok(new StreamingOutputMarshaller(null, returnValue, hh.getAcceptableMediaTypes())).build();
}
-
- @GET
- @Path("{context}/metadata")
- public Response getTypes(@PathParam("context") String persistenceUnit, @Context HttpHeaders hh, @Context UriInfo uriInfo) {
- return getTypes(persistenceUnit, hh, uriInfo.getBaseUri());
- }
-
- public Response getTypes(String persistenceUnit, HttpHeaders hh, URI baseURI) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- } else {
- PersistenceUnit pu = new PersistenceUnit();
- pu.setPersistenceUnitName(persistenceUnit);
- Map<Class, ClassDescriptor> descriptors = app.getJpaSession().getDescriptors();
- String mediaType = StreamingOutputMarshaller.mediaType(hh.getAcceptableMediaTypes()).toString();
- Iterator<Class> contextIterator = descriptors.keySet().iterator();
- while (contextIterator.hasNext()){
- ClassDescriptor descriptor = descriptors.get(contextIterator.next());
- pu.getTypes().add(new Link(descriptor.getAlias(), mediaType, baseURI + persistenceUnit + "/metadata/entity/" + descriptor.getAlias()));
- }
- String result = null;
- try {
- result = marshallMetadata(pu, mediaType);
- } catch (JAXBException e){
- JPARSLogger.fine("exception_marshalling_persitence_unit", new Object[]{persistenceUnit, e.toString()});
- return Response.status(Status.INTERNAL_SERVER_ERROR).build();
- }
- ResponseBuilder rb = Response.ok(new StreamingOutputMarshaller(null , result, hh.getAcceptableMediaTypes()));
- rb.header("Content-Type", MediaType.APPLICATION_JSON);
- return rb.build();
- }
- }
-
-
- @GET
- @Path("{context}/metadata/entity/{descriptorAlias}")
- public Response getDescriptorMetadata(@PathParam("context") String persistenceUnit, @PathParam("descriptorAlias") String descriptorAlias, @Context HttpHeaders hh, @Context UriInfo uriInfo) {
- return getDescriptorMetadata(persistenceUnit, descriptorAlias, hh, uriInfo.getBaseUri());
- }
-
- public Response getDescriptorMetadata(String persistenceUnit, String descriptorAlias, HttpHeaders hh, URI baseURI) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- } else {
- ClassDescriptor descriptor = app.getJpaSession().getDescriptorForAlias(descriptorAlias);
- if (descriptor == null){
- JPARSLogger.fine("jpars_could_not_find_entity_type", new Object[]{descriptorAlias, persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- } else {
- String mediaType = StreamingOutputMarshaller.mediaType(hh.getAcceptableMediaTypes()).toString();
- Descriptor returnDescriptor = buildDescriptor(app, persistenceUnit, descriptor, baseURI.toString());
- String result = null;
- try {
- result = marshallMetadata(returnDescriptor, mediaType);
- } catch (JAXBException e){
- JPARSLogger.fine("exception_marshalling_entity_metadata", new Object[]{descriptorAlias, persistenceUnit, e.toString()});
- return Response.status(Status.INTERNAL_SERVER_ERROR).build();
- }
- return Response.ok(new StreamingOutputMarshaller(null , result, hh.getAcceptableMediaTypes())).build();
- }
- }
- }
-
- @GET
- @Path("{context}/metadata/query/")
- public Response getQueriesMetadata(@PathParam("context") String persistenceUnit, @Context HttpHeaders hh, @Context UriInfo uriInfo) {
- return getQueriesMetadata(persistenceUnit, hh, uriInfo.getBaseUri());
- }
-
- public Response getQueriesMetadata(String persistenceUnit, HttpHeaders hh, URI baseURI) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- } else {
- List<Query> queries = new ArrayList<Query>();
- addQueries(queries, app, null);
- String mediaType = StreamingOutputMarshaller.mediaType(hh.getAcceptableMediaTypes()).toString();
- String result = null;
- try {
- result = marshallMetadata(queries, mediaType);
- } catch (JAXBException e){
- JPARSLogger.fine("exception_marshalling_query_metadata", new Object[]{persistenceUnit, e.toString()});
- return Response.status(Status.INTERNAL_SERVER_ERROR).build();
- }
- return Response.ok(new StreamingOutputMarshaller(null , result, hh.getAcceptableMediaTypes())).build();
- }
- }
-
- @GET
- @Path("{context}/metadata/query/{queryName}")
- public Response getQueryMetadata(@PathParam("context") String persistenceUnit, @PathParam("queryName") String queryName, @Context HttpHeaders hh, @Context UriInfo uriInfo) {
- return getQueryMetadata(persistenceUnit, queryName, hh, uriInfo.getBaseUri());
- }
-
- public Response getQueryMetadata(String persistenceUnit, String queryName, HttpHeaders hh, URI baseURI) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- } else {
- List<Query> returnQueries = new ArrayList<Query>();
- Map<String, List<DatabaseQuery>> queries = app.getJpaSession().getQueries();
- if (queries.get(queryName) != null){
- for (DatabaseQuery query :queries.get(queryName)){
- returnQueries.add(getQuery(query, app));
- }
- }
- String mediaType = StreamingOutputMarshaller.mediaType(hh.getAcceptableMediaTypes()).toString();
- String result = null;
- try {
- result = marshallMetadata(returnQueries, mediaType);
- } catch (JAXBException e){
- JPARSLogger.fine("exception_marshalling_individual_query_metadata", new Object[]{queryName, persistenceUnit, e.toString()});
- return Response.status(Status.INTERNAL_SERVER_ERROR).build();
- }
- return Response.ok(new StreamingOutputMarshaller(null , result, hh.getAcceptableMediaTypes())).build();
- }
- }
-
- @GET
- @Path("{context}/entity/{type}/{key}")
- public Response find(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @PathParam("key") String key, @Context HttpHeaders hh, @Context UriInfo ui) {
- return find(persistenceUnit, type, key, hh, ui, ui.getBaseUri());
- }
-
- public Response find(String persistenceUnit, String type, String key, HttpHeaders hh, UriInfo ui, URI baseURI) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null || app.getClass(type) == null){
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- } else {
- JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
- }
- return Response.status(Status.NOT_FOUND).build();
- }
- Map<String, String> discriminators = getParameterMap(ui, persistenceUnit);
-
- Object id = IdHelper.buildId(app, type, key, discriminators);
-
- Object entity = app.find(discriminators, type, id, ServiceBase.getHintMap(ui));
-
- if (entity == null) {
- JPARSLogger.fine("jpars_could_not_entity_for_key", new Object[]{type, key, persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- } else {
- return Response.ok(new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes())).build();
- }
- }
-
- @GET
- @Path("{context}/entity/{type}/{key}/{attribute}")
- public Response findAttribute(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @PathParam("key") String key, @PathParam("attribute") String attribute, @Context HttpHeaders hh, @Context UriInfo ui) {
- return findAttribute(persistenceUnit, type, key, attribute, hh, ui, ui.getBaseUri());
- }
-
- public Response findAttribute(String persistenceUnit, String type, String key, String attribute, HttpHeaders hh, UriInfo ui, URI baseURI) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null || app.getClass(type) == null){
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- } else {
- JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
- }
- return Response.status(Status.NOT_FOUND).build();
- }
- Map<String, String> discriminators = getParameterMap(ui, persistenceUnit);
- Object id = IdHelper.buildId(app, type, key, discriminators);
-
- Object entity = app.findAttribute(discriminators, type, id, ServiceBase.getHintMap(ui), attribute);
-
- if (entity == null) {
- JPARSLogger.fine("jpars_could_not_entity_for_attribute", new Object[]{type, key, attribute, persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- } else {
- return Response.ok(new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes())).build();
- }
- }
-
- @POST
- @Path("{context}/entity/{type}/{key}/{attribute}")
- public Response setOrAddAttribute(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @PathParam("key") String key, @PathParam("attribute") String attribute, @Context HttpHeaders hh, @Context UriInfo ui, InputStream in) {
- return setOrAddAttribute(persistenceUnit, type, key, attribute, hh, ui, ui.getBaseUri(), in);
- }
-
- public Response setOrAddAttribute(String persistenceUnit, String type, String key, String attribute, HttpHeaders hh, UriInfo ui, URI baseURI, InputStream in) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null || app.getClass(type) == null){
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- } else {
- JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
- }
- return Response.status(Status.NOT_FOUND).build();
- }
-
- Map<String, String> discriminators = getParameterMap(ui, persistenceUnit);
- Object id = IdHelper.buildId(app, type, key, discriminators);
-
- Object entity = null;
- String partner = (String)ServiceBase.getParameterMap(ui, attribute).get(RELATIONSHIP_PARTNER);
- try{
- ClassDescriptor descriptor = app.getDescriptor(type);
- DatabaseMapping mapping = (DatabaseMapping)descriptor.getMappingForAttributeName(attribute);
- if (!mapping.isForeignReferenceMapping()){
- JPARSLogger.fine("jpars_could_find_appropriate_mapping_for_update", new Object[]{attribute, type, key, persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- }
- entity = app.unmarshalEntity(((ForeignReferenceMapping)mapping).getReferenceDescriptor().getAlias(), mediaType(hh.getAcceptableMediaTypes()), in);
- } catch (JAXBException e){
- JPARSLogger.fine("exception_while_ummarhalling_entity", new Object[]{type, persistenceUnit, e.toString()});
- return Response.status(Status.BAD_REQUEST).build();
- }
-
- Object result = app.updateOrAddAttribute(getParameterMap(ui, persistenceUnit), type, id, ServiceBase.getHintMap(ui), attribute, entity, partner);
-
- if (result == null) {
- JPARSLogger.fine("jpars_could_not_update_attribute", new Object[]{attribute, type, key, persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- } else {
- return Response.ok(new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes())).build();
- }
- }
-
- @DELETE
- @Path("{context}/entity/{type}/{key}/{attribute}")
- public Response removeAttribute(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @PathParam("key") String key, @PathParam("attribute") String attribute, @Context HttpHeaders hh, @Context UriInfo ui, InputStream in) {
- return removeAttribute(persistenceUnit, type, key, attribute, hh, ui, ui.getBaseUri(), in);
- }
-
- public Response removeAttribute(String persistenceUnit, String type, String key, String attribute, HttpHeaders hh, UriInfo ui, URI baseURI, InputStream in) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null || app.getClass(type) == null){
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- } else {
- JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
- }
- return Response.status(Status.NOT_FOUND).build();
- }
-
- Map<String, String> discriminators = getParameterMap(ui, persistenceUnit);
- Object id = IdHelper.buildId(app, type, key, discriminators);
-
- Object entity = null;
- String partner = (String)ServiceBase.getParameterMap(ui, attribute).get(RELATIONSHIP_PARTNER);
- try{
- ClassDescriptor descriptor = app.getDescriptor(type);
- DatabaseMapping mapping = (DatabaseMapping)descriptor.getMappingForAttributeName(attribute);
- if (!mapping.isForeignReferenceMapping()){
- JPARSLogger.fine("jpars_could_find_appropriate_mapping_for_update", new Object[]{attribute, type, key, persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- }
- entity = app.unmarshalEntity(((ForeignReferenceMapping)mapping).getReferenceDescriptor().getAlias(), mediaType(hh.getAcceptableMediaTypes()), in);
- } catch (JAXBException e){
- JPARSLogger.fine("exception_while_ummarhalling_entity", new Object[]{type, persistenceUnit, e.toString()});
- return Response.status(Status.BAD_REQUEST).build();
- }
-
- Object result = app.removeAttribute(getParameterMap(ui, persistenceUnit), type, id, ServiceBase.getHintMap(ui), attribute, entity, partner);
- if (result == null) {
- JPARSLogger.fine("jpars_could_not_update_attribute", new Object[]{attribute, type, key, persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- } else {
- return Response.ok(new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes())).build();
- }
- }
-
- @PUT
- @Path("{context}/entity/{type}")
- public Response create(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, InputStream in) throws JAXBException {
- return create(persistenceUnit, type, hh, uriInfo, uriInfo.getBaseUri(), in);
- }
-
- public Response create(String persistenceUnit, String type, HttpHeaders hh, UriInfo uriInfo, URI baseURI, InputStream in) throws JAXBException {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- }
- ClassDescriptor descriptor = app.getDescriptor(type);
- if (descriptor == null){
- JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- }
- Object entity = null;
- try{
- entity = app.unmarshalEntity(type, mediaType(hh.getAcceptableMediaTypes()), in);
- } catch (JAXBException e){
- JPARSLogger.fine("exception_while_ummarhalling_entity", new Object[]{type, persistenceUnit, e.toString()});
- return Response.status(Status.BAD_REQUEST).build();
- }
-
- // maintain itempotence on PUT by disallowing sequencing
- AbstractDirectMapping sequenceMapping = descriptor.getObjectBuilder().getSequenceMapping();
- if (sequenceMapping != null){
- Object value = sequenceMapping.getAttributeAccessor().getAttributeValueFromObject(entity);
-
- if (descriptor.getObjectBuilder().isPrimaryKeyComponentInvalid(value, descriptor.getPrimaryKeyFields().indexOf(descriptor.getSequenceNumberField())) || descriptor.getSequence().shouldAlwaysOverrideExistingValue()){
- JPARSLogger.fine("jpars_put_not_itempotent", new Object[]{type, persistenceUnit});
- return Response.status(Status.BAD_REQUEST).build();
- }
- }
-
- app.create(getParameterMap(uriInfo, persistenceUnit), entity);
- ResponseBuilder rb = Response.status(Status.CREATED);
- rb.entity(new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes()));
- return rb.build();
- }
-
- @POST
- @Path("{context}/entity/{type}")
- public Response update(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, InputStream in) {
- return update(persistenceUnit, type, hh, uriInfo, uriInfo.getBaseUri(), in);
- }
-
- public Response update(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, URI baseURI, InputStream in) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null || app.getClass(type) == null){
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- } else {
- JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
- }
- return Response.status(Status.NOT_FOUND).build();
- }
- MediaType contentType = mediaType(hh.getRequestHeader(HttpHeaders.CONTENT_TYPE));
- Object entity = null;
- try {
- entity = app.unmarshalEntity(type, contentType, in);
- } catch (JAXBException e){
- JPARSLogger.fine("exception_while_ummarhalling_entity", new Object[]{type, persistenceUnit, e.toString()});
- return Response.status(Status.BAD_REQUEST).build();
- }
- entity = app.merge(getParameterMap(uriInfo, persistenceUnit), entity);
- return Response.ok(new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes())).build();
- }
-
- @DELETE
- @Path("{context}/entity/{type}/{key}")
- public Response delete(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @PathParam("key") String key, @Context HttpHeaders hh, @Context UriInfo ui) {
- return delete(persistenceUnit, type, key, hh, ui, ui.getBaseUri());
- }
-
- public Response delete(String persistenceUnit, String type, String key, HttpHeaders hh, UriInfo ui, URI baseURI) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null || app.getClass(type) == null){
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- } else {
- JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
- }
- return Response.status(Status.NOT_FOUND).build();
- }
- Map<String, String> discriminators = getParameterMap(ui, persistenceUnit);
- Object id = IdHelper.buildId(app, type, key, discriminators);
- app.delete(discriminators, type, id);
- return Response.ok().build();
- }
-
- @GET
- @Path("{context}/query/{name}")
- public Response namedQuery(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {
- return namedQuery(persistenceUnit, name, hh, ui, ui.getBaseUri());
- }
-
- public Response namedQuery(String persistenceUnit, String name, HttpHeaders hh, UriInfo ui, URI baseURI) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- }
- Object result = app.query(getParameterMap(ui, persistenceUnit), name, ServiceBase.getParameterMap(ui, name), ServiceBase.getHintMap(ui), false, false);
- return Response.ok(new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes())).build();
- }
-
- @POST
- @Path("{context}/query/{name}")
- @Produces({ MediaType.APPLICATION_OCTET_STREAM})
- public Response namedQueryUpdate(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {
- return namedQueryUpdate(persistenceUnit, name, hh, ui, ui.getBaseUri());
- }
-
- public Response namedQueryUpdate(String persistenceUnit, String name, HttpHeaders hh, UriInfo ui, URI baseURI) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- }
- Object result = app.query(getParameterMap(ui, persistenceUnit), name, ServiceBase.getParameterMap(ui, name), ServiceBase.getHintMap(ui), false, true);
- return Response.ok(new StreamingOutputMarshaller(app, result.toString(), hh.getAcceptableMediaTypes())).build();
- }
-
- @GET
- @Path("{context}/singleResultQuery/{name}")
- @Produces(MediaType.WILDCARD)
- public Response namedQuerySingleResult(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {
- return namedQuerySingleResult(persistenceUnit, name, hh, ui, ui.getBaseUri());
- }
-
- public Response namedQuerySingleResult(String persistenceUnit, String name, HttpHeaders hh, UriInfo ui, URI baseURI) {
- PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
- if (app == null){
- JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
- return Response.status(Status.NOT_FOUND).build();
- }
- Object result = app.query(getParameterMap(ui, persistenceUnit), name, ServiceBase.getParameterMap(ui, name), ServiceBase.getHintMap(ui), true, false);
- return Response.ok(new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes())).build();
- }
-
- protected Descriptor buildDescriptor(PersistenceContext app, String persistenceUnit, ClassDescriptor descriptor, String baseUri){
- Descriptor returnDescriptor = new Descriptor();
- returnDescriptor.setName(descriptor.getAlias());
- returnDescriptor.setType(descriptor.getJavaClassName());
- returnDescriptor.getLinkTemplates().add(new LinkTemplate("find", "get", baseUri + persistenceUnit + "/entity/" + descriptor.getAlias() + "/{primaryKey}"));
- returnDescriptor.getLinkTemplates().add(new LinkTemplate("persist", "put", baseUri + persistenceUnit + "/entity/" + descriptor.getAlias()));
- returnDescriptor.getLinkTemplates().add(new LinkTemplate("update", "post", baseUri + persistenceUnit + "/entity/" + descriptor.getAlias()));
- returnDescriptor.getLinkTemplates().add(new LinkTemplate("delete", "delete", baseUri + persistenceUnit + "/entity/" + descriptor.getAlias() + "/{primaryKey}"));
-
- if (!descriptor.getMappings().isEmpty()){
- Iterator<DatabaseMapping> mappingIterator = descriptor.getMappings().iterator();
- while (mappingIterator.hasNext()){
- DatabaseMapping mapping = mappingIterator.next();
- addMapping(returnDescriptor, mapping);
- }
- }
- addQueries(returnDescriptor.getQueries(), app, descriptor.getJavaClassName());
- return returnDescriptor;
- }
-
- protected void addMapping(Descriptor descriptor, DatabaseMapping mapping){
- String target = null;
- if (mapping.isCollectionMapping()){
- CollectionMapping collectionMapping = (CollectionMapping)mapping;
- String collectionType = collectionMapping.getContainerPolicy().getContainerClassName();
- if (collectionMapping.getContainerPolicy().isMapPolicy()){
- String mapKeyType = ((MapContainerPolicy)collectionMapping.getContainerPolicy()).getKeyType().toString();
- target = collectionType + "<" + mapKeyType + ", " + collectionMapping.getReferenceClassName() + ">";
- } else {
- target = collectionType + "<" + collectionMapping.getReferenceClassName() + ">";
- }
- } else if (mapping.isForeignReferenceMapping()){
- target = ((ForeignReferenceMapping)mapping).getReferenceClass().getName();
- } else {
- target = mapping.getAttributeClassification().getName();
- }
- descriptor.getAttributes().add(new Attribute(mapping.getAttributeName(), target));
- }
-
- protected void addQueries(List<Query> queryList, PersistenceContext app, String javaClassName){
- Map<String, List<DatabaseQuery>> queries = app.getJpaSession().getQueries();
- List<DatabaseQuery> returnQueries = new ArrayList<DatabaseQuery>();
- for (String key: queries.keySet()){
- List<DatabaseQuery> keyQueries = queries.get(key);
- Iterator<DatabaseQuery> queryIterator = keyQueries.iterator();
- while (queryIterator.hasNext()){
- DatabaseQuery query= queryIterator.next();
- if (javaClassName == null || (query.getReferenceClassName() != null && query.getReferenceClassName().equals(javaClassName))){
- returnQueries.add(query);
- }
- }
- }
- Iterator<DatabaseQuery> queryIterator = returnQueries.iterator();
- while(queryIterator.hasNext()){
- queryList.add(getQuery(queryIterator.next(), app));
- }
- }
-
- protected Query getQuery(DatabaseQuery query, PersistenceContext app){
- String method = query.isReadQuery() ? "get" : "post";
- String jpql = query.getJPQLString() == null? "" : query.getJPQLString();
- StringBuffer parameterString = new StringBuffer();
- Iterator<String> argumentsIterator = query.getArguments().iterator();
- while (argumentsIterator.hasNext()){
- String argument = argumentsIterator.next();
- parameterString.append(";");
- parameterString.append(argument + "={" + argument + "}");
- }
- Query returnQuery = new Query(query.getName(), jpql, new LinkTemplate("execute", method, app.getBaseURI() + app.getName() + "/query/" + query.getName() + parameterString));
- if (query.isReportQuery()){
- query.checkPrepare(app.getJpaSession(), new DatabaseRecord());
- for (ReportItem item: ((ReportQuery)query).getItems()){
- if (item.getMapping() != null) {
- if (item.getAttributeExpression() != null && item.getAttributeExpression().isMapEntryExpression()){
- if (((MapEntryExpression)item.getAttributeExpression()).shouldReturnMapEntry()){
- returnQuery.getReturnTypes().add(Map.Entry.class.getName());
- } else {
- returnQuery.getReturnTypes().add(((Class)((CollectionMapping)item.getMapping()).getContainerPolicy().getKeyType()).getName());
- }
- } else {
+
+ @GET
+ @Path("{context}/metadata")
+ public Response getTypes(@PathParam("context") String persistenceUnit, @Context HttpHeaders hh, @Context UriInfo uriInfo) {
+ return getTypes(persistenceUnit, hh, uriInfo.getBaseUri());
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Response getTypes(String persistenceUnit, HttpHeaders hh, URI baseURI) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ } else {
+ PersistenceUnit pu = new PersistenceUnit();
+ pu.setPersistenceUnitName(persistenceUnit);
+ Map<Class, ClassDescriptor> descriptors = app.getJpaSession().getDescriptors();
+ String mediaType = StreamingOutputMarshaller.mediaType(hh.getAcceptableMediaTypes()).toString();
+ Iterator<Class> contextIterator = descriptors.keySet().iterator();
+ while (contextIterator.hasNext()){
+ ClassDescriptor descriptor = descriptors.get(contextIterator.next());
+ pu.getTypes().add(new Link(descriptor.getAlias(), mediaType, baseURI + persistenceUnit + "/metadata/entity/" + descriptor.getAlias()));
+ }
+ String result = null;
+ try {
+ result = marshallMetadata(pu, mediaType);
+ } catch (JAXBException e){
+ JPARSLogger.fine("exception_marshalling_persitence_unit", new Object[]{persistenceUnit, e.toString()});
+ return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+ }
+ ResponseBuilder rb = Response.ok(new StreamingOutputMarshaller(null , result, hh.getAcceptableMediaTypes()));
+ rb.header("Content-Type", MediaType.APPLICATION_JSON);
+ return rb.build();
+ }
+ }
+
+
+ @GET
+ @Path("{context}/metadata/entity/{descriptorAlias}")
+ public Response getDescriptorMetadata(@PathParam("context") String persistenceUnit, @PathParam("descriptorAlias") String descriptorAlias, @Context HttpHeaders hh, @Context UriInfo uriInfo) {
+ return getDescriptorMetadata(persistenceUnit, descriptorAlias, hh, uriInfo.getBaseUri());
+ }
+
+ public Response getDescriptorMetadata(String persistenceUnit, String descriptorAlias, HttpHeaders hh, URI baseURI) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ } else {
+ ClassDescriptor descriptor = app.getJpaSession().getDescriptorForAlias(descriptorAlias);
+ if (descriptor == null){
+ JPARSLogger.fine("jpars_could_not_find_entity_type", new Object[]{descriptorAlias, persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ } else {
+ String mediaType = StreamingOutputMarshaller.mediaType(hh.getAcceptableMediaTypes()).toString();
+ Descriptor returnDescriptor = buildDescriptor(app, persistenceUnit, descriptor, baseURI.toString());
+ String result = null;
+ try {
+ result = marshallMetadata(returnDescriptor, mediaType);
+ } catch (JAXBException e){
+ JPARSLogger.fine("exception_marshalling_entity_metadata", new Object[]{descriptorAlias, persistenceUnit, e.toString()});
+ return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+ }
+ return Response.ok(new StreamingOutputMarshaller(null , result, hh.getAcceptableMediaTypes())).build();
+ }
+ }
+ }
+
+ @GET
+ @Path("{context}/metadata/query/")
+ public Response getQueriesMetadata(@PathParam("context") String persistenceUnit, @Context HttpHeaders hh, @Context UriInfo uriInfo) {
+ return getQueriesMetadata(persistenceUnit, hh, uriInfo.getBaseUri());
+ }
+
+ public Response getQueriesMetadata(String persistenceUnit, HttpHeaders hh, URI baseURI) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ } else {
+ List<Query> queries = new ArrayList<Query>();
+ addQueries(queries, app, null);
+ String mediaType = StreamingOutputMarshaller.mediaType(hh.getAcceptableMediaTypes()).toString();
+ String result = null;
+ try {
+ result = marshallMetadata(queries, mediaType);
+ } catch (JAXBException e){
+ JPARSLogger.fine("exception_marshalling_query_metadata", new Object[]{persistenceUnit, e.toString()});
+ return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+ }
+ return Response.ok(new StreamingOutputMarshaller(null , result, hh.getAcceptableMediaTypes())).build();
+ }
+ }
+
+ @GET
+ @Path("{context}/metadata/query/{queryName}")
+ public Response getQueryMetadata(@PathParam("context") String persistenceUnit, @PathParam("queryName") String queryName, @Context HttpHeaders hh, @Context UriInfo uriInfo) {
+ return getQueryMetadata(persistenceUnit, queryName, hh, uriInfo.getBaseUri());
+ }
+
+ public Response getQueryMetadata(String persistenceUnit, String queryName, HttpHeaders hh, URI baseURI) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ } else {
+ List<Query> returnQueries = new ArrayList<Query>();
+ Map<String, List<DatabaseQuery>> queries = app.getJpaSession().getQueries();
+ if (queries.get(queryName) != null){
+ for (DatabaseQuery query :queries.get(queryName)){
+ returnQueries.add(getQuery(query, app));
+ }
+ }
+ String mediaType = StreamingOutputMarshaller.mediaType(hh.getAcceptableMediaTypes()).toString();
+ String result = null;
+ try {
+ result = marshallMetadata(returnQueries, mediaType);
+ } catch (JAXBException e){
+ JPARSLogger.fine("exception_marshalling_individual_query_metadata", new Object[]{queryName, persistenceUnit, e.toString()});
+ return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+ }
+ return Response.ok(new StreamingOutputMarshaller(null , result, hh.getAcceptableMediaTypes())).build();
+ }
+ }
+
+ @GET
+ @Path("{context}/entity/{type}/{key}")
+ public Response find(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @PathParam("key") String key, @Context HttpHeaders hh, @Context UriInfo ui) {
+ return find(persistenceUnit, type, key, hh, ui, ui.getBaseUri());
+ }
+
+ public Response find(String persistenceUnit, String type, String key, HttpHeaders hh, UriInfo ui, URI baseURI) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null || app.getClass(type) == null){
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ } else {
+ JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
+ }
+ return Response.status(Status.NOT_FOUND).build();
+ }
+ Map<String, String> discriminators = getParameterMap(ui, persistenceUnit);
+
+ Object id = IdHelper.buildId(app, type, key, discriminators);
+
+ Object entity = app.find(discriminators, type, id, ServiceBase.getHintMap(ui));
+
+ if (entity == null) {
+ JPARSLogger.fine("jpars_could_not_entity_for_key", new Object[]{type, key, persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ } else {
+ return Response.ok(new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes())).build();
+ }
+ }
+
+ @GET
+ @Path("{context}/entity/{type}/{key}/{attribute}")
+ public Response findAttribute(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @PathParam("key") String key, @PathParam("attribute") String attribute, @Context HttpHeaders hh, @Context UriInfo ui) {
+ return findAttribute(persistenceUnit, type, key, attribute, hh, ui, ui.getBaseUri());
+ }
+
+ public Response findAttribute(String persistenceUnit, String type, String key, String attribute, HttpHeaders hh, UriInfo ui, URI baseURI) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null || app.getClass(type) == null){
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ } else {
+ JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
+ }
+ return Response.status(Status.NOT_FOUND).build();
+ }
+ Map<String, String> discriminators = getParameterMap(ui, persistenceUnit);
+ Object id = IdHelper.buildId(app, type, key, discriminators);
+
+ Object entity = app.findAttribute(discriminators, type, id, ServiceBase.getHintMap(ui), attribute);
+
+ if (entity == null) {
+ JPARSLogger.fine("jpars_could_not_entity_for_attribute", new Object[]{type, key, attribute, persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ } else {
+ return Response.ok(new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes())).build();
+ }
+ }
+
+ @POST
+ @Path("{context}/entity/{type}/{key}/{attribute}")
+ public Response setOrAddAttribute(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @PathParam("key") String key, @PathParam("attribute") String attribute, @Context HttpHeaders hh, @Context UriInfo ui, InputStream in) {
+ return setOrAddAttribute(persistenceUnit, type, key, attribute, hh, ui, ui.getBaseUri(), in);
+ }
+
+ public Response setOrAddAttribute(String persistenceUnit, String type, String key, String attribute, HttpHeaders hh, UriInfo ui, URI baseURI, InputStream in) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null || app.getClass(type) == null){
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ } else {
+ JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
+ }
+ return Response.status(Status.NOT_FOUND).build();
+ }
+
+ Map<String, String> discriminators = getParameterMap(ui, persistenceUnit);
+ Object id = IdHelper.buildId(app, type, key, discriminators);
+
+ Object entity = null;
+ String partner = (String)ServiceBase.getParameterMap(ui, attribute).get(RELATIONSHIP_PARTNER);
+ try{
+ ClassDescriptor descriptor = app.getDescriptor(type);
+ DatabaseMapping mapping = (DatabaseMapping)descriptor.getMappingForAttributeName(attribute);
+ if (!mapping.isForeignReferenceMapping()){
+ JPARSLogger.fine("jpars_could_find_appropriate_mapping_for_update", new Object[]{attribute, type, key, persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ }
+ entity = app.unmarshalEntity(((ForeignReferenceMapping)mapping).getReferenceDescriptor().getAlias(), mediaType(hh.getAcceptableMediaTypes()), in);
+ } catch (JAXBException e){
+ JPARSLogger.fine("exception_while_ummarhalling_entity", new Object[]{type, persistenceUnit, e.toString()});
+ return Response.status(Status.BAD_REQUEST).build();
+ } catch (ConversionException e) {
+ // unmarshaller might also throw ConversionException if it cannot
+ // unmarshal input stream
+ JPARSLogger.fine("exception_while_ummarhalling_entity",
+ new Object[] { type, persistenceUnit, e.toString() });
+ return Response.status(Status.BAD_REQUEST).build();
+ }
+
+ Object result = app.updateOrAddAttribute(getParameterMap(ui, persistenceUnit), type, id, ServiceBase.getHintMap(ui), attribute, entity, partner);
+
+ if (result == null) {
+ JPARSLogger.fine("jpars_could_not_update_attribute", new Object[]{attribute, type, key, persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ } else {
+ return Response.ok(new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes())).build();
+ }
+ }
+
+ @DELETE
+ @Path("{context}/entity/{type}/{key}/{attribute}")
+ public Response removeAttribute(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @PathParam("key") String key, @PathParam("attribute") String attribute, @Context HttpHeaders hh, @Context UriInfo ui, InputStream in) {
+ return removeAttribute(persistenceUnit, type, key, attribute, hh, ui, ui.getBaseUri(), in);
+ }
+
+ public Response removeAttribute(String persistenceUnit, String type, String key, String attribute, HttpHeaders hh, UriInfo ui, URI baseURI, InputStream in) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null || app.getClass(type) == null){
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ } else {
+ JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
+ }
+ return Response.status(Status.NOT_FOUND).build();
+ }
+
+ Map<String, String> discriminators = getParameterMap(ui, persistenceUnit);
+ Object id = IdHelper.buildId(app, type, key, discriminators);
+
+ Object entity = null;
+ String partner = (String)ServiceBase.getParameterMap(ui, attribute).get(RELATIONSHIP_PARTNER);
+ try{
+ ClassDescriptor descriptor = app.getDescriptor(type);
+ DatabaseMapping mapping = (DatabaseMapping)descriptor.getMappingForAttributeName(attribute);
+ if (!mapping.isForeignReferenceMapping()){
+ JPARSLogger.fine("jpars_could_find_appropriate_mapping_for_update", new Object[]{attribute, type, key, persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ }
+ entity = app.unmarshalEntity(((ForeignReferenceMapping)mapping).getReferenceDescriptor().getAlias(), mediaType(hh.getAcceptableMediaTypes()), in);
+ } catch (JAXBException e){
+ JPARSLogger.fine("exception_while_ummarhalling_entity", new Object[]{type, persistenceUnit, e.toString()});
+ return Response.status(Status.BAD_REQUEST).build();
+ } catch (ConversionException e) {
+ // unmarshaller might also throw ConversionException if it cannot
+ // unmarshal input stream
+ JPARSLogger.fine("exception_while_ummarhalling_entity",
+ new Object[] { type, persistenceUnit, e.toString() });
+ return Response.status(Status.BAD_REQUEST).build();
+ }
+
+ Object result = app.removeAttribute(getParameterMap(ui, persistenceUnit), type, id, ServiceBase.getHintMap(ui), attribute, entity, partner);
+ if (result == null) {
+ JPARSLogger.fine("jpars_could_not_update_attribute", new Object[]{attribute, type, key, persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ } else {
+ return Response.ok(new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes())).build();
+ }
+ }
+
+ @PUT
+ @Path("{context}/entity/{type}")
+ public Response create(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, InputStream in) throws JAXBException {
+ return create(persistenceUnit, type, hh, uriInfo, uriInfo.getBaseUri(), in);
+ }
+
+ public Response create(String persistenceUnit, String type, HttpHeaders hh, UriInfo uriInfo, URI baseURI, InputStream in) throws JAXBException {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ }
+ ClassDescriptor descriptor = app.getDescriptor(type);
+ if (descriptor == null){
+ JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ }
+ Object entity = null;
+ try{
+ entity = app.unmarshalEntity(type, mediaType(hh.getAcceptableMediaTypes()), in);
+ } catch (JAXBException e){
+ JPARSLogger.fine("exception_while_ummarhalling_entity", new Object[]{type, persistenceUnit, e.toString()});
+ return Response.status(Status.BAD_REQUEST).build();
+ } catch (ConversionException e){
+ // unmarshaller might also throw ConversionException if it cannot unmarshal input stream
+ JPARSLogger.fine("exception_while_ummarhalling_entity", new Object[]{type, persistenceUnit, e.toString()});
+ return Response.status(Status.BAD_REQUEST).build();
+ }
+
+ // maintain idempotence on PUT by disallowing sequencing
+ AbstractDirectMapping sequenceMapping = descriptor.getObjectBuilder().getSequenceMapping();
+ if (sequenceMapping != null){
+ Object value = sequenceMapping.getAttributeAccessor().getAttributeValueFromObject(entity);
+
+ if (descriptor.getObjectBuilder().isPrimaryKeyComponentInvalid(value, descriptor.getPrimaryKeyFields().indexOf(descriptor.getSequenceNumberField())) || descriptor.getSequence().shouldAlwaysOverrideExistingValue()){
+ JPARSLogger.fine("jpars_put_not_itempotent", new Object[]{type, persistenceUnit});
+ return Response.status(Status.BAD_REQUEST).build();
+ }
+ }
+
+ app.create(getParameterMap(uriInfo, persistenceUnit), entity);
+ ResponseBuilder rb = Response.status(Status.CREATED);
+ rb.entity(new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes()));
+ return rb.build();
+ }
+
+ @POST
+ @Path("{context}/entity/{type}")
+ public Response update(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, InputStream in) {
+ return update(persistenceUnit, type, hh, uriInfo, uriInfo.getBaseUri(), in);
+ }
+
+ public Response update(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, URI baseURI, InputStream in) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null || app.getClass(type) == null){
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ } else {
+ JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
+ }
+ return Response.status(Status.NOT_FOUND).build();
+ }
+ MediaType contentType = mediaType(hh.getRequestHeader(HttpHeaders.CONTENT_TYPE));
+ Object entity = null;
+ try {
+ entity = app.unmarshalEntity(type, contentType, in);
+ } catch (JAXBException e){
+ JPARSLogger.fine("exception_while_ummarhalling_entity", new Object[]{type, persistenceUnit, e.toString()});
+ return Response.status(Status.BAD_REQUEST).build();
+ } catch (ConversionException e) {
+ // unmarshaller might also throw ConversionException if it cannot
+ // unmarshal input stream
+ JPARSLogger.fine("exception_while_ummarhalling_entity",
+ new Object[] { type, persistenceUnit, e.toString() });
+ return Response.status(Status.BAD_REQUEST).build();
+ }
+
+ entity = app.merge(getParameterMap(uriInfo, persistenceUnit), entity);
+ return Response.ok(new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes())).build();
+ }
+
+ @DELETE
+ @Path("{context}/entity/{type}/{key}")
+ public Response delete(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @PathParam("key") String key, @Context HttpHeaders hh, @Context UriInfo ui) {
+ return delete(persistenceUnit, type, key, hh, ui, ui.getBaseUri());
+ }
+
+ public Response delete(String persistenceUnit, String type, String key, HttpHeaders hh, UriInfo ui, URI baseURI) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null || app.getClass(type) == null){
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ } else {
+ JPARSLogger.fine("jpars_could_not_find_class_in_persistence_unit", new Object[]{type, persistenceUnit});
+ }
+ return Response.status(Status.NOT_FOUND).build();
+ }
+ Map<String, String> discriminators = getParameterMap(ui, persistenceUnit);
+ Object id = IdHelper.buildId(app, type, key, discriminators);
+ app.delete(discriminators, type, id);
+ return Response.ok().build();
+ }
+
+ @GET
+ @Path("{context}/query/{name}")
+ public Response namedQuery(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {
+ return namedQuery(persistenceUnit, name, hh, ui, ui.getBaseUri());
+ }
+
+ public Response namedQuery(String persistenceUnit, String name, HttpHeaders hh, UriInfo ui, URI baseURI) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ }
+ Object result = app.query(getParameterMap(ui, persistenceUnit), name, ServiceBase.getParameterMap(ui, name), ServiceBase.getHintMap(ui), false, false);
+ return Response.ok(new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes())).build();
+ }
+
+ @POST
+ @Path("{context}/query/{name}")
+ @Produces({ MediaType.APPLICATION_OCTET_STREAM})
+ public Response namedQueryUpdate(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {
+ return namedQueryUpdate(persistenceUnit, name, hh, ui, ui.getBaseUri());
+ }
+
+ public Response namedQueryUpdate(String persistenceUnit, String name, HttpHeaders hh, UriInfo ui, URI baseURI) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ }
+ Object result = app.query(getParameterMap(ui, persistenceUnit), name, ServiceBase.getParameterMap(ui, name), ServiceBase.getHintMap(ui), false, true);
+ return Response.ok(new StreamingOutputMarshaller(app, result.toString(), hh.getAcceptableMediaTypes())).build();
+ }
+
+ @GET
+ @Path("{context}/singleResultQuery/{name}")
+ @Produces(MediaType.WILDCARD)
+ public Response namedQuerySingleResult(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {
+ return namedQuerySingleResult(persistenceUnit, name, hh, ui, ui.getBaseUri());
+ }
+
+ public Response namedQuerySingleResult(String persistenceUnit, String name, HttpHeaders hh, UriInfo ui, URI baseURI) {
+ PersistenceContext app = getPersistenceFactory().get(persistenceUnit, baseURI, null);
+ if (app == null){
+ JPARSLogger.fine("jpars_could_not_find_persistence_context", new Object[]{persistenceUnit});
+ return Response.status(Status.NOT_FOUND).build();
+ }
+ Object result = app.query(getParameterMap(ui, persistenceUnit), name, ServiceBase.getParameterMap(ui, name), ServiceBase.getHintMap(ui), true, false);
+ return Response.ok(new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes())).build();
+ }
+
+ protected Descriptor buildDescriptor(PersistenceContext app, String persistenceUnit, ClassDescriptor descriptor, String baseUri){
+ Descriptor returnDescriptor = new Descriptor();
+ returnDescriptor.setName(descriptor.getAlias());
+ returnDescriptor.setType(descriptor.getJavaClassName());
+ returnDescriptor.getLinkTemplates().add(new LinkTemplate("find", "get", baseUri + persistenceUnit + "/entity/" + descriptor.getAlias() + "/{primaryKey}"));
+ returnDescriptor.getLinkTemplates().add(new LinkTemplate("persist", "put", baseUri + persistenceUnit + "/entity/" + descriptor.getAlias()));
+ returnDescriptor.getLinkTemplates().add(new LinkTemplate("update", "post", baseUri + persistenceUnit + "/entity/" + descriptor.getAlias()));
+ returnDescriptor.getLinkTemplates().add(new LinkTemplate("delete", "delete", baseUri + persistenceUnit + "/entity/" + descriptor.getAlias() + "/{primaryKey}"));
+
+ if (!descriptor.getMappings().isEmpty()){
+ Iterator<DatabaseMapping> mappingIterator = descriptor.getMappings().iterator();
+ while (mappingIterator.hasNext()){
+ DatabaseMapping mapping = mappingIterator.next();
+ addMapping(returnDescriptor, mapping);
+ }
+ }
+ addQueries(returnDescriptor.getQueries(), app, descriptor.getJavaClassName());
+ return returnDescriptor;
+ }
+
+ protected void addMapping(Descriptor descriptor, DatabaseMapping mapping){
+ String target = null;
+ if (mapping.isCollectionMapping()){
+ CollectionMapping collectionMapping = (CollectionMapping)mapping;
+ String collectionType = collectionMapping.getContainerPolicy().getContainerClassName();
+ if (collectionMapping.getContainerPolicy().isMapPolicy()){
+ String mapKeyType = ((MapContainerPolicy)collectionMapping.getContainerPolicy()).getKeyType().toString();
+ target = collectionType + "<" + mapKeyType + ", " + collectionMapping.getReferenceClassName() + ">";
+ } else {
+ target = collectionType + "<" + collectionMapping.getReferenceClassName() + ">";
+ }
+ } else if (mapping.isForeignReferenceMapping()){
+ target = ((ForeignReferenceMapping)mapping).getReferenceClass().getName();
+ } else {
+ target = mapping.getAttributeClassification().getName();
+ }
+ descriptor.getAttributes().add(new Attribute(mapping.getAttributeName(), target));
+ }
+
+ protected void addQueries(List<Query> queryList, PersistenceContext app, String javaClassName){
+ Map<String, List<DatabaseQuery>> queries = app.getJpaSession().getQueries();
+ List<DatabaseQuery> returnQueries = new ArrayList<DatabaseQuery>();
+ for (String key: queries.keySet()){
+ List<DatabaseQuery> keyQueries = queries.get(key);
+ Iterator<DatabaseQuery> queryIterator = keyQueries.iterator();
+ while (queryIterator.hasNext()){
+ DatabaseQuery query= queryIterator.next();
+ if (javaClassName == null || (query.getReferenceClassName() != null && query.getReferenceClassName().equals(javaClassName))){
+ returnQueries.add(query);
+ }
+ }
+ }
+ Iterator<DatabaseQuery> queryIterator = returnQueries.iterator();
+ while(queryIterator.hasNext()){
+ queryList.add(getQuery(queryIterator.next(), app));
+ }
+ }
+
+ protected Query getQuery(DatabaseQuery query, PersistenceContext app){
+ String method = query.isReadQuery() ? "get" : "post";
+ String jpql = query.getJPQLString() == null? "" : query.getJPQLString();
+ StringBuffer parameterString = new StringBuffer();
+ Iterator<String> argumentsIterator = query.getArguments().iterator();
+ while (argumentsIterator.hasNext()){
+ String argument = argumentsIterator.next();
+ parameterString.append(";");
+ parameterString.append(argument + "={" + argument + "}");
+ }
+ Query returnQuery = new Query(query.getName(), jpql, new LinkTemplate("execute", method, app.getBaseURI() + app.getName() + "/query/" + query.getName() + parameterString));
+ if (query.isReportQuery()){
+ query.checkPrepare(app.getJpaSession(), new DatabaseRecord());
+ for (ReportItem item: ((ReportQuery)query).getItems()){
+ if (item.getMapping() != null) {
+ if (item.getAttributeExpression() != null && item.getAttributeExpression().isMapEntryExpression()){
+ if (((MapEntryExpression)item.getAttributeExpression()).shouldReturnMapEntry()){
+ returnQuery.getReturnTypes().add(Map.Entry.class.getName());
+ } else {
+ returnQuery.getReturnTypes().add(((Class)((CollectionMapping)item.getMapping()).getContainerPolicy().getKeyType()).getName());
+ }
+ } else {
returnQuery.getReturnTypes().add(item.getMapping().getAttributeClassification().getName());
- }
- } else if (item.getResultType() != null) {
- returnQuery.getReturnTypes().add(item.getResultType().getName());
- } else if (item.getDescriptor() != null) {
- returnQuery.getReturnTypes().add(item.getDescriptor().getJavaClass().getName());
- } else if (item.getAttributeExpression() != null && item.getAttributeExpression().isConstantExpression()){
- returnQuery.getReturnTypes().add(((ConstantExpression)item.getAttributeExpression()).getValue().getClass().getName());
- } else {
- // Use Object.class by default.
- returnQuery.getReturnTypes().add(ClassConstants.OBJECT.getName());
- }
- }
- } else {
- returnQuery.getReturnTypes().add(query.getReferenceClassName() == null ? "" : query.getReferenceClassName());
- }
- return returnQuery;
- }
-
- protected static Map<String, Object> getHintMap(UriInfo info){
- Map<String, Object> hints = new HashMap<String, Object>();
- for(String key : info.getQueryParameters().keySet()) {
- hints.put(key, info.getQueryParameters().getFirst(key));
- }
- return hints;
- }
-
- /**
- * This method has been temporarily added to allow processing of either query or matrix parameters
- * When the final protocol is worked out, it should be removed or altered.
- *
- * Here we check for query parameters and if they don't exist, we get the matrix parameters.
- * @param info
- * @return
- */
- protected static Map<String, String> getParameterMap(UriInfo info, String segment){
- Map<String, String> parameters = new HashMap<String, String>();
- for (PathSegment pathSegment: info.getPathSegments()){
- if (pathSegment.getPath() != null && pathSegment.getPath().equals(segment)){
- for(Entry<String, List<String>> entry : pathSegment.getMatrixParameters().entrySet()) {
- parameters.put(entry.getKey(), entry.getValue().get(0));
- }
- return parameters;
- }
- }
- return parameters;
- }
-
- protected String getSingleHeader(String parameterName, HttpHeaders hh){
- List<String> params = hh.getRequestHeader(parameterName);
- if (params == null || params.isEmpty()) {
- return null;
- }
- if (params.size() != 1) {
- throw new WebApplicationException(Status.BAD_REQUEST);
- }
- return params.get(0);
- }
-
-
- protected String marshallMetadata(Object metadata, String mediaType) throws JAXBException {
- Class[] jaxbClasses = new Class[]{Link.class, Attribute.class, Descriptor.class, LinkTemplate.class, PersistenceUnit.class, Query.class};
- JAXBContext context = (JAXBContext)JAXBContextFactory.createContext(jaxbClasses, null);
- Marshaller marshaller = context.createMarshaller();
- marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, Boolean.FALSE);
- marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, mediaType);
- StringWriter writer = new StringWriter();
- marshaller.marshal(metadata, writer);
- return writer.toString();
- }
-
- protected SessionBeanCall unmarshallSessionBeanCall(InputStream data) throws JAXBException {
- Class[] jaxbClasses = new Class[]{SessionBeanCall.class};
- JAXBContext context = (JAXBContext)JAXBContextFactory.createContext(jaxbClasses, null);
- Unmarshaller unmarshaller = context.createUnmarshaller();
- unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, Boolean.FALSE);
- unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);
- StreamSource ss = new StreamSource(data);
- return unmarshaller.unmarshal(ss, SessionBeanCall.class).getValue();
- }
+ }
+ } else if (item.getResultType() != null) {
+ returnQuery.getReturnTypes().add(item.getResultType().getName());
+ } else if (item.getDescriptor() != null) {
+ returnQuery.getReturnTypes().add(item.getDescriptor().getJavaClass().getName());
+ } else if (item.getAttributeExpression() != null && item.getAttributeExpression().isConstantExpression()){
+ returnQuery.getReturnTypes().add(((ConstantExpression)item.getAttributeExpression()).getValue().getClass().getName());
+ } else {
+ // Use Object.class by default.
+ returnQuery.getReturnTypes().add(ClassConstants.OBJECT.getName());
+ }
+ }
+ } else {
+ returnQuery.getReturnTypes().add(query.getReferenceClassName() == null ? "" : query.getReferenceClassName());
+ }
+ return returnQuery;
+ }
+
+ protected static Map<String, Object> getHintMap(UriInfo info){
+ Map<String, Object> hints = new HashMap<String, Object>();
+ for(String key : info.getQueryParameters().keySet()) {
+ hints.put(key, info.getQueryParameters().getFirst(key));
+ }
+ return hints;
+ }
+
+ /**
+ * This method has been temporarily added to allow processing of either query or matrix parameters
+ * When the final protocol is worked out, it should be removed or altered.
+ *
+ * Here we check for query parameters and if they don't exist, we get the matrix parameters.
+ * @param info
+ * @return
+ */
+ protected static Map<String, String> getParameterMap(UriInfo info, String segment){
+ Map<String, String> parameters = new HashMap<String, String>();
+ for (PathSegment pathSegment: info.getPathSegments()){
+ if (pathSegment.getPath() != null && pathSegment.getPath().equals(segment)){
+ for(Entry<String, List<String>> entry : pathSegment.getMatrixParameters().entrySet()) {
+ parameters.put(entry.getKey(), entry.getValue().get(0));
+ }
+ return parameters;
+ }
+ }
+ return parameters;
+ }
+
+ protected String getSingleHeader(String parameterName, HttpHeaders hh){
+ List<String> params = hh.getRequestHeader(parameterName);
+ if (params == null || params.isEmpty()) {
+ return null;
+ }
+ if (params.size() != 1) {
+ throw new WebApplicationException(Status.BAD_REQUEST);
+ }
+ return params.get(0);
+ }
+
+
+ protected String marshallMetadata(Object metadata, String mediaType) throws JAXBException {
+ Class[] jaxbClasses = new Class[]{Link.class, Attribute.class, Descriptor.class, LinkTemplate.class, PersistenceUnit.class, Query.class};
+ JAXBContext context = (JAXBContext)JAXBContextFactory.createContext(jaxbClasses, null);
+ Marshaller marshaller = context.createMarshaller();
+ marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, Boolean.FALSE);
+ marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, mediaType);
+ StringWriter writer = new StringWriter();
+ marshaller.marshal(metadata, writer);
+ return writer.toString();
+ }
+
+ protected SessionBeanCall unmarshallSessionBeanCall(InputStream data) throws JAXBException {
+ Class[] jaxbClasses = new Class[]{SessionBeanCall.class};
+ JAXBContext context = (JAXBContext)JAXBContextFactory.createContext(jaxbClasses, null);
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+ unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, Boolean.FALSE);
+ unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);
+ StreamSource ss = new StreamSource(data);
+ return unmarshaller.unmarshal(ss, SessionBeanCall.class).getValue();
+ }
}
diff --git a/jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/ReferenceAdapter.java b/jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/ReferenceAdapter.java
new file mode 100644
index 0000000..f708d87
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/ReferenceAdapter.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * - Initial implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.jpa.rs.util;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+import org.eclipse.persistence.descriptors.ClassDescriptor;
+import org.eclipse.persistence.internal.jpa.rs.metadata.model.Link;
+import org.eclipse.persistence.internal.weaving.PersistenceWeavedRest;
+import org.eclipse.persistence.jpa.rs.PersistenceContext;
+
+public class ReferenceAdapter<T extends PersistenceWeavedRest> extends
+ XmlAdapter<T, T> {
+ private String baseURI = null;
+ private PersistenceContext context = null;
+
+ /**
+ * Instantiates a new reference adapter.
+ */
+ public ReferenceAdapter() {
+ super();
+ }
+
+ /**
+ * Instantiates a new reference adapter.
+ *
+ * @param baseURI
+ * the base uri
+ * @param context
+ * the context
+ */
+ public ReferenceAdapter(String baseURI, PersistenceContext context) {
+ this.baseURI = baseURI;
+ this.context = context;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public T marshal(T persistenceWeavedRest) throws Exception {
+ if (persistenceWeavedRest == null) {
+ return null;
+ }
+ ClassDescriptor descriptor = context
+ .getJAXBDescriptorForClass(persistenceWeavedRest.getClass());
+ T returnT = (T) descriptor.getObjectBuilder().buildNewInstance();
+ Link link = new Link();
+ link.setMethod("GET");
+ link.setRel("self");
+ String id = IdHelper.stringifyId(persistenceWeavedRest,
+ descriptor.getAlias(), context);
+ link.setHref(baseURI + context.getName() + "/entity/"
+ + descriptor.getAlias() + "/" + id);
+ descriptor.getMappingForAttributeName("persistence_href")
+ .setAttributeValueInObject(returnT, link);
+ return returnT;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang.Object)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public T unmarshal(T persistenceWeavedRest) throws Exception {
+ Link href = persistenceWeavedRest.getPersistence_href();
+ if (null == href) {
+ return persistenceWeavedRest;
+ }
+
+ // Construct object from the href
+ String uri = href.getHref().replace("\\/", "/");
+ String entityType = uri.substring(uri.indexOf("/entity/"),
+ uri.lastIndexOf('/'));
+ entityType = entityType.substring(entityType.lastIndexOf("/") + 1);
+ String entityId = uri.substring(uri.lastIndexOf("/") + 1);
+ ClassDescriptor descriptor = context.getDescriptor(entityType);
+ Object id = IdHelper.buildId(context, descriptor.getAlias(), entityId,
+ null);
+ T foundEntity = (T) getObjectById(entityType, id);
+ return foundEntity;
+ }
+
+ private Object getObjectById(String entityType, Object id) throws Exception {
+ Object entity = context.find(null, entityType, id, null);
+ if (entity != null) {
+ return entity;
+ }
+ // It is an error if the object referred by a link in unmarshal doesn't
+ // exist, so throw exception
+ throw new RuntimeException("Entity " + entityType + " with id " + id
+ + " does not exist.");
+ }
+} \ No newline at end of file