// $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
import java.io.IOException;\r
import java.lang.reflect.InvocationTargetException;\r
import java.lang.reflect.Method;\r
+import java.lang.reflect.ParameterizedType;\r
+import java.lang.reflect.Type;\r
import java.util.ArrayList;\r
import java.util.Arrays;\r
import java.util.Collection;\r
import eu.etaxonomy.cdm.api.service.IService;\r
import eu.etaxonomy.cdm.api.service.pager.Pager;\r
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;\r
+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
+import eu.etaxonomy.cdm.remote.exception.NoRecordsMatchException;\r
\r
/**\r
* based on org.cateproject.controller.common\r
* @param <SERVICE>\r
*/\r
\r
-public abstract class BaseController<T extends CdmBase, SERVICE extends IService<T>> extends AbstractController {\r
+public abstract class BaseController<T extends CdmBase, SERVICE extends IService<T>> extends AbstractController<T, SERVICE> {\r
\r
- protected SERVICE service;\r
- \r
- protected Class<T> baseClass;\r
- \r
- public abstract void setService(SERVICE service);\r
+/* protected SERVICE service;\r
\r
- @InitBinder\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
- logger.info("doGet() " + request.getServletPath());\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
- logger.info("doGetMethod()[doGet" + StringUtils.capitalize(baseName) + "] " + request.getServletPath());\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 = doGetProperty(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 returend 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
- 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 doGetProperty(UUID uuid, String property, HttpServletResponse response) throws IOException{\r
- \r
- T instance = 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
- 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
- result = method.invoke(instance, (Object[])null);\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
+ throw new NoRecordsMatchException("No instance found for UUID " + uuid.toString());\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