From d8c2b3440de26af2f60e90e4e1b1f4fdbc7b0735 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Tue, 10 Nov 2009 20:46:52 +0000 Subject: [PATCH] Improve light DAOs git-svn-id: https://svn.argeo.org/commons/trunk@3078 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../server/dao/AbstractMemoryDaoSupport.java | 247 ++++++++++++ .../server/dao/AbstractTabularDaoSupport.java | 49 +++ .../org/argeo/server/dao/LightDaoSupport.java | 2 + .../argeo/server/jxl/dao/JxlDaoSupport.java | 367 ++++++------------ .../server/jxl/dao/CollectionsObject.java | 63 +++ .../server/jxl/dao/JxlDaoSupportTest.java | 4 + .../argeo/server/jxl/dao/SimpleObject.java | 11 + .../server/jxl/dao/SimpleObjectEditor.java | 19 + .../src/test/resources/dao/simple.xls | Bin 6656 -> 9216 bytes 9 files changed, 517 insertions(+), 245 deletions(-) create mode 100644 server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/AbstractMemoryDaoSupport.java create mode 100644 server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/AbstractTabularDaoSupport.java create mode 100644 server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/CollectionsObject.java create mode 100644 server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/SimpleObjectEditor.java diff --git a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/AbstractMemoryDaoSupport.java b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/AbstractMemoryDaoSupport.java new file mode 100644 index 000000000..39655d4fe --- /dev/null +++ b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/AbstractMemoryDaoSupport.java @@ -0,0 +1,247 @@ +package org.argeo.server.dao; + +import java.beans.PropertyEditor; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.server.ArgeoServerException; +import org.springframework.beans.BeanWrapper; +import org.springframework.beans.BeanWrapperImpl; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.generic.GenericBeanFactoryAccessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.core.io.Resource; + +public abstract class AbstractMemoryDaoSupport implements LightDaoSupport, + ApplicationContextAware, InitializingBean { + private final static Log log = LogFactory + .getLog(AbstractMemoryDaoSupport.class); + + private ClassLoader classLoader = getClass().getClassLoader(); + private ApplicationContext applicationContext; + private List> additionalClasses = new ArrayList>(); + + private Map, Map> model = new HashMap, Map>(); + + private Map externalRefs = new HashMap(); + + private List scannedPackages = new ArrayList(); + + private List workbooks = new ArrayList(); + + private Map, PropertyEditor> customEditors = new HashMap, PropertyEditor>();; + + protected abstract void load(InputStream in, List references); + + protected abstract Object findInternalRef(Reference reference); + + public void afterPropertiesSet() throws Exception { + init(); + } + + public void init() { + // used to resolve inner references + // Map> tempRefs = new HashMap>(); + + List references = new ArrayList(); + + for (Resource res : workbooks) { + InputStream in = null; + try { + in = res.getInputStream(); + load(in, references); + } catch (Exception e) { + throw new ArgeoServerException("Cannot load stream", e); + } finally { + IOUtils.closeQuietly(in); + } + } + + // Inject references + for (Reference ref : references) { + injectReference(ref); + } + if (log.isDebugEnabled()) + log.debug(references.size() + " references linked"); + } + + public List> getSupportedClasses() { + List> res = new ArrayList>(); + res.addAll(additionalClasses); + res.addAll(model.keySet()); + return res; + } + + protected void injectReference(Reference reference) { + BeanWrapper bw = new BeanWrapperImpl(reference.object); + Object targetObject; + if (reference.getExternalRef() != null) { + String ref = reference.getExternalRef(); + if (externalRefs.containsKey(ref)) + targetObject = externalRefs.get(ref); + else if (applicationContext != null) + targetObject = applicationContext.getBean(ref); + else { + targetObject = null; + log.warn("Ref " + ref + " not found"); + } + } else { + targetObject = findInternalRef(reference); + } + bw.setPropertyValue(reference.property, targetObject); + + } + + protected BeanWrapper newBeanWrapper(Class targetClass) { + BeanWrapperImpl bw = new BeanWrapperImpl(targetClass); + for (Class clss : customEditors.keySet()) + bw.registerCustomEditor(clss, customEditors.get(clss)); + return bw; + } + + @SuppressWarnings("unchecked") + public T getByKey(Class clss, Object key) { + return (T) model.get(findClass(clss)).get(key); + } + + /** + * Slow. + * + * @return the first found + */ + public T getByField(Class clss, String field, Object value) { + List all = list(clss, null); + T res = null; + for (T obj : all) { + if (new BeanWrapperImpl(obj).getPropertyValue(field).equals(value)) { + res = obj; + break; + } + } + return res; + } + + @SuppressWarnings("unchecked") + public List list(Class clss, Object filter) { + List res = new ArrayList(); + + Class classToUse = findClass(clss); + if (classToUse != null) + res.addAll((Collection) model.get(classToUse).values()); + + if (applicationContext != null) + res.addAll(new GenericBeanFactoryAccessor(applicationContext) + .getBeansOfType(clss).values()); + + return res; + } + + @SuppressWarnings("unchecked") + protected Class findClass(Class parent) { + if (model.containsKey(parent)) + return parent; + + for (Class clss : model.keySet()) { + if (parent.isAssignableFrom(clss)) + return clss;// return the first found + } + if (log.isDebugEnabled()) + log.warn("No class found for " + parent.getName()); + return null; + } + + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + this.applicationContext = applicationContext; + } + + /** + * When it should be stored under a different class (e.g. super class or + * interface) + */ + public void saveOrUpdate(Object key, Object value, Class clss) { + if (!model.containsKey(clss)) + model.put(clss, new TreeMap()); + model.get(clss).put(key, value); + } + + protected ClassLoader getClassLoader() { + return classLoader; + } + + public void setExternalRefs(Map externalRefs) { + this.externalRefs = externalRefs; + } + + public Map getExternalRefs() { + return externalRefs; + } + + public void setScannedPackages(List scannedPackages) { + this.scannedPackages = scannedPackages; + } + + public List getScannedPackages() { + return scannedPackages; + } + + public void setWorkbooks(List workbooks) { + this.workbooks = workbooks; + } + + public List getWorkbooks() { + return workbooks; + } + + public void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + public List> getAdditionalClasses() { + return additionalClasses; + } + + public void setAdditionalClasses(List> additionalClasses) { + this.additionalClasses = additionalClasses; + } + + public void setCustomEditors(Map, PropertyEditor> propertyEditors) { + this.customEditors = propertyEditors; + } + + protected static class Reference { + private Object object; + private String property; + private String externalRef; + + public Reference(Object object, String property, String externalRef) { + this.object = object; + this.property = property; + this.externalRef = externalRef; + } + + public Object getObject() { + return object; + } + + public String getProperty() { + return property; + } + + public String getExternalRef() { + return externalRef; + } + + } +} diff --git a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/AbstractTabularDaoSupport.java b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/AbstractTabularDaoSupport.java new file mode 100644 index 000000000..a2195b4d4 --- /dev/null +++ b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/AbstractTabularDaoSupport.java @@ -0,0 +1,49 @@ +package org.argeo.server.dao; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public abstract class AbstractTabularDaoSupport extends + AbstractMemoryDaoSupport { + private Map> tabularView = new HashMap>(); + + @Override + protected Object findInternalRef(Reference reference) { + TabularInternalReference tabReference = (TabularInternalReference) reference; + return getFromTabularView(tabReference.getTargetTableName(), + tabReference.getTargetRow()); + } + + protected Object getFromTabularView(String tableName, Integer row) { + return tabularView.get(tableName).get(row - 2); + } + + protected void registerInTabularView(String tableName, Object object) { + if (!tabularView.containsKey(tableName)) + tabularView.put(tableName, new ArrayList()); + tabularView.get(tableName).add(object); + } + + protected static class TabularInternalReference extends Reference { + private String targetTableName; + private Integer targetRow; + + public TabularInternalReference(Object object, String property, + String targetSheet, Integer targetRow) { + super(object, property, null); + this.targetTableName = targetSheet; + this.targetRow = targetRow; + } + + public String getTargetTableName() { + return targetTableName; + } + + public Integer getTargetRow() { + return targetRow; + } + + } +} diff --git a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/LightDaoSupport.java b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/LightDaoSupport.java index fa5ce4187..fc40c60e6 100644 --- a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/LightDaoSupport.java +++ b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/LightDaoSupport.java @@ -10,4 +10,6 @@ public interface LightDaoSupport { public List list(Class clss, Object filter); public List> getSupportedClasses(); + + public void saveOrUpdate(Object key, Object value, Class clss); } diff --git a/server/runtime/org.argeo.server.jxl/src/main/java/org/argeo/server/jxl/dao/JxlDaoSupport.java b/server/runtime/org.argeo.server.jxl/src/main/java/org/argeo/server/jxl/dao/JxlDaoSupport.java index fecd7f291..48dd8b233 100644 --- a/server/runtime/org.argeo.server.jxl/src/main/java/org/argeo/server/jxl/dao/JxlDaoSupport.java +++ b/server/runtime/org.argeo.server.jxl/src/main/java/org/argeo/server/jxl/dao/JxlDaoSupport.java @@ -1,147 +1,167 @@ package org.argeo.server.jxl.dao; import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.TreeMap; import jxl.Cell; import jxl.CellType; import jxl.FormulaCell; import jxl.JXLException; -import jxl.LabelCell; -import jxl.NumberCell; import jxl.Sheet; import jxl.Workbook; import jxl.WorkbookSettings; -import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.server.ArgeoServerException; +import org.argeo.server.dao.AbstractTabularDaoSupport; import org.argeo.server.dao.LightDaoSupport; import org.springframework.beans.BeanWrapper; -import org.springframework.beans.BeanWrapperImpl; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.generic.GenericBeanFactoryAccessor; -import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; -import org.springframework.core.io.Resource; import org.springframework.util.StringUtils; -public class JxlDaoSupport implements LightDaoSupport, ApplicationContextAware, - InitializingBean { +public class JxlDaoSupport extends AbstractTabularDaoSupport implements + LightDaoSupport, ApplicationContextAware, InitializingBean { private final static Log log = LogFactory.getLog(JxlDaoSupport.class); - private ClassLoader classLoader = getClass().getClassLoader(); - private ApplicationContext applicationContext; - private List> additionalClasses = new ArrayList>(); - - private Map, Map> model = new HashMap, Map>(); - - private Map externalRefs = new HashMap(); - - private List scannedPackages = new ArrayList(); - - private List workbooks = new ArrayList(); - private Integer charset = 0; - public void afterPropertiesSet() throws Exception { - init(); - } - - public void init() { - // used to resolve inner references - Map> tempRefs = new HashMap>(); - - List references = new ArrayList(); - - for (Resource res : workbooks) { - InputStream in = null; - try { - in = res.getInputStream(); - load(in, references, tempRefs); - } catch (Exception e) { - throw new ArgeoServerException("Cannot load stream", e); - } finally { - IOUtils.closeQuietly(in); - } - } - - // Inject references - for (Reference ref : references) { - injectReference(ref, tempRefs); - } - if (log.isDebugEnabled()) - log.debug(references.size() + " references linked"); - } - - public List> getSupportedClasses() { - List> res = new ArrayList>(); - res.addAll(additionalClasses); - res.addAll(model.keySet()); - return res; - } - - public void load(InputStream in, List references, - Map> tempRefs) { + protected void load(InputStream in, List references) { try { WorkbookSettings workbookSettings = new WorkbookSettings(); workbookSettings.setCharacterSet(charset); Workbook workbook = Workbook.getWorkbook(in, workbookSettings); for (Sheet sheet : workbook.getSheets()) { - loadSheet(sheet, references, tempRefs); + loadSheet(sheet, references); } } catch (Exception e) { throw new ArgeoServerException("Cannot load workbook", e); } } - protected void loadSheet(Sheet sheet, List references, - Map> tempRefs) throws JXLException { + protected void loadSheet(Sheet sheet, List references) + throws JXLException { if (log.isTraceEnabled()) log.debug("Instantiate sheet " + sheet.getName()); Cell[] firstRow = sheet.getRow(0); Class clss = findClassToInstantiate(sheet); - model.put(clss, new TreeMap()); + // model.put(clss, new TreeMap()); - tempRefs.put(sheet.getName(), new ArrayList()); + // tempRefs.put(sheet.getName(), new ArrayList()); String keyProperty = firstRow[0].getContents(); + + if (keyProperty.charAt(keyProperty.length() - 1) == '>') { + loadAsColumns(clss, keyProperty.substring(0, + keyProperty.length() - 1), sheet, firstRow, references); + } else { + loadAsRows(clss, keyProperty, sheet, firstRow, references); + } + } + + protected void loadAsRows(Class clss, String keyProperty, Sheet sheet, + Cell[] firstRow, List references) throws JXLException { for (int row = 1; row < sheet.getRows(); row++) { if (log.isTraceEnabled()) log.trace(" row " + row); Cell[] currentRow = sheet.getRow(row); - BeanWrapper bw = new BeanWrapperImpl(clss); + BeanWrapper bw = newBeanWrapper(clss); cells: for (int col = 0; col < firstRow.length; col++) { String pName = firstRow[col].getContents(); if (col < currentRow.length) { Cell cell = currentRow[col]; if (overrideCell(cell, bw, pName, keyProperty, row, - references, tempRefs)) + references)) continue cells; loadCell(cell, bw, pName, keyProperty, row, references); } }// cells - model.get(clss).put(bw.getPropertyValue(keyProperty), - bw.getWrappedInstance()); - tempRefs.get(sheet.getName()).add(bw.getWrappedInstance()); + saveOrUpdate(bw.getPropertyValue(keyProperty), bw + .getWrappedInstance(), clss); + // tempRefs.get(sheet.getName()).add(bw.getWrappedInstance()); + registerInTabularView(sheet.getName(), bw.getWrappedInstance()); } + } + + protected void loadAsColumns(Class clss, String keyProperty, + Sheet sheet, Cell[] firstRow, List references) + throws JXLException { + Cell[] firstColumn = sheet.getColumn(0); - if (log.isDebugEnabled()) - log.debug(model.get(clss).size() + " objects of type " + clss - + " instantiated"); + for (int col = 1; col < firstRow.length; col++) { + if (log.isTraceEnabled()) + log.trace(" column " + col); + BeanWrapper bw = newBeanWrapper(clss); + Cell[] column = sheet.getColumn(col); + for (int row = 0; row < column.length; row++) { + Cell cell = column[row]; + + String propertyName; + if (row == 0) + propertyName = keyProperty; + else + propertyName = firstColumn[row].getContents(); + + Class rowType = bw.getPropertyType(propertyName); + if (log.isTraceEnabled()) + log.trace(" " + propertyName + " rowType=" + + rowType.getName()); + if (Map.class.isAssignableFrom(rowType)) { + if (log.isTraceEnabled()) + log.trace(" start building map " + propertyName); + row++; + Map map = new HashMap(); + String firstColContents = firstColumn[row].getContents(); + mapRows: for (; row < column.length; row++) { + cell = column[row]; + + Object key = firstColContents; + CellType type = cell.getType(); + if (log.isTraceEnabled()) + log.trace(" row=" + row + ", firstColContents=" + + firstColContents + ", key=" + key + + ", type=" + type); + if (type.equals(CellType.NUMBER)) { + map + .put(key, Double.parseDouble(cell + .getContents())); + } else { + map.put(key, cell.getContents()); + } + + // check next row too see if one should break + if (row < firstColumn.length - 1) + firstColContents = firstColumn[row + 1] + .getContents(); + if (bw.isWritableProperty(firstColContents) + || firstColContents.trim().equals("") + || row == firstColumn.length - 1) { + bw.setPropertyValue(propertyName, map); + if (log.isTraceEnabled()) + log.trace(" set map " + propertyName + + " of size " + map.size()); + break mapRows;// map is over + } + } + } else { + loadCell(cell, bw, propertyName, keyProperty, row, + references); + } + } + saveOrUpdate(bw.getPropertyValue(keyProperty), bw + .getWrappedInstance(), clss); + // tempRefs.get(sheet.getName()).add(bw.getWrappedInstance()); + registerInTabularView(sheet.getName(), bw.getWrappedInstance()); + }// columns } protected void loadCell(Cell cell, BeanWrapper bw, String propertyName, @@ -161,8 +181,9 @@ public class JxlDaoSupport implements LightDaoSupport, ApplicationContextAware, if (targetRowStr.charAt(0) == '$') targetRowStr = targetRowStr.substring(1); Integer targetRow = Integer.parseInt(targetRowStr); - references.add(new Reference(bw.getWrappedInstance(), propertyName, - targetSheet, targetRow)); + references.add(new TabularInternalReference( + bw.getWrappedInstance(), propertyName, targetSheet, + targetRow)); if (log.isTraceEnabled()) log.debug(" formula: " + formula + " | content: " @@ -171,15 +192,15 @@ public class JxlDaoSupport implements LightDaoSupport, ApplicationContextAware, } else { String contents = cell.getContents(); -// if (cell.getType() == CellType.LABEL) { -// LabelCell lc = (LabelCell) cell; -// contents = lc.getString(); -// } else if (cell.getType() == CellType.NUMBER) { -// NumberCell nc = (NumberCell) cell; -// contents = new Double(nc.getValue()).toString(); -// } else { -// contents = cell.getContents(); -// } + // if (cell.getType() == CellType.LABEL) { + // LabelCell lc = (LabelCell) cell; + // contents = lc.getString(); + // } else if (cell.getType() == CellType.NUMBER) { + // NumberCell nc = (NumberCell) cell; + // contents = new Double(nc.getValue()).toString(); + // } else { + // contents = cell.getContents(); + // } if (propertyName.equals(keyProperty) && !StringUtils.hasText(contents)) { @@ -203,30 +224,19 @@ public class JxlDaoSupport implements LightDaoSupport, ApplicationContextAware, /** Returns true if property was set (thus bypassing standard process). */ protected Boolean overrideCell(Cell cell, BeanWrapper bw, String propertyName, String keyProperty, Integer row, - List references, Map> tempRefs) { + List references) { return false; } - protected void injectReference(Reference reference, - Map> tempRefs) { - BeanWrapper bw = new BeanWrapperImpl(reference.object); - Object targetObject; - if (reference.getExternalRef() != null) { - String ref = reference.getExternalRef(); - if (externalRefs.containsKey(ref)) - targetObject = externalRefs.get(ref); - else if (applicationContext != null) - targetObject = applicationContext.getBean(ref); - else { - targetObject = null; - log.warn("Ref " + ref + " not found"); - } - } else { - targetObject = tempRefs.get(reference.getTargetSheet()).get( - reference.targetRow - 2); - } - bw.setPropertyValue(reference.property, targetObject); - + /** + * @deprecated use + * {@link #overrideCell(Cell, BeanWrapper, String, String, Integer, List)} + * instead. This method is not called anymore. + */ + protected Boolean overrideCell(Cell cell, BeanWrapper bw, + String propertyName, String keyProperty, Integer row, + List references, Map> tempRefs) { + throw new UnsupportedOperationException(); } protected Class findClassToInstantiate(Sheet sheet) { @@ -234,15 +244,15 @@ public class JxlDaoSupport implements LightDaoSupport, ApplicationContextAware, String className = sheet.getName(); Class clss = null; try { - clss = classLoader.loadClass(className); + clss = getClassLoader().loadClass(className); return clss; } catch (ClassNotFoundException e) { // silent } - scannedPkgs: for (String pkg : scannedPackages) { + scannedPkgs: for (String pkg : getScannedPackages()) { try { - clss = classLoader.loadClass(pkg.trim() + "." + className); + clss = getClassLoader().loadClass(pkg.trim() + "." + className); break scannedPkgs; } catch (ClassNotFoundException e) { // silent @@ -258,140 +268,7 @@ public class JxlDaoSupport implements LightDaoSupport, ApplicationContextAware, return clss; } - @SuppressWarnings("unchecked") - public T getByKey(Class clss, Object key) { - return (T) model.get(findClass(clss)).get(key); - } - - /** - * Slow. - * - * @return the first found - */ - public T getByField(Class clss, String field, Object value) { - List all = list(clss, null); - T res = null; - for (T obj : all) { - if (new BeanWrapperImpl(obj).getPropertyValue(field).equals(value)) { - res = obj; - break; - } - } - return res; - } - - @SuppressWarnings("unchecked") - public List list(Class clss, Object filter) { - List res = new ArrayList(); - - Class classToUse = findClass(clss); - if (classToUse != null) - res.addAll((Collection) model.get(classToUse).values()); - - if (applicationContext != null) - res.addAll(new GenericBeanFactoryAccessor(applicationContext) - .getBeansOfType(clss).values()); - - return res; - } - - @SuppressWarnings("unchecked") - protected Class findClass(Class parent) { - if (model.containsKey(parent)) - return parent; - - for (Class clss : model.keySet()) { - if (parent.isAssignableFrom(clss)) - return clss;// return the first found - } - return null; - } - - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - this.applicationContext = applicationContext; - } - - public void setExternalRefs(Map externalRefs) { - this.externalRefs = externalRefs; - } - - public Map getExternalRefs() { - return externalRefs; - } - - public void setScannedPackages(List scannedPackages) { - this.scannedPackages = scannedPackages; - } - - public List getScannedPackages() { - return scannedPackages; - } - - public void setWorkbooks(List workbooks) { - this.workbooks = workbooks; - } - - public List getWorkbooks() { - return workbooks; - } - - public void setClassLoader(ClassLoader classLoader) { - this.classLoader = classLoader; - } - - public List> getAdditionalClasses() { - return additionalClasses; - } - - public void setAdditionalClasses(List> additionalClasses) { - this.additionalClasses = additionalClasses; - } - public void setCharset(Integer charset) { this.charset = charset; } - - public static class Reference { - private Object object; - private String property; - private String targetSheet; - private Integer targetRow; - private String externalRef; - - public Reference(Object object, String property, String targetSheet, - Integer targetRow) { - this.object = object; - this.property = property; - this.targetSheet = targetSheet; - this.targetRow = targetRow; - } - - public Reference(Object object, String property, String externalRef) { - this.object = object; - this.property = property; - this.externalRef = externalRef; - } - - public Object getObject() { - return object; - } - - public String getProperty() { - return property; - } - - public String getTargetSheet() { - return targetSheet; - } - - public Integer getTargetRow() { - return targetRow; - } - - public String getExternalRef() { - return externalRef; - } - - } } diff --git a/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/CollectionsObject.java b/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/CollectionsObject.java new file mode 100644 index 000000000..2e5f33b28 --- /dev/null +++ b/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/CollectionsObject.java @@ -0,0 +1,63 @@ +package org.argeo.server.jxl.dao; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CollectionsObject { + private String id; + private String label; + private SimpleObject simpleObject; + private List stringList = new ArrayList(); + private Map floatMap = new HashMap(); + private Map objectMap = new HashMap(); + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public SimpleObject getSimpleObject() { + return simpleObject; + } + + public void setSimpleObject(SimpleObject simpleObject) { + this.simpleObject = simpleObject; + } + + public List getStringList() { + return stringList; + } + + public void setStringList(List stringList) { + this.stringList = stringList; + } + + public Map getFloatMap() { + return floatMap; + } + + public void setFloatMap(Map floatMap) { + this.floatMap = floatMap; + } + + public Map getObjectMap() { + return objectMap; + } + + public void setObjectMap(Map objectMap) { + this.objectMap = objectMap; + } +} diff --git a/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/JxlDaoSupportTest.java b/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/JxlDaoSupportTest.java index 76c44a7f5..51b209656 100644 --- a/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/JxlDaoSupportTest.java +++ b/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/JxlDaoSupportTest.java @@ -29,5 +29,9 @@ public class JxlDaoSupportTest extends TestCase { List simpleObjects = jsd.list(SimpleObject.class, null); assertEquals(4, simpleObjects.size()); + + List collectionsObjects = jsd.list( + CollectionsObject.class, null); + assertEquals(3, collectionsObjects.size()); } } diff --git a/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/SimpleObject.java b/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/SimpleObject.java index f04166789..abe3706cb 100644 --- a/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/SimpleObject.java +++ b/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/SimpleObject.java @@ -37,4 +37,15 @@ public class SimpleObject { public void setAnotherObject(OtherObject anotherObject) { this.anotherObject = anotherObject; } + + @Override + public boolean equals(Object obj) { + return string.equals(((SimpleObject) obj).string); + } + + @Override + public int hashCode() { + return string.hashCode(); + } + } diff --git a/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/SimpleObjectEditor.java b/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/SimpleObjectEditor.java new file mode 100644 index 000000000..5c1a4e36c --- /dev/null +++ b/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/SimpleObjectEditor.java @@ -0,0 +1,19 @@ +package org.argeo.server.jxl.dao; + +import java.beans.PropertyEditorSupport; + +public class SimpleObjectEditor extends PropertyEditorSupport { + + @Override + public String getAsText() { + return ((SimpleObject) getValue()).getString(); + } + + @Override + public void setAsText(String text) throws IllegalArgumentException { + SimpleObject obj = new SimpleObject(); + obj.setString(text); + setValue(obj); + } + +} diff --git a/server/runtime/org.argeo.server.jxl/src/test/resources/dao/simple.xls b/server/runtime/org.argeo.server.jxl/src/test/resources/dao/simple.xls index d016ce939d26207b2dbe919b8ea6704b9044cfa7..f04b9d87788c0cea0dc2ecea49ba2f431764ca34 100644 GIT binary patch delta 2070 zcma)7|7%-S6hHUnCGVwq$<3D~sZ-k~cGVV@B<)s2?4naToTI~EMu*^1O-Dzx!DLLU z_~H-Zewc3d{s#&J5fsf2f><_C5cG%rI1v0<5RqCs1_Kw*=ib+)#v;4$PTu+4&-vUh z=bV?$Oy}t3Qe09nl0@EDPyH;E8yU~u>GgVe5T1EDEX5 z-NUZMlY*{T-7WW!B}h%iesvZjkUgO0y#4B7FKJzkswcdu*!xtW(;lX#Fg0>ywb7`* z(q378y|u7(mftRt&02!K5H_nfz5Mi9;w^42A%-HGkFXUiVDoP%cmyzh%sv=bUwcnF z!(x)LakcGT^qINx>YPio+*qx(kJp+^EuUmlftiLWABPKb2&TLU7iJn}2Ik-*>y%52 zVWLKDsor33{+ScJnbyi{%|_iEAWF2VPr|D(v0ZPq%gNxS(xV|7r`fQ&5O0RYsi0m? z<z@lyHE=XVS ztzS=mc<+)6>aWzJqSYNqpBHL9zI^YI$AnOSrXEkzXR)AkEEEY*M*W^Rz>`Ut^|v)b zLK1e0JlVWcJpv5*8^rjQ{)3^626@gN80WUn^Mge=7kx0mhW5Z>dtfNi!G+^{U^x6B z&&SPh9iu3@G|erbg}Ac+g{2rn4)q9l=>hC-t{DtTP}rbhwt_v}jMQ_Iu!#_X33=%g zgyC}4G6|9!Y%Lx5CFeuZVZLo{U``%e_LucYRS|`RNy_M`VfL`xH#%ybqa@wnwas!! zqojQS6Rj(0KJ4$1B%R^J7%H+WDH~A3nhGJqk#vi*Wtiq(_jiAs=^ z*UU6In#npogCLpnIZT!`H+19E=Ej&lABsili+tA_B3FlLQN9hAqxx*zkGm_rsN+#r zlI~-R`KXTH(Ffv3cZn3MSR|@NW;unpU}RL%{y+d(+gY+$MWT>6NnlI*k#lKIi!zmT zKU-8mOh@%Ol1_5QG}9+kucQY8s;8+CG9*dAamtJ+YFg5R0W+?d5HcJ|=Q$6Ci6WCU z!WKtJXePE~JZuV?{WWYPFi7 zvZ~rj7k%SF)QtZL#0JnQk_v3$p&3jQ7!S8y4Cc@prqnT))_Z%1u|MbptiK>itwl0XgdM-QWJp24hQ%gSyRj~J|PPU^i*$40H?_R6_KDwT3N05iA vrPgw55!~-%8Ff3irb@Q0-ps!vEOj&Qi;y}u?1#}nZS|ggglAp#gZz8>lSuoo0tQa$uJ+OtfyBuj2q=3QU?bY#)3EN_y=u~mA>8Z%%$jSn}o zVBEv&E8R4M*uA#@YVQVE8An90n#y6d*@0NTyNl7s`vdc(5!-YI