You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2010/10/28 02:36:37 UTC

svn commit: r1028146 - in /openjpa/trunk/openjpa-persistence-jdbc/src: main/resources/META-INF/ test/java/org/apache/openjpa/persistence/jest/ test/resources/META-INF/

Author: ppoddar
Date: Thu Oct 28 00:36:36 2010
New Revision: 1028146

URL: http://svn.apache.org/viewvc?rev=1028146&view=rev
Log:
OPENJPA-1851: Few basic tests on JEST (RESTful remote access to OpenJPA runtime)

Added:
    openjpa/trunk/openjpa-persistence-jdbc/src/main/resources/META-INF/jest-instance.xsd   (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/JObject.java   (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/SchemaErrorDetector.java   (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/TestObjectEncoding.java   (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/TestRequestParsing.java   (with props)
Modified:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/resources/META-INF/jest-instance.xsd
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/resources/META-INF/jest-instance.xsd?rev=1028146&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/resources/META-INF/jest-instance.xsd (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/resources/META-INF/jest-instance.xsd Thu Oct 28 00:36:36 2010
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+	license agreements. See the NOTICE file distributed with this work for additional 
+	information regarding copyright ownership. The ASF licenses this file to 
+	you under the Apache License, Version 2.0 (the "License"); you may not use 
+	this file except in compliance with the License. You may obtain a copy of 
+	the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
+	by applicable law or agreed to in writing, software distributed under the 
+	License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
+	OF ANY KIND, either express or implied. See the License for the specific 
+	language governing permissions and limitations under the License. -->
+<!-- ========================================================================= -->
+<!-- Schema for serialized persistence instance.                               -->
+<!-- ========================================================================= -->
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+	attributeFormDefault="unqualified" elementFormDefault="qualified"
+	version="1.0">
+
+	<xsd:annotation>
+		<xsd:documentation><![CDATA[
+         Describes closure of managed persistence instance.
+         Each instance is described by all its loaded persistent attribute.
+         The related instances are resolved within the document root.
+         Document root represents zero or more instances. 
+          
+         The file must be named "META-INF/jest-instance.xsd".
+         ]]>
+		</xsd:documentation>
+	</xsd:annotation>
+
+    <!-- The root element of the document contains zero or more instances -->
+	<xsd:element name="instances">
+		<xsd:complexType>
+			<xsd:sequence>
+				<xsd:element name="instance" maxOccurs="unbounded" type="instance-type" />
+			</xsd:sequence>
+			<xsd:attribute name="version" type="xsd:string" />
+		</xsd:complexType>
+	</xsd:element>
+
+	<!-- The root element for a single instance -->
+	<xsd:complexType name="instance-type">
+		<xsd:sequence>
+			<xsd:element name="basic" type="basic-attr-type"  minOccurs="0" maxOccurs="unbounded" />
+			<xsd:element name="lob" type="lob-attr-type"      minOccurs="0" maxOccurs="unbounded"/>
+			<xsd:element name="embedded" type="instance-type" minOccurs="0" maxOccurs="unbounded" />
+			<xsd:element name="singular" type="singular-attr-type"  	minOccurs="0" maxOccurs="unbounded" />
+			<xsd:element name="collection" type="collection-attr-type"	minOccurs="0" maxOccurs="unbounded" />
+			<xsd:element name="map" type="map-attr-type"                minOccurs="0" maxOccurs="unbounded" />
+		</xsd:sequence>
+		<xsd:attribute name="id" type="xsd:ID" use="required" />
+	</xsd:complexType>
+
+	<!-- A reference to another instance within the same(?) document -->
+	<xsd:complexType name="ref-type">
+		<xsd:attribute name="id" type="xsd:IDREF" />
+	</xsd:complexType>
+	
+	<!-- A null reference                                            -->
+	<xsd:complexType name="ref-null">
+	</xsd:complexType>
+
+	<!-- Basic Attribute has a name and its runtime type   -->
+	<!-- non-null value appears as text content.           -->
+	<!-- null value appears as attribute with empty text . -->
+	<xsd:complexType name="basic-attr-type">
+		<xsd:simpleContent>
+			<xsd:extension base="xsd:string">
+				<xsd:attribute name="name" type="xsd:string" use="required" />
+				<xsd:attribute name="type" type="xsd:string" use="required" />
+				<xsd:attribute name="null" type="xsd:boolean" />
+			</xsd:extension>
+		</xsd:simpleContent>
+	</xsd:complexType>
+	
+	<!-- Large Binary Objects (LOB) represented as hex array -->
+	<xsd:complexType name="lob-attr-type">
+		<xsd:simpleContent>
+			<xsd:extension base="xsd:hexBinary">
+				<xsd:attribute name="name" type="xsd:string" use="required" />
+				<xsd:attribute name="type" type="xsd:string" use="required" />
+				<xsd:attribute name="null" type="xsd:boolean" />
+			</xsd:extension>
+		</xsd:simpleContent>
+	</xsd:complexType>
+
+	<!-- Singular attribute can be a reference or another instance. -->
+	<xsd:complexType name="singular-attr-type">
+		<xsd:choice>
+			<xsd:element name="null" type="ref-null" />
+			<xsd:element name="ref" type="ref-type" />
+			<xsd:element name="instance" type="instance-type" />
+		</xsd:choice>
+		<xsd:attribute name="name" type="xsd:string" use="required" />
+		<xsd:attribute name="type" type="xsd:string" use="required" />
+	</xsd:complexType>
+
+	<!-- Collection attributes list their members with their runtime type -->
+	<!-- Members can be basic or other managed instance                   -->
+	<xsd:complexType name="collection-attr-type">
+		<xsd:sequence>
+			<xsd:element name="member" type="member-type" minOccurs="0"
+				maxOccurs="unbounded" />
+		</xsd:sequence>
+		<xsd:attribute name="name" type="xsd:string" use="required" />
+		<xsd:attribute name="type" type="xsd:string" use="required" />
+		<xsd:attribute name="member-type" type="xsd:string" use="required" />
+	</xsd:complexType>
+
+	<!-- Map attributes list their entries with runtime type of key and value    -->
+	<!-- Both key and value can be independently basic or other managed instance -->
+	<xsd:complexType name="map-attr-type">
+		<xsd:sequence>
+			<xsd:element name="entry" type="entry-type" />
+		</xsd:sequence>
+		<xsd:attribute name="name" type="xsd:string" use="required" />
+		<xsd:attribute name="type" type="xsd:string" use="required" />
+		<xsd:attribute name="key-type" type="xsd:string" use="required" />
+		<xsd:attribute name="value-type" type="xsd:string" use="required" />
+	</xsd:complexType>
+
+	<!-- Value of a member of basic type. -->
+	<xsd:complexType name="basic-value-type">
+		<xsd:simpleContent>
+			<xsd:extension base="xsd:string">
+				<xsd:attribute name="null" type="xsd:boolean" />
+			</xsd:extension>
+		</xsd:simpleContent>
+	</xsd:complexType>
+
+	<!-- Value of a member of a collection/map -->
+	<xsd:complexType name="member-type">
+		<xsd:choice>
+			<xsd:element name="basic" type="basic-value-type" />
+			<xsd:element name="instance" type="instance-type" />
+			<xsd:element name="null" type="ref-null" />
+			<xsd:element name="ref" type="ref-type" />
+		</xsd:choice>
+	</xsd:complexType>
+
+	<!-- Denotes entry of a map element -->
+	<xsd:complexType name="entry-type">
+		<xsd:sequence>
+			<xsd:element name="key"   type="member-type" minOccurs="1" maxOccurs="1" />
+			<xsd:element name="value" type="member-type" minOccurs="1" maxOccurs="1"  />
+		</xsd:sequence>
+	</xsd:complexType>
+	
+</xsd:schema>

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/main/resources/META-INF/jest-instance.xsd
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/JObject.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/JObject.java?rev=1028146&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/JObject.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/JObject.java Thu Oct 28 00:36:36 2010
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.openjpa.persistence.jest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+
+/**
+ * A persistent entity with singular and plural association used for testing encoding to XML and JSON.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class JObject {
+    @Id
+    private long ssn;
+    
+    private String name;
+    
+    private int age;
+    
+    @OneToOne
+    private JObject spouse;
+    
+    @OneToMany
+    private List<JObject> friends;
+
+    public long getSsn() {
+        return ssn;
+    }
+
+    public void setSsn(long ssn) {
+        this.ssn = ssn;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getAge() {
+        return age;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+    
+    public List<JObject> getFriends() {
+        return friends;
+    }
+    
+    public void addFriend(JObject friend) {
+        if (friends == null)
+            friends = new ArrayList<JObject>();
+        friends.add(friend);
+    }
+    
+    public void setSpouse(JObject p) {
+        spouse = p;
+    }
+    
+    public JObject getSpouse() {
+        return spouse;
+    }
+    
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/JObject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/SchemaErrorDetector.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/SchemaErrorDetector.java?rev=1028146&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/SchemaErrorDetector.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/SchemaErrorDetector.java Thu Oct 28 00:36:36 2010
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * A SAX Default Handler to catch any errors during parsing.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class SchemaErrorDetector extends DefaultHandler {
+    private List<String> errors = new ArrayList<String>();
+    private Locator _locator;
+    private String _source;
+    
+    
+    SchemaErrorDetector(String source) {
+        _source = source;
+    }
+    
+    @Override
+    public void setDocumentLocator(Locator locator) {
+        _locator = locator;
+    }
+    
+    @Override
+    public void error(SAXParseException exception) throws SAXException {
+        handleError(exception);
+    }
+
+    @Override
+    public void fatalError(SAXParseException exception) throws SAXException {
+        handleError(exception);
+    }
+
+    @Override
+    public void warning(SAXParseException exception) throws SAXException {
+        handleError(exception);
+    }
+    
+    private void handleError(SAXParseException exception) {
+        String msg = _source + ":" + _locator.getLineNumber() + ":" + exception.getMessage();
+        System.err.println(msg);
+        errors.add(msg);
+    }
+    
+    boolean hasErrors() {
+        return !errors.isEmpty();
+    }
+    
+    void print() {
+        for (String s : errors) {
+            System.err.println(s);
+        }
+    }
+    public String toString() {
+        StringBuilder buf = new StringBuilder();
+        for (String s : errors) {
+            buf.append(s).append("\r\n");
+        }
+        return buf.toString();
+    }
+}
+

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/SchemaErrorDetector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/TestObjectEncoding.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/TestObjectEncoding.java?rev=1028146&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/TestObjectEncoding.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/TestObjectEncoding.java Thu Oct 28 00:36:36 2010
@@ -0,0 +1,238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.openjpa.persistence.jest;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.lib.util.Files;
+import org.apache.openjpa.persistence.EntityManagerFactoryImpl;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.meta.MetamodelImpl;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Pinaki Poddar
+ *
+ */
+public class TestObjectEncoding extends TestCase {
+    private static EntityManagerFactory _emf;
+    private static DocumentBuilderFactory _factory;
+    private DocumentBuilder _builder; 
+    
+    static final String W3C_XML_SCHEMA          = "http://www.w3.org/2001/XMLSchema";
+    static final String W3C_XML_SCHEMA_INSTANCE = "http://www.w3.org/2001/XMLSchema-instance";
+    static final String JAXP_SCHEMA_SOURCE      = "http://java.sun.com/xml/jaxp/properties/schemaSource";
+    static final String JAXP_SCHEMA_LANGUAGE    = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
+    static final String JEST_INSTANCE_XSD       = "jest-instance.xsd";
+    static final String JEST_INSTANCE_XSD_PATH  = "META-INF/" + JEST_INSTANCE_XSD;
+
+    static SAXParser validatingParser;
+    static InputStream xsd;
+    static URI _schemaFile;
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (_emf == null) {
+            _emf = Persistence.createEntityManagerFactory("jest");
+            _factory = DocumentBuilderFactory.newInstance();
+            _builder = _factory.newDocumentBuilder();
+            File f = Files.getFile(JEST_INSTANCE_XSD_PATH, Thread.currentThread().getContextClassLoader());
+            assertNotNull(JEST_INSTANCE_XSD_PATH + " not found", f);
+            _schemaFile = f.toURI();
+            xsd = new FileInputStream(f);
+            
+            SAXParserFactory factory = SAXParserFactory.newInstance();
+            factory.setValidating(true);
+            factory.setNamespaceAware(true);
+
+            validatingParser = factory.newSAXParser();
+            validatingParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
+            validatingParser.setProperty(JAXP_SCHEMA_SOURCE, xsd);
+        }
+    }
+
+    /**
+     * Test encoding of a persistent closure.
+     * Ensure that it is compliant to schema.
+     * 
+     * @throws Exception
+     */
+    public void testXMLEncoding() throws Exception {
+        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jest");
+        long ssn = System.currentTimeMillis();
+        createObjectGraph(ssn);
+        
+        
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        JObject p = em.find(JObject.class, ssn);
+        assertNotNull(p.getSpouse());
+        assertFalse(p.getFriends().isEmpty());
+        
+        Document doc = encodeXML(em, p);
+        
+        File file = new File(getName()+".xml");
+        writeDoc(doc, file);
+        System.err.println("Encoded document written to " + file.getAbsolutePath());
+        validateDoc(file);
+    }
+    
+    /**
+     * Encode persistent closure of the given object in the given persistent context.
+     * 
+     * @return XML document
+     */
+    Document encodeXML(EntityManager em, Object obj) {
+        Document doc = _builder.newDocument();
+        OpenJPAStateManager sm = ((StoreContext)JPAFacadeHelper.toBroker(em)).getStateManager(obj);
+        Element root = doc.createElement("instances");
+        doc.appendChild(root);
+        new XMLEncoder((MetamodelImpl)em.getMetamodel()).encode(sm, root);
+        addSchemaToRoot(doc);
+        return doc;
+    }
+    
+    
+    void addSchemaToRoot(Document doc) {
+        Element root = doc.getDocumentElement();
+        String[] nvpairs = new String[] {
+                "xmlns:xsi",                     W3C_XML_SCHEMA_INSTANCE,
+                "xsi:noNamespaceSchemaLocation", JEST_INSTANCE_XSD,
+                "version",                       "1.0",
+        };
+        for (int i = 0; i < nvpairs.length; i += 2) {
+            root.setAttribute(nvpairs[i], nvpairs[i+1]);
+        }
+    }
+    
+    /**
+     * Write the given XML document to the given file.
+     */
+    void writeDoc(Document doc, File file) throws Exception {
+        OutputStream out = new FileOutputStream(file);
+        TransformerFactory tfactory = TransformerFactory.newInstance();
+        Transformer serializer = tfactory.newTransformer();
+        serializer.setOutputProperty(OutputKeys.METHOD,     "xml");
+        serializer.setOutputProperty(OutputKeys.INDENT,     "yes");
+        serializer.setOutputProperty(OutputKeys.STANDALONE, "no");
+        serializer.setOutputProperty(OutputKeys.ENCODING,   "UTF-8");
+        serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+        serializer.transform(new DOMSource(doc), new StreamResult(out));
+    }
+    
+    /**
+     * Validate the XML in the given file. 
+     */
+    public void validateDoc(File file) {
+        try {
+            SchemaErrorDetector detector = new SchemaErrorDetector(file.getAbsolutePath()); 
+            InputStream is = new FileInputStream(file);
+            validatingParser.parse(is, detector);
+            assertTrue(detector.toString(), !detector.hasErrors());
+        } catch (SAXException e) {
+            e.printStackTrace();
+            fail();
+        } catch (IOException e) {
+            e.printStackTrace();
+            fail();
+        }
+    }
+
+    public void testRemoteAccessImplicitInActive() {
+         assertFalse(((EntityManagerFactoryImpl)_emf).allowsRemoteAccess());
+    }
+    
+    public void testRemoteAccessActiveByConfiguration() {
+        Map<String,Object> config = new HashMap<String, Object>();
+        config.put("openjpa.RemoteAccess", "true");
+        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jest", config);
+        assertTrue(((EntityManagerFactoryImpl)emf).allowsRemoteAccess());
+    }
+    
+    
+
+    public void testJSONEncoding() throws Exception {
+        long ssn = System.currentTimeMillis();
+        createObjectGraph(ssn);
+        
+        // Encoding happens within a transaction
+        EntityManager em = _emf.createEntityManager();
+        em.getTransaction().begin();
+        JObject p = em.find(JObject.class, ssn);
+        assertNotNull(p.getSpouse());
+        assertFalse(p.getFriends().isEmpty());
+        String json = encodeJSON(em, p);
+        em.getTransaction().rollback();
+        System.err.println(json);
+    }
+    
+    String encodeJSON(EntityManager em, Object obj) {
+        OpenJPAStateManager sm = ((StoreContext)JPAFacadeHelper.toBroker(em)).getStateManager(obj);
+        StringBuilder root = new JSONEncoder((MetamodelImpl)em.getMetamodel()).encode(sm);
+        return root.toString();
+     }
+    
+    /**
+     * Create and persist a connected object graph with circular reference. 
+     * @param ssn the id for the root object
+     */
+    void createObjectGraph(long ssn) {
+        EntityManager em = _emf.createEntityManager();
+        em.getTransaction().begin();
+        JObject p1 = new JObject(); p1.setAge(20); p1.setName("P1");  p1.setSsn(ssn);
+        JObject p2 = new JObject(); p2.setAge(20); p2.setName("P2");  p2.setSsn(ssn+1);
+        JObject p3 = new JObject(); p3.setAge(20); p3.setName("P3");  p3.setSsn(ssn+2);
+        em.persist(p1); em.persist(p2); em.persist(p3);
+        p1.setSpouse(p2); p2.setSpouse(p1);
+        p1.addFriend(p2); p1.addFriend(p3);
+        p2.addFriend(p1); 
+        p3.addFriend(p3);
+        em.getTransaction().commit();
+    }
+
+
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/TestObjectEncoding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/TestRequestParsing.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/TestRequestParsing.java?rev=1028146&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/TestRequestParsing.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/TestRequestParsing.java Thu Oct 28 00:36:36 2010
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.openjpa.persistence.jest;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests parsing of JEST requests.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class TestRequestParsing extends TestCase {
+    
+    public void testRequestFindImplicitParam() throws IOException {
+        GETRequest req = new GETRequest();
+        req.read(Arrays.asList("/find?Person;1234"));
+        
+        assertEquals("find", req.getAction());
+        assertTrue(req.hasParameter("Person"));
+        assertEquals(null, req.getParameter("Person"));
+        assertEquals("Person", req.getParameter(0).getKey());
+        assertEquals(null, req.getParameter(0).getValue());
+        assertTrue(req.hasParameter("1234"));
+        assertEquals(null, req.getParameter("1234"));
+        assertEquals("1234", req.getParameter(1).getKey());
+        assertEquals(null, req.getParameter(1).getValue());
+    }
+    
+    public void testRequestFindExplicitParam() throws IOException {
+        GETRequest req = new GETRequest();
+        req.read(Arrays.asList("/find?Person;ssn=1234"));
+        
+        assertEquals("find", req.getAction());
+        assertTrue(req.hasParameter("Person"));
+        assertEquals(null, req.getParameter("Person"));
+        assertEquals("Person", req.getParameter(0).getKey());
+        assertEquals(null, req.getParameter(0).getValue());
+        assertTrue(req.hasParameter("ssn"));
+        assertEquals("1234", req.getParameter("ssn"));
+        assertEquals("ssn", req.getParameter(1).getKey());
+        assertEquals("1234", req.getParameter(1).getValue());
+    }
+    
+    public void testRequestQueryWithParameters() throws IOException {
+        GETRequest req = new GETRequest();
+        req.read(Arrays.asList("/query?select p from Person p where p.name=:name;name=xyz;age=20"));
+        
+        assertEquals("query", req.getAction());
+        assertEquals("select p from Person p where p.name=:name", req.getParameter(0).getKey());
+        assertEquals(null, req.getParameter(0).getValue());
+        assertTrue(req.hasParameter("name"));
+        assertEquals("xyz", req.getParameter("name"));
+        assertEquals("name", req.getParameter(1).getKey());
+        assertEquals("xyz", req.getParameter(1).getValue());
+        assertTrue(req.hasParameter("age"));
+        assertEquals("20", req.getParameter("age"));
+        assertEquals("age", req.getParameter(2).getKey());
+        assertEquals("20", req.getParameter(2).getValue());
+    }
+    
+    public void testRequestQueryWithoutParameters() throws IOException {
+        GETRequest req = new GETRequest();
+        req.read(Arrays.asList("/query?select p from Person p where p.name='xyz'"));
+        
+        assertEquals("query", req.getAction());
+        assertEquals("select p from Person p where p.name='xyz'", req.getParameter(0).getKey());
+        assertEquals(null, req.getParameter(0).getValue());
+    }
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jest/TestRequestParsing.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml?rev=1028146&r1=1028145&r2=1028146&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml Thu Oct 28 00:36:36 2010
@@ -379,4 +379,13 @@
                 value="buildSchema"/>
         </properties>
     </persistence-unit>
+    
+    <persistence-unit name="jest">
+    	<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+        <class>org.apache.openjpa.persistence.jest.JObject</class>
+        <properties>
+        <property name="openjpa.Log" value="Tool=Trace,SQL=WARN,Remote=TRACE"/>
+        <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
+        </properties>
+    </persistence-unit>
 </persistence>