Introduce service servlet
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 8 Dec 2008 16:09:54 +0000 (16:09 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 8 Dec 2008 16:09:54 +0000 (16:09 +0000)
ASSIGNED - bug 71: Extend capabilities of web services
https://www.argeo.org/bugzilla/show_bug.cgi?id=71

git-svn-id: https://svn.argeo.org/slc/trunk@1959 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

org.argeo.slc.webapp/src/main/config/jetty/jetty-test.xml
org.argeo.slc.webapp/src/main/webapp/WEB-INF/slc-service-servlet.xml [new file with mode: 0644]
org.argeo.slc.webapp/src/main/webapp/WEB-INF/web.xml
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/AbstractServiceController.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/MarshallerView.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/MarshallerViewResolver.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/XsltMarshallerViewResolver.java
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/result/GetResultController.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/resources/org/argeo/slc/server/spring/slc-service-servlet.xml [new file with mode: 0644]
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/msg/ExecutionAnswer.java

index fda6c169271d0ceb0ca3d91970fc8f4d44feed11..a214a0140bf04d95c70bb2e8260e2caa0bd17003 100644 (file)
@@ -24,7 +24,7 @@
                        <New class="org.hsqldb.jdbc.jdbcDataSource">
                                <Set name="database">
                                        <Property name="jdbcUrl"
-                                               default="jdbc:hsqldb:mem:mainDs" />
+                                               default="jdbc:hsqldb:file:/home/mbaudier/dev/work/slcDbs/slcMainDs" />
                                </Set>
                                <Set name="user">sa</Set>
                                <Set name="password"></Set>
diff --git a/org.argeo.slc.webapp/src/main/webapp/WEB-INF/slc-service-servlet.xml b/org.argeo.slc.webapp/src/main/webapp/WEB-INF/slc-service-servlet.xml
new file mode 100644 (file)
index 0000000..11ae538
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+       <import
+               resource="classpath:/org/argeo/slc/server/spring/slc-service-servlet.xml" />
+</beans>
\ No newline at end of file
index 987fcf098d0a4f3d229537f5de11177e281a1456..55a5734493649f255a6a2f55f6eff63ab27644a4 100644 (file)
@@ -5,6 +5,17 @@
 
        <display-name>SLC Web Application</display-name>
 
+       <!-- SERVICE servlet -->
+       <servlet>
+               <servlet-name>slc-service</servlet-name>
+               <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+       </servlet>
+
+       <servlet-mapping>
+               <servlet-name>slc-service</servlet-name>
+               <url-pattern>*.service</url-pattern>
+       </servlet-mapping>
+
        <!-- WS servlet -->
        <servlet>
                <servlet-name>slc-ws</servlet-name>
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/AbstractServiceController.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/AbstractServiceController.java
new file mode 100644 (file)
index 0000000..3b10f0b
--- /dev/null
@@ -0,0 +1,59 @@
+package org.argeo.slc.web.mvc;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.argeo.slc.msg.ExecutionAnswer;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.AbstractController;
+
+public abstract class AbstractServiceController extends AbstractController {
+       public final static String KEY_ANSWER = "__answer";
+
+       private String viewName = null;
+
+       @Override
+       protected final ModelAndView handleRequestInternal(
+                       HttpServletRequest request, HttpServletResponse response)
+                       throws Exception {
+               ModelAndView mv = new ModelAndView();
+               mv.setViewName(getViewName());
+               try {
+                       handleServiceRequest(request, response, mv);
+               } catch (Exception e) {
+                       StringWriter writer = new StringWriter();
+                       e.printStackTrace(new PrintWriter(writer));
+                       ExecutionAnswer answer = ExecutionAnswer.error(writer.toString());
+                       ModelAndView errorMv = new ModelAndView();
+                       errorMv.addObject(KEY_ANSWER, answer);
+                       errorMv.setViewName(KEY_ANSWER);
+                       return errorMv;
+               }
+
+               if (mv.getModel().size() == 0) {
+                       mv.addObject(KEY_ANSWER, ExecutionAnswer
+                                       .ok("Execution completed properly"));
+               }
+
+               if (mv.getViewName() == null && mv.getModel().size() == 1)
+                       mv.setViewName(mv.getModel().keySet().iterator().next().toString());
+
+               return mv;
+       }
+
+       protected abstract void handleServiceRequest(HttpServletRequest request,
+                       HttpServletResponse response, ModelAndView modelAndView)
+                       throws Exception;
+
+       public void setViewName(String viewName) {
+               this.viewName = viewName;
+       }
+
+       public String getViewName() {
+               return viewName;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/MarshallerView.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/MarshallerView.java
new file mode 100644 (file)
index 0000000..61bafce
--- /dev/null
@@ -0,0 +1,52 @@
+package org.argeo.slc.web.mvc;
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.transform.stream.StreamResult;
+
+import org.argeo.slc.SlcException;
+import org.springframework.oxm.Marshaller;
+import org.springframework.web.servlet.view.AbstractView;
+
+/** Marshal one of the object of the map to the output. */
+public class MarshallerView extends AbstractView {
+       private String modelKey = null;
+       private final Marshaller marshaller;
+
+       public MarshallerView(Marshaller marshaller) {
+               this.marshaller = marshaller;
+       }
+
+       public MarshallerView(Marshaller marshaller, String modelKey) {
+               this(marshaller);
+               this.modelKey = modelKey;
+       }
+
+       @Override
+       protected void renderMergedOutputModel(Map model,
+                       HttpServletRequest request, HttpServletResponse response)
+                       throws Exception {
+               final Object answer;
+               if (modelKey != null) {
+                       if (!model.containsKey(modelKey))
+                               throw new SlcException("Key " + modelKey
+                                               + " not found in model.");
+                       answer = model.get(modelKey);
+               } else {
+                       if (model.size() != 1)
+                               throw new SlcException(
+                                               "Model has a size different from 1. Specify a modelKey.");
+                       answer = model.values().iterator().next();
+               }
+
+               StreamResult streamResult = new StreamResult(response.getOutputStream());
+               marshaller.marshal(answer, streamResult);
+       }
+
+       public void setModelKey(String modelKey) {
+               this.modelKey = modelKey;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/MarshallerViewResolver.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/MarshallerViewResolver.java
new file mode 100644 (file)
index 0000000..52ff190
--- /dev/null
@@ -0,0 +1,32 @@
+package org.argeo.slc.web.mvc;
+
+import java.util.Locale;
+
+import org.springframework.oxm.Marshaller;
+import org.springframework.web.servlet.View;
+import org.springframework.web.servlet.view.AbstractCachingViewResolver;
+
+/**
+ * Returns a MarshallerView based on the underlying marshaller. View name is the
+ * model key of the marshaller view.
+ */
+public class MarshallerViewResolver extends AbstractCachingViewResolver {
+       private final Marshaller marshaller;
+
+       public MarshallerViewResolver(Marshaller marshaller) {
+               super();
+               this.marshaller = marshaller;
+       }
+
+       /**
+        * Caches a marshaller view.
+        * 
+        * @param viewName
+        *            van be null, default marshaller view behavior is then used
+        */
+       @Override
+       protected View loadView(String viewName, Locale locale) throws Exception {
+               return new MarshallerView(marshaller, viewName);
+       }
+
+}
index f8b89aa036219c8b918fe40d46bbf7bcffeedb43..b28a39ca690eb375bbd81528784e771aed6f9086 100644 (file)
@@ -17,6 +17,12 @@ import org.springframework.oxm.Marshaller;
 import org.springframework.web.servlet.view.AbstractUrlBasedView;\r
 import org.springframework.web.servlet.view.xslt.XsltViewResolver;\r
 \r
+/**\r
+ * Xslt View resolver implementing URI resolver as well.\r
+ * \r
+ * @see URIResolver\r
+ * @see XsltViewResolver\r
+ */\r
 public class XsltMarshallerViewResolver extends XsltViewResolver implements\r
                URIResolver {\r
        private final static Log log = LogFactory\r
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/result/GetResultController.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/result/GetResultController.java
new file mode 100644 (file)
index 0000000..4fef228
--- /dev/null
@@ -0,0 +1,32 @@
+package org.argeo.slc.web.mvc.result;\r
+\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.servlet.http.HttpServletResponse;\r
+\r
+import org.argeo.slc.core.test.tree.TreeTestResult;\r
+import org.argeo.slc.dao.test.tree.TreeTestResultDao;\r
+import org.argeo.slc.web.mvc.AbstractServiceController;\r
+import org.springframework.web.servlet.ModelAndView;\r
+\r
+/** Returns one single result. */\r
+public class GetResultController extends AbstractServiceController {\r
+       public final static String MODELKEY_RESULT = "result";\r
+\r
+       private final TreeTestResultDao testResultDao;\r
+\r
+       public GetResultController(TreeTestResultDao testResultDao) {\r
+               this.testResultDao = testResultDao;\r
+       }\r
+\r
+       @Override\r
+       protected void handleServiceRequest(HttpServletRequest request,\r
+                       HttpServletResponse response, ModelAndView modelAndView)\r
+                       throws Exception {\r
+\r
+               String uuid = request.getParameter("uuid");\r
+               TreeTestResult result = testResultDao.getTestResult(uuid);\r
+\r
+               modelAndView.addObject(MODELKEY_RESULT, result);\r
+       }\r
+\r
+}\r
diff --git a/runtime/org.argeo.slc.server/src/main/resources/org/argeo/slc/server/spring/slc-service-servlet.xml b/runtime/org.argeo.slc.server/src/main/resources/org/argeo/slc/server/spring/slc-service-servlet.xml
new file mode 100644 (file)
index 0000000..0e30401
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+       <import resource="classpath:/org/argeo/slc/castor/spring/applicationContext.xml" />
+
+       <bean name="/resultList.service" class="org.argeo.slc.web.mvc.result.ResultListController">
+               <constructor-arg ref="testResultDao" />
+               <property name="viewName" value="resultList" />
+       </bean>
+
+       <bean name="/getResult.service" class="org.argeo.slc.web.mvc.result.GetResultController">
+               <constructor-arg ref="testResultDao" />
+       </bean>
+
+       <bean name="/resultCollectionList.service"
+               class="org.argeo.slc.web.mvc.result.ResultCollectionListController">
+               <constructor-arg ref="testResultCollectionDao" />
+               <property name="viewName" value="resultCollectionList" />
+       </bean>
+
+       <bean name="/resultCollectionView.service"
+               class="org.argeo.slc.web.mvc.result.ResultCollectionViewController">
+               <constructor-arg ref="testResultCollectionDao" />
+               <property name="viewName" value="resultCollectionView" />
+       </bean>
+
+       <bean name="/addResultToCollection.service"
+               class="org.argeo.slc.web.mvc.result.AddResultToCollectionController">
+               <constructor-arg ref="testManagerService" />
+               <property name="viewName" value="addResultToCollectionS" />
+       </bean>
+
+       <bean name="/removeResultFromCollection.service"
+               class="org.argeo.slc.web.mvc.result.RemoveResultFromCollectionController">
+               <constructor-arg ref="testManagerService" />
+               <property name="viewName" value="removeResultFromCollectionS" />
+       </bean>
+
+       <bean id="handlerMapping"
+               class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
+               <property name="interceptors">
+                       <list>
+                               <ref bean="osivInterceptor" />
+                       </list>
+               </property>
+       </bean>
+
+       <bean id="viewResolver" class="org.argeo.slc.web.mvc.MarshallerViewResolver">
+               <constructor-arg ref="slcDefault.castor.marshaller" />
+       </bean>
+
+
+</beans>
\ No newline at end of file
index 4a036ccfeedbcbffb1ac430af301ffe5be1f5a90..e113f98bb65a95d012b87791c59d019649384b56 100644 (file)
@@ -40,4 +40,12 @@ public class ExecutionAnswer {
                this.message = message;
        }
 
+       public static ExecutionAnswer error(String message) {
+               return new ExecutionAnswer(ERROR, message);
+       }
+
+       public static ExecutionAnswer ok(String message) {
+               return new ExecutionAnswer(OK, message);
+       }
+
 }