Introduce JXL DAO support
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 1 Oct 2009 11:34:48 +0000 (11:34 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 1 Oct 2009 11:34:48 +0000 (11:34 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@2998 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

13 files changed:
server/runtime/org.argeo.server.jxl/.classpath [new file with mode: 0644]
server/runtime/org.argeo.server.jxl/.project [new file with mode: 0644]
server/runtime/org.argeo.server.jxl/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
server/runtime/org.argeo.server.jxl/.settings/org.maven.ide.eclipse.prefs [new file with mode: 0644]
server/runtime/org.argeo.server.jxl/pom.xml
server/runtime/org.argeo.server.jxl/src/main/java/org/argeo/server/jxl/dao/JxlDaoSheet.java [new file with mode: 0644]
server/runtime/org.argeo.server.jxl/src/main/java/org/argeo/server/jxl/dao/JxlDaoSupport.java [new file with mode: 0644]
server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/JxlDaoSupportTest.java [new file with mode: 0644]
server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/OtherObject.java [new file with mode: 0644]
server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/SimpleObject.java [new file with mode: 0644]
server/runtime/org.argeo.server.jxl/src/test/resources/dao/simple.xls [new file with mode: 0644]
server/runtime/org.argeo.server.jxl/src/test/resources/log4j.properties [new file with mode: 0644]
server/runtime/pom.xml

diff --git a/server/runtime/org.argeo.server.jxl/.classpath b/server/runtime/org.argeo.server.jxl/.classpath
new file mode 100644 (file)
index 0000000..6b67f51
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" output="target/classes" path="src/main/java"/>
+       <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+       <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+       <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+       <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/server/runtime/org.argeo.server.jxl/.project b/server/runtime/org.argeo.server.jxl/.project
new file mode 100644 (file)
index 0000000..77aace3
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.server.jxl</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.maven.ide.eclipse.maven2Builder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.maven.ide.eclipse.maven2Nature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/server/runtime/org.argeo.server.jxl/.settings/org.eclipse.jdt.core.prefs b/server/runtime/org.argeo.server.jxl/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..737c94c
--- /dev/null
@@ -0,0 +1,5 @@
+#Thu Oct 01 12:06:12 CEST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/server/runtime/org.argeo.server.jxl/.settings/org.maven.ide.eclipse.prefs b/server/runtime/org.argeo.server.jxl/.settings/org.maven.ide.eclipse.prefs
new file mode 100644 (file)
index 0000000..ef3da62
--- /dev/null
@@ -0,0 +1,9 @@
+#Thu Oct 01 12:05:59 CEST 2009
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
index 12fde803f9a6f2ec70a37889564e58ea7c994f7a..06213f5588d3e74fae7a1b12bc64fe6e71ea88d2 100644 (file)
                        <artifactId>com.springsource.jxl</artifactId>
                </dependency>
 
+               <!-- TEST -->
+               <dependency>
+                       <groupId>org.junit</groupId>
+                       <artifactId>com.springsource.junit</artifactId>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.basic</groupId>
+                       <artifactId>org.argeo.basic.dep.log4j</artifactId>
+                       <version>0.1.1-SNAPSHOT</version>
+                       <type>pom</type>
+                       <scope>test</scope>
+               </dependency>
+
+
        </dependencies>
 </project>
diff --git a/server/runtime/org.argeo.server.jxl/src/main/java/org/argeo/server/jxl/dao/JxlDaoSheet.java b/server/runtime/org.argeo.server.jxl/src/main/java/org/argeo/server/jxl/dao/JxlDaoSheet.java
new file mode 100644 (file)
index 0000000..307d3b9
--- /dev/null
@@ -0,0 +1,5 @@
+package org.argeo.server.jxl.dao;
+
+public class JxlDaoSheet {
+       private Class targetClass;
+}
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
new file mode 100644 (file)
index 0000000..390fae7
--- /dev/null
@@ -0,0 +1,147 @@
+package org.argeo.server.jxl.dao;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import jxl.Cell;
+import jxl.FormulaCell;
+import jxl.Sheet;
+import jxl.Workbook;
+
+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;
+
+public class JxlDaoSupport {
+       private final static Log log = LogFactory.getLog(JxlDaoSupport.class);
+
+       private ClassLoader classLoader = getClass().getClassLoader();
+
+       private Map<Class, Map<Object, Object>> model = new HashMap<Class, Map<Object, Object>>();
+
+       public void load(InputStream in) {
+
+               try {
+                       // used to resolve inner references
+                       Map<String, List<Object>> tempRefs = new HashMap<String, List<Object>>();
+                       List<Link> links = new ArrayList<Link>();
+
+                       Workbook workbook = Workbook.getWorkbook(in);
+
+                       for (Sheet sheet : workbook.getSheets()) {
+                               if (log.isDebugEnabled())
+                                       log
+                                                       .debug("Instantiate objects of sheet "
+                                                                       + sheet.getName());
+                               
+                               Cell[] firstRow = sheet.getRow(0);
+
+                               // TODO: ability to map sheet names and class names
+                               String className = sheet.getName();
+                               Class<?> clss = classLoader.loadClass(className);
+                               model.put(clss, new HashMap<Object, Object>());
+
+                               tempRefs.put(sheet.getName(), new ArrayList<Object>());
+
+                               String keyProperty = firstRow[0].getContents();
+                               for (int i = 1; i < sheet.getRows(); i++) {
+                                       if (log.isTraceEnabled())
+                                               log.trace(" row " + i);
+
+                                       Cell[] currentRow = sheet.getRow(i);
+                                       BeanWrapper bw = new BeanWrapperImpl(clss);
+                                       for (int j = 0; j < firstRow.length; j++) {
+                                               String pName = firstRow[j].getContents();
+
+                                               Cell cell = currentRow[j];
+                                               if (cell instanceof FormulaCell) {
+                                                       String formula = ((FormulaCell) cell).getFormula();
+                                                       int index = formula.indexOf('!');
+                                                       String targetSheet = formula.substring(0, index);
+                                                       // assume no double letters
+                                                       Integer targetRow = Integer.parseInt(formula
+                                                                       .substring(index + 2));
+                                                       links.add(new Link(bw.getWrappedInstance(), pName,
+                                                                       targetSheet, targetRow));
+
+                                                       if (log.isTraceEnabled())
+                                                               log.debug("  formula: " + formula
+                                                                               + " | content: " + cell.getContents()
+                                                                               + " | targetSheet=" + targetSheet
+                                                                               + ", targetRow=" + targetRow);
+                                               } else {
+                                                       bw.setPropertyValue(pName, cell.getContents());
+
+                                                       if (log.isTraceEnabled())
+                                                               log.debug("  " + pName + "="
+                                                                               + cell.getContents());
+                                               }
+                                       }// properties set
+
+                                       model.get(clss).put(bw.getPropertyValue(keyProperty),
+                                                       bw.getWrappedInstance());
+                                       tempRefs.get(sheet.getName()).add(bw.getWrappedInstance());
+                               }
+
+                               if (log.isDebugEnabled())
+                                       log.debug(model.get(clss).size() + " objects of type "
+                                                       + clss);
+                       }
+
+                       if (log.isDebugEnabled())
+                               log.debug("Link " + links.size() + " references");
+                       for (Link link : links) {
+                               BeanWrapper bw = new BeanWrapperImpl(link.object);
+                               Object targetObject = tempRefs.get(link.getTargetSheet()).get(
+                                               link.targetRow - 2);
+                               bw.setPropertyValue(link.property, targetObject);
+                       }
+
+               } catch (Exception e) {
+                       throw new ArgeoServerException("Cannot load workbook", e);
+               }
+       }
+
+       @SuppressWarnings("unchecked")
+       public <T> T getByKey(Class<T> clss, Object key) {
+               return (T) model.get(clss).get(key);
+       }
+
+       public static class Link {
+               private Object object;
+               private String property;
+               private String targetSheet;
+               private Integer targetRow;
+
+               public Link(Object object, String property, String targetSheet,
+                               Integer targetRow) {
+                       super();
+                       this.object = object;
+                       this.property = property;
+                       this.targetSheet = targetSheet;
+                       this.targetRow = targetRow;
+               }
+
+               public Object getObject() {
+                       return object;
+               }
+
+               public String getProperty() {
+                       return property;
+               }
+
+               public String getTargetSheet() {
+                       return targetSheet;
+               }
+
+               public Integer getTargetRow() {
+                       return targetRow;
+               }
+
+       }
+}
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
new file mode 100644 (file)
index 0000000..b79a8a0
--- /dev/null
@@ -0,0 +1,26 @@
+package org.argeo.server.jxl.dao;
+
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+
+public class JxlDaoSupportTest extends TestCase {
+       public void testBasic() {
+               JxlDaoSupport jsd = new JxlDaoSupport();
+               InputStream in = getClass().getResourceAsStream("/dao/simple.xls");
+               jsd.load(in);
+
+               SimpleObject soAaa = jsd.getByKey(SimpleObject.class, "aaa");
+               assertNotNull(soAaa);
+               assertEquals("aaa", soAaa.getString());
+               assertEquals(1, soAaa.getInteger().intValue());
+               assertNotNull(soAaa.getOtherObject());
+               assertEquals("USD", soAaa.getOtherObject().getKey());
+               assertEquals("US Dollar", soAaa.getOtherObject().getValue());
+
+               SimpleObject soBbb = jsd.getByKey(SimpleObject.class, "bbb");
+               assertNotNull(soBbb.getOtherObject());
+               assertEquals("bbb", ((SimpleObject) soBbb.getOtherObject().getValue())
+                               .getString());
+       }
+}
diff --git a/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/OtherObject.java b/server/runtime/org.argeo.server.jxl/src/test/java/org/argeo/server/jxl/dao/OtherObject.java
new file mode 100644 (file)
index 0000000..2d7abd6
--- /dev/null
@@ -0,0 +1,22 @@
+package org.argeo.server.jxl.dao;
+
+public class OtherObject {
+       private String key;
+       private Object value;
+
+       public String getKey() {
+               return key;
+       }
+
+       public void setKey(String key) {
+               this.key = key;
+       }
+
+       public Object getValue() {
+               return value;
+       }
+
+       public void setValue(Object value) {
+               this.value = value;
+       }
+}
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
new file mode 100644 (file)
index 0000000..ae5aea5
--- /dev/null
@@ -0,0 +1,31 @@
+package org.argeo.server.jxl.dao;
+
+public class SimpleObject {
+       private String string;
+       private Integer integer;
+       private OtherObject otherObject;
+
+       public String getString() {
+               return string;
+       }
+
+       public void setString(String sting) {
+               this.string = sting;
+       }
+
+       public Integer getInteger() {
+               return integer;
+       }
+
+       public void setInteger(Integer integer) {
+               this.integer = integer;
+       }
+
+       public OtherObject getOtherObject() {
+               return otherObject;
+       }
+
+       public void setOtherObject(OtherObject otherObject) {
+               this.otherObject = otherObject;
+       }
+}
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
new file mode 100644 (file)
index 0000000..7cb8841
Binary files /dev/null and b/server/runtime/org.argeo.server.jxl/src/test/resources/dao/simple.xls differ
diff --git a/server/runtime/org.argeo.server.jxl/src/test/resources/log4j.properties b/server/runtime/org.argeo.server.jxl/src/test/resources/log4j.properties
new file mode 100644 (file)
index 0000000..6a9667c
--- /dev/null
@@ -0,0 +1,13 @@
+log4j.rootLogger=WARN, console
+
+## Levels
+log4j.logger.org.argeo=DEBUG
+log4j.logger.org.argeo.server.jxl=TRACE
+
+## Appenders
+# console is set to be a ConsoleAppender.
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+
+# console uses PatternLayout.
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c%n
index f496689b9fbeb61d55567befa946236c199e0729..7032ecbf67bd8c80dc18f7e558126a82f1e480c7 100644 (file)
@@ -16,5 +16,6 @@
                <module>org.argeo.server.core</module>
                <module>org.argeo.server.json</module>
                <module>org.argeo.server.osgi</module>
+               <module>org.argeo.server.jxl</module>
        </modules>
 </project>
\ No newline at end of file