[infinispan-commits] Infinispan SVN: r829 - in trunk/server/rest: src/main/scala/org/infinispan/rest and 1 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Thu Sep 17 03:40:24 EDT 2009


Author: michael.neale at jboss.com
Date: 2009-09-17 03:40:24 -0400 (Thu, 17 Sep 2009)
New Revision: 829

Modified:
   trunk/server/rest/pom.xml
   trunk/server/rest/src/main/scala/org/infinispan/rest/Server.scala
   trunk/server/rest/src/test/scala/org/infinispan/rest/IntegrationTest.scala
Log:
added content conversion

Modified: trunk/server/rest/pom.xml
===================================================================
--- trunk/server/rest/pom.xml	2009-09-17 01:58:44 UTC (rev 828)
+++ trunk/server/rest/pom.xml	2009-09-17 07:40:24 UTC (rev 829)
@@ -95,13 +95,24 @@
 		</dependency>
 
         <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <version>0.9.9-6</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.thoughtworks.xstream</groupId>
+            <artifactId>xstream</artifactId>
+            <version>1.3.1</version>
+        </dependency>
+
+        <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>servlet-api</artifactId>
             <version>2.5</version>
             <scope>provided</scope>
         </dependency>
 
-
         <!-- and now for unit and integration tests -->
         <dependency>
 			<groupId>org.mortbay.jetty</groupId>

Modified: trunk/server/rest/src/main/scala/org/infinispan/rest/Server.scala
===================================================================
--- trunk/server/rest/src/main/scala/org/infinispan/rest/Server.scala	2009-09-17 01:58:44 UTC (rev 828)
+++ trunk/server/rest/src/main/scala/org/infinispan/rest/Server.scala	2009-09-17 07:40:24 UTC (rev 829)
@@ -1,6 +1,8 @@
 package org.infinispan.rest
 
-import java.io.{OutputStream, ObjectOutputStream, Serializable}
+import codehaus.jackson.map.ObjectMapper
+import com.thoughtworks.xstream.XStream
+import java.io._
 import remoting.MIMECacheEntry
 import java.util.concurrent.TimeUnit
 import javax.ws.rs._
@@ -22,17 +24,30 @@
           }
         }
         case s: String => Response.ok(s, "text/plain").build
-        case ser: Serializable => {
-           Response.ok.`type`("application/x-java-serialized-object").entity(new StreamingOutput {
-             def write(out: OutputStream) = {
-               new ObjectOutputStream(out).writeObject(ser)
-             }
-           }).build
+        case obj: Any => {
+           val variant = request.selectVariant(variantList)
+           val selectedMediaType =  if (variant != null) variant.getMediaType.toString else "application/x-java-serialized-object"
+           selectedMediaType match {
+             case MediaType.APPLICATION_JSON =>  Response.ok.`type`(selectedMediaType).entity(streamIt(jsonMapper.writeValue(_, obj))).build
+             case MediaType.APPLICATION_XML => Response.ok.`type`(selectedMediaType).entity(streamIt(xstream.toXML(obj, _))).build
+             case _ =>
+               obj match {
+                 case ser: Serializable =>
+                  Response.ok.`type`("application/x-java-serialized-object").entity(streamIt(new ObjectOutputStream(_).writeObject(ser))).build
+                 case _ => Response.notAcceptable(variantList).build
+               }
+
+           }
         }
         case null => Response status(Status.NOT_FOUND) build
       }
   }
 
+  /** create a JAX-RS streaming output */
+  def streamIt(action: (OutputStream) => Unit) = new StreamingOutput { def write(o: OutputStream) = {action(o)}}
+
+
+
   @HEAD
   @Path("/{cacheName}/{cacheKey}")
   def headEntry(@PathParam("cacheName") cacheName: String, @PathParam("cacheKey") key: String) = {
@@ -60,20 +75,22 @@
             if (request.getMethod == "POST" && cache.containsKey(key)) {
                 Response.status(Status.CONFLICT).build()
             } else {
+              val obj = if (mediaType == "application/x-java-serialized-object")
+                new ObjectInputStream(new ByteArrayInputStream(data)).readObject
+                else new MIMECacheEntry(mediaType, data)
               (ttl, idleTime, useAsync) match {
-                //todo, check if it is serialized object, and put it as such...
-                case (0, 0, false) => cache.put(key, new MIMECacheEntry(mediaType, data))
-                case (x, 0, false) => cache.put(key, new MIMECacheEntry(mediaType, data), ttl, TimeUnit.SECONDS)
-                case (x, y, false) => cache.put(key, new MIMECacheEntry(mediaType, data), ttl, TimeUnit.SECONDS, idleTime, TimeUnit.SECONDS)
-                case (0, 0, true) => cache.putAsync(key, new MIMECacheEntry(mediaType, data))
-                case (x, 0, true) => cache.putAsync(key, new MIMECacheEntry(mediaType, data), ttl, TimeUnit.SECONDS)
-                case (x, y, true) => cache.putAsync(key, new MIMECacheEntry(mediaType, data), ttl, TimeUnit.SECONDS, idleTime, TimeUnit.SECONDS)
+                case (0, 0, false) => cache.put(key, obj)
+                case (x, 0, false) => cache.put(key, obj, ttl, TimeUnit.SECONDS)
+                case (x, y, false) => cache.put(key, obj, ttl, TimeUnit.SECONDS, idleTime, TimeUnit.SECONDS)
+                case (0, 0, true) => cache.putAsync(key, obj)
+                case (x, 0, true) => cache.putAsync(key, obj, ttl, TimeUnit.SECONDS)
+                case (x, y, true) => cache.putAsync(key, obj, ttl, TimeUnit.SECONDS, idleTime, TimeUnit.SECONDS)
               }
               Response.ok.build
             }
-
   }
 
+
   @DELETE
   @Path("/{cacheName}/{cacheKey}")
   def removeEntry(@PathParam("cacheName") cacheName: String, @PathParam("cacheKey") key: String) = {
@@ -95,6 +112,12 @@
 
   }
 
+
+  /** For dealing with binary entries in the cache */
+  lazy val variantList = Variant.VariantListBuilder.newInstance.mediaTypes(MediaType.APPLICATION_XML_TYPE, MediaType.APPLICATION_JSON_TYPE).build
+  lazy val jsonMapper = new ObjectMapper
+  lazy val xstream = new XStream
+
 }
 
 /**

Modified: trunk/server/rest/src/test/scala/org/infinispan/rest/IntegrationTest.scala
===================================================================
--- trunk/server/rest/src/test/scala/org/infinispan/rest/IntegrationTest.scala	2009-09-17 01:58:44 UTC (rev 828)
+++ trunk/server/rest/src/test/scala/org/infinispan/rest/IntegrationTest.scala	2009-09-17 07:40:24 UTC (rev 829)
@@ -214,41 +214,79 @@
     obj.name = "mic"
     ManagerInstance getCache("wang") put("wangKey", obj)
     ManagerInstance getCache("wang") put("wangKey2", "hola")
+    ManagerInstance getCache("wang") put("wangKey3", new MyNonSer)
 
-    val get = Client.call(new GetMethod(HOST + "rest/wang/wangKey"))
+
+    //check we can get it back as an object...
+    val get = new GetMethod(HOST + "rest/wang/wangKey");
+    get.setRequestHeader("Accept", "application/x-java-serialized-object")
+    Client.call(get)
     assertEquals(HttpServletResponse.SC_OK, get.getStatusCode)
     val in = new ObjectInputStream(get.getResponseBodyAsStream)
     val res = in.readObject.asInstanceOf[MySer]
     assertNotNull(res)
     assertEquals("mic", res.name)
     assertEquals("application/x-java-serialized-object", get.getResponseHeader("Content-Type").getValue)
-//    assertEquals("application/text", get.getResponseHeader("Content-Type").getValue)
-    //assertEquals("this is a thing with a thing", get.getResponseBodyAsString)
 
-
     val getStr = Client.call(new GetMethod(HOST + "rest/wang/wangKey2"))
     assertEquals("hola", getStr.getResponseBodyAsString)
     assertEquals("text/plain", getStr.getResponseHeader("Content-Type").getValue)
-    
-  }
 
 
+    //now check we can get it back as JSON if we want...
+    get.setRequestHeader("Accept", "application/json")
+    Client.call(get)
+    assertEquals("""{"name":"mic"}""", get.getResponseBodyAsString)
+    assertEquals("application/json", get.getResponseHeader("Content-Type").getValue)
 
 
+    //and why not XML
+    get.setRequestHeader("Accept", "application/xml")
+    Client.call(get)
+    assertEquals("application/xml", get.getResponseHeader("Content-Type").getValue)
+    assertTrue(get.getResponseBodyAsString.indexOf("<org.infinispan.rest.MySer>") > -1)
 
+    //now check we can get it back as JSON if we want...
+    val get3 = new GetMethod(HOST + "rest/wang/wangKey3")
+    get3.setRequestHeader("Accept", "application/json")
+    Client.call(get3)
+    assertEquals("""{"name":"mic"}""", get3.getResponseBodyAsString)
+    assertEquals("application/json", get3.getResponseHeader("Content-Type").getValue)
 
 
+    get3.setRequestHeader("Accept", "*/*")
+    Client.call(get3)
+    assertEquals(HttpServletResponse.SC_NOT_ACCEPTABLE, get3.getStatusCode)
 
+  }
 
 
+  @Test def insertSerializableObjects = {
+    val put = new PutMethod(HOST + "rest/posteee/something")
+    put.setRequestHeader("Content-Type", "application/x-java-serialized-object")
+    val bout = new ByteArrayOutputStream
+    new ObjectOutputStream(bout).writeObject(new MySer)
+    put.setRequestBody(new ByteArrayInputStream(bout.toByteArray))
+    Client.call(put)
 
+    val x = ManagerInstance.getCache("posteee").get("something").asInstanceOf[MySer]
+    assertTrue(x.name == "mic")
 
+  }
 
 
 }
 
 
+class MyNonSer {
+  var name: String = "mic"
+  def getName = name
+  def setName(s: String) = {name = s}
+}
 
-   class MySer extends Serializable {
-      var name: String = "mic"
-   }
\ No newline at end of file
+class MySer extends Serializable {
+    var name: String = "mic"
+    /** These are needed for Jackson to Do Its Thing */
+    def getName = name
+    def setName(s: String) = {name = s}
+}
\ No newline at end of file



More information about the infinispan-commits mailing list