--- /dev/null
+/**\r
+ * This document is a part of the source code and related artifacts\r
+ * for CollectionSpace, an open source collections management system\r
+ * for museums and related institutions:\r
+\r
+ * http://www.collectionspace.org\r
+ * http://wiki.collectionspace.org\r
+\r
+ * Copyright 2009 University of California at Berkeley\r
+\r
+ * Licensed under the Educational Community License (ECL), Version 2.0.\r
+ * You may not use this file except in compliance with this License.\r
+\r
+ * You may obtain a copy of the ECL 2.0 License at\r
+\r
+ * https://source.collectionspace.org/collection-space/LICENSE.txt\r
+\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.collectionspace.services.nuxeo.client.java;\r
+\r
+import java.lang.reflect.Method;\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import org.collectionspace.services.common.ReflectionMapper;\r
+import org.collectionspace.services.common.Tools;\r
+import org.collectionspace.services.common.document.DocumentWrapper;\r
+import org.collectionspace.services.jaxb.AbstractCommonList;\r
+import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;\r
+import org.collectionspace.services.nuxeo.util.NuxeoUtils;\r
+import org.nuxeo.ecm.core.api.DocumentModel;\r
+import org.nuxeo.ecm.core.api.DocumentModelList;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ * This class is generified by the marker types T and TL,\r
+ * however, T is expected to map to something like BlobCommon, MediaCommon, ObjectexitCommon, etc.,\r
+ * whereas TL is expected to map to AbstractCommonList,\r
+ * since, for example, BlobCommonList and ObjectexitCommonList descend from AbstractCommonList,\r
+ * and so on for every JAXB-generated schema class.\r
+ *\r
+ * User: laramie\r
+ * $LastChangedRevision: $\r
+ * $LastChangedDate: $\r
+ *\r
+ */\r
+public abstract class DocHandlerBase<T, TL> extends RemoteDocumentModelHandlerImpl<T, TL> {\r
+\r
+ /** The logger. */\r
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());\r
+\r
+ private AbstractCommonList commonList;\r
+\r
+ @Override\r
+ public TL getCommonPartList() {\r
+ return (TL)commonList;\r
+ }\r
+\r
+ public void setCommonPartList(AbstractCommonList aCommonList) {\r
+ this.commonList = aCommonList;\r
+ }\r
+\r
+ private T commonPart;\r
+\r
+ @Override\r
+ public T getCommonPart() {\r
+ return (T)commonPart;\r
+ }\r
+\r
+ public void setCommonPart(T commonPart) {\r
+ this.commonPart = commonPart;\r
+ }\r
+\r
+ /** Subclass DocHandlers may override this method to control exact creation of the common list.\r
+ * This class instantiates an AbstractCommonList from the classname returned by getCommonListReflection().AbstractCommonListClassname.\r
+ * @return\r
+ * @throws Exception\r
+ */\r
+ public AbstractCommonList createAbstractCommonListImpl() throws Exception {\r
+ // String classname = this.commonList.getClass().getName();\r
+ String classname = getAbstractCommonListClassname();\r
+ return (AbstractCommonList)(ReflectionMapper.instantiate(classname));\r
+ }\r
+\r
+\r
+ /** DocHandlerBase calls this method with the CSID as id */\r
+ public Object createItemForCommonList(DocumentModel docModel, String label, String id) throws Exception {\r
+ return createItemForCommonList(getCommonListItemClassname(), docModel, label, id, true);\r
+ }\r
+\r
+ public static class CommonListReflection {\r
+ public String NuxeoSchemaName;\r
+ public String DublinCoreTitle; // TODO: for CollectionObjectDocumentModelHandler, NUXEO_DC_TITLE = "CollectionSpace-CollectionObject"\r
+ public String SummaryFields;\r
+ public String AbstractCommonListClassname;\r
+ public String CommonListItemClassname;\r
+ public String ListItemMethodName;\r
+ public String[][] ListItemsArray; //setter, element, container, sub-element\r
+ public static int SETTER=0, ELEMENT=1, CONTAINER=2, SUBELEMENT=3;\r
+ }\r
+\r
+ public abstract CommonListReflection getCommonListReflection();\r
+\r
+ public String getNuxeoSchemaName(){\r
+ return getCommonListReflection().NuxeoSchemaName;\r
+ }\r
+\r
+ public String getSummaryFields(AbstractCommonList commonList){\r
+ return getCommonListReflection().SummaryFields;\r
+ }\r
+\r
+ public String getAbstractCommonListClassname(){\r
+ return getCommonListReflection().AbstractCommonListClassname;\r
+ }\r
+\r
+ public String getCommonListItemClassname(){\r
+ return getCommonListReflection().CommonListItemClassname;\r
+ }\r
+\r
+ public String[][] getListItemsArray(){\r
+ return getCommonListReflection().ListItemsArray;\r
+ }\r
+\r
+\r
+\r
+ @Override\r
+ public T extractCommonPart(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+ public void fillCommonPart(T objectexitObject, DocumentWrapper<DocumentModel> wrapDoc) throws Exception {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+ @Override\r
+ public TL extractCommonPartList(DocumentWrapper<DocumentModelList> wrapDoc) throws Exception {\r
+ String label = getServiceContext().getCommonPartLabel();\r
+\r
+ AbstractCommonList commonList = createAbstractCommonListImpl();\r
+ extractPagingInfo(((TL)commonList), wrapDoc);\r
+ commonList.setFieldsReturned(getSummaryFields(commonList));\r
+ List list = createItemsList(commonList);\r
+ Iterator<DocumentModel> iter = wrapDoc.getWrappedObject().iterator();\r
+ while(iter.hasNext()){\r
+ DocumentModel docModel = iter.next();\r
+ String id = NuxeoUtils.extractId(docModel.getPathAsString());\r
+ Object item = createItemForCommonList(docModel, label, id);\r
+ list.add(item);\r
+ }\r
+ return (TL)commonList;\r
+ }\r
+\r
+ @Override\r
+ public String getQProperty(String prop) {\r
+ return getNuxeoSchemaName() + ":" + prop;\r
+ }\r
+\r
+ //============= dublin core handling =======================================\r
+\r
+ @Override\r
+ public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {\r
+ super.fillAllParts(wrapDoc, action);\r
+ fillDublinCoreObject(wrapDoc);\r
+ }\r
+\r
+ protected void fillDublinCoreObject(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {\r
+ String title = getCommonListReflection().DublinCoreTitle;\r
+ if (Tools.isEmpty(title)){\r
+ return;\r
+ }\r
+ DocumentModel docModel = wrapDoc.getWrappedObject();\r
+ docModel.setPropertyValue("dublincore:title", title);\r
+ }\r
+\r
+ //================== UTILITY METHODS ================================================\r
+\r
+ public static ReflectionMapper.STATUS callSetter(DocumentModel docModel,\r
+ Object listItem,\r
+ String label,\r
+ String id,\r
+ String setterName,\r
+ String elementName)\r
+ throws Exception {\r
+ Object prop = docModel.getProperty(label, elementName);\r
+ return ReflectionMapper.callSetter(listItem, setterName, prop);\r
+ }\r
+\r
+ public static ReflectionMapper.STATUS callSetter(Object target, String name, Object arg) {\r
+ return ReflectionMapper.callSetter(target, name, arg);\r
+ }\r
+\r
+ /** @param commonListClassname is a package-qualified java classname, including inner class $ notation, such as\r
+ * "org.collectionspace.services.objectexit.ObjectexitCommonList$ObjectexitListItem".\r
+ * @param includeStdFields set to true to have the method set Uri and Csid automatically, based on id param.\r
+ */\r
+ public Object createItemForCommonList(String commonListClassname, DocumentModel docModel, String label, String id, boolean includeStdFields) throws Exception {\r
+ //createItemForCommonList(docModel, label, id);\r
+ Object item = ReflectionMapper.instantiate(commonListClassname);\r
+ String [][] names = getListItemsArray();\r
+ for (String[] row : names){\r
+ if (row.length >2\r
+ && Tools.notEmpty(row[CommonListReflection.CONTAINER])\r
+ && Tools.notEmpty(row[CommonListReflection.SUBELEMENT])){\r
+ String container = row[CommonListReflection.CONTAINER];//"lenderGroupList"; //LoaninListItemJAXBSchema.LENDER_GROUP_LIST;\r
+ String element = row[CommonListReflection.SUBELEMENT];//"lender"; //LoaninListItemJAXBSchema.LENDER;\r
+ String setter = row[CommonListReflection.SETTER];\r
+ List<Object> listOfMulti = (List<Object>) docModel.getProperty(label, container);\r
+ String primary = primaryValueFromMultivalue(listOfMulti, element);\r
+ callSetter(item, setter, primary); //"Lender" //item.setLender(primary);\r
+ } else {\r
+ callSetter(docModel, item, label, id, row[CommonListReflection.SETTER], row[CommonListReflection.ELEMENT]);\r
+ }\r
+ }\r
+ if (includeStdFields){\r
+ callSetter(item, "Csid", id);\r
+ callSetter(item, "Uri", getServiceContextPath() + id);\r
+ }\r
+ return item;\r
+ }\r
+\r
+ /** Subclasses should override this method if they don't want to automatically\r
+ * call List createItemsList(AbstractCommonList commonList, String listItemMethodName)\r
+ * which will use introspection to create a summary list, and will find the primary\r
+ * field for you if specified.\r
+ */\r
+ public List createItemsList(AbstractCommonList commonList) throws Exception {\r
+ return createItemsList(commonList, getCommonListReflection().ListItemMethodName);\r
+ }\r
+\r
+ /** e.g. createItemsList(commonList, "getObjectexitListItem" */\r
+ public List createItemsList(AbstractCommonList commonList, String listItemMethodName) throws Exception {\r
+ Class commonListClass = commonList.getClass();\r
+ Class[] types = new Class[] {};\r
+ try {\r
+ Method m = commonListClass.getMethod(listItemMethodName, types);\r
+ return (List)(ReflectionMapper.fireGetMethod(m, commonList));\r
+ } catch (NoSuchMethodException nsm){\r
+ return new ArrayList();\r
+ }\r
+ }\r
+\r
+\r
+\r
+}\r
+\r