further harmonization of pager parameters
authorAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Tue, 18 Jun 2013 11:03:00 +0000 (11:03 +0000)
committerAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Tue, 18 Jun 2013 11:03:00 +0000 (11:03 +0000)
cdmlib-remote/src/main/java/eu/etaxonomy/cdm/remote/controller/AbstractController.java
cdmlib-remote/src/main/java/eu/etaxonomy/cdm/remote/controller/BaseController.java
cdmlib-remote/src/main/java/eu/etaxonomy/cdm/remote/controller/BaseListController.java
cdmlib-remote/src/main/java/eu/etaxonomy/cdm/remote/controller/util/PagerParameters.java

index e384a3082effdf3e394bcb8c2bea2218459ea8fe..e8c1860e93e0209b48b5a7a5b4edbf408939053a 100644 (file)
@@ -18,6 +18,7 @@ import org.apache.log4j.Logger;
 \r
 import eu.etaxonomy.cdm.api.service.IService;\r
 import eu.etaxonomy.cdm.model.common.CdmBase;\r
+import eu.etaxonomy.cdm.remote.controller.util.PagerParameters;\r
 \r
 /**\r
  * @author a.kohlbecker\r
@@ -38,7 +39,7 @@ public abstract class AbstractController<T extends CdmBase, SERVICE extends ISer
 \r
     public abstract void setService(SERVICE service);\r
 \r
-    protected static final Integer DEFAULT_PAGE_SIZE = 30;\r
+    protected static final Integer DEFAULT_PAGE_SIZE = PagerParameters.DEFAULT_PAGESIZE;\r
 \r
     /**\r
      * Default thread priority for long term processes which are running in\r
index 5a4e6c3f152ca6494bc29c1a972b1b800904ce67..24ac3b28e50c33697782885ef29554eda00fe4f9 100644 (file)
@@ -1,9 +1,9 @@
 // $Id$\r
 /**\r
 * Copyright (C) 2007 EDIT\r
-* European Distributed Institute of Taxonomy \r
+* European Distributed Institute of Taxonomy\r
 * http://www.e-taxonomy.eu\r
-* \r
+*\r
 * The contents of this file are subject to the Mozilla Public License Version 1.1\r
 * See LICENSE.TXT at the top of this package for the full license terms.\r
 */\r
@@ -29,7 +29,6 @@ import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.commons.io.FilenameUtils;\r
 import org.apache.commons.lang.StringUtils;\r
 import org.hibernate.mapping.Map;\r
-import org.springframework.beans.factory.annotation.Autowired;\r
 import org.springframework.web.bind.WebDataBinder;\r
 import org.springframework.web.bind.annotation.InitBinder;\r
 import org.springframework.web.bind.annotation.PathVariable;\r
@@ -44,6 +43,7 @@ import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;\r
 import eu.etaxonomy.cdm.model.common.CdmBase;\r
 import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;\r
+import eu.etaxonomy.cdm.remote.controller.util.PagerParameters;\r
 import eu.etaxonomy.cdm.remote.editor.UUIDPropertyEditor;\r
 \r
 /**\r
@@ -58,356 +58,359 @@ import eu.etaxonomy.cdm.remote.editor.UUIDPropertyEditor;
 public abstract class BaseController<T extends CdmBase, SERVICE extends IService<T>> extends AbstractController<T, SERVICE> {\r
 \r
 /*     protected SERVICE service;\r
-       \r
-       public abstract void setService(SERVICE service);*/\r
-       \r
-       protected Class<T> baseClass;\r
-       \r
-       public BaseController (){\r
-               \r
-               Type superClass = this.getClass().getGenericSuperclass();\r
-               if(superClass instanceof ParameterizedType){\r
-                       ParameterizedType parametrizedSuperClass = (ParameterizedType) superClass;\r
-                       Type[] typeArguments = parametrizedSuperClass.getActualTypeArguments();\r
-                       \r
-                       if(typeArguments.length > 1 && typeArguments[0] instanceof Class<?>){\r
-                               baseClass = (Class<T>) typeArguments[0];\r
-                       } else {\r
-                               logger.error("unable to find baseClass");\r
-                       }\r
-               }\r
-       }\r
-\r
-       @InitBinder\r
+\r
+    public abstract void setService(SERVICE service);*/\r
+\r
+    protected Class<T> baseClass;\r
+\r
+    public BaseController (){\r
+\r
+        Type superClass = this.getClass().getGenericSuperclass();\r
+        if(superClass instanceof ParameterizedType){\r
+            ParameterizedType parametrizedSuperClass = (ParameterizedType) superClass;\r
+            Type[] typeArguments = parametrizedSuperClass.getActualTypeArguments();\r
+\r
+            if(typeArguments.length > 1 && typeArguments[0] instanceof Class<?>){\r
+                baseClass = (Class<T>) typeArguments[0];\r
+            } else {\r
+                logger.error("unable to find baseClass");\r
+            }\r
+        }\r
+    }\r
+\r
+    @InitBinder\r
     public void initBinder(WebDataBinder binder) {\r
-               binder.registerCustomEditor(UUID.class, new UUIDPropertyEditor());\r
-       }\r
-       \r
-       //TODO implement bulk version of this method\r
-       @RequestMapping(method = RequestMethod.GET)\r
-       public T doGet(@PathVariable("uuid") UUID uuid,\r
-                               HttpServletRequest request, \r
-                               HttpServletResponse response) throws IOException {\r
-               if(request != null)\r
-                       logger.info("doGet() " + request.getRequestURI());\r
-               T obj = (T) getCdmBaseInstance(uuid, response, initializationStrategy);\r
-               return obj;\r
-       }\r
-       \r
-       /**\r
-        * @param uuid\r
-        * @param request\r
-        * @param response\r
-        * @return\r
-        * @throws IOException\r
-        * \r
-        * TODO implement bulk version of this method\r
-        */\r
-       @RequestMapping(value = "*", method = RequestMethod.GET)\r
-       public ModelAndView doGetMethod(\r
-                       @PathVariable("uuid") UUID uuid,\r
-                       // doPage request parametes\r
-                       @RequestParam(value = "pageNumber", required = false) Integer pageNumber,\r
-                       @RequestParam(value = "pageSize", required = false) Integer pageSize,\r
-                       // doList request parametes\r
-                       @RequestParam(value = "start", required = false) Integer start,\r
-                       @RequestParam(value = "limit", required = false) Integer limit,\r
-                       HttpServletRequest request,\r
-                       HttpServletResponse response) throws IOException {\r
-               \r
-               ModelAndView modelAndView = new ModelAndView();\r
-               \r
-               String servletPath = request.getServletPath();\r
-               String baseName = FilenameUtils.getBaseName(servletPath);\r
-               \r
-               if(request != null)\r
-                       logger.info("doGetMethod()[doGet" + StringUtils.capitalize(baseName) + "] " + request.getRequestURI());\r
-               \r
-               // <CUT\r
+        binder.registerCustomEditor(UUID.class, new UUIDPropertyEditor());\r
+    }\r
+\r
+    //TODO implement bulk version of this method\r
+    @RequestMapping(method = RequestMethod.GET)\r
+    public T doGet(@PathVariable("uuid") UUID uuid,\r
+                HttpServletRequest request,\r
+                HttpServletResponse response) throws IOException {\r
+        if(request != null) {\r
+            logger.info("doGet() " + request.getRequestURI());\r
+        }\r
+        T obj = getCdmBaseInstance(uuid, response, initializationStrategy);\r
+        return obj;\r
+    }\r
+\r
+    /**\r
+     * @param uuid\r
+     * @param request\r
+     * @param response\r
+     * @return\r
+     * @throws IOException\r
+     *\r
+     * TODO implement bulk version of this method\r
+     */\r
+    @RequestMapping(value = "*", method = RequestMethod.GET)\r
+    public ModelAndView doGetMethod(\r
+            @PathVariable("uuid") UUID uuid,\r
+            // doPage request parametes\r
+            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,\r
+            @RequestParam(value = "pageSize", required = false) Integer pageSize,\r
+            // doList request parametes\r
+            @RequestParam(value = "start", required = false) Integer start,\r
+            @RequestParam(value = "limit", required = false) Integer limit,\r
+            HttpServletRequest request,\r
+            HttpServletResponse response) throws IOException {\r
+\r
+        ModelAndView modelAndView = new ModelAndView();\r
+\r
+        String servletPath = request.getServletPath();\r
+        String baseName = FilenameUtils.getBaseName(servletPath);\r
+\r
+        if(request != null) {\r
+            logger.info("doGetMethod()[doGet" + StringUtils.capitalize(baseName) + "] " + request.getRequestURI());\r
+        }\r
+\r
+        // <CUT\r
 //             T instance = getCdmBaseInstance(uuid, response, (List<String>)null);\r
-               \r
-               //Class<?> propertyClass = propertyClass(instance, baseName);\r
-               \r
-               Object objectFromProperty = getCdmBaseProperty(uuid, baseName, response);//   invokeProperty(instance, baseName, response);\r
-               \r
-               // CUT>\r
-               \r
-               if(objectFromProperty != null){\r
-\r
-                       if( Collection.class.isAssignableFrom(objectFromProperty.getClass())){\r
-                               // Map types cannot be returned as list or in a pager!\r
-                               \r
-                               Collection c = (Collection)objectFromProperty;\r
-                               if(start != null){\r
-                                       // return list\r
-                                       limit = (limit == null ? DEFAULT_PAGE_SIZE : limit);\r
-                                       Collection sub_c = subCollection(c, start, limit);\r
-                                       modelAndView.addObject(sub_c);\r
-                                       \r
-                               } else {\r
-                                       //FIXME use real paging mechanism of according service class instead of subCollection()\r
-                                       //FIXME use BaseListController.normalizeAndValidatePagerParameters(pageNumber, pageSize, response);\r
-                                       pageSize = (pageSize == null ? DEFAULT_PAGE_SIZE : pageSize);\r
-                                       pageNumber = (pageNumber == null ? 0 : pageNumber);\r
-                                       start = pageNumber * pageSize;\r
-                                       List sub_c = subCollection(c, start, pageSize);\r
-                                       Pager p = new DefaultPagerImpl(pageNumber, c.size(), pageSize, sub_c);\r
-                                       modelAndView.addObject(p);\r
-                               }\r
-                               \r
-                       } else {\r
-                               modelAndView.addObject(objectFromProperty);                                                                                             \r
-                       }\r
-\r
-               }\r
-\r
-               if(modelAndView.isEmpty()){\r
-                       return null;    \r
-               } else {\r
-                       \r
-                       return modelAndView;\r
-               }\r
-       }\r
-\r
-       public Object getCdmBaseProperty(UUID uuid, String property, HttpServletResponse response) throws IOException{\r
-               \r
-               T instance = (T) HibernateProxyHelper.deproxy(getCdmBaseInstance(uuid, response, property));\r
-               \r
-               Object objectFromProperty = invokeProperty(instance, property, response);\r
-               \r
-               return objectFromProperty;\r
-       }\r
-       \r
-       private Class<?> propertyClass(T instance, String baseName) {\r
-               PropertyDescriptor propertyDescriptor = null;\r
-               Class<?> c = null;\r
-               try {\r
-                       propertyDescriptor = PropertyUtils.getPropertyDescriptor(instance, baseName);\r
-                       if(propertyDescriptor != null){\r
-                               c =  propertyDescriptor.getClass(); \r
-                       }\r
-               } catch (IllegalAccessException e) {\r
-                       // TODO Auto-generated catch block\r
-                       e.printStackTrace();\r
-               } catch (InvocationTargetException e) {\r
-                       // TODO Auto-generated catch block\r
-                       e.printStackTrace();\r
-               } catch (NoSuchMethodException e) {\r
-                       // TODO Auto-generated catch block\r
-                       e.printStackTrace();\r
-               }\r
-               return c;\r
-       }\r
-\r
-       /**\r
-        * @param <SUB_T>\r
-        * @param clazz\r
-        * @param uuid\r
-        * @param response\r
-        * @param pathProperties\r
-        * @return\r
-        * @throws IOException\r
-        */\r
-       @SuppressWarnings("unchecked")\r
-       protected final <SUB_T extends T> SUB_T getCdmBaseInstance(Class<SUB_T> clazz, UUID uuid, HttpServletResponse response, List<String> pathProperties)\r
-       throws IOException {\r
-\r
-               CdmBase cdmBaseObject = getCdmBaseInstance(uuid, response, pathProperties);\r
-               if(!clazz.isAssignableFrom(cdmBaseObject.getClass())){\r
-                       HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);\r
-               }\r
-               return (SUB_T) cdmBaseObject;\r
-       }\r
-       \r
-       /**\r
-        * @param <SUB_T>\r
-        * @param clazz\r
-        * @param uuid\r
-        * @param response\r
-        * @param pathProperty\r
-        * @return\r
-        * @throws IOException\r
-        */\r
-       @SuppressWarnings("unchecked")\r
-       protected final <SUB_T extends T> SUB_T getCdmBaseInstance(Class<SUB_T> clazz, UUID uuid, HttpServletResponse response, String pathProperty)\r
-       throws IOException {\r
-               \r
-               CdmBase cdmBaseObject = getCdmBaseInstance(uuid, response, pathProperty);\r
-               if(!clazz.isAssignableFrom(cdmBaseObject.getClass())){\r
-                       HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);\r
-               }\r
-               return (SUB_T) cdmBaseObject;\r
-       }\r
-       \r
-       /**\r
-        * @param uuid\r
-        * @param response\r
-        * @param pathProperty\r
-        * @return\r
-        * @throws IOException\r
-        */\r
-       protected final T getCdmBaseInstance(UUID uuid, HttpServletResponse response, String pathProperty)\r
-                       throws IOException {\r
-               return getCdmBaseInstance(baseClass, uuid, response, Arrays\r
-                               .asList(new String[] { pathProperty }));\r
-       }\r
-       \r
-       \r
-       /**\r
-        * @param uuid\r
-        * @param response\r
-        * @param pathProperties\r
-        * @return\r
-        * @throws IOException\r
-        */\r
-       protected final T getCdmBaseInstance(UUID uuid, HttpServletResponse response, List<String> pathProperties)\r
-                       throws IOException {\r
-               return getCdmBaseInstance(baseClass, service, uuid, response, pathProperties);\r
-       }\r
-\r
-       /**\r
-        * @param <CDM_BASE>\r
-        * @param clazz\r
-        * @param service\r
-        * @param uuid\r
-        * @param response\r
-        * @param pathProperties\r
-        * @return\r
-        * @throws IOException\r
-        */\r
-       protected final <CDM_BASE extends CdmBase> CDM_BASE getCdmBaseInstance(Class<CDM_BASE> clazz, IService<CDM_BASE> service, UUID uuid, HttpServletResponse response, List<String> pathProperties)\r
-       throws IOException {\r
-       \r
-               CDM_BASE cdmBaseObject = service.load(uuid, pathProperties);\r
-               if (cdmBaseObject == null) {\r
-                       HttpStatusMessage.UUID_NOT_FOUND.send(response);\r
-               }\r
-               return cdmBaseObject;\r
-               }\r
-\r
-       /**\r
-        * @param instance\r
-        * @param baseName\r
-        * @param response\r
-        * @return\r
-        * @throws IOException\r
-        */\r
-       private final Object invokeProperty(T instance,\r
-                       String baseName, HttpServletResponse response) throws IOException {\r
-               \r
-               Object result = null; \r
-               try {\r
-                       PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(instance, baseName);\r
-                       if(propertyDescriptor == null){\r
-                               throw new NoSuchMethodException("No such method: " + instance.getClass().getSimpleName() + ".get" + baseName);\r
-                       }\r
-                       Method method = propertyDescriptor.getReadMethod();\r
-                       \r
-                       Class<?> returnType = method.getReturnType();\r
-                       \r
-                       if(CdmBase.class.isAssignableFrom(returnType) \r
-                                       || Collection.class.isAssignableFrom(returnType) \r
-                                       || Map.class.isAssignableFrom(returnType)\r
-                                       || INomenclaturalReference.class.isAssignableFrom(returnType)){\r
-                               \r
-                               result = method.invoke(instance, (Object[])null);\r
-                               \r
-                               result = HibernateProxyHelper.deproxy(result);\r
-                               \r
-                       }else{\r
-                               HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);\r
-                       }\r
-               } catch (SecurityException e) {\r
-                       logger.error("SecurityException: ", e);\r
-                       HttpStatusMessage.INTERNAL_ERROR.send(response);\r
-               } catch (NoSuchMethodException e) {\r
-                       HttpStatusMessage.PROPERTY_NOT_FOUND.send(response);\r
-               } catch (IllegalArgumentException e) {\r
-                       HttpStatusMessage.PROPERTY_NOT_FOUND.send(response);\r
-               } catch (IllegalAccessException e) {\r
-                       HttpStatusMessage.PROPERTY_NOT_FOUND.send(response);\r
-               } catch (InvocationTargetException e) {\r
-                       HttpStatusMessage.PROPERTY_NOT_FOUND.send(response);\r
-               }\r
-               return result;\r
-       }\r
-       \r
-       private <E> List<E> subCollection(Collection<? extends E> c, Integer start, Integer length){\r
-               List<E> sub_c = new ArrayList<E>(length);\r
-               if(c.size() > length){\r
-                       E[] a = (E[]) c.toArray();\r
-                       for(int i = start; i < start + length; i++){\r
-                               sub_c.add(a[i]);\r
-                       }\r
-               } else {\r
-                       sub_c.addAll(c);\r
-               }\r
-               return sub_c;\r
-               \r
-       }\r
-       \r
-       \r
-         /* TODO implement\r
-          \r
-         private Validator validator;\r
-         \r
-         private javax.validation.Validator javaxValidator;\r
-       \r
-         @RequestMapping(method = RequestMethod.PUT, headers="content-type=multipart/form-data")\r
-         public T doPutForm(@PathVariable(value = "uuid") UUID uuid, @ModelAttribute("object") T object, BindingResult result) {\r
-                 object.setUuid(uuid);\r
-             validator.validate(object, result);\r
-             if (result.hasErrors()) {\r
-               throw new Error();\r
-                   // set http status code depending upon what happened, possibly return\r
-                   // the put object and errors so that they can be rendered into a suitable error response\r
-             } else {\r
-                // requires merging detached object ?gilead?\r
-                service.save(object);\r
-             }\r
-               \r
-               return object;\r
-         }\r
-         \r
-         @RequestMapping(method = RequestMethod.PUT, headers="content-type=text/json")\r
-         public T doPutJSON(@PathVariable(value = "uuid") UUID uuid, @RequestBody String jsonMessage) {\r
-                 JSONObject jsonObject = JSONObject.fromObject(jsonMessage);\r
-                 T object = (T)JSONObject.toBean(jsonObject, this.getClass());\r
-                 \r
-\r
-                 Set<ConstraintViolation<T>> constraintViolations = javaxValidator.validate(object);\r
-               if (!constraintViolations.isEmpty()) {\r
-                       throw new Error();\r
-                       // set http status code depending upon what happened, possibly return\r
-                   // the put object and errors so that they can be rendered into a suitable error response\r
-               } else {\r
-                 // requires merging detached object ?gilead?\r
-                 service.save(object);\r
-               }\r
-               \r
-               return object;\r
-         }\r
-\r
-         @RequestMapping(method = RequestMethod.PUT) // the cdm-server may not allow clients to specify the uuid for resources\r
-         public T doPut(@PathVariable(value = "uuid") UUID uuid, @ModelAttribute("object") T object, BindingResult result) {\r
-               validator.validate(object, result);\r
-               if (result.hasErrors()) {\r
-                       // set http status code depending upon what happened, possibly return\r
-                   // the put object and errors so that they can be rendered into a suitable error response\r
-               } else {\r
-                 service.save(object);\r
-               }\r
-         }\r
-\r
-          @RequestMapping(method = RequestMethod.DELETE)\r
-          public void doDelete(@PathVariable(value = "uuid") UUID uuid) {\r
-              T object = service.find(uuid);\r
-              // provided the object exists\r
-              service.delete(uuid);\r
-              // might return 204 or 200\r
-          }\r
-       }\r
+\r
+        //Class<?> propertyClass = propertyClass(instance, baseName);\r
+\r
+        Object objectFromProperty = getCdmBaseProperty(uuid, baseName, response);//   invokeProperty(instance, baseName, response);\r
+\r
+        // CUT>\r
+\r
+        if(objectFromProperty != null){\r
+\r
+            if( Collection.class.isAssignableFrom(objectFromProperty.getClass())){\r
+                // Map types cannot be returned as list or in a pager!\r
+\r
+                Collection c = (Collection)objectFromProperty;\r
+                if(start != null){\r
+                    // return list\r
+                    limit = (limit == null ? DEFAULT_PAGE_SIZE : limit);\r
+                    Collection sub_c = subCollection(c, start, limit);\r
+                    modelAndView.addObject(sub_c);\r
+\r
+                } else {\r
+                    //FIXME use real paging mechanism of according service class instead of subCollection()\r
+                    //FIXME use BaseListController.normalizeAndValidatePagerParameters(pageNumber, pageSize, response);\r
+                    PagerParameters pagerParameters = new PagerParameters(pageSize, pageNumber);\r
+                    pagerParameters.normalizeAndValidate(response);\r
+\r
+                    start = pagerParameters.getPageIndex() * pagerParameters.getPageSize();\r
+                    List sub_c = subCollection(c, start, pagerParameters.getPageSize());\r
+                    Pager p = new DefaultPagerImpl(pageNumber, c.size(), pagerParameters.getPageSize(), sub_c);\r
+                    modelAndView.addObject(p);\r
+                }\r
+\r
+            } else {\r
+                modelAndView.addObject(objectFromProperty);\r
+            }\r
+\r
+        }\r
+\r
+        if(modelAndView.isEmpty()){\r
+            return null;\r
+        } else {\r
+\r
+            return modelAndView;\r
+        }\r
+    }\r
+\r
+    public Object getCdmBaseProperty(UUID uuid, String property, HttpServletResponse response) throws IOException{\r
+\r
+        T instance = (T) HibernateProxyHelper.deproxy(getCdmBaseInstance(uuid, response, property));\r
+\r
+        Object objectFromProperty = invokeProperty(instance, property, response);\r
+\r
+        return objectFromProperty;\r
+    }\r
+\r
+    private Class<?> propertyClass(T instance, String baseName) {\r
+        PropertyDescriptor propertyDescriptor = null;\r
+        Class<?> c = null;\r
+        try {\r
+            propertyDescriptor = PropertyUtils.getPropertyDescriptor(instance, baseName);\r
+            if(propertyDescriptor != null){\r
+                c =  propertyDescriptor.getClass();\r
+            }\r
+        } catch (IllegalAccessException e) {\r
+            // TODO Auto-generated catch block\r
+            e.printStackTrace();\r
+        } catch (InvocationTargetException e) {\r
+            // TODO Auto-generated catch block\r
+            e.printStackTrace();\r
+        } catch (NoSuchMethodException e) {\r
+            // TODO Auto-generated catch block\r
+            e.printStackTrace();\r
+        }\r
+        return c;\r
+    }\r
+\r
+    /**\r
+     * @param <SUB_T>\r
+     * @param clazz\r
+     * @param uuid\r
+     * @param response\r
+     * @param pathProperties\r
+     * @return\r
+     * @throws IOException\r
+     */\r
+    @SuppressWarnings("unchecked")\r
+    protected final <SUB_T extends T> SUB_T getCdmBaseInstance(Class<SUB_T> clazz, UUID uuid, HttpServletResponse response, List<String> pathProperties)\r
+    throws IOException {\r
+\r
+        CdmBase cdmBaseObject = getCdmBaseInstance(uuid, response, pathProperties);\r
+        if(!clazz.isAssignableFrom(cdmBaseObject.getClass())){\r
+            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);\r
+        }\r
+        return (SUB_T) cdmBaseObject;\r
+    }\r
+\r
+    /**\r
+     * @param <SUB_T>\r
+     * @param clazz\r
+     * @param uuid\r
+     * @param response\r
+     * @param pathProperty\r
+     * @return\r
+     * @throws IOException\r
+     */\r
+    @SuppressWarnings("unchecked")\r
+    protected final <SUB_T extends T> SUB_T getCdmBaseInstance(Class<SUB_T> clazz, UUID uuid, HttpServletResponse response, String pathProperty)\r
+    throws IOException {\r
+\r
+        CdmBase cdmBaseObject = getCdmBaseInstance(uuid, response, pathProperty);\r
+        if(!clazz.isAssignableFrom(cdmBaseObject.getClass())){\r
+            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);\r
+        }\r
+        return (SUB_T) cdmBaseObject;\r
+    }\r
+\r
+    /**\r
+     * @param uuid\r
+     * @param response\r
+     * @param pathProperty\r
+     * @return\r
+     * @throws IOException\r
+     */\r
+    protected final T getCdmBaseInstance(UUID uuid, HttpServletResponse response, String pathProperty)\r
+            throws IOException {\r
+        return getCdmBaseInstance(baseClass, uuid, response, Arrays\r
+                .asList(new String[] { pathProperty }));\r
+    }\r
+\r
+\r
+    /**\r
+     * @param uuid\r
+     * @param response\r
+     * @param pathProperties\r
+     * @return\r
+     * @throws IOException\r
+     */\r
+    protected final T getCdmBaseInstance(UUID uuid, HttpServletResponse response, List<String> pathProperties)\r
+            throws IOException {\r
+        return getCdmBaseInstance(baseClass, service, uuid, response, pathProperties);\r
+    }\r
+\r
+    /**\r
+     * @param <CDM_BASE>\r
+     * @param clazz\r
+     * @param service\r
+     * @param uuid\r
+     * @param response\r
+     * @param pathProperties\r
+     * @return\r
+     * @throws IOException\r
+     */\r
+    protected final <CDM_BASE extends CdmBase> CDM_BASE getCdmBaseInstance(Class<CDM_BASE> clazz, IService<CDM_BASE> service, UUID uuid, HttpServletResponse response, List<String> pathProperties)\r
+    throws IOException {\r
+\r
+        CDM_BASE cdmBaseObject = service.load(uuid, pathProperties);\r
+        if (cdmBaseObject == null) {\r
+            HttpStatusMessage.UUID_NOT_FOUND.send(response);\r
+        }\r
+        return cdmBaseObject;\r
+        }\r
+\r
+    /**\r
+     * @param instance\r
+     * @param baseName\r
+     * @param response\r
+     * @return\r
+     * @throws IOException\r
+     */\r
+    private final Object invokeProperty(T instance,\r
+            String baseName, HttpServletResponse response) throws IOException {\r
+\r
+        Object result = null;\r
+        try {\r
+            PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(instance, baseName);\r
+            if(propertyDescriptor == null){\r
+                throw new NoSuchMethodException("No such method: " + instance.getClass().getSimpleName() + ".get" + baseName);\r
+            }\r
+            Method method = propertyDescriptor.getReadMethod();\r
+\r
+            Class<?> returnType = method.getReturnType();\r
+\r
+            if(CdmBase.class.isAssignableFrom(returnType)\r
+                    || Collection.class.isAssignableFrom(returnType)\r
+                    || Map.class.isAssignableFrom(returnType)\r
+                    || INomenclaturalReference.class.isAssignableFrom(returnType)){\r
+\r
+                result = method.invoke(instance, (Object[])null);\r
+\r
+                result = HibernateProxyHelper.deproxy(result);\r
+\r
+            }else{\r
+                HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);\r
+            }\r
+        } catch (SecurityException e) {\r
+            logger.error("SecurityException: ", e);\r
+            HttpStatusMessage.INTERNAL_ERROR.send(response);\r
+        } catch (NoSuchMethodException e) {\r
+            HttpStatusMessage.PROPERTY_NOT_FOUND.send(response);\r
+        } catch (IllegalArgumentException e) {\r
+            HttpStatusMessage.PROPERTY_NOT_FOUND.send(response);\r
+        } catch (IllegalAccessException e) {\r
+            HttpStatusMessage.PROPERTY_NOT_FOUND.send(response);\r
+        } catch (InvocationTargetException e) {\r
+            HttpStatusMessage.PROPERTY_NOT_FOUND.send(response);\r
+        }\r
+        return result;\r
+    }\r
+\r
+    private <E> List<E> subCollection(Collection<? extends E> c, Integer start, Integer length){\r
+        List<E> sub_c = new ArrayList<E>(length);\r
+        if(c.size() > length){\r
+            E[] a = (E[]) c.toArray();\r
+            for(int i = start; i < start + length; i++){\r
+                sub_c.add(a[i]);\r
+            }\r
+        } else {\r
+            sub_c.addAll(c);\r
+        }\r
+        return sub_c;\r
+\r
+    }\r
+\r
+\r
+      /* TODO implement\r
+\r
+      private Validator validator;\r
+\r
+      private javax.validation.Validator javaxValidator;\r
+\r
+      @RequestMapping(method = RequestMethod.PUT, headers="content-type=multipart/form-data")\r
+      public T doPutForm(@PathVariable(value = "uuid") UUID uuid, @ModelAttribute("object") T object, BindingResult result) {\r
+          object.setUuid(uuid);\r
+          validator.validate(object, result);\r
+          if (result.hasErrors()) {\r
+              throw new Error();\r
+                // set http status code depending upon what happened, possibly return\r
+                // the put object and errors so that they can be rendered into a suitable error response\r
+          } else {\r
+             // requires merging detached object ?gilead?\r
+             service.save(object);\r
+          }\r
+\r
+            return object;\r
+      }\r
+\r
+      @RequestMapping(method = RequestMethod.PUT, headers="content-type=text/json")\r
+      public T doPutJSON(@PathVariable(value = "uuid") UUID uuid, @RequestBody String jsonMessage) {\r
+          JSONObject jsonObject = JSONObject.fromObject(jsonMessage);\r
+          T object = (T)JSONObject.toBean(jsonObject, this.getClass());\r
+\r
+\r
+          Set<ConstraintViolation<T>> constraintViolations = javaxValidator.validate(object);\r
+            if (!constraintViolations.isEmpty()) {\r
+                throw new Error();\r
+                    // set http status code depending upon what happened, possibly return\r
+                // the put object and errors so that they can be rendered into a suitable error response\r
+            } else {\r
+              // requires merging detached object ?gilead?\r
+              service.save(object);\r
+            }\r
+\r
+            return object;\r
+      }\r
+\r
+      @RequestMapping(method = RequestMethod.PUT) // the cdm-server may not allow clients to specify the uuid for resources\r
+      public T doPut(@PathVariable(value = "uuid") UUID uuid, @ModelAttribute("object") T object, BindingResult result) {\r
+            validator.validate(object, result);\r
+            if (result.hasErrors()) {\r
+                    // set http status code depending upon what happened, possibly return\r
+                // the put object and errors so that they can be rendered into a suitable error response\r
+            } else {\r
+              service.save(object);\r
+            }\r
+      }\r
+\r
+       @RequestMapping(method = RequestMethod.DELETE)\r
+       public void doDelete(@PathVariable(value = "uuid") UUID uuid) {\r
+           T object = service.find(uuid);\r
+           // provided the object exists\r
+           service.delete(uuid);\r
+           // might return 204 or 200\r
+       }\r
+    }\r
 */\r
-       \r
+\r
 \r
 }\r
index 76b0342377838194e957efceffefc1b6e32f9fd8..e161e46314561d6f1c58922c21ad5c27c97d4e90 100644 (file)
@@ -57,11 +57,12 @@ public abstract class BaseListController <T extends CdmBase, SERVICE extends ISe
      *\r
      * @param pageIndex\r
      *            the index of the page to be returned, the first page has the\r
-     *            pageIndex = 0 - <i>optional parameter</i>\r
+     *            pageIndex = 0 - <i>optional parameter</i>. Defaults to 0 if\r
+     *            set to <code>NULL</code>.\r
      * @param pageSize\r
-     *            the maximum number of entities returned per page (can be null\r
-     *            to return all entities in a single page) - <i>optional\r
-     *            parameter</i>\r
+     *            the maximum number of entities returned per page.\r
+     *            The {@link #DEFAULT_PAGE_SIZE} will be used if pageSize is set to\r
+     *            <code>null</code> - <i>optional parameter</i>\r
      * @param type\r
      *            Further restricts the type of entities to be returned.\r
      *            If null the base type <code>&lt;T&gt;</code> is being used. - <i>optional parameter</i>\r
index 535fef2fc757bc2fa433087990c51813f3101c7c..41b3489421f0cb4e540cb8e3db3dc91a65925a61 100644 (file)
@@ -37,7 +37,7 @@ public class PagerParameters {
 
     private Integer pageIndex;
 
-    public static final Integer DEFAULT_PAGESIZE = 20;
+    public static final Integer DEFAULT_PAGESIZE = 30;
 
     public void setPageSize(Integer pageSize) {
         this.pageSize = pageSize;
@@ -68,6 +68,17 @@ public class PagerParameters {
         this.pageIndex = pageIndex;
     }
 
+    /**
+     * Normalizes this <code>PagerParameters</code> according to the following
+     * rules and responds with an HTTP error in case of invalid parameters.
+     * <ul>
+     * <li>pageIndex defaults to 0 if set to <code>NULL</code>.</li>
+     * <li>pageSize defaults to {@link #DEFAULT_PAGESIZE} if set to <code>NULL</code>.</li>
+     * <li>Sends {@link HTTP_BAD_REQUEST} if <code>pageIndex</code> or <code>pageSize</code> are smaller than 0.
+     * </ul>
+     * @param response
+     * @throws IOException
+     */
     public void normalizeAndValidate(HttpServletResponse response) throws IOException{
 
         if(pageIndex == null){
@@ -79,7 +90,7 @@ public class PagerParameters {
         if(pageIndex < 0){
             HttpStatusMessage.fromString("The query parameter 'pageIndex' must not be a negative number").setStatusCode(HTTP_BAD_REQUEST).send(response);
         }
-        if(pageSize != null && pageSize < 0){
+        if(pageSize < 0){
             HttpStatusMessage.fromString("The query parameter 'pageSize' must not be a negative number").setStatusCode(HTTP_BAD_REQUEST).send(response);
         }
     }