Updates for in memory DB and links
diff --git a/JPA-RS Incubator/JPA-RS/.settings/org.eclipse.jdt.core.prefs b/JPA-RS Incubator/JPA-RS/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index c83400b..0000000
--- a/JPA-RS Incubator/JPA-RS/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,8 +0,0 @@
-#Fri Nov 04 08:55:45 EDT 2011
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java
index 1ad7e46..d9347c5 100644
--- a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java
+++ b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java
@@ -175,9 +175,9 @@
if (isList(type)){
mergedEntity = newEntity(type);
List<Object> returnValues = new ArrayList<Object>();
- mergedEntity.set("serializedData", returnValues);
+ mergedEntity.set("list", returnValues);
@SuppressWarnings("unchecked")
- List<Object> values = (List<Object>)entity.get("serializedData");
+ List<Object> values = (List<Object>)entity.get("list");
for (Object value: values){
Object merged = em.merge(value);
returnValues.add(merged);
@@ -271,10 +271,14 @@
}
public DynamicEntity find(String tenantId, String entityName, Object id) {
+ return find(tenantId, entityName, id, null);
+ }
+
+ public DynamicEntity find(String tenantId, String entityName, Object id, Map<String, Object> properties) {
EntityManager em = getEmf().createEntityManager();
try {
- return (DynamicEntity) em.find(getClass(entityName), id);
+ return (DynamicEntity) em.find(getClass(entityName), id, properties);
} finally {
em.close();
}
diff --git a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/Service.java b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/Service.java
index 249538d..a1d3fa2 100644
--- a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/Service.java
+++ b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/Service.java
@@ -43,7 +43,6 @@
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.StreamingOutput;
import javax.ws.rs.core.UriInfo;
-import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
@@ -53,6 +52,7 @@
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.jpa.rs.metadata.DatabaseMetadataStore;
import org.eclipse.persistence.jpa.rs.util.IdHelper;
+import org.eclipse.persistence.jpa.rs.util.LinkAdapter;
import org.eclipse.persistence.jpa.rs.util.StreamingOutputMarshaller;
import com.sun.jersey.core.spi.factory.ResponseBuilderImpl;
@@ -140,7 +140,7 @@
rb.status(Status.NOT_FOUND);
} else {
rb.status(Status.OK);
- rb.entity(new StreamingOutputMarshaller(app.getJAXBContext(), entity, hh.getAcceptableMediaTypes()));
+ rb.entity(new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes()));
}
return rb.build();
}
@@ -155,7 +155,7 @@
ResponseBuilder rb = new ResponseBuilderImpl();
rb.status(Status.OK);
- rb.entity(new StreamingOutputMarshaller(app.getJAXBContext(), entity, hh.getAcceptableMediaTypes()));
+ rb.entity(new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes()));
return rb.build();
}
@@ -165,12 +165,10 @@
PersistenceContext app = get(persistenceUnit);
String tenantId = getTenantId(hh);
MediaType contentType = mediaType(hh.getRequestHeader(HttpHeaders.CONTENT_TYPE));
-
DynamicEntity entity = unmarshalEntity(app, type, tenantId, contentType, in);
entity = app.merge(type, tenantId, entity);
- JAXBContext context = app.getJAXBContext();
- return new StreamingOutputMarshaller(context, entity, hh.getAcceptableMediaTypes());
+ return new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes());
}
@GET
@@ -178,8 +176,7 @@
public StreamingOutput namedQuery(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {
PersistenceContext app = get(persistenceUnit);
Object result = app.query(name, Service.getParameterMap(ui), false);
- JAXBContext context = app.getJAXBContext();
- return new StreamingOutputMarshaller(context, result, hh.getAcceptableMediaTypes());
+ return new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes());
}
@GET
@@ -188,8 +185,7 @@
public StreamingOutput namedQuerySingleResult(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {
PersistenceContext app = get(persistenceUnit);
Object result = app.query(name, Service.getParameterMap(ui), true);
- JAXBContext context = app.getJAXBContext();
- return new StreamingOutputMarshaller(context, result, hh.getAcceptableMediaTypes());
+ return new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes());
}
/**
@@ -240,6 +236,7 @@
try {
unmarshaller = app.getJAXBContext().createUnmarshaller();
unmarshaller.setProperty(MEDIA_TYPE, acceptedMedia.toString());
+ unmarshaller.setAdapter(new LinkAdapter("http://localhost:8080/JPA-RS/auction/entity/", app));
JAXBElement<?> element = unmarshaller.unmarshal(new StreamSource(in), app.getClass(type));
return (DynamicEntity) element.getValue();
} catch (JAXBException e) {
diff --git a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/qcn/JPARSDatabaseChangeListener.java b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/qcn/JPARSDatabaseChangeListener.java
index 089682b..72ef625 100644
--- a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/qcn/JPARSDatabaseChangeListener.java
+++ b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/qcn/JPARSDatabaseChangeListener.java
@@ -70,7 +70,7 @@
ExpressionBuilder builder = new ExpressionBuilder();
Expression expression = builder.getField(OracleChangeNotificationListener.ROWID).equal(rowChange.getRowid());
ReadObjectQuery query = new ReadObjectQuery(descriptor.getJavaClass(), expression);
-
+ query.refreshIdentityMapResult();
updatedObject = session.executeQuery(query);
} else {
updatedObject = key.getObject();
diff --git a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/CustomSerializationMetadataSource.java b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/CustomSerializationMetadataSource.java
index a2453ee..79cb3af 100644
--- a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/CustomSerializationMetadataSource.java
+++ b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/CustomSerializationMetadataSource.java
@@ -20,7 +20,6 @@
import org.eclipse.persistence.jaxb.xmlmodel.ObjectFactory;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElement;
-import org.eclipse.persistence.jaxb.xmlmodel.XmlElements;
import org.eclipse.persistence.jaxb.xmlmodel.JavaType.JavaAttributes;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.JavaTypes;
import org.eclipse.persistence.sessions.server.Server;
@@ -50,27 +49,34 @@
JavaTypes javaTypes = new JavaTypes();
xmlBindings.setJavaTypes(javaTypes);
- addSerializationType(persistenceUnitName, session, objectFactory, javaTypes);
+ addSerializationTypes(persistenceUnitName, session, objectFactory, javaTypes);
}
- private void addSerializationType(String persistenceUnitName, Server session, ObjectFactory objectFactory, JavaTypes javaTypes){
- JavaType serializationType = new JavaType();
- serializationType.setName(persistenceUnitName + "SerializedData");
- serializationType.setJavaAttributes(new JavaAttributes());
-
- XmlElements xmlElements = new XmlElements();
- xmlElements.setJavaAttribute("serializedData");
-
- xmlElements.setContainerType("java.util.List");
+ private void addSerializationTypes(String persistenceUnitName, Server session, ObjectFactory objectFactory, JavaTypes javaTypes){
+
for (ClassDescriptor ormDescriptor : session.getProject().getOrderedDescriptors()) {
- XmlElement childElement = new XmlElement();
- childElement.setType(ormDescriptor.getJavaClassName());
- childElement.setName(ormDescriptor.getAlias());
- xmlElements.getXmlElement().add(childElement);
- }
- serializationType.getJavaAttributes().getJavaAttribute().add(objectFactory.createXmlElements(xmlElements));
- serializationType.setXmlRootElement(new org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement());
- javaTypes.getJavaType().add(serializationType);
+
+ JavaType serializationType = new JavaType();
+ serializationType.setName(ormDescriptor.getAlias() + "ListWrapper");
+ serializationType.setJavaAttributes(new JavaAttributes());
+
+ XmlElement xmlElement = new XmlElement();
+ xmlElement.setJavaAttribute("list");
+
+ xmlElement.setContainerType("java.util.List");
+
+ xmlElement.setType(ormDescriptor.getJavaClassName());
+
+ serializationType.getJavaAttributes().getJavaAttribute().add(objectFactory.createXmlElement(xmlElement));
+
+ // serializationType.getJavaAttributes().getJavaAttribute().add(DynamicXMLMetadataSource.createSelfProperty(ormDescriptor.getAlias() + "ListWrapper", objectFactory));
+
+ org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement root = new org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement();
+ root.setName(ormDescriptor.getAlias() + "ListWrapper");
+
+ serializationType.setXmlRootElement(root);
+ javaTypes.getJavaType().add(serializationType);
+ }
}
@Override
diff --git a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/DynamicXMLMetadataSource.java b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/DynamicXMLMetadataSource.java
index 9e14af0..c141294 100644
--- a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/DynamicXMLMetadataSource.java
+++ b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/DynamicXMLMetadataSource.java
@@ -23,7 +23,10 @@
import org.eclipse.persistence.jaxb.xmlmodel.JavaType.JavaAttributes;
import org.eclipse.persistence.jaxb.xmlmodel.ObjectFactory;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings;
+import org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter;
+import org.eclipse.persistence.jaxb.xmlmodel.XmlSchema;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.JavaTypes;
+import org.eclipse.persistence.jaxb.xmlmodel.XmlSchema.XmlNs;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElement;
import org.eclipse.persistence.jpa.rs.PersistenceFactory;
import org.eclipse.persistence.mappings.CollectionMapping;
@@ -40,6 +43,10 @@
*/
public class DynamicXMLMetadataSource implements MetadataSource {
+ private static final String LINK_NAMESPACE_URI = "http://www.w3.org/2005/Atom";
+ private static final String LINK_PREFIX = "atom";
+ private static final String LINK_LOCAL_NAME = "link";
+
private XmlBindings xmlBindings;
public DynamicXMLMetadataSource(String persistenceUnitName, Server session, String packageName) {
@@ -49,7 +56,14 @@
JavaTypes javaTypes = new JavaTypes();
xmlBindings.setJavaTypes(javaTypes);
-
+
+ XmlSchema xmlSchema = new XmlSchema();
+ XmlNs atomNs = new XmlNs();
+ atomNs.setPrefix(LINK_PREFIX);
+ atomNs.setNamespaceUri(LINK_NAMESPACE_URI);
+ xmlSchema.getXmlNs().add(atomNs);
+ xmlBindings.setXmlSchema(xmlSchema);
+
for (ClassDescriptor ormDescriptor : session.getProject().getOrderedDescriptors()) {
javaTypes.getJavaType().add(createJAXBType(ormDescriptor, objectFactory));
}
@@ -62,6 +76,7 @@
for (DatabaseMapping ormMapping : classDescriptor.getMappings()) {
javaType.getJavaAttributes().getJavaAttribute().add(createJAXBProperty(ormMapping, objectFactory));
}
+ // javaType.getJavaAttributes().getJavaAttribute().add(createSelfProperty(classDescriptor.getJavaClassName(), objectFactory));
// Make them all root elements for now
javaType.setXmlRootElement(new org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement());
@@ -73,14 +88,38 @@
xmlElement.setJavaAttribute(mapping.getAttributeName());
if (mapping.isObjectReferenceMapping()){
xmlElement.setType(((ObjectReferenceMapping)mapping).getReferenceClassName());
+ if (!mapping.isPrivateOwned()){
+ addXmlAdapter(xmlElement);
+ }
} else if (mapping.isCollectionMapping()){
xmlElement.setType(((CollectionMapping)mapping).getReferenceClassName());
+ if (!mapping.isPrivateOwned()){
+ addXmlAdapter(xmlElement);
+ }
} else {
xmlElement.setType(mapping.getAttributeClassification().getName());
}
return objectFactory.createXmlElement(xmlElement);
}
+ public static JAXBElement<XmlElement> createSelfProperty(String ownerClassName, ObjectFactory objectFactory){
+ XmlElement xmlElement = new XmlElement();
+ xmlElement.setJavaAttribute("self");
+ xmlElement.setType(ownerClassName);
+ addXmlAdapter(xmlElement);
+ return objectFactory.createXmlElement(xmlElement);
+ }
+
+ public static void addXmlAdapter(XmlElement xmlElement) {
+ xmlElement.setXmlPath(LINK_PREFIX + ":" + LINK_LOCAL_NAME + "[@rel='" + xmlElement.getJavaAttribute() + "']/@href");
+
+ XmlJavaTypeAdapter adapter = new XmlJavaTypeAdapter();
+ adapter.setValue(LinkAdapter.class.getName());
+ adapter.setValueType(String.class.getName());
+ adapter.setType(xmlElement.getType());
+ xmlElement.setXmlJavaTypeAdapter(adapter);
+ }
+
@Override
public XmlBindings getXmlBindings(Map<String, ?> properties, ClassLoader classLoader) {
return this.xmlBindings;
diff --git a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/LinkAdapter.java b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/LinkAdapter.java
new file mode 100644
index 0000000..80dac13
--- /dev/null
+++ b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/LinkAdapter.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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.
+ *
+ * Contributors:
+ * bdoughan - initial implementation
+ * tware - initial unmarshall method
+ ******************************************************************************/
+package org.eclipse.persistence.jpa.rs.util;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+import org.eclipse.persistence.config.CacheUsage;
+import org.eclipse.persistence.config.QueryHints;
+import org.eclipse.persistence.descriptors.ClassDescriptor;
+import org.eclipse.persistence.dynamic.DynamicEntity;
+import org.eclipse.persistence.internal.dynamic.DynamicEntityImpl;
+import org.eclipse.persistence.internal.helper.ConversionManager;
+import org.eclipse.persistence.internal.queries.EntityFetchGroup;
+import org.eclipse.persistence.jpa.JpaHelper;
+import org.eclipse.persistence.jpa.rs.PersistenceContext;
+import org.eclipse.persistence.mappings.DatabaseMapping;
+import org.eclipse.persistence.queries.FetchGroup;
+
+public class LinkAdapter extends XmlAdapter<String, Object> {
+
+ private String baseURI = "http://example.com/DEFAULT/";
+ protected PersistenceContext context;
+
+ public LinkAdapter() {
+ }
+
+ public LinkAdapter(String baseURI, PersistenceContext context) {
+ this.baseURI = baseURI;
+ this.context = context;
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ // TODO Composite keys
+ public Object unmarshal(String v) throws Exception {
+ int lastSlash = v.lastIndexOf('/');
+ String entityType = v.substring(baseURI.length(), lastSlash);
+ String entityId = v.substring(lastSlash + 1);
+ ClassDescriptor descriptor = context.getDescriptor(entityType);
+ Iterator<DatabaseMapping> i = descriptor.getMappings().iterator();
+ String idField = null;
+ Class idType = null;
+ while (i.hasNext()){
+ DatabaseMapping mapping = i.next();
+ if (mapping.isPrimaryKeyMapping()){
+ idField = mapping.getAttributeName();
+ idType = mapping.getAttributeClassification();
+ break;
+ }
+ }
+ Object id = ConversionManager.getDefaultManager().convertObject(entityId, idType);
+ return constructObjectForId(entityType, idField, id);
+ }
+
+ protected Object constructObjectForId(String entityType, String entityIdField, Object id){
+ FetchGroup fetchGroup = new FetchGroup();
+ fetchGroup.addAttribute(entityIdField);
+ Map<String, Object> properties = new HashMap<String, Object>();
+ properties.put(QueryHints.FETCH_GROUP, fetchGroup);
+ properties.put(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
+ DynamicEntityImpl entity = (DynamicEntityImpl)context.find(null, entityType, id, properties);
+ if (entity == null){
+ entity = (DynamicEntityImpl)context.newEntity(entityType);
+ entity.set(entityIdField, id);
+ EntityFetchGroup group = new EntityFetchGroup(entityIdField);
+ entity._persistence_setFetchGroup(group);
+ entity._persistence_setId(id);
+ entity._persistence_setSession(JpaHelper.getDatabaseSession(context.getEmf()));
+ }
+ return entity;
+ }
+
+ @Override
+ public String marshal(Object v) throws Exception {
+ if (null == v) {
+ return null;
+ }
+ DynamicEntity de = (DynamicEntity) v;
+ String href = baseURI + v.getClass().getSimpleName() + "/"
+ + de.get("id");
+ return href;
+ }
+
+}
\ No newline at end of file
diff --git a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/StreamingOutputMarshaller.java b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/StreamingOutputMarshaller.java
index f332f6c..dfd5fee 100644
--- a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/StreamingOutputMarshaller.java
+++ b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/util/StreamingOutputMarshaller.java
@@ -20,6 +20,7 @@
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
+import java.io.StringWriter;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -31,6 +32,8 @@
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
+import org.eclipse.persistence.jpa.rs.PersistenceContext;
+
/**
* Simple {@link StreamingOutput} implementation that uses the provided
* {@link JAXBContext} to marshal the result when requested to either XML or
@@ -40,28 +43,29 @@
* @since EclipseLink 2.4.0
*/
public class StreamingOutputMarshaller implements StreamingOutput {
- private JAXBContext jaxbContext;
+ private PersistenceContext context;
private Object result;
private MediaType mediaType;
private static final String COLLECTION_ELEMENT_NAME = "collection";
- public StreamingOutputMarshaller(JAXBContext jaxbContext, Object result, MediaType acceptedType) {
- this.jaxbContext = jaxbContext;
+ public StreamingOutputMarshaller(PersistenceContext context, Object result, MediaType acceptedType) {
+ this.context = context;
this.result = result;
this.mediaType = acceptedType;
}
- public StreamingOutputMarshaller(JAXBContext jaxbContext, Object result, List<MediaType> acceptedTypes) {
- this(jaxbContext, result, mediaType(acceptedTypes));
+ public StreamingOutputMarshaller(PersistenceContext context, Object result, List<MediaType> acceptedTypes) {
+ this(context, result, mediaType(acceptedTypes));
}
public void write(OutputStream output) throws IOException, WebApplicationException {
- if (this.jaxbContext != null && this.result != null && !this.mediaType.equals(MediaType.WILDCARD_TYPE)) {
+ if (this.context.getJAXBContext() != null && this.result != null && !this.mediaType.equals(MediaType.WILDCARD_TYPE)) {
try {
- Marshaller marshaller = jaxbContext.createMarshaller();
+ Marshaller marshaller = this.context.getJAXBContext().createMarshaller();
marshaller.setProperty(MEDIA_TYPE, this.mediaType.toString());
marshaller.setProperty(org.eclipse.persistence.jaxb.JAXBContext.INCLUDE_ROOT, false);
+ marshaller.setAdapter(new LinkAdapter("http://localhost:8080/JPA-RS/auction/entity/", context));
if (result instanceof Collection) {
@SuppressWarnings("unchecked")
Collection<Object> objs = (Collection<Object>) result;
diff --git a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/websockets/JPARSWebSocket.java b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/websockets/JPARSWebSocket.java
index f92b53d..214f562 100644
--- a/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/websockets/JPARSWebSocket.java
+++ b/JPA-RS Incubator/JPA-RS/src/org/eclipse/persistence/jpa/rs/websockets/JPARSWebSocket.java
@@ -24,6 +24,7 @@
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.jpa.rs.PersistenceContext;
+import org.eclipse.persistence.jpa.rs.util.LinkAdapter;
import com.sun.grizzly.websockets.DataFrame;
import com.sun.grizzly.websockets.DefaultWebSocket;
@@ -100,8 +101,10 @@
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(MEDIA_TYPE, MediaType.APPLICATION_JSON);
marshaller.setProperty(org.eclipse.persistence.jaxb.JAXBContext.INCLUDE_ROOT, false);
+ marshaller.setAdapter(new LinkAdapter("http://localhost:8080/JPA-RS/auction/entity/", context));
StringWriter stringWriter = new StringWriter();
marshaller.marshal(entity, stringWriter);
+
String jsonString = stringWriter.toString();
return jsonString;
} catch (Exception e) {
diff --git a/JPA-RS Incubator/tests/JPA-RS Tests/src/jpars/test/bootstrap/TestBootstrap.java b/JPA-RS Incubator/tests/JPA-RS Tests/src/jpars/test/bootstrap/TestBootstrap.java
index 580c84d..214cc08 100644
--- a/JPA-RS Incubator/tests/JPA-RS Tests/src/jpars/test/bootstrap/TestBootstrap.java
+++ b/JPA-RS Incubator/tests/JPA-RS Tests/src/jpars/test/bootstrap/TestBootstrap.java
@@ -62,6 +62,9 @@
assertTrue("JAXB Session did not contain Auction.", session.getProject().getAliasDescriptors().containsKey("Auction"));
assertTrue("JAXB Session did not contain Bid.", session.getProject().getAliasDescriptors().containsKey("Bid"));
assertTrue("JAXB Session did not contain User.", session.getProject().getAliasDescriptors().containsKey("User"));
+ assertTrue("JAXB Session did not contain Auction.", session.getProject().getAliasDescriptors().containsKey("AuctionListWrapper"));
+ assertTrue("JAXB Session did not contain Bid.", session.getProject().getAliasDescriptors().containsKey("BidListWrapper"));
+ assertTrue("JAXB Session did not contain User.", session.getProject().getAliasDescriptors().containsKey("UserListWrapper"));
}
diff --git a/JPA-RS Incubator/tests/JPA-RS Tests/src/jpars/test/service/TestService.java b/JPA-RS Incubator/tests/JPA-RS Tests/src/jpars/test/service/TestService.java
index 9536195..c786f0d 100644
--- a/JPA-RS Incubator/tests/JPA-RS Tests/src/jpars/test/service/TestService.java
+++ b/JPA-RS Incubator/tests/JPA-RS Tests/src/jpars/test/service/TestService.java
@@ -34,6 +34,7 @@
import javax.ws.rs.core.Response.Status;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
@@ -44,13 +45,19 @@
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.jaxb.JAXBContext;
import org.eclipse.persistence.jaxb.JAXBMarshaller;
+import org.eclipse.persistence.jpa.JpaHelper;
import org.eclipse.persistence.jpa.rs.PersistenceContext;
import org.eclipse.persistence.jpa.rs.PersistenceFactory;
import org.eclipse.persistence.jpa.rs.Service;
import org.eclipse.persistence.jpa.rs.metadata.DatabaseMetadataStore;
+import org.eclipse.persistence.jpa.rs.util.LinkAdapter;
+import org.eclipse.persistence.sessions.server.ServerSession;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
+
+import com.sun.xml.bind.marshaller.MarshallerImpl;
+
import static org.junit.Assert.*;
/**
@@ -73,6 +80,8 @@
factory.getMetadataStore().setProperties(properties);
factory.getMetadataStore().clearMetadata();
factory.bootstrapPersistenceContext("auction", new URL("file:///C:/EclipseLinkView2/incubator/JPA-RS Incubator/tests/JPA-RS Tests/src/xmldocs/auction-persistence.xml"), properties, true);
+ factory.bootstrapPersistenceContext("phonebook", new URL("file:///C:/EclipseLinkView2/incubator/JPA-RS Incubator/tests/JPA-RS Tests/src/xmldocs/phonebook-persistence.xml"), properties, true);
+
clearData();
} catch (Exception e){
fail(e.toString());
@@ -91,11 +100,16 @@
em.createQuery("delete from Bid b").executeUpdate();
em.createQuery("delete from Auction a").executeUpdate();
em.createQuery("delete from User u").executeUpdate();
+
+ em.getTransaction().commit();
+ em = factory.getPersistenceContext("phonebook").getEmf().createEntityManager();
+ em.getTransaction().begin();
+ em.createQuery("delete from Person p").executeUpdate();
em.getTransaction().commit();
}
@Test
- public void testUpdateList(){
+ public void testUpdateUserList(){
Service service = new Service();
service.setPersistenceFactory(factory);
PersistenceContext context = factory.getPersistenceContext("auction");
@@ -112,20 +126,13 @@
entity2.set("name", "Gillian");
- DynamicEntity entity3 = context.newEntity("Auction");
- entity3.set("name", "Computer");
- context.create(null, entity3);
-
- entity3.set("name", "Tablet");
-
- DynamicEntity serializedData = context.newEntity("auctionSerializedData");
+ DynamicEntity serializedData = context.newEntity("UserListWrapper");
List<DynamicEntity> entities = new ArrayList<DynamicEntity>();
entities.add(entity);
entities.add(entity2);
- entities.add(entity3);
- serializedData.set("serializedData", entities);
+ serializedData.set("list", entities);
- StreamingOutput output = service.update("auction", "auctionSerializedData", generateHTTPHeader(MediaType.APPLICATION_XML_TYPE, MediaType.APPLICATION_XML), serializeToSteam(serializedData, context, MediaType.APPLICATION_XML));
+ StreamingOutput output = service.update("auction", "UserListWrapper", generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), serializeToSteam(serializedData, context, MediaType.APPLICATION_JSON));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try{
@@ -134,18 +141,17 @@
fail(ex.toString());
}
InputStream stream = new ByteArrayInputStream(outputStream.toByteArray());
- serializedData = unmarshalEntity(context, "auctionSerializedData", null, MediaType.APPLICATION_XML, stream);
+ serializedData = unmarshalEntity(context, "UserListWrapper", null, MediaType.APPLICATION_JSON, stream);
assertNotNull("returned data was null", serializedData);
- entities = serializedData.get("serializedData");
+ entities = serializedData.get("list");
assertNotNull("returned data had null list", entities);
- assertTrue("returned data had wrong list size", entities.size() == 3);
+ assertTrue("returned data had wrong list size", entities.size() == 2);
List<String> values = new ArrayList<String>();
values.add("James");
values.add("Gillian");
- values.add("Tablet");
for (DynamicEntity value: entities){
- assertTrue("Incorrect name returned", value.get("name").equals("Tablet") || value.get("name").equals("James") || value.get("name").equals("Gillian"));
+ assertTrue("Incorrect name returned", value.get("name").equals("James") || value.get("name").equals("Gillian"));
values.remove(value.get("name"));
}
assertTrue("Incorrent set of names.", values.isEmpty());
@@ -154,6 +160,60 @@
}
@Test
+ public void testUpdatePhoneNumberList(){
+ Service service = new Service();
+ service.setPersistenceFactory(factory);
+ PersistenceContext context = factory.getPersistenceContext("phonebook");
+
+ DynamicEntity entity = context.newEntity("Person");
+ entity.set("firstName", "Jim");
+ entity.set("lastName", "Jones");
+ entity.set("phoneNumber", "1234567");
+ context.create(null, entity);
+
+ entity.set("firstName", "James");
+
+ DynamicEntity entity2 = context.newEntity("Person");
+ entity2.set("firstName", "Jill");
+ entity2.set("lastName", "Jones");
+ context.create(null, entity2);
+
+ entity2.set("firstName", "Gillian");
+
+ DynamicEntity serializedData = context.newEntity("PersonListWrapper");
+ List<DynamicEntity> entities = new ArrayList<DynamicEntity>();
+ entities.add(entity);
+ entities.add(entity2);
+ serializedData.set("list", entities);
+
+ StreamingOutput output = service.update("phonebook", "PersonListWrapper", generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), serializeToSteam(serializedData, context, MediaType.APPLICATION_JSON));
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ try{
+ output.write(outputStream);
+ } catch (IOException ex){
+ fail(ex.toString());
+ }
+ InputStream stream = new ByteArrayInputStream(outputStream.toByteArray());
+ serializedData = unmarshalEntity(context, "PersonListWrapper", null, MediaType.APPLICATION_JSON, stream);
+
+ assertNotNull("returned data was null", serializedData);
+ entities = serializedData.get("list");
+ assertNotNull("returned data had null list", entities);
+ assertTrue("returned data had wrong list size", entities.size() == 2);
+ List<String> values = new ArrayList<String>();
+ values.add("James");
+ values.add("Gillian");
+ for (DynamicEntity value: entities){
+ assertTrue("Incorrect firstName returned", value.get("firstName").equals("James") || value.get("firstName").equals("Gillian"));
+ values.remove(value.get("firstName"));
+ }
+ assertTrue("Incorrent set of names.", values.isEmpty());
+
+ clearData();
+ }
+
+ @Test
public void testRestart(){
factory.close();
Map<String, Object> properties = new HashMap<String, Object>();
@@ -170,6 +230,42 @@
assertTrue("factory was not recreated at boot time.", factory.getPersistenceContext("auction") != null);
}
+ @Test
+ public void testMarshallBid(){
+ Service service = new Service();
+ service.setPersistenceFactory(factory);
+ PersistenceContext context = factory.getPersistenceContext("auction");
+
+ DynamicEntity entity1 = context.newEntity("Auction");
+ entity1.set("name", "Computer");
+ context.create(null, entity1);
+
+ DynamicEntity entity2 = context.newEntity("User");
+ entity2.set("name", "Bob");
+ context.create(null, entity2);
+
+ DynamicEntity entity3 = context.newEntity("Bid");
+ entity3.set("bid", 200d);
+ entity3.set("user", entity2);
+ entity3.set("auction", entity1);
+ context.create(null, entity3);
+
+ InputStream stream = serializeToSteam(entity3, context, MediaType.APPLICATION_JSON);
+
+ entity3 = unmarshalEntity(context, "Bid", null, MediaType.APPLICATION_JSON, stream);
+
+ System.out.println(entity3);
+ entity2 = entity3.get("auction");
+
+ assertNotNull("Name of auction is null.", entity2.get("name"));
+ assertTrue("Name of auction is incorrect.", entity2.get("name").equals("Computer"));
+
+ entity1 = entity3.get("user");
+
+ assertNotNull("Name of user is null.", entity1.get("name"));
+ assertTrue("Name of user is incorrect.", entity1.get("name").equals("Bob"));
+ }
+
@Test
public void testNamedQuery(){
Service service = new Service();
@@ -261,6 +357,7 @@
try {
unmarshaller = app.getJAXBContext().createUnmarshaller();
unmarshaller.setProperty(MEDIA_TYPE, acceptedMedia);
+ unmarshaller.setAdapter(new LinkAdapter("http://localhost:8080/JPA-RS/auction/entity/", app));
JAXBElement<?> element = unmarshaller.unmarshal(new StreamSource(in), app.getClass(type));
return (DynamicEntity) element.getValue();
} catch (JAXBException e) {
@@ -283,7 +380,15 @@
JAXBMarshaller marshaller = null;
try{
marshaller = (JAXBMarshaller)context.getJAXBContext().createMarshaller();
+ /* marshaller.setListener(new Marshaller.Listener() {
+ @Override
+ public void beforeMarshal(Object source) {
+ ((DynamicEntity)source).set("self", source);
+ }
+ }
+ );*/
marshaller.setProperty("eclipselink.media-type", mediaType);
+ marshaller.setAdapter(new LinkAdapter("http://localhost:8080/JPA-RS/auction/entity/", context));
marshaller.setProperty(JAXBContext.INCLUDE_ROOT, Boolean.FALSE);
marshaller.marshal(object, writer);
} catch (Exception e){
diff --git a/JPA-RS Incubator/tests/JPA-RS Tests/src/xmldocs/auction-orm.xml b/JPA-RS Incubator/tests/JPA-RS Tests/src/xmldocs/auction-orm.xml
index 358505e..1390bc5 100644
--- a/JPA-RS Incubator/tests/JPA-RS Tests/src/xmldocs/auction-orm.xml
+++ b/JPA-RS Incubator/tests/JPA-RS Tests/src/xmldocs/auction-orm.xml
@@ -9,6 +9,10 @@
<query>SELECT a FROM Auction a</query>
</named-query>
+ <named-query name="Auction.forName">
+ <query>SELECT a FROM Auction a WHERE a.name = :name</query>
+ </named-query>
+
<named-query name="Auction.open">
<query>SELECT a FROM Auction a where a.sold = false</query>
</named-query>
@@ -77,9 +81,11 @@
<basic name="time" attribute-type="Long"/>
<one-to-one name="user" fetch="EAGER" target-entity="User">
<join-column name="USER_ID" />
+ <private-owned/>
</one-to-one>
<one-to-one name="auction" fetch="EAGER" target-entity="Auction">
<join-column name="AUCTION_ID" />
+ <private-owned/>
</one-to-one>
</attributes>
</entity>
diff --git a/JPA-RS Incubator/tests/JPA-RS Tests/src/xmldocs/phonebook-orm.xml b/JPA-RS Incubator/tests/JPA-RS Tests/src/xmldocs/phonebook-orm.xml
new file mode 100644
index 0000000..37d4f73
--- /dev/null
+++ b/JPA-RS Incubator/tests/JPA-RS Tests/src/xmldocs/phonebook-orm.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entity-mappings version="2.3"
+ xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <package>jpars.app.phonebook.model</package>
+
+ <named-query name="Person.all">
+ <query>SELECT p FROM Person p</query>
+ </named-query>
+
+ <named-query name="Person.likeName">
+ <query>SELECT p FROM Person p WHERE p.lastName LIKE :lastName</query>
+ </named-query>
+
+ <entity class="Person" access="VIRTUAL">
+ <table name="PHONEBOOK_PERSON" />
+ <attributes>
+ <id name="id" attribute-type="Integer">
+ <column name="ID" />
+ <generated-value/>
+ </id>
+ <basic name="firstName" attribute-type="String" />
+ <basic name="lastName" attribute-type="String" />
+ <basic name="phoneNumber" attribute-type="String" />
+ </attributes>
+ </entity>
+
+</entity-mappings>
\ No newline at end of file
diff --git a/JPA-RS Incubator/tests/JPA-RS Tests/src/xmldocs/phonebook-persistence.xml b/JPA-RS Incubator/tests/JPA-RS Tests/src/xmldocs/phonebook-persistence.xml
new file mode 100644
index 0000000..75f433a
--- /dev/null
+++ b/JPA-RS Incubator/tests/JPA-RS Tests/src/xmldocs/phonebook-persistence.xml
@@ -0,0 +1,17 @@
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_2_0.xsd"
+ version="2.0">
+ <persistence-unit name="phonebook" transaction-type="RESOURCE_LOCAL">
+
+ <provider>
+ org.eclipse.persistence.jpa.PersistenceProvider
+ </provider>
+
+ <class>jpars.app.phonebook.model.Person</class>
+ <properties>
+ <property name="eclipselink.metadata-source" value="XML"/>
+ <property name="eclipselink.metadata-source.xml.file" value="xmldocs/phonebook-orm.xml"/>
+ </properties>
+ </persistence-unit>
+</persistence>
\ No newline at end of file