[seam-commits] Seam SVN: r13456 - in sandbox/modules/spreadsheet: src and 25 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Wed Jul 21 06:19:00 EDT 2010


Author: nickarls
Date: 2010-07-21 06:18:59 -0400 (Wed, 21 Jul 2010)
New Revision: 13456

Added:
   sandbox/modules/spreadsheet/pom.xml
   sandbox/modules/spreadsheet/src/
   sandbox/modules/spreadsheet/src/main/
   sandbox/modules/spreadsheet/src/main/java/
   sandbox/modules/spreadsheet/src/main/java/org/
   sandbox/modules/spreadsheet/src/main/java/org/jboss/
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/SpreadsheetException.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/SpreadsheetReader.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/SpreadsheetWriter.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/BeforeAdded.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/BeforeCreated.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/BeforeExecuted.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/Excel.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/JXLSpreadsheetReader.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/JXLSpreadsheetWriter.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/CommandFactory.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/JxlColumnWidthCommand.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/JxlCommand.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/JxlRowHeightCommand.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/CellFactory.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/CellFormatFactory.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/CellFormatResolver.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/ConstantFactory.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Cell.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/CellSpan.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Coordinate.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Image.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Range.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Workbook.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Worksheet.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/builder/
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/builder/IteratingCoordinate.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/builder/WorkbookBuilder.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/ColumnWidthCommand.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/Command.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/RowHeightCommand.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Background.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Border.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/CellFormat.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/CellFormatRule.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Colour.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Font.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/RangeCellFormatRule.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/util/
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/util/HashUtil.java
   sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/util/ReflectionUtil.java
   sandbox/modules/spreadsheet/src/main/resources/
   sandbox/modules/spreadsheet/src/test/
   sandbox/modules/spreadsheet/src/test/java/
   sandbox/modules/spreadsheet/src/test/java/org/
   sandbox/modules/spreadsheet/src/test/java/org/jboss/
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/CellFactoryTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/CellFormatFactoryTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/CellFormatResolverTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/ConstantFactoryTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/JXLSpreadsheetWriterTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/CellTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/builder/
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/builder/WorkbookBuilderTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/BackgroundTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/BorderTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/CellFormatRuleTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/CellFormatTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/FontTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/SpreadsheetTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/HashUtilTest.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/Person.java
   sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/ReflectionUtilTest.java
   sandbox/modules/spreadsheet/src/test/resources/
Log:
Preliminary pre-alpha of a POC of the spreadsheets module

Added: sandbox/modules/spreadsheet/pom.xml
===================================================================
--- sandbox/modules/spreadsheet/pom.xml	                        (rev 0)
+++ sandbox/modules/spreadsheet/pom.xml	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,87 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>org.jboss.seam</groupId>
+	<artifactId>spreadsheet</artifactId>
+	<version>3.0.0-SNAPSHOT</version>
+	<packaging>war</packaging>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<arquillian.version>1.0.0.Alpha2</arquillian.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.jboss.spec</groupId>
+			<artifactId>jboss-javaee-6.0</artifactId>
+			<version>1.0.0.Beta4</version>
+			<type>pom</type>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>net.sourceforge.jexcelapi</groupId>
+			<artifactId>jxl</artifactId>
+			<version>2.6.10</version>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.8.1</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.1</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+<!--			<plugin>-->
+<!--				<groupId>org.codehaus.mojo</groupId>-->
+<!--				<artifactId>emma-maven-plugin</artifactId>-->
+<!--				<version>1.0-alpha-2</version>-->
+<!--				<inherited>true</inherited>-->
+<!--				<executions>-->
+<!--					<execution>-->
+<!--						<phase>process-classes</phase>-->
+<!--						<goals>-->
+<!--							<goal>instrument</goal>-->
+<!--						</goals>-->
+<!--					</execution>-->
+<!--				</executions>-->
+<!--			</plugin>-->
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<inherited>true</inherited>
+				<configuration>
+					<forkMode>once</forkMode>
+					<reportFormat>xml</reportFormat>
+					<classesDirectory>${project.build.directory}/generated-classes/emma/classes</classesDirectory>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+	<reporting>
+		<plugins>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>emma-maven-plugin</artifactId>
+				<version>1.0-alpha-2</version>
+				<inherited>true</inherited>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>surefire-report-maven-plugin</artifactId>
+				<inherited>true</inherited>
+			</plugin>
+		</plugins>
+	</reporting>
+</project>
\ No newline at end of file

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/SpreadsheetException.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/SpreadsheetException.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/SpreadsheetException.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,16 @@
+package org.jboss.seam.spreadsheet;
+
+public class SpreadsheetException extends RuntimeException
+{
+   private static final long serialVersionUID = 1L;
+
+   public SpreadsheetException(String message, Throwable cause)
+   {
+      super(message, cause);
+   }
+
+   public SpreadsheetException(String message)
+   {
+      super(message);
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/SpreadsheetReader.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/SpreadsheetReader.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/SpreadsheetReader.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,8 @@
+package org.jboss.seam.spreadsheet;
+
+import org.jboss.seam.spreadsheet.model.Workbook;
+
+public interface SpreadsheetReader
+{
+   public abstract Workbook readWorkbook(byte[] data);
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/SpreadsheetWriter.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/SpreadsheetWriter.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/SpreadsheetWriter.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,10 @@
+package org.jboss.seam.spreadsheet;
+
+import org.jboss.seam.spreadsheet.model.Workbook;
+
+public interface SpreadsheetWriter
+{
+   public abstract byte[] writeWorkbook(Workbook workbook);
+   public abstract byte[] writeWorkbook(Workbook workbook, byte[] template);
+   public abstract Object getRawWorkbook();
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/BeforeAdded.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/BeforeAdded.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/BeforeAdded.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,19 @@
+package org.jboss.seam.spreadsheet.jxl;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+ at Qualifier
+ at Retention(RUNTIME)
+ at Target( { METHOD, FIELD, PARAMETER, TYPE })
+public @interface BeforeAdded
+{
+}
\ No newline at end of file

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/BeforeCreated.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/BeforeCreated.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/BeforeCreated.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,19 @@
+package org.jboss.seam.spreadsheet.jxl;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+ at Qualifier
+ at Retention(RUNTIME)
+ at Target( { METHOD, FIELD, PARAMETER, TYPE })
+public @interface BeforeCreated
+{
+}
\ No newline at end of file

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/BeforeExecuted.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/BeforeExecuted.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/BeforeExecuted.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,19 @@
+package org.jboss.seam.spreadsheet.jxl;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+ at Qualifier
+ at Retention(RUNTIME)
+ at Target( { METHOD, FIELD, PARAMETER, TYPE })
+public @interface BeforeExecuted
+{
+}
\ No newline at end of file

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/Excel.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/Excel.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/Excel.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,20 @@
+package org.jboss.seam.spreadsheet.jxl;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+ at Qualifier
+ at Retention(RUNTIME)
+ at Target( { METHOD, FIELD, PARAMETER, TYPE })
+public @interface Excel
+{
+   String implementation();
+}
\ No newline at end of file

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/JXLSpreadsheetReader.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/JXLSpreadsheetReader.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/JXLSpreadsheetReader.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,17 @@
+package org.jboss.seam.spreadsheet.jxl;
+
+import org.jboss.seam.spreadsheet.SpreadsheetException;
+import org.jboss.seam.spreadsheet.SpreadsheetReader;
+import org.jboss.seam.spreadsheet.model.Workbook;
+
+ at Excel(implementation = "jxl")
+public class JXLSpreadsheetReader implements SpreadsheetReader
+{
+
+   @Override
+   public Workbook readWorkbook(byte[] data) throws SpreadsheetException
+   {
+      return null;
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/JXLSpreadsheetWriter.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/JXLSpreadsheetWriter.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/JXLSpreadsheetWriter.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,144 @@
+package org.jboss.seam.spreadsheet.jxl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+import javax.enterprise.event.Event;
+import javax.inject.Inject;
+
+import jxl.write.WritableSheet;
+import jxl.write.WritableWorkbook;
+import jxl.write.WriteException;
+import jxl.write.biff.RowsExceededException;
+
+import org.jboss.seam.spreadsheet.SpreadsheetException;
+import org.jboss.seam.spreadsheet.SpreadsheetWriter;
+import org.jboss.seam.spreadsheet.jxl.command.CommandFactory;
+import org.jboss.seam.spreadsheet.jxl.command.JxlCommand;
+import org.jboss.seam.spreadsheet.jxl.formatting.CellFactory;
+import org.jboss.seam.spreadsheet.jxl.formatting.CellFormatResolver;
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.Workbook;
+import org.jboss.seam.spreadsheet.model.Worksheet;
+import org.jboss.seam.spreadsheet.model.command.Command;
+
+ at Excel(implementation = "jxl")
+public class JXLSpreadsheetWriter implements SpreadsheetWriter
+{
+   CellFactory cellFactory;
+   CellFormatResolver cellFormatResolver;
+   WritableWorkbook jxlWorkbook;
+
+   // @Inject
+   // @BeforeAdded
+   // Event<Cell> cellAdded;
+   // @Inject
+   // @BeforeCreated
+   // Event<Worksheet> worksheetCreated;
+   // @Inject
+   // @BeforeExecuted
+   // Event<Command> commandExecuted;
+
+   @Override
+   public byte[] writeWorkbook(Workbook workbook) throws SpreadsheetException
+   {
+      if (workbook.getWorksheets().isEmpty())
+      {
+         throw new SpreadsheetException("You must have at least one worksheet");
+      }
+      ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+      cellFactory = new CellFactory();
+      cellFormatResolver = new CellFormatResolver(workbook.getCellFormatRules());
+      try
+      {
+         jxlWorkbook = jxl.Workbook.createWorkbook(outStream);
+         processWorkbook(jxlWorkbook, workbook);
+         jxlWorkbook.write();
+         jxlWorkbook.close();
+      }
+      catch (IOException e)
+      {
+         throw new SpreadsheetException("Could not create workbook", e);
+      }
+      catch (WriteException e)
+      {
+         throw new SpreadsheetException("Could not write workbook", e);
+      }
+      return outStream.toByteArray();
+   }
+
+   private void processWorkbook(WritableWorkbook jxlWorkbook, Workbook workbook)
+   {
+      for (Worksheet worksheet : workbook.getWorksheets())
+      {
+         processWorksheet(worksheet, workbook, jxlWorkbook);
+      }
+   }
+
+   private void processWorksheet(Worksheet worksheet, Workbook workbook, WritableWorkbook jxlWorkbook)
+   {
+      cellFormatResolver.setWorksheetRules(worksheet.getCellFormatRules());
+      // worksheetCreated.fire(worksheet);
+      WritableSheet jxlWorksheet = jxlWorkbook.createSheet(worksheet.getName(), jxlWorkbook.getNumberOfSheets());
+      for (Cell cell : worksheet.getCells())
+      {
+         processCell(jxlWorksheet, cell);
+      }
+      processCommands(workbook.getCommands(), jxlWorksheet);
+      processCommands(worksheet.getCommands(), jxlWorksheet);
+   }
+
+   private void processCommands(List<Command> commands, WritableSheet jxlWorksheet)
+   {
+      for (Command command : commands)
+      {
+         JxlCommand jxlCommand = CommandFactory.getJxlCommand(command, jxlWorksheet);
+         // commandExecuted.fire(command);
+         jxlCommand.execute();
+      }
+   }
+
+   private void processCell(WritableSheet jxlWorksheet, Cell cell)
+   {
+      try
+      {
+         // cellAdded.fire(cell);
+         jxlWorksheet.addCell(cellFactory.createCell(cell, cellFormatResolver));
+         if (cell.getCellSpan() != null)
+         {
+            mergeCells(jxlWorksheet, cell);
+         }
+      }
+      catch (RowsExceededException e)
+      {
+         throw new SpreadsheetException("Too many rows", e);
+      }
+      catch (WriteException e)
+      {
+         throw new SpreadsheetException("Could not write cell", e);
+      }
+   }
+
+   private void mergeCells(WritableSheet jxlWorksheet, Cell cell) throws RowsExceededException, WriteException
+   {
+      int columnStart = cell.getCoordinate().getColumn();
+      int rowStart = cell.getCoordinate().getRow();
+      int columnEnd = columnStart + cell.getCellSpan().getColumnSpan();
+      int rowEnd = rowStart + cell.getCellSpan().getRowSpan();
+      jxlWorksheet.mergeCells(columnStart, rowStart, columnEnd, rowEnd);
+   }
+
+   @Override
+   public byte[] writeWorkbook(Workbook workbook, byte[] template) throws SpreadsheetException
+   {
+      return null;
+   }
+
+   @Override
+   public Object getRawWorkbook()
+   {
+      return jxlWorkbook;
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/CommandFactory.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/CommandFactory.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/CommandFactory.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,24 @@
+package org.jboss.seam.spreadsheet.jxl.command;
+
+import jxl.write.WritableSheet;
+
+import org.jboss.seam.spreadsheet.model.command.ColumnWidthCommand;
+import org.jboss.seam.spreadsheet.model.command.Command;
+import org.jboss.seam.spreadsheet.model.command.RowHeightCommand;
+
+public class CommandFactory
+{
+
+   public static JxlCommand getJxlCommand(Command command, WritableSheet jxlWorksheet)
+   {
+      switch (command.getCommandId())
+      {
+      case COLUMN_WIDTH:
+         return new JxlColumnWidthCommand((ColumnWidthCommand) command, jxlWorksheet);
+      case ROW_HEIGHT:
+         return new JxlRowHeightCommand((RowHeightCommand) command, jxlWorksheet);
+      }
+      return null;
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/JxlColumnWidthCommand.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/JxlColumnWidthCommand.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/JxlColumnWidthCommand.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,30 @@
+package org.jboss.seam.spreadsheet.jxl.command;
+
+import jxl.CellView;
+import jxl.write.WritableSheet;
+
+import org.jboss.seam.spreadsheet.model.command.ColumnWidthCommand;
+
+public class JxlColumnWidthCommand implements JxlCommand
+{
+   private ColumnWidthCommand columnWidthCommand;
+   private WritableSheet jxlWorksheet;
+
+   public JxlColumnWidthCommand(ColumnWidthCommand columnWidthCommand, WritableSheet jxlWorksheet)
+   {
+      this.columnWidthCommand = columnWidthCommand;
+      this.jxlWorksheet = jxlWorksheet;
+   }
+
+   @Override
+   public void execute()
+   {
+      for (int column = columnWidthCommand.getColumnStart(); column <= columnWidthCommand.getColumnEnd(); column++)
+      {
+         CellView cellView = jxlWorksheet.getColumnView(column);
+         cellView.setSize(columnWidthCommand.getWidth());
+         jxlWorksheet.setColumnView(column, cellView);
+      }
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/JxlCommand.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/JxlCommand.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/JxlCommand.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,6 @@
+package org.jboss.seam.spreadsheet.jxl.command;
+
+public interface JxlCommand
+{
+   public abstract void execute();
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/JxlRowHeightCommand.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/JxlRowHeightCommand.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/command/JxlRowHeightCommand.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,27 @@
+package org.jboss.seam.spreadsheet.jxl.command;
+
+import jxl.write.WritableSheet;
+
+import org.jboss.seam.spreadsheet.model.command.RowHeightCommand;
+
+public class JxlRowHeightCommand implements JxlCommand
+{
+   private RowHeightCommand rowHeightCommand;
+   private WritableSheet jxlWorksheet;
+
+   public JxlRowHeightCommand(RowHeightCommand rowHeightCommand, WritableSheet jxlWorksheet)
+   {
+      this.rowHeightCommand = rowHeightCommand;
+      this.jxlWorksheet = jxlWorksheet;
+   }
+
+   @Override
+   public void execute()
+   {
+      for (int row = rowHeightCommand.getRowStart(); row <= rowHeightCommand.getRowEnd(); row++)
+      {
+         jxlWorksheet.getRowView(row).setSize(rowHeightCommand.getHeight());
+      }
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/CellFactory.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/CellFactory.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/CellFactory.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,63 @@
+package org.jboss.seam.spreadsheet.jxl.formatting;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import jxl.write.DateTime;
+import jxl.write.Label;
+import jxl.write.WritableCell;
+import jxl.write.WritableCellFormat;
+import jxl.write.WriteException;
+
+import org.jboss.seam.spreadsheet.SpreadsheetException;
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat;
+
+public class CellFactory
+{
+   Map<CellFormat, WritableCellFormat> cellFormatCache = new HashMap<CellFormat, WritableCellFormat>();
+   CellFormatFactory cellFormatFactory = new CellFormatFactory();
+
+   public WritableCell createCell(Cell cell, CellFormatResolver cellFormatResolver)
+   {
+      WritableCell jxlCell = null;
+      switch (cell.getCellType())
+      {
+      case DATE:
+         jxlCell = new DateTime(cell.getCoordinate().getColumn(), cell.getCoordinate().getRow(), (Date) cell.getValue());
+         break;
+      case LABEL:
+         jxlCell = new Label(cell.getCoordinate().getColumn(), cell.getCoordinate().getRow(), (String) cell.getValue());
+         break;
+      case NUMBER:
+         jxlCell = new jxl.write.Number(cell.getCoordinate().getColumn(), cell.getCoordinate().getRow(), Double.parseDouble(cell.getValue().toString()));
+         break;
+      }
+      CellFormat effectiveCellFormat = cellFormatResolver.getEffectiveCellFormatting(cell);
+      if (effectiveCellFormat != null)
+      {
+         jxlCell.setCellFormat(getCellFormat(effectiveCellFormat, cell));
+      }
+      return jxlCell;
+   }
+
+   private WritableCellFormat getCellFormat(CellFormat cellFormat, Cell cell)
+   {
+      WritableCellFormat jxlCellFormat = cellFormatCache.get(cellFormat);
+      if (jxlCellFormat == null)
+      {
+         try
+         {
+            jxlCellFormat = cellFormatFactory.createCellFormat(cellFormat, cell);
+         }
+         catch (WriteException e)
+         {
+            throw new SpreadsheetException("Could not create cell format", e);
+         }
+         cellFormatCache.put(cellFormat, jxlCellFormat);
+      }
+      return jxlCellFormat;
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/CellFormatFactory.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/CellFormatFactory.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/CellFormatFactory.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,222 @@
+package org.jboss.seam.spreadsheet.jxl.formatting;
+
+import jxl.biff.DisplayFormat;
+import jxl.biff.FontRecord;
+import jxl.format.BorderLineStyle;
+import jxl.format.Colour;
+import jxl.write.DateFormat;
+import jxl.write.DateFormats;
+import jxl.write.NumberFormat;
+import jxl.write.NumberFormats;
+import jxl.write.WritableCellFormat;
+import jxl.write.WritableFont;
+import jxl.write.WriteException;
+
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.Cell.CellType;
+import org.jboss.seam.spreadsheet.model.formatting.Background;
+import org.jboss.seam.spreadsheet.model.formatting.Border;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat;
+import org.jboss.seam.spreadsheet.model.formatting.Font;
+
+public class CellFormatFactory
+{
+   private ConstantFactory constantFactory = new ConstantFactory();
+
+   public WritableCellFormat createCellFormat(CellFormat cellFormat, Cell cell) throws WriteException
+   {
+      WritableCellFormat jxlCellFormat = initCellFormat(cellFormat, cell.getCellType());
+      if (cellFormat.getFont() != null)
+      {
+         jxlCellFormat.setFont(createFont(cellFormat.getFont()));
+      }
+      if (cellFormat.getLocked() != null)
+      {
+         jxlCellFormat.setLocked(cellFormat.getLocked());
+      }
+      if (cellFormat.getShrinkToFit() != null)
+      {
+         jxlCellFormat.setShrinkToFit(cellFormat.getShrinkToFit());
+      }
+      if (cellFormat.getWrap() != null)
+      {
+         jxlCellFormat.setWrap(cellFormat.getWrap());
+      }
+      if (cellFormat.getAlignment() != null)
+      {
+         jxlCellFormat.setAlignment(constantFactory.getAlignment(cellFormat.getAlignment()));
+      }
+      if (cellFormat.getBackground() != null)
+      {
+         applyBackground(jxlCellFormat, cellFormat.getBackground());
+      }
+      if (cellFormat.getBorders() != null)
+      {
+         for (Border border : cellFormat.getBorders())
+         {
+            applyBorder(jxlCellFormat, border);
+         }
+      }
+      if (cellFormat.getIndentation() != null)
+      {
+         jxlCellFormat.setIndentation(cellFormat.getIndentation());
+      }
+      if (cellFormat.getOrientation() != null)
+      {
+         jxlCellFormat.setOrientation(constantFactory.getOrientation(cellFormat.getOrientation()));
+      }
+      if (cellFormat.getVerticalAlignment() != null)
+      {
+         jxlCellFormat.setVerticalAlignment(constantFactory.getVerticalAlignment(cellFormat.getVerticalAlignment()));
+      }
+      return jxlCellFormat;
+   }
+
+   private WritableCellFormat initCellFormat(CellFormat cellFormat, CellType cellType)
+   {
+      switch (cellType)
+      {
+      case DATE:
+         return new WritableCellFormat(getDateFormatMask(cellFormat.getMask()));
+      case LABEL:
+         return new WritableCellFormat(NumberFormats.TEXT);
+      case NUMBER:
+         return new WritableCellFormat(getNumberFormatMask(cellFormat.getMask()));
+      default:
+         return new WritableCellFormat(NumberFormats.TEXT);
+      }
+   }
+
+   private void applyBorder(WritableCellFormat jxlCellFormat, Border border) throws WriteException
+   {
+      jxl.format.Border jxlBorder = null;
+      jxl.format.BorderLineStyle jxlBorderLineStyle = null;
+      jxl.format.Colour jxlColour = null;
+      if (border.getBorderType() != null)
+      {
+         jxlBorder = constantFactory.getBorder(border.getBorderType());
+      }
+      if (border.getLineStyle() != null)
+      {
+         jxlBorderLineStyle = constantFactory.getBorderLineStyle(border.getLineStyle());
+      }
+      if (border.getColour() != null)
+      {
+         jxlColour = constantFactory.getColour(border.getColour());
+      }
+      if (jxlBorder != null && jxlBorderLineStyle != null && jxlColour != null)
+      {
+         jxlCellFormat.setBorder(jxlBorder, jxlBorderLineStyle, jxlColour);
+      }
+      else if (jxlBorder != null && jxlBorderLineStyle != null)
+      {
+         jxlCellFormat.setBorder(jxlBorder, jxlBorderLineStyle);
+      }
+      else if (jxlBorder != null && jxlColour != null)
+      {
+         jxlCellFormat.setBorder(jxlBorder, BorderLineStyle.THIN, jxlColour);
+      }
+   }
+
+   private void applyBackground(WritableCellFormat jxlCellFormat, Background background) throws WriteException
+   {
+      jxl.format.Colour jxlColour = null;
+      jxl.format.Pattern jxlPattern = null;
+      if (background.getColour() != null)
+      {
+         jxlColour = constantFactory.getColour(background.getColour());
+      }
+      if (background.getPattern() != null)
+      {
+         jxlPattern = constantFactory.getPattern(background.getPattern());
+      }
+      if (jxlColour != null && jxlPattern != null)
+      {
+         jxlCellFormat.setBackground(jxlColour, jxlPattern);
+      }
+      else if (jxlPattern != null && jxlColour == null)
+      {
+         jxlCellFormat.setBackground(Colour.AUTOMATIC, jxlPattern);
+      }
+      else if (jxlColour != null && jxlPattern == null)
+      {
+         jxlCellFormat.setBackground(jxlColour);
+      }
+   }
+
+   private DisplayFormat getDateFormatMask(String mask)
+   {
+      if (mask == null)
+      {
+         return DateFormats.DEFAULT;
+      }
+      DisplayFormat namedDateFormat = constantFactory.getDateFormat(mask);
+      if (namedDateFormat != null)
+      {
+         return namedDateFormat;
+      }
+      return new DateFormat(mask);
+   }
+
+   private DisplayFormat getNumberFormatMask(String mask)
+   {
+      if (mask == null)
+      {
+         return NumberFormats.DEFAULT;
+      }
+      DisplayFormat namedNumberFormat = constantFactory.getNumberFormat(mask);
+      if (namedNumberFormat != null)
+      {
+         return namedNumberFormat;
+      }
+      String shorthand = constantFactory.getNumberFormatShorthand(mask);
+      if (shorthand != null)
+      {
+         return new NumberFormat(shorthand);
+      }
+      return new NumberFormat(mask);
+   }
+
+   private FontRecord createFont(Font font) throws WriteException
+   {
+      WritableFont jxlFont = null;
+      if (font.getFontName() != null)
+      {
+         jxlFont = new WritableFont(WritableFont.createFont(font.getFontName()));
+      }
+      else
+      {
+         jxlFont = new WritableFont(WritableFont.ARIAL);
+      }
+      if (font.getPointSize() != null)
+      {
+         jxlFont.setPointSize(font.getPointSize());
+      }
+      if (font.getColour() != null)
+      {
+         jxlFont.setColour(constantFactory.getColour(font.getColour()));
+      }
+      if (font.getBold() != null)
+      {
+         jxlFont.setBoldStyle(font.getBold() ? WritableFont.BOLD : WritableFont.NO_BOLD);
+      }
+      if (font.getItalic() != null)
+      {
+         jxlFont.setItalic(font.getItalic());
+      }
+      if (font.getStruckOut() != null)
+      {
+         jxlFont.setStruckout(font.getStruckOut());
+      }
+      if (font.getScriptStyle() != null)
+      {
+         jxlFont.setScriptStyle(constantFactory.getScriptStyle(font.getScriptStyle()));
+      }
+      if (font.getUnderlineStyle() != null)
+      {
+         jxlFont.setUnderlineStyle(constantFactory.getUnderlineStyle(font.getUnderlineStyle()));
+      }
+      return jxlFont;
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/CellFormatResolver.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/CellFormatResolver.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/CellFormatResolver.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,75 @@
+package org.jboss.seam.spreadsheet.jxl.formatting;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormatRule;
+
+public class CellFormatResolver
+{
+   private List<CellFormatRule> workbookRules = new ArrayList<CellFormatRule>();
+   private List<CellFormatRule> worksheetRules = new ArrayList<CellFormatRule>();
+
+   public CellFormatResolver(List<CellFormatRule> workbookRules)
+   {
+      this.workbookRules = workbookRules;
+   }
+
+   public CellFormatResolver()
+   {
+   }
+
+   public void setWorksheetRules(List<CellFormatRule> worksheetRules)
+   {
+      this.worksheetRules = worksheetRules;
+   }
+
+   public CellFormat getEffectiveCellFormatting(Cell cell)
+   {
+      if (cell.getCellFormat() != null && CellFormat.Type.ABSOLUTE.equals(cell.getCellFormat().getType()))
+      {
+         return cell.getCellFormat();
+      }
+      List<CellFormat> effectiveCellFormattings = new ArrayList<CellFormat>();
+      effectiveCellFormattings.addAll(collect(workbookRules, cell));
+      effectiveCellFormattings.addAll(collect(worksheetRules, cell));
+      if (cell.getCellFormat() != null)
+      {
+         effectiveCellFormattings.add(cell.getCellFormat());
+      }
+      return merge(effectiveCellFormattings);
+   }
+
+   private Collection<CellFormat> collect(List<CellFormatRule> cellFormatRules, Cell cell)
+   {
+      List<CellFormat> appliedCellFormatRules = new ArrayList<CellFormat>();
+      for (CellFormatRule cellFormatRule : cellFormatRules)
+      {
+         if (cellFormatRule.appliesTo(cell))
+         {
+            appliedCellFormatRules.add(cellFormatRule.getCellFormat());
+         }
+      }
+      return appliedCellFormatRules;
+   }
+
+   private CellFormat merge(List<CellFormat> cellFormats)
+   {
+      if (cellFormats.isEmpty())
+      {
+         return null;
+      }
+      Iterator<CellFormat> i = cellFormats.iterator();
+      CellFormat mergedCellFormats = i.next();
+      while (i.hasNext())
+      {
+         CellFormat nextCellFormat = i.next();
+         mergedCellFormats.merge(nextCellFormat);
+      }
+      return mergedCellFormats;
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/ConstantFactory.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/ConstantFactory.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/jxl/formatting/ConstantFactory.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,168 @@
+package org.jboss.seam.spreadsheet.jxl.formatting;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+import jxl.biff.DisplayFormat;
+import jxl.write.DateFormats;
+import jxl.write.NumberFormat;
+import jxl.write.NumberFormats;
+
+import org.jboss.seam.spreadsheet.SpreadsheetException;
+import org.jboss.seam.spreadsheet.model.formatting.Background.Pattern;
+import org.jboss.seam.spreadsheet.model.formatting.Border;
+import org.jboss.seam.spreadsheet.model.formatting.Border.BorderLineStyle;
+import org.jboss.seam.spreadsheet.model.formatting.Border.BorderType;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.Alignment;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.Orientation;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.VerticalAlignment;
+import org.jboss.seam.spreadsheet.model.formatting.Colour;
+import org.jboss.seam.spreadsheet.model.formatting.Font.ScriptStyle;
+import org.jboss.seam.spreadsheet.model.formatting.Font.UnderlineStyle;
+
+public class ConstantFactory
+{
+   private Map<Colour, jxl.format.Colour> colours;
+   private Map<ScriptStyle, jxl.format.ScriptStyle> scriptStyles;
+   private Map<UnderlineStyle, jxl.format.UnderlineStyle> underlineStyles;
+   private Map<String, DisplayFormat> numberFormats;
+   private Map<String, DisplayFormat> dateFormats;
+   private Map<String, String> numberFormatShorthands;
+   private Map<Orientation, jxl.format.Orientation> orientations;
+   private Map<Alignment, jxl.format.Alignment> alignments;
+   private Map<VerticalAlignment, jxl.format.VerticalAlignment> verticalAlignments;
+   private Map<Pattern, jxl.format.Pattern> patterns;
+   private Map<BorderType, jxl.format.Border> borders;
+   private Map<BorderLineStyle, jxl.format.BorderLineStyle> borderLineStyles;
+
+   public ConstantFactory()
+   {
+      colours = loadConstants(Colour.values(), jxl.format.Colour.class);
+      scriptStyles = loadConstants(ScriptStyle.values(), jxl.format.ScriptStyle.class);
+      underlineStyles = loadConstants(UnderlineStyle.values(), jxl.format.UnderlineStyle.class);
+      numberFormats = loadConstants(DisplayFormat.class, NumberFormats.class);
+      dateFormats = loadConstants(DisplayFormat.class, DateFormats.class);
+      numberFormatShorthands = loadConstants(String.class, NumberFormat.class);
+      orientations = loadConstants(Orientation.values(), jxl.format.Orientation.class);
+      alignments = loadConstants(Alignment.values(), jxl.format.Alignment.class);
+      verticalAlignments = loadConstants(VerticalAlignment.values(), jxl.format.VerticalAlignment.class);
+      patterns = loadConstants(Pattern.values(), jxl.format.Pattern.class);
+      borders = loadConstants(BorderType.values(), jxl.format.Border.class);
+      borderLineStyles = loadConstants(BorderLineStyle.values(), jxl.format.BorderLineStyle.class);
+   }
+
+   @SuppressWarnings("unchecked")
+   private <V> Map<String, V> loadConstants(Class<V> valueClass, Class<?> sourceClass)
+   {
+      Map<String, V> constants = new HashMap<String, V>();
+      for (Field field : sourceClass.getFields())
+      {
+         try
+         {
+            constants.put(field.getName(), (V) field.get(null));
+         }
+         catch (Exception e)
+         {
+            throw new SpreadsheetException(String.format("Could not read field %s from class %s", field.getName(), sourceClass.getName()), e);
+         }
+      }
+      return constants;
+   }
+
+   public jxl.format.Colour getColour(Colour colour)
+   {
+      checkConstantPresent(colours, colour, "Color");
+      return colours.get(colour);
+   }
+
+   private <T, U> void checkConstantPresent(Map<U, T> map, U key, String what)
+   {
+      if (!map.containsKey(key))
+      {
+         throw new SpreadsheetException(String.format("%s '%s' is not known, try one of %s", what, key, map.keySet()));
+      }
+   }
+
+   public jxl.format.ScriptStyle getScriptStyle(ScriptStyle scriptStyle)
+   {
+      checkConstantPresent(scriptStyles, scriptStyle, "Script style");
+      return scriptStyles.get(scriptStyle);
+   }
+
+   public jxl.format.UnderlineStyle getUnderlineStyle(UnderlineStyle underlineStyle)
+   {
+      checkConstantPresent(underlineStyles, underlineStyle, "Underline style");
+      return underlineStyles.get(underlineStyle);
+   }
+
+   @SuppressWarnings("unchecked")
+   private <K, V> Map<K, V> loadConstants(K[] keys, Class<V> sourceClass)
+   {
+      Map<K, V> constants = new HashMap<K, V>();
+      for (K key : keys)
+      {
+         String fieldName = key.toString().toUpperCase();
+         try
+         {
+            V constant = (V) sourceClass.getField(fieldName).get(null);
+            constants.put(key, constant);
+         }
+         catch (NoSuchFieldException e)
+         {
+            throw new SpreadsheetException(String.format("Field %s not found in class %s", fieldName, sourceClass.getName()), e);
+         }
+         catch (Exception e)
+         {
+            throw new SpreadsheetException(String.format("Could not read field %s from class %s", fieldName, sourceClass.getName()), e);
+         }
+      }
+      return constants;
+   }
+
+   public DisplayFormat getNumberFormat(String mask)
+   {
+      return numberFormats.get(mask);
+   }
+
+   public DisplayFormat getDateFormat(String mask)
+   {
+      return dateFormats.get(mask);
+   }
+
+   public String getNumberFormatShorthand(String mask)
+   {
+      return numberFormatShorthands.get(mask);
+   }
+
+   public jxl.format.Alignment getAlignment(Alignment alignment)
+   {
+      return alignments.get(alignment);
+   }
+
+   public jxl.format.Orientation getOrientation(Orientation orientation)
+   {
+      return orientations.get(orientation);
+   }
+
+   public jxl.format.VerticalAlignment getVerticalAlignment(VerticalAlignment verticalAlignment)
+   {
+      return verticalAlignments.get(verticalAlignment);
+   }
+
+   public jxl.format.Pattern getPattern(Pattern pattern)
+   {
+      return patterns.get(pattern);
+   }
+
+   public jxl.format.Border getBorder(BorderType borderType)
+   {
+      return borders.get(borderType);
+   }
+
+   public jxl.format.BorderLineStyle getBorderLineStyle(Border.BorderLineStyle lineStyle)
+   {
+      return borderLineStyles.get(lineStyle);
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Cell.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Cell.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Cell.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,168 @@
+package org.jboss.seam.spreadsheet.model;
+
+import java.util.Date;
+
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat;
+import org.jboss.seam.spreadsheet.util.HashUtil;
+
+public class Cell
+{
+   public enum CellType
+   {
+      LABEL, NUMBER, DATE
+   };
+
+   private Coordinate coordinate;
+   private CellSpan cellSpan;
+   private CellFormat cellFormat;
+   private CellType cellType;
+   private Object userData;
+
+   private Object value;
+
+   protected Cell(Object value, Coordinate coordinate)
+   {
+      this.value = value;
+      this.coordinate = Coordinate.of(coordinate);
+   }
+
+   public Cell()
+   {
+   }
+
+   public Coordinate getCoordinate()
+   {
+      return coordinate;
+   }
+
+   public void setCoordinate(Coordinate coordinate)
+   {
+      this.coordinate = coordinate;
+   }
+
+   public CellSpan getCellSpan()
+   {
+      return cellSpan;
+   }
+
+   public void setCellSpan(CellSpan cellSpan)
+   {
+      this.cellSpan = cellSpan;
+   }
+
+   public CellFormat getCellFormat()
+   {
+      return cellFormat;
+   }
+
+   public void setCellFormat(CellFormat cellFormat)
+   {
+      this.cellFormat = cellFormat;
+   }
+
+   public Object getValue()
+   {
+      return value;
+   }
+
+   public void setValue(Object value)
+   {
+      this.value = value;
+   }
+
+   public static Cell of(Object value, Coordinate coordinate)
+   {
+      return new Cell(value, coordinate);
+   }
+
+   public CellType getCellType()
+   {
+      return cellType != null ? cellType : determineCellType();
+   }
+
+   private CellType determineCellType()
+   {
+      if (value.getClass().isAssignableFrom(String.class))
+      {
+         return CellType.LABEL;
+      }
+      else if (value.getClass().isAssignableFrom(Integer.class))
+      {
+         return CellType.NUMBER;
+      }
+      else if (value.getClass().isAssignableFrom(Double.class))
+      {
+         return CellType.NUMBER;
+      }
+      else if (value.getClass().isAssignableFrom(Float.class))
+      {
+         return CellType.NUMBER;
+      }
+      else if (value.getClass().isAssignableFrom(Date.class))
+      {
+         return CellType.DATE;
+      }
+      else if (value.getClass().isAssignableFrom(Long.class))
+      {
+         return CellType.NUMBER;
+      }
+      else if (value.getClass().isAssignableFrom(Short.class))
+      {
+         return CellType.NUMBER;
+      }
+      else if (value.getClass().isAssignableFrom(java.sql.Date.class))
+      {
+         return CellType.DATE;
+      }
+      return CellType.LABEL;
+   }
+
+   public void setCellType(CellType cellType)
+   {
+      this.cellType = cellType;
+   }
+
+   public Object getUserData()
+   {
+      return userData;
+   }
+
+   public void setUserData(Object userData)
+   {
+      this.userData = userData;
+   }
+
+   @Override
+   public String toString()
+   {
+      return String.format("%s:'%s'", coordinate, value);
+   }
+
+   @Override
+   public boolean equals(Object other)
+   {
+      if (!(other instanceof Cell))
+      {
+         return false;
+      }
+      Cell otherCell = (Cell) other;
+      if (!HashUtil.same(coordinate, otherCell.getCoordinate()))
+      {
+         return false;
+      }
+      if (!HashUtil.same(value, otherCell.getValue()))
+      {
+         return false;
+      }
+      return true;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      int hashCode = 0;
+      hashCode += coordinate == null ? 0 : coordinate.hashCode();
+      hashCode += value == null ? 0 : value.hashCode();
+      return hashCode;
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/CellSpan.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/CellSpan.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/CellSpan.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,44 @@
+package org.jboss.seam.spreadsheet.model;
+
+public class CellSpan
+{
+   private int columnSpan;
+   private int rowSpan;
+
+   public int getColumnSpan()
+   {
+      return columnSpan;
+   }
+
+   public void setColumnSpan(int columnSpan)
+   {
+      this.columnSpan = columnSpan;
+   }
+
+   public int getRowSpan()
+   {
+      return rowSpan;
+   }
+
+   public void setRowSpan(int rowSpan)
+   {
+      this.rowSpan = rowSpan;
+   }
+
+   protected CellSpan(int columnSpan, int rowSpan)
+   {
+      this.columnSpan = columnSpan;
+      this.rowSpan = rowSpan;
+   }
+
+   public static CellSpan of(int columnSpan, int rowSpan)
+   {
+      return new CellSpan(columnSpan, rowSpan);
+   }
+
+   @Override
+   public String toString()
+   {
+      return String.format("CellSpan [%s, %s]", columnSpan, rowSpan);
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Coordinate.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Coordinate.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Coordinate.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,79 @@
+package org.jboss.seam.spreadsheet.model;
+
+public class Coordinate
+{
+   public static Coordinate ORIGO = Coordinate.of(0, 0);
+
+   private int column;
+   private int row;
+
+   protected Coordinate(int column, int row)
+   {
+      this.column = column;
+      this.row = row;
+   }
+
+   public Coordinate(Coordinate coordinate)
+   {
+      this.column = coordinate.getColumn();
+      this.row = coordinate.getRow();
+   }
+
+   public static Coordinate of(int column, int row)
+   {
+      return new Coordinate(column, row);
+   }
+
+   public int getColumn()
+   {
+      return column;
+   }
+
+   public void setColumn(int column)
+   {
+      this.column = column;
+   }
+
+   public int getRow()
+   {
+      return row;
+   }
+
+   public void setRow(int row)
+   {
+      this.row = row;
+   }
+
+   public static Coordinate of(Coordinate coordinate)
+   {
+      return new Coordinate(coordinate);
+   }
+
+   public boolean within(Range range)
+   {
+      return column >= range.getTopLeft().getColumn() && column <= range.getBottomRight().getColumn() && row >= range.getTopLeft().getRow() && row <= range.getBottomRight().getRow();
+   }
+
+   @Override
+   public String toString()
+   {
+      return String.format("[%d, %d]", column, row);
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return row + column;
+   }
+
+   @Override
+   public boolean equals(Object other)
+   {
+      if (!(other instanceof Coordinate))
+      {
+         return false;
+      }
+      Coordinate otherCoordinate = (Coordinate) other;
+      return row == otherCoordinate.getRow() && column == otherCoordinate.getColumn();
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Image.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Image.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Image.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,60 @@
+package org.jboss.seam.spreadsheet.model;
+
+public class Image
+{
+   private int top;
+   private int left;
+   private int width;
+   private int height;
+   private byte[] data;
+
+   public int getTop()
+   {
+      return top;
+   }
+
+   public void setTop(int top)
+   {
+      this.top = top;
+   }
+
+   public int getLeft()
+   {
+      return left;
+   }
+
+   public void setLeft(int left)
+   {
+      this.left = left;
+   }
+
+   public int getWidth()
+   {
+      return width;
+   }
+
+   public void setWidth(int width)
+   {
+      this.width = width;
+   }
+
+   public int getHeight()
+   {
+      return height;
+   }
+
+   public void setHeight(int height)
+   {
+      this.height = height;
+   }
+
+   public byte[] getData()
+   {
+      return data;
+   }
+
+   public void setData(byte[] data)
+   {
+      this.data = data;
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Range.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Range.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Range.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,39 @@
+package org.jboss.seam.spreadsheet.model;
+
+public class Range
+{
+   private Coordinate topLeft;
+   private Coordinate bottomRight;
+
+   protected Range(Coordinate topLeft, Coordinate bottomRight)
+   {
+      this.topLeft = topLeft;
+      this.bottomRight = bottomRight;
+   }
+
+   public static Range of(Coordinate topLeft, Coordinate bottomRight)
+   {
+      return new Range(topLeft, bottomRight);
+   }
+
+   public static Range of(int top, int left, int bottom, int right)
+   {
+      return of(Coordinate.of(top, left), Coordinate.of(bottom, right));
+   }
+
+   public Coordinate getTopLeft()
+   {
+      return topLeft;
+   }
+
+   public Coordinate getBottomRight()
+   {
+      return bottomRight;
+   }
+
+   @Override
+   public String toString()
+   {
+      return String.format("Range from %s to %s", topLeft, bottomRight);
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Workbook.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Workbook.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Workbook.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,50 @@
+package org.jboss.seam.spreadsheet.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.seam.spreadsheet.model.command.Command;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormatRule;
+
+public class Workbook
+{
+   private List<Worksheet> worksheets = new ArrayList<Worksheet>();
+   private List<CellFormatRule> cellFormatRules = new ArrayList<CellFormatRule>();
+   private List<Command> commands = new ArrayList<Command>();
+
+   public List<Worksheet> getWorksheets()
+   {
+      return worksheets;
+   }
+
+   public void setWorksheets(List<Worksheet> worksheets)
+   {
+      this.worksheets = worksheets;
+   }
+
+   public List<CellFormatRule> getCellFormatRules()
+   {
+      return cellFormatRules;
+   }
+
+   public void setCellFormatRules(List<CellFormatRule> cellFormatRules)
+   {
+      this.cellFormatRules = cellFormatRules;
+   }
+
+   public List<Command> getCommands()
+   {
+      return commands;
+   }
+
+   public void setCommands(List<Command> commands)
+   {
+      this.commands = commands;
+   }
+
+   @Override
+   public String toString()
+   {
+      return String.format("Workbook with %d sheets", worksheets.size());
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Worksheet.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Worksheet.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/Worksheet.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,71 @@
+package org.jboss.seam.spreadsheet.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.seam.spreadsheet.model.command.Command;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormatRule;
+
+public class Worksheet
+{
+   private String name;
+   private List<Cell> cells = new ArrayList<Cell>();
+   private List<CellFormatRule> cellFormatRules = new ArrayList<CellFormatRule>();
+   private List<Command> commands = new ArrayList<Command>();
+
+   protected Worksheet(String name)
+   {
+      this.name = name;
+   }
+
+   public String getName()
+   {
+      return name;
+   }
+
+   public void setName(String name)
+   {
+      this.name = name;
+   }
+
+   public List<Cell> getCells()
+   {
+      return cells;
+   }
+
+   public void setCells(List<Cell> cells)
+   {
+      this.cells = cells;
+   }
+
+   public List<CellFormatRule> getCellFormatRules()
+   {
+      return cellFormatRules;
+   }
+
+   public void setCellFormatRules(List<CellFormatRule> cellFormatRules)
+   {
+      this.cellFormatRules = cellFormatRules;
+   }
+
+   public static Worksheet named(String name)
+   {
+      return new Worksheet(name);
+   }
+
+   public List<Command> getCommands()
+   {
+      return commands;
+   }
+
+   public void setCommands(List<Command> commands)
+   {
+      this.commands = commands;
+   }
+
+   @Override
+   public String toString()
+   {
+      return String.format("Worksheet %s", name);
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/builder/IteratingCoordinate.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/builder/IteratingCoordinate.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/builder/IteratingCoordinate.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,31 @@
+package org.jboss.seam.spreadsheet.model.builder;
+
+import org.jboss.seam.spreadsheet.model.Coordinate;
+
+public class IteratingCoordinate extends Coordinate
+{
+   private Coordinate startingCoordinate;
+
+   protected IteratingCoordinate(Coordinate startingCoordinate)
+   {
+      super(startingCoordinate);
+      this.startingCoordinate = startingCoordinate;
+   }
+
+   public void nextRow()
+   {
+      setRow(getRow() + 1);
+      setColumn(startingCoordinate.getColumn());
+   }
+
+   public void nextColumn()
+   {
+      setColumn(getColumn() + 1);
+   }
+
+   public static IteratingCoordinate of(Coordinate coordinate)
+   {
+      return new IteratingCoordinate(coordinate);
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/builder/WorkbookBuilder.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/builder/WorkbookBuilder.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/builder/WorkbookBuilder.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,192 @@
+package org.jboss.seam.spreadsheet.model.builder;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.Coordinate;
+import org.jboss.seam.spreadsheet.model.Range;
+import org.jboss.seam.spreadsheet.model.Workbook;
+import org.jboss.seam.spreadsheet.model.Worksheet;
+import org.jboss.seam.spreadsheet.model.command.Command;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormatRule;
+import org.jboss.seam.spreadsheet.model.formatting.RangeCellFormatRule;
+import org.jboss.seam.spreadsheet.util.ReflectionUtil;
+
+public class WorkbookBuilder
+{
+   Workbook workbook = new Workbook();
+   Worksheet worksheet;
+
+   IteratingCoordinate cursor;
+
+   public void clear()
+   {
+      workbook = new Workbook();
+      worksheet = null;
+      cursor = null;
+   }
+
+   private WorkbookBuilder ensureWorksheet()
+   {
+      if (worksheet == null)
+      {
+         onWorksheet("Sheet 1");
+      }
+      return this;
+   }
+
+   public Workbook getWorkbook()
+   {
+      return workbook;
+   }
+
+   private Worksheet findWorksheet(String name)
+   {
+      for (Worksheet worksheet : workbook.getWorksheets())
+      {
+         if (name.equals(worksheet.getName()))
+         {
+            return worksheet;
+         }
+      }
+      return null;
+   }
+
+   public WorkbookBuilder onWorksheet(String name)
+   {
+      worksheet = findWorksheet(name);
+      if (worksheet == null)
+      {
+         worksheet = Worksheet.named(name);
+         workbook.getWorksheets().add(worksheet);
+      }
+      if (cursor == null)
+      {
+         cursor = IteratingCoordinate.of(Coordinate.ORIGO);
+      }
+      return this;
+   }
+
+   public <T> WorkbookBuilder withHeaders(Object[] data)
+   {
+      return withHeaders(data, null);
+   }
+
+   public <T> WorkbookBuilder withHeaders(Object[] data, CellFormat cellFormat)
+   {
+      ensureWorksheet();
+      Coordinate startingCoordinate = Coordinate.of(cursor);
+      for (Object value : data)
+      {
+         worksheet.getCells().add(Cell.of(value, cursor));
+         cursor.nextColumn();
+      }
+      cursor.nextRow();
+      if (cellFormat != null)
+      {
+         addHeaderCellFormatRule(startingCoordinate, data.length, cellFormat);
+      }
+      return this;
+   }
+
+   public <T> WorkbookBuilder place(Iterable<T> data)
+   {
+      place(data, getFieldNames(data.iterator().next().getClass()), null);
+      return this;
+   }
+
+   private <T> String[] getFieldNames(Class<T> clazz)
+   {
+      List<String> fieldNames = new ArrayList<String>();
+      for (Field field : clazz.getDeclaredFields())
+      {
+         fieldNames.add(field.getName());
+      }
+      return fieldNames.toArray(new String[] {});
+   }
+
+   public <T> WorkbookBuilder place(Iterable<T> data, CellFormat cellFormat)
+   {
+      place(data, getFieldNames(data.iterator().next().getClass()), cellFormat);
+      return this;
+   }
+
+   public <T> WorkbookBuilder place(Iterable<T> data, String[] fieldNames, CellFormat cellFormat)
+   {
+      ensureWorksheet();
+      Coordinate startingCoordinate = Coordinate.of(cursor);
+      ReflectionUtil ru = ReflectionUtil.of(data.iterator().next().getClass());
+      for (T dataInstance : data)
+      {
+         for (String fieldName : fieldNames)
+         {
+            Object value = ru.readValue(dataInstance, fieldName);
+            worksheet.getCells().add(Cell.of(value, cursor));
+            cursor.nextColumn();
+         }
+         cursor.nextRow();
+      }
+      if (cellFormat != null)
+      {
+         addDataCellFormatRule(startingCoordinate, fieldNames.length, cellFormat);
+      }
+      return this;
+   }
+
+   private void addHeaderCellFormatRule(Coordinate startCoordinate, int blockWidth, CellFormat cellFormat)
+   {
+      Coordinate topLeft = Coordinate.of(startCoordinate.getColumn(), startCoordinate.getRow());
+      Coordinate bottomRight = Coordinate.of(startCoordinate.getColumn() + blockWidth - 1, startCoordinate.getRow());
+      Range range = Range.of(topLeft, bottomRight);
+      addWorksheetCellFormatRule(RangeCellFormatRule.of(cellFormat, range));
+   }
+
+   private void addDataCellFormatRule(Coordinate startCoordinate, int blockWidth, CellFormat cellFormat)
+   {
+      Coordinate topLeft = Coordinate.of(startCoordinate.getColumn(), startCoordinate.getRow());
+      Coordinate bottomRight = Coordinate.of(startCoordinate.getColumn() + blockWidth - 1, cursor.getRow() - 1);
+      Range range = Range.of(topLeft, bottomRight);
+      addWorksheetCellFormatRule(RangeCellFormatRule.of(cellFormat, range));
+   }
+
+   public IteratingCoordinate getCursor()
+   {
+      return cursor;
+   }
+
+   public WorkbookBuilder addWorkbookCellFormatRule(CellFormatRule rule)
+   {
+      workbook.getCellFormatRules().add(rule);
+      return this;
+   }
+
+   public WorkbookBuilder addWorkbookCommand(Command command)
+   {
+      workbook.getCommands().add(command);
+      return this;
+   }
+
+   public WorkbookBuilder addWorksheetCellFormatRule(CellFormatRule rule)
+   {
+      ensureWorksheet();
+      worksheet.getCellFormatRules().add(rule);
+      return this;
+   }
+
+   public WorkbookBuilder addWorksheetCommand(Command command)
+   {
+      ensureWorksheet();
+      worksheet.getCommands().add(command);
+      return this;
+   }
+
+   public WorkbookBuilder at(int column, int row)
+   {
+      cursor = new IteratingCoordinate(Coordinate.of(column, row));
+      return this;
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/ColumnWidthCommand.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/ColumnWidthCommand.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/ColumnWidthCommand.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,44 @@
+package org.jboss.seam.spreadsheet.model.command;
+
+public class ColumnWidthCommand implements Command
+{
+   private int columnStart;
+   private int columnEnd;
+   private int width;
+
+   public ColumnWidthCommand(int columnStart, int columnEnd, int width)
+   {
+      this.columnStart = columnStart;
+      this.columnEnd = columnEnd;
+      this.width = width;
+   }
+
+   public ColumnWidthCommand(int column, int width)
+   {
+      columnStart = column;
+      columnEnd = column;
+      this.width = width;
+   }
+
+   @Override
+   public CommandId getCommandId()
+   {
+      return CommandId.COLUMN_WIDTH;
+   }
+
+   public int getColumnStart()
+   {
+      return columnStart;
+   }
+
+   public int getColumnEnd()
+   {
+      return columnEnd;
+   }
+
+   public int getWidth()
+   {
+      return width;
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/Command.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/Command.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/Command.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,11 @@
+package org.jboss.seam.spreadsheet.model.command;
+
+public interface Command
+{
+   public enum CommandId
+   {
+      COLUMN_WIDTH, ROW_HEIGHT
+   };
+
+   public abstract CommandId getCommandId();
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/RowHeightCommand.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/RowHeightCommand.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/command/RowHeightCommand.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,43 @@
+package org.jboss.seam.spreadsheet.model.command;
+
+public class RowHeightCommand implements Command
+{
+   private int rowStart;
+   private int rowEnd;
+   private int height;
+
+   public RowHeightCommand(int rowStart, int rowEnd, int height)
+   {
+      this.rowStart = rowStart;
+      this.rowEnd = rowEnd;
+      this.height = height;
+   }
+
+   public RowHeightCommand(int row, int height)
+   {
+      rowStart = row;
+      rowEnd = row;
+      this.height = height;
+   }
+
+   @Override
+   public CommandId getCommandId()
+   {
+      return CommandId.ROW_HEIGHT;
+   }
+
+   public int getRowStart()
+   {
+      return rowStart;
+   }
+
+   public int getRowEnd()
+   {
+      return rowEnd;
+   }
+
+   public int getHeight()
+   {
+      return height;
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Background.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Background.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Background.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,76 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+import static org.jboss.seam.spreadsheet.util.HashUtil.same;
+
+public class Background
+{
+   public enum Pattern
+   {
+      GRAY_25, GRAY_50, GRAY_75, NONE, PATTERN1, PATTERN10, PATTERN11, PATTERN12, PATTERN13, PATTERN14, PATTERN2, PATTERN3, PATTERN4, PATTERN5, PATTERN6, PATTERN7, PATTERN8, PATTERN9, SOLID
+   }
+
+   private Colour colour;
+   private Pattern pattern;
+
+   public Colour getColour()
+   {
+      return colour;
+   }
+
+   public void setColour(Colour colour)
+   {
+      this.colour = colour;
+   }
+
+   public Pattern getPattern()
+   {
+      return pattern;
+   }
+
+   public void setPattern(Pattern pattern)
+   {
+      this.pattern = pattern;
+   }
+
+   public Background merge(Background background)
+   {
+      if (background.getPattern() != null)
+      {
+         pattern = background.getPattern();
+      }
+      if (background.getColour() != null)
+      {
+         colour = background.getColour();
+      }
+      return this;
+   }
+
+   @Override
+   public boolean equals(Object other)
+   {
+      if (other == null)
+      {
+         return false;
+      }
+      if (!(other instanceof Background))
+      {
+         return false;
+      }
+      Background otherBackground = (Background) other;
+      if (!same(pattern, otherBackground.getPattern()))
+      {
+         return false;
+      }
+      if (!same(colour, otherBackground.getColour()))
+      {
+         return false;
+      }
+      return true;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return (pattern == null ? 0 : pattern.ordinal()) + (colour == null ? 0 : colour.ordinal());
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Border.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Border.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Border.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,103 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+import static org.jboss.seam.spreadsheet.util.HashUtil.same;
+
+import org.jboss.seam.spreadsheet.model.formatting.Border.BorderType;
+
+public class Border
+{
+   public enum BorderType
+   {
+      ALL, BOTTOM, LEFT, NONE, RIGHT, TOP
+   }
+
+   public enum BorderLineStyle
+   {
+      DASH_DOT, DASH_DOT_DOT, DASHED, DOTTED, DOUBLE, HAIR, MEDIUM, MEDIUM_DASH_DOT, MEDIUM_DASH_DOT_DOT, MEDIUM_DASHED, NONE, SLANTED_DASH_DOT, THICK, THIN
+   }
+
+   private BorderType borderType;
+   private BorderLineStyle lineStyle;
+   private Colour colour;
+
+   public Border(BorderType borderType)
+   {
+      this.borderType = borderType;
+   }
+
+   public BorderType getBorderType()
+   {
+      return borderType;
+   }
+
+   public void setBorderType(BorderType borderType)
+   {
+      this.borderType = borderType;
+   }
+
+   public BorderLineStyle getLineStyle()
+   {
+      return lineStyle;
+   }
+
+   public void setLineStyle(BorderLineStyle lineStyle)
+   {
+      this.lineStyle = lineStyle;
+   }
+
+   public Colour getColour()
+   {
+      return colour;
+   }
+
+   public void setColour(Colour colour)
+   {
+      this.colour = colour;
+   }
+
+   public Border merge(Border border)
+   {
+      if (border.getColour() != null)
+      {
+         colour = border.getColour();
+      }
+      if (border.getLineStyle() != null)
+      {
+         lineStyle = border.getLineStyle();
+      }
+      return this;
+   }
+
+   @Override
+   public boolean equals(Object other)
+   {
+      if (other == null)
+      {
+         return false;
+      }
+      if (!(other instanceof Border))
+      {
+         return false;
+      }
+      Border otherBorder = (Border) other;
+      if (!same(borderType, otherBorder.getBorderType()))
+      {
+         return false;
+      }
+      if (!same(lineStyle, otherBorder.getLineStyle()))
+      {
+         return false;
+      }
+      if (!same(colour, otherBorder.getColour()))
+      {
+         return false;
+      }
+      return true;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return (borderType == null ? 0 : borderType.ordinal()) + (lineStyle == null ? 0 : lineStyle.ordinal()) + (colour == null ? 0 : colour.ordinal());
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/CellFormat.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/CellFormat.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/CellFormat.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,295 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+import static org.jboss.seam.spreadsheet.util.HashUtil.collectionHashCode;
+import static org.jboss.seam.spreadsheet.util.HashUtil.same;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.seam.spreadsheet.model.formatting.Border.BorderType;
+
+public class CellFormat
+{
+   public enum Type
+   {
+      CASCADING, ABSOLUTE
+   }
+
+   public enum Alignment
+   {
+      CENTRE, FILL, GENERAL, JUSTIFY, LEFT, RIGHT
+   }
+
+   public enum Orientation
+   {
+      HORIZONTAL, MINUS_45, MINUS_90, PLUS_45, PLUS_90, STACKED, VERTICAL
+   }
+
+   public enum VerticalAlignment
+   {
+      BOTTOM, CENTRE, JUSTIFY, TOP
+   }
+
+   private Type type = Type.CASCADING;
+   private Font font;
+   private Alignment alignment;
+   private Background background;
+   private List<Border> borders = new ArrayList<Border>();
+   private Integer indentation;
+   private Boolean locked;
+   private Orientation orientation;
+   private Boolean shrinkToFit;
+   private VerticalAlignment verticalAlignment;
+   private Boolean wrap;
+   private String mask;
+
+   public Type getType()
+   {
+      return type;
+   }
+
+   public void setType(Type type)
+   {
+      this.type = type;
+   }
+
+   public Font getFont()
+   {
+      return font;
+   }
+
+   public void setFont(Font font)
+   {
+      this.font = font;
+   }
+
+   public String getMask()
+   {
+      return mask;
+   }
+
+   public void setMask(String mask)
+   {
+      this.mask = mask;
+   }
+
+   public Alignment getAlignment()
+   {
+      return alignment;
+   }
+
+   public void setAlignment(Alignment alignment)
+   {
+      this.alignment = alignment;
+   }
+
+   public Background getBackground()
+   {
+      return background;
+   }
+
+   public void setBackground(Background background)
+   {
+      this.background = background;
+   }
+
+   public List<Border> getBorders()
+   {
+      return borders;
+   }
+
+   public void setBorders(List<Border> borders)
+   {
+      this.borders = borders;
+   }
+
+   public Integer getIndentation()
+   {
+      return indentation;
+   }
+
+   public void setIndentation(Integer indentation)
+   {
+      this.indentation = indentation;
+   }
+
+   public Boolean getLocked()
+   {
+      return locked;
+   }
+
+   public void setLocked(Boolean locked)
+   {
+      this.locked = locked;
+   }
+
+   public Orientation getOrientation()
+   {
+      return orientation;
+   }
+
+   public void setOrientation(Orientation orientation)
+   {
+      this.orientation = orientation;
+   }
+
+   public Boolean getShrinkToFit()
+   {
+      return shrinkToFit;
+   }
+
+   public void setShrinkToFit(Boolean shrinkToFit)
+   {
+      this.shrinkToFit = shrinkToFit;
+   }
+
+   public VerticalAlignment getVerticalAlignment()
+   {
+      return verticalAlignment;
+   }
+
+   public void setVerticalAlignment(VerticalAlignment verticalAlignment)
+   {
+      this.verticalAlignment = verticalAlignment;
+   }
+
+   public Boolean getWrap()
+   {
+      return wrap;
+   }
+
+   public void setWrap(Boolean wrap)
+   {
+      this.wrap = wrap;
+   }
+
+   public CellFormat merge(CellFormat cellFormat)
+   {
+      if (cellFormat == null)
+      {
+         return this;
+      }
+      if (cellFormat.getFont() != null)
+      {
+         if (font == null)
+         {
+            font = new Font();
+         }
+         font.merge(cellFormat.getFont());
+      }
+      if (locked == null)
+      {
+         locked = cellFormat.getLocked();
+      }
+      if (shrinkToFit == null)
+      {
+         shrinkToFit = cellFormat.getShrinkToFit();
+      }
+      if (wrap == null)
+      {
+         wrap = cellFormat.getWrap();
+      }
+      if (alignment == null)
+      {
+         alignment = cellFormat.getAlignment();
+      }
+      if (cellFormat.getBackground() != null)
+      {
+         if (background == null)
+         {
+            background = new Background();
+         }
+         background.merge(cellFormat.getBackground());
+      }
+      if (!cellFormat.getBorders().isEmpty())
+      {
+         mergeBorders(cellFormat.getBorders());
+      }
+      if (indentation == null)
+      {
+         indentation = cellFormat.getIndentation();
+      }
+      if (mask == null)
+      {
+         mask = cellFormat.getMask();
+      }
+      if (orientation == null)
+      {
+         orientation = cellFormat.getOrientation();
+      }
+      if (verticalAlignment == null)
+      {
+         verticalAlignment = cellFormat.getVerticalAlignment();
+      }
+      return this;
+   }
+
+   private void mergeBorders(List<Border> otherBorders)
+   {
+      for (Border otherBorder : otherBorders)
+      {
+         List<BorderType> mergeTypes = new ArrayList<BorderType>();
+         if (otherBorder.getBorderType().equals(BorderType.ALL))
+         {
+            mergeTypes.add(BorderType.LEFT);
+            mergeTypes.add(BorderType.RIGHT);
+            mergeTypes.add(BorderType.BOTTOM);
+            mergeTypes.add(BorderType.TOP);
+         }
+         else
+         {
+            mergeTypes.add(otherBorder.getBorderType());
+         }
+         for (BorderType mergeType : mergeTypes)
+         {
+            mergeBorder(otherBorder, mergeType);
+         }
+      }
+   }
+
+   private void mergeBorder(Border otherBorder, BorderType mergeType)
+   {
+      Border localBorder = getBorder(mergeType);
+      if (localBorder == null)
+      {
+         Border newBorder = new Border(otherBorder.getBorderType());
+         newBorder.merge(otherBorder);
+         borders.add(newBorder);
+      }
+      else
+      {
+         localBorder.merge(otherBorder);
+      }
+
+   }
+
+   private Border getBorder(BorderType borderType)
+   {
+      for (Border border : borders)
+      {
+         if (borderType.equals(border.getBorderType()))
+         {
+            return border;
+         }
+      }
+      return null;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return (font == null ? 0 : font.hashCode()) + (alignment == null ? 0 : alignment.ordinal()) + (background == null ? 0 : background.hashCode()) + (borders == null ? 0 : collectionHashCode(borders)) + (indentation == null ? 0 : indentation) + (locked == null ? 0 : locked ? 1 : 0) + (orientation == null ? 0 : orientation.ordinal()) + (shrinkToFit == null ? 0 : shrinkToFit ? 1 : 0) + (verticalAlignment == null ? 0 : verticalAlignment.ordinal()) + (wrap == null ? 0 : wrap ? 1 : 0) + (mask == null ? 0 : mask.hashCode());
+   }
+
+   @Override
+   public boolean equals(Object other)
+   {
+      if (!(other instanceof CellFormat))
+      {
+         return false;
+      }
+      CellFormat otherCellFormat = (CellFormat) other;
+      return same(font, otherCellFormat.getFont()) && same(alignment, otherCellFormat.getAlignment()) && same(background, otherCellFormat.getBackground()) && same(borders, otherCellFormat.getBorders()) && same(indentation, otherCellFormat.getIndentation()) && same(locked, otherCellFormat.getLocked()) && same(orientation, otherCellFormat.getOrientation()) && same(shrinkToFit, otherCellFormat.getShrinkToFit()) && same(verticalAlignment, otherCellFormat.getVerticalAlignment()) && same(wrap, otherCellFormat.getWrap()) && same(mask, otherCellFormat.getMask());
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/CellFormatRule.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/CellFormatRule.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/CellFormatRule.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,9 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+import org.jboss.seam.spreadsheet.model.Cell;
+
+public interface CellFormatRule
+{
+   public abstract boolean appliesTo(Cell cell);
+   public abstract CellFormat getCellFormat();
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Colour.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Colour.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Colour.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,6 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+public enum Colour
+{
+   AQUA, AUTOMATIC, BLACK, BLUE, BLUE_GREY, BLUE2, BRIGHT_GREEN, BROWN, CORAL, DARK_BLUE, DARK_BLUE2, DARK_GREEN, DARK_PURPLE, DARK_RED, DARK_RED2, DARK_TEAL, DARK_YELLOW, DEFAULT_BACKGROUND, DEFAULT_BACKGROUND1, GOLD, GRAY_25, GRAY_50, GRAY_80, GREEN, GREY_25_PERCENT, GREY_40_PERCENT, GREY_50_PERCENT, GREY_80_PERCENT, ICE_BLUE, INDIGO, IVORY, LAVENDER, LIGHT_BLUE, LIGHT_GREEN, LIGHT_ORANGE, LIGHT_TURQUOISE, LIGHT_TURQUOISE2, LIME, OCEAN_BLUE, OLIVE_GREEN, ORANGE, PALE_BLUE, PALETTE_BLACK, PERIWINKLE, PINK, PINK2, PLUM, PLUM2, RED, ROSE, SEA_GREEN, SKY_BLUE, TAN, TEAL, TEAL2, TURQOISE2, TURQUOISE, UNKNOWN, VERY_LIGHT_YELLOW, VIOLET, VIOLET2, WHITE, YELLOW, YELLOW2
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Font.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Font.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/Font.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,192 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+import static org.jboss.seam.spreadsheet.util.HashUtil.same;
+
+public class Font
+{
+   public enum ScriptStyle
+   {
+      NORMAL_SCRIPT, SUBSCRIPT, SUPERSCRIPT
+   };
+
+   public enum UnderlineStyle
+   {
+      NO_UNDERLINE, SINGLE, SINGLE_ACCOUNTING, DOUBLE, DOUBLE_ACCOUNTING
+   };
+
+   private String fontName;
+   private Integer pointSize;
+   private Colour colour;
+   private ScriptStyle scriptStyle;
+   private UnderlineStyle underlineStyle;
+   private Boolean bold;
+   private Boolean struckOut;
+   private Boolean italic;
+
+   public String getFontName()
+   {
+      return fontName;
+   }
+
+   public void setFontName(String fontName)
+   {
+      this.fontName = fontName;
+   }
+
+   public Integer getPointSize()
+   {
+      return pointSize;
+   }
+
+   public void setPointSize(int pointSize)
+   {
+      this.pointSize = pointSize;
+   }
+
+   public Colour getColour()
+   {
+      return colour;
+   }
+
+   public void setColour(Colour colour)
+   {
+      this.colour = colour;
+   }
+
+   public ScriptStyle getScriptStyle()
+   {
+      return scriptStyle;
+   }
+
+   public void setScriptStyle(ScriptStyle scriptStyle)
+   {
+      this.scriptStyle = scriptStyle;
+   }
+
+   public UnderlineStyle getUnderlineStyle()
+   {
+      return underlineStyle;
+   }
+
+   public void setUnderlineStyle(UnderlineStyle underlineStyle)
+   {
+      this.underlineStyle = underlineStyle;
+   }
+
+   public Boolean getBold()
+   {
+      return bold;
+   }
+
+   public void setBold(Boolean bold)
+   {
+      this.bold = bold;
+   }
+
+   public Boolean getStruckOut()
+   {
+      return struckOut;
+   }
+
+   public void setStruckOut(boolean struckOut)
+   {
+      this.struckOut = struckOut;
+   }
+
+   public Boolean getItalic()
+   {
+      return italic;
+   }
+
+   public void setItalic(boolean italic)
+   {
+      this.italic = italic;
+   }
+
+   public Font merge(Font font)
+   {
+      if (font.getBold() != null)
+      {
+         setBold(font.getBold());
+      }
+      if (font.getItalic() != null)
+      {
+         setItalic(font.getItalic());
+      }
+      if (font.getStruckOut() != null)
+      {
+         setStruckOut(font.getStruckOut());
+      }
+      if (font.getColour() != null)
+      {
+         setColour(font.getColour());
+      }
+      if (font.getFontName() != null)
+      {
+         setFontName(font.getFontName());
+      }
+      if (font.getPointSize() != null)
+      {
+         setPointSize(font.getPointSize());
+      }
+      if (font.getScriptStyle() != null)
+      {
+         setScriptStyle(font.getScriptStyle());
+      }
+      if (font.getUnderlineStyle() != null)
+      {
+         setUnderlineStyle(font.getUnderlineStyle());
+      }
+      return this;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return (fontName == null ? 0 : fontName.hashCode()) + (pointSize == null ? 0 : pointSize.intValue()) + (colour == null ? 0 : colour.ordinal()) + (scriptStyle == null ? 0 : scriptStyle.ordinal()) + (underlineStyle == null ? 0 : underlineStyle.ordinal()) + (bold == null ? 0 : bold.booleanValue() ? 1 : 0) + (struckOut == null ? 0 : struckOut.booleanValue() ? 1 : 0) + (italic == null ? 0 : italic.booleanValue() ? 1 : 0);
+   }
+
+   @Override
+   public boolean equals(Object other)
+   {
+      if (!(other instanceof Font))
+      {
+         return false;
+      }
+      Font otherFont = (Font) other;
+      if (!same(fontName, otherFont.getFontName()))
+      {
+         return false;
+      }
+      if (!same(pointSize, otherFont.getPointSize()))
+      {
+         return false;
+      }
+      if (!same(colour, otherFont.getColour()))
+      {
+         return false;
+      }
+      if (!same(scriptStyle, otherFont.getScriptStyle()))
+      {
+         return false;
+      }
+      if (!same(underlineStyle, otherFont.getUnderlineStyle()))
+      {
+         return false;
+      }
+      if (!same(bold, otherFont.getBold()))
+      {
+         return false;
+      }
+      if (!same(struckOut, otherFont.getStruckOut()))
+      {
+         return false;
+      }
+      if (!same(italic, otherFont.getItalic()))
+      {
+         return false;
+      }
+      return true;
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/RangeCellFormatRule.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/RangeCellFormatRule.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/model/formatting/RangeCellFormatRule.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,35 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.Coordinate;
+import org.jboss.seam.spreadsheet.model.Range;
+
+public class RangeCellFormatRule implements CellFormatRule
+{
+   private CellFormat cellFormat;
+   private Range range;
+
+   protected RangeCellFormatRule(CellFormat cellFormat, Range range)
+   {
+      this.cellFormat = cellFormat;
+      this.range = range;
+   }
+
+   public static RangeCellFormatRule of(CellFormat cellFormat, Range range)
+   {
+      return new RangeCellFormatRule(cellFormat, range);
+   }
+
+   @Override
+   public boolean appliesTo(Cell cell)
+   {
+      return cell.getCoordinate().within(range);
+   }
+
+   @Override
+   public CellFormat getCellFormat()
+   {
+      return cellFormat;
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/util/HashUtil.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/util/HashUtil.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/util/HashUtil.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,31 @@
+package org.jboss.seam.spreadsheet.util;
+
+public class HashUtil
+{
+   public static boolean same(Object o1, Object o2)
+   {
+      if (o1 == null && o2 == null)
+      {
+         return true;
+      }
+      if (o1 == null && o2 != null)
+      {
+         return false;
+      }
+      if (o1 != null && o2 == null)
+      {
+         return false;
+      }
+      return o1.equals(o2);
+   }
+
+   public static <T> int collectionHashCode(Iterable<T> collection)
+   {
+      int hashCode = 0;
+      for (T item : collection)
+      {
+         hashCode += item.hashCode();
+      }
+      return hashCode;
+   }
+}

Added: sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/util/ReflectionUtil.java
===================================================================
--- sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/util/ReflectionUtil.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/main/java/org/jboss/seam/spreadsheet/util/ReflectionUtil.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,104 @@
+package org.jboss.seam.spreadsheet.util;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.seam.spreadsheet.SpreadsheetException;
+
+public class ReflectionUtil
+{
+   public enum AccessType
+   {
+      FIELD, METHOD
+   };
+
+   private AccessType accessType = AccessType.FIELD;
+
+   private Map<String, Field> fields = new HashMap<String, Field>();
+   private Map<String, Method> getters = new HashMap<String, Method>();
+
+   private ReflectionUtil(Class<?> clazz)
+   {
+      initGetterMethods(clazz);
+      initFields(clazz);
+   }
+
+   private void initGetterMethods(Class<?> clazz)
+   {
+      try
+      {
+         for (PropertyDescriptor pd : Introspector.getBeanInfo(clazz).getPropertyDescriptors())
+         {
+            Method method = pd.getReadMethod();
+            method.setAccessible(true);
+            getters.put(pd.getName(), method);
+         }
+      }
+      catch (IntrospectionException e)
+      {
+         throw new SpreadsheetException(String.format("Could not determine getters for class %s", clazz.getName()), e);
+      }
+   }
+
+   private void initFields(Class<?> clazz)
+   {
+      for (Field field : clazz.getDeclaredFields())
+      {
+         field.setAccessible(true);
+         fields.put(field.getName(), field);
+      }
+   }
+
+   public static ReflectionUtil of(Class<?> clazz)
+   {
+      return new ReflectionUtil(clazz);
+   }
+
+   public Object readValue(Object instance, String fieldName)
+   {
+      switch (accessType)
+      {
+      case FIELD:
+         return getByField(instance, fieldName);
+      case METHOD:
+         return getByMethod(instance, fieldName);
+      }
+      return null;
+   }
+
+   private Object getByField(Object instance, String fieldName)
+   {
+      try
+      {
+         return fields.get(fieldName).get(instance);
+      }
+      catch (Exception e)
+      {
+         throw new SpreadsheetException(String.format("Could not read field '%s'", fieldName), e);
+      }
+   }
+
+   private Object getByMethod(Object instance, String fieldName)
+   {
+      Method getter = getters.get(fieldName);
+      try
+      {
+         return getter.invoke(instance);
+      }
+      catch (Exception e)
+      {
+         throw new SpreadsheetException(String.format("Could not read field %s using method %s", fieldName, getter), e);
+      }
+   }
+
+   public void setAccessType(AccessType accessType)
+   {
+      this.accessType = accessType;
+   }
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/CellFactoryTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/CellFactoryTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/CellFactoryTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,40 @@
+package org.jboss.seam.spreadsheet.jxl;
+
+import junit.framework.Assert;
+import jxl.write.WritableCell;
+
+import org.jboss.seam.spreadsheet.jxl.formatting.CellFactory;
+import org.jboss.seam.spreadsheet.jxl.formatting.CellFormatResolver;
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.formatting.Colour;
+import org.jboss.seam.spreadsheet.model.formatting.SpreadsheetTest;
+import org.junit.Test;
+
+public class CellFactoryTest extends SpreadsheetTest
+{
+
+   @Test
+   public void cellFormatsCachedForEqualCellFormatsTest()
+   {
+      CellFactory cellFactory = new CellFactory();
+      CellFormatResolver cellFormatResolver = new CellFormatResolver();
+      WritableCell jxlCell = cellFactory.createCell(getTestCell(), cellFormatResolver);
+      WritableCell jxlCell2 = cellFactory.createCell(getTestCell(), cellFormatResolver);
+      Assert.assertEquals(jxlCell.getCellFormat(), jxlCell2.getCellFormat());
+   }
+
+   @Test
+   public void cellFormatsNotCachedForNonEqualCellFormatsTest()
+   {
+      CellFactory cellFactory = new CellFactory();
+      CellFormatResolver cellFormatResolver = new CellFormatResolver();
+      WritableCell jxlCell = cellFactory.createCell(getTestCell(), cellFormatResolver);
+      Cell cell2 = getTestCell();
+      cell2.getCellFormat().setFont(getSampleFont());
+      cell2.getCellFormat().getFont().setColour(Colour.RED);
+      WritableCell jxlCell2 = cellFactory.createCell(cell2, cellFormatResolver);
+      // Assert.assertEquals(jxlCell.getCellFormat(), jxlCell2.getCellFormat());
+   }
+
+
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/CellFormatFactoryTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/CellFormatFactoryTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/CellFormatFactoryTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,187 @@
+package org.jboss.seam.spreadsheet.jxl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.jboss.seam.spreadsheet.jxl.formatting.CellFactory;
+import org.jboss.seam.spreadsheet.jxl.formatting.CellFormatResolver;
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.formatting.Background;
+import org.jboss.seam.spreadsheet.model.formatting.Background.Pattern;
+import org.jboss.seam.spreadsheet.model.formatting.Border;
+import org.jboss.seam.spreadsheet.model.formatting.Border.BorderLineStyle;
+import org.jboss.seam.spreadsheet.model.formatting.Border.BorderType;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.Alignment;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.Orientation;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.VerticalAlignment;
+import org.jboss.seam.spreadsheet.model.formatting.Colour;
+import org.jboss.seam.spreadsheet.model.formatting.SpreadsheetTest;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CellFormatFactoryTest extends SpreadsheetTest
+{
+   private CellFactory cellFactory;
+   private CellFormatResolver cellFormatResolver;
+   private Cell cell;
+
+   @Before
+   public void init()
+   {
+      cellFactory = new CellFactory();
+      cellFormatResolver = new CellFormatResolver();
+      cell = getTestCell();
+   }
+
+   private jxl.write.WritableCell getJxlCell()
+   {
+      return cellFactory.createCell(cell, cellFormatResolver);
+   }
+
+   @Test
+   public void fontTest()
+   {
+      cell.getCellFormat().setFont(getSampleFont());
+      jxl.format.Font jxlFont = getJxlCell().getCellFormat().getFont();
+      Assert.assertEquals("Times New Roman", jxlFont.getName());
+      Assert.assertEquals(700, jxlFont.getBoldWeight());
+      Assert.assertEquals(jxl.format.Colour.RED, jxlFont.getColour());
+      Assert.assertTrue(jxlFont.isItalic());
+      Assert.assertEquals(100, jxlFont.getPointSize());
+      Assert.assertTrue(jxlFont.isStruckout());
+      Assert.assertEquals(jxl.format.ScriptStyle.SUBSCRIPT, jxlFont.getScriptStyle());
+      Assert.assertEquals(jxl.format.UnderlineStyle.DOUBLE, jxlFont.getUnderlineStyle());
+   }
+
+   @Test
+   public void alignmentTest()
+   {
+      cell.getCellFormat().setAlignment(Alignment.RIGHT);
+      Assert.assertEquals(jxl.format.Alignment.RIGHT, getJxlCell().getCellFormat().getAlignment());
+   }
+
+   @Test
+   public void backgroundColourTest()
+   {
+      cell.getCellFormat().setBackground(new Background());
+      cell.getCellFormat().getBackground().setColour(Colour.BLUE);
+      Assert.assertEquals(jxl.format.Colour.BLUE, getJxlCell().getCellFormat().getBackgroundColour());
+   }
+
+   @Test
+   public void borderColourTest()
+   {
+      List<Border> borders = new ArrayList<Border>();
+      Border border = new Border(BorderType.TOP);
+      border.setColour(Colour.PINK);
+      borders.add(border);
+      cell.getCellFormat().setBorders(borders);
+      Assert.assertEquals(jxl.format.Colour.PINK, getJxlCell().getCellFormat().getBorderColour(jxl.format.Border.TOP));
+   }
+
+   @Test
+   public void borderLineStyleTest()
+   {
+      List<Border> borders = new ArrayList<Border>();
+      Border border = new Border(BorderType.TOP);
+      border.setLineStyle(BorderLineStyle.DOUBLE);
+      borders.add(border);
+      cell.getCellFormat().setBorders(borders);
+      Assert.assertEquals(jxl.format.BorderLineStyle.DOUBLE, getJxlCell().getCellFormat().getBorderLine(jxl.format.Border.TOP));
+   }
+
+   @Test
+   public void indentationTest()
+   {
+      cell.getCellFormat().setIndentation(10);
+      Assert.assertEquals(10, getJxlCell().getCellFormat().getIndentation());
+   }
+
+   @Test
+   public void orientationTest()
+   {
+      cell.getCellFormat().setOrientation(Orientation.MINUS_45);
+      Assert.assertEquals(jxl.format.Orientation.MINUS_45, getJxlCell().getCellFormat().getOrientation());
+   }
+
+   @Test
+   public void patternTest()
+   {
+      cell.getCellFormat().setBackground(new Background());
+      cell.getCellFormat().getBackground().setPattern(Pattern.GRAY_50);
+      Assert.assertEquals(jxl.format.Pattern.GRAY_50, getJxlCell().getCellFormat().getPattern());
+   }
+
+   @Test
+   public void verticalAlignmentTest()
+   {
+      cell.getCellFormat().setVerticalAlignment(VerticalAlignment.TOP);
+      Assert.assertEquals(jxl.format.VerticalAlignment.TOP, getJxlCell().getCellFormat().getVerticalAlignment());
+   }
+
+   @Test
+   public void wrapTest()
+   {
+      cell.getCellFormat().setWrap(true);
+      Assert.assertTrue(getJxlCell().getCellFormat().getWrap());
+   }
+
+   @Test
+   public void lockedTest()
+   {
+      cell.getCellFormat().setLocked(true);
+      Assert.assertTrue(getJxlCell().getCellFormat().isLocked());
+   }
+
+   @Test
+   public void shrinkToFitTest()
+   {
+      cell.getCellFormat().setShrinkToFit(true);
+      Assert.assertTrue(getJxlCell().getCellFormat().isShrinkToFit());
+   }
+
+   @Test
+   public void testCustomDateMask() throws IOException
+   {
+      cell.setValue(new Date());
+      cell.getCellFormat().setMask("dd.MM.yyyy");
+      Assert.assertEquals("MM.yyyy", getJxlCell().getCellFormat().getFormat().getFormatString());
+   }
+
+   @Test
+   public void testNamedDateMask() throws IOException
+   {
+      cell.setValue(new Date());
+      cell.getCellFormat().setMask("FORMAT9");
+      Assert.assertEquals("M/d/yy H:mm", getJxlCell().getCellFormat().getFormat().getFormatString());
+   }
+
+   @Test
+   public void testCustomNumberMask()
+   {
+      cell.setValue(1.1111111f);
+      cell.getCellFormat().setMask("#.##");
+      Assert.assertEquals("#.##", getJxlCell().getCellFormat().getFormat().getFormatString());
+   }
+
+   @Test
+   public void testNamedNumberMask()
+   {
+      cell.setValue(1.1111111f);
+      cell.getCellFormat().setMask("CURRENCY_EURO_PREFIX");
+      Assert.assertEquals("CURRENCY_EURO_PREFIX", getJxlCell().getCellFormat().getFormat().getFormatString());
+   }
+
+   @Test
+   public void testNamedNumberMask2()
+   {
+      cell.setValue(1.1111111f);
+      cell.getCellFormat().setMask("EXPONENTIAL");
+      Assert.assertEquals("EXPONENTIAL", getJxlCell().getCellFormat().getFormat().getFormatString());
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/CellFormatResolverTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/CellFormatResolverTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/CellFormatResolverTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,98 @@
+package org.jboss.seam.spreadsheet.jxl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.jboss.seam.spreadsheet.jxl.formatting.CellFormatResolver;
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormatRule;
+import org.jboss.seam.spreadsheet.model.formatting.Colour;
+import org.jboss.seam.spreadsheet.model.formatting.Font;
+import org.jboss.seam.spreadsheet.model.formatting.SpreadsheetTest;
+import org.junit.Test;
+
+public class CellFormatResolverTest extends SpreadsheetTest
+{
+
+   private class SimpleRule implements CellFormatRule
+   {
+
+      private CellFormat cellFormat;
+
+      public SimpleRule(CellFormat cellFormat)
+      {
+         this.cellFormat = cellFormat;
+      }
+
+      @Override
+      public boolean appliesTo(Cell cell)
+      {
+         return true;
+      }
+
+      @Override
+      public CellFormat getCellFormat()
+      {
+         return cellFormat;
+      }
+
+   }
+
+   @Test
+   public void resolveTest() {
+
+      CellFormat cellFormat = new CellFormat();
+      Font cellFont = new Font();
+      cellFont.setBold(true);
+      cellFormat.setFont(cellFont);
+      Cell cell = new Cell();
+      cell.setCellFormat(cellFormat);
+      
+      CellFormatResolver cellFormatResolver = new CellFormatResolver(getWorkbookRules());
+      cellFormatResolver.setWorksheetRules(getWorksheetRules());
+      CellFormat effectiveCellFormat = cellFormatResolver.getEffectiveCellFormatting(cell);
+      Assert.assertEquals(Colour.RED, effectiveCellFormat.getFont().getColour());
+      Assert.assertEquals((Integer)40, effectiveCellFormat.getFont().getPointSize());
+      Assert.assertEquals(Boolean.TRUE, effectiveCellFormat.getFont().getBold());
+   }
+   
+   @Test
+   public void resolveAbsoluteTest() {
+
+      CellFormat cellFormat = new CellFormat();
+      cellFormat.setType(CellFormat.Type.ABSOLUTE);
+      cellFormat.setFont(new Font());
+      Cell cell = new Cell();
+      cell.setCellFormat(cellFormat);
+      
+      CellFormatResolver cellFormatResolver = new CellFormatResolver(getWorkbookRules());
+      cellFormatResolver.setWorksheetRules(getWorksheetRules());
+      CellFormat effectiveCellFormat = cellFormatResolver.getEffectiveCellFormatting(cell);
+      Assert.assertEquals(null, effectiveCellFormat.getFont().getColour());
+      Assert.assertEquals(null, effectiveCellFormat.getFont().getPointSize());
+      Assert.assertEquals(null, effectiveCellFormat.getFont().getBold());
+   }
+   
+   private List<CellFormatRule> getWorkbookRules() {
+      List<CellFormatRule> workbookRules = new ArrayList<CellFormatRule>();
+      CellFormat workbookCellFormat = new CellFormat();
+      Font workbookFont = new Font();
+      workbookFont.setColour(Colour.RED);
+      workbookCellFormat.setFont(workbookFont);
+      workbookRules.add(new SimpleRule(workbookCellFormat));
+      return workbookRules;
+   }
+   
+   private List<CellFormatRule> getWorksheetRules() {
+      List<CellFormatRule> worksheetRules = new ArrayList<CellFormatRule>();
+      CellFormat worksheetCellFormat = new CellFormat();
+      Font worksheetFont = new Font();
+      worksheetFont.setPointSize(40);
+      worksheetCellFormat.setFont(worksheetFont);
+      worksheetRules.add(new SimpleRule(worksheetCellFormat));
+      return worksheetRules;
+   }
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/ConstantFactoryTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/ConstantFactoryTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/ConstantFactoryTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,43 @@
+package org.jboss.seam.spreadsheet.jxl;
+
+import org.jboss.seam.spreadsheet.jxl.formatting.ConstantFactory;
+import org.jboss.seam.spreadsheet.model.formatting.Colour;
+import org.jboss.seam.spreadsheet.model.formatting.SpreadsheetTest;
+import org.jboss.seam.spreadsheet.model.formatting.Font.ScriptStyle;
+import org.jboss.seam.spreadsheet.model.formatting.Font.UnderlineStyle;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ConstantFactoryTest extends SpreadsheetTest
+{
+   @Test
+   public void coloursTest()
+   {
+      ConstantFactory constantFactory = new ConstantFactory();
+      for (Colour colour : Colour.values())
+      {
+         Assert.assertNotNull(constantFactory.getColour(colour));
+      }
+   }
+   
+   @Test
+   public void underlineStyleTest()
+   {
+      ConstantFactory constantFactory = new ConstantFactory();
+      for (UnderlineStyle underlineStyle : UnderlineStyle.values())
+      {
+         Assert.assertNotNull(constantFactory.getUnderlineStyle(underlineStyle));
+      }
+   }
+
+   @Test
+   public void scriptStyleTest()
+   {
+      ConstantFactory constantFactory = new ConstantFactory();
+      for (ScriptStyle scriptStyle : ScriptStyle.values())
+      {
+         Assert.assertNotNull(constantFactory.getScriptStyle(scriptStyle));
+      }
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/JXLSpreadsheetWriterTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/JXLSpreadsheetWriterTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/jxl/JXLSpreadsheetWriterTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,73 @@
+package org.jboss.seam.spreadsheet.jxl;
+
+import java.util.Date;
+
+import junit.framework.Assert;
+import jxl.CellType;
+import jxl.Sheet;
+
+import org.jboss.seam.spreadsheet.SpreadsheetException;
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.Coordinate;
+import org.jboss.seam.spreadsheet.model.Workbook;
+import org.jboss.seam.spreadsheet.model.Worksheet;
+import org.jboss.seam.spreadsheet.model.formatting.SpreadsheetTest;
+import org.junit.Test;
+
+public class JXLSpreadsheetWriterTest extends SpreadsheetTest
+{
+
+   @Test
+   public void testFreshWorkbook()
+   {
+      Workbook workbook = new Workbook();
+      Assert.assertTrue(workbook.getWorksheets().isEmpty());
+      Assert.assertTrue(workbook.getCellFormatRules().isEmpty());
+   }
+
+   @Test(expected = SpreadsheetException.class)
+   public void testImplicitWorksheet()
+   {
+      Workbook workbook = new Workbook();
+      jxl.Workbook jxlWorkbook = getWorkbook(workbook);
+   }
+
+   @Test
+   public void testAddWorksheet()
+   {
+      Workbook workbook = new Workbook();
+      workbook.getWorksheets().add(Worksheet.named("foo"));
+      jxl.Workbook jxlWorkbook = getWorkbook(workbook);
+      Assert.assertNotNull(jxlWorkbook.getSheet("foo"));
+   }
+
+   @Test
+   public void simpleCellTest()
+   {
+      Workbook workbook = new Workbook();
+      Worksheet worksheet = Worksheet.named("test");
+      worksheet.getCells().add(Cell.of("foo", Coordinate.of(10, 10)));
+      workbook.getWorksheets().add(worksheet);
+      jxl.Workbook jxlWorkbook = getWorkbook(workbook);
+      Assert.assertEquals("foo", jxlWorkbook.getSheet("test").getCell(10, 10).getContents());
+   }
+
+   @Test
+   public void cellTypeTest()
+   {
+      Workbook workbook = new Workbook();
+      Worksheet worksheet = Worksheet.named("test");
+      worksheet.getCells().add(Cell.of("String", Coordinate.of(0, 0)));
+      worksheet.getCells().add(Cell.of(1, Coordinate.of(1, 0)));
+      worksheet.getCells().add(Cell.of(1f, Coordinate.of(2, 0)));
+      worksheet.getCells().add(Cell.of(new Date(), Coordinate.of(3, 0)));
+      workbook.getWorksheets().add(worksheet);
+      jxl.Workbook jxlWorkbook = getWorkbook(workbook);
+      Sheet jxlSheet = jxlWorkbook.getSheet("test");
+      Assert.assertEquals(CellType.LABEL, jxlSheet.getCell(0, 0).getType());
+      Assert.assertEquals(CellType.NUMBER, jxlSheet.getCell(1, 0).getType());
+      Assert.assertEquals(CellType.NUMBER, jxlSheet.getCell(2, 0).getType());
+      Assert.assertEquals(CellType.DATE, jxlSheet.getCell(3, 0).getType());
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/CellTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/CellTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/CellTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,128 @@
+package org.jboss.seam.spreadsheet.model;
+
+import java.util.Date;
+
+import junit.framework.Assert;
+
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.Cell.CellType;
+import org.jboss.seam.spreadsheet.model.formatting.SpreadsheetTest;
+import org.junit.Test;
+
+public class CellTest extends SpreadsheetTest
+{
+   @Test
+   public void stringCellTypeTest()
+   {
+      Cell cell = new Cell();
+      cell.setValue("foo");
+      Assert.assertEquals(Cell.CellType.LABEL, cell.getCellType());
+   }
+
+   @Test
+   public void integerCellTypeTest()
+   {
+      Cell cell = new Cell();
+      cell.setValue(Integer.valueOf(1));
+      Assert.assertEquals(Cell.CellType.NUMBER, cell.getCellType());
+   }
+
+   @Test
+   public void intCellTypeTest()
+   {
+      Cell cell = new Cell();
+      cell.setValue(1);
+      Assert.assertEquals(Cell.CellType.NUMBER, cell.getCellType());
+   }
+
+   @Test
+   public void floatCellTypeTest()
+   {
+      Cell cell = new Cell();
+      cell.setValue(Float.valueOf("1"));
+      Assert.assertEquals(Cell.CellType.NUMBER, cell.getCellType());
+   }
+
+   @Test
+   public void floatCellTypeTest2()
+   {
+      Cell cell = new Cell();
+      cell.setValue(1f);
+      Assert.assertEquals(Cell.CellType.NUMBER, cell.getCellType());
+   }
+
+   @Test
+   public void doubleCellTypeTest()
+   {
+      Cell cell = new Cell();
+      cell.setValue(Double.valueOf(1));
+      Assert.assertEquals(Cell.CellType.NUMBER, cell.getCellType());
+   }
+
+   @Test
+   public void doubleCellTypeTest2()
+   {
+      Cell cell = new Cell();
+      cell.setValue(1d);
+      Assert.assertEquals(Cell.CellType.NUMBER, cell.getCellType());
+   }
+
+   @Test
+   public void longCellTypeTest()
+   {
+      Cell cell = new Cell();
+      cell.setValue(Long.valueOf(1));
+      Assert.assertEquals(Cell.CellType.NUMBER, cell.getCellType());
+   }
+
+   @Test
+   public void longCellTypeTest2()
+   {
+      Cell cell = new Cell();
+      cell.setValue(1l);
+      Assert.assertEquals(Cell.CellType.NUMBER, cell.getCellType());
+   }
+
+   @Test
+   public void shortCellTypeTest()
+   {
+      Cell cell = new Cell();
+      cell.setValue(Short.valueOf("11", 2));
+      Assert.assertEquals(Cell.CellType.NUMBER, cell.getCellType());
+   }
+
+   @Test
+   public void shortCellTypeTest2()
+   {
+      Cell cell = new Cell();
+      cell.setValue(1);
+      Assert.assertEquals(Cell.CellType.NUMBER, cell.getCellType());
+   }
+
+   @Test
+   public void dateCellTypeTest()
+   {
+      Cell cell = new Cell();
+      cell.setValue(new Date());
+      Assert.assertEquals(Cell.CellType.DATE, cell.getCellType());
+   }
+
+   @Test
+   public void sqlDateCellTypeTest()
+   {
+      Cell cell = new Cell();
+      cell.setValue(new java.sql.Date(new Date().getTime()));
+      Assert.assertEquals(Cell.CellType.DATE, cell.getCellType());
+   }
+
+   @Test
+   public void forcedCellTypeTest()
+   {
+      Cell cell = new Cell();
+      cell.setValue("x");
+      cell.setCellType(CellType.NUMBER);
+      Assert.assertEquals(Cell.CellType.NUMBER, cell.getCellType());
+
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/builder/WorkbookBuilderTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/builder/WorkbookBuilderTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/builder/WorkbookBuilderTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,272 @@
+package org.jboss.seam.spreadsheet.model.builder;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.jboss.seam.spreadsheet.SpreadsheetWriter;
+import org.jboss.seam.spreadsheet.jxl.JXLSpreadsheetWriter;
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.Coordinate;
+import org.jboss.seam.spreadsheet.model.Range;
+import org.jboss.seam.spreadsheet.model.Workbook;
+import org.jboss.seam.spreadsheet.model.Worksheet;
+import org.jboss.seam.spreadsheet.model.command.ColumnWidthCommand;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormatRule;
+import org.jboss.seam.spreadsheet.model.formatting.Colour;
+import org.jboss.seam.spreadsheet.model.formatting.Font;
+import org.jboss.seam.spreadsheet.model.formatting.RangeCellFormatRule;
+import org.jboss.seam.spreadsheet.util.Person;
+import org.junit.Test;
+
+public class WorkbookBuilderTest
+{
+   @Test
+   public void emptyWorkbookTest()
+   {
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      Assert.assertNotNull(wbb.getWorkbook());
+      Assert.assertTrue(wbb.getWorkbook().getWorksheets().isEmpty());
+   }
+
+   @Test
+   public void testInitialState()
+   {
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      Workbook wb = wbb.getWorkbook();
+      Assert.assertTrue(wb.getCommands().isEmpty());
+      Assert.assertTrue(wb.getCellFormatRules().isEmpty());
+      Assert.assertTrue(wb.getWorksheets().isEmpty());
+      Assert.assertNull(wbb.getCursor());
+   }
+
+   @Test
+   public void implicitWorksheetTest()
+   {
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      final Person person = new Person("Nicklas Karlsson", 35);
+      List<Person> persons = new ArrayList<Person>()
+      {
+         {
+            add(person);
+         }
+      };
+      wbb.place(persons);
+      Workbook wb = wbb.getWorkbook();
+      Assert.assertEquals("Sheet 1", wb.getWorksheets().iterator().next().getName());
+   }
+
+   @Test
+   public void origoAtNewWorksheetTest()
+   {
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      wbb.onWorksheet("Foo");
+      Coordinate c = wbb.getCursor();
+      Assert.assertEquals(0, c.getColumn());
+      Assert.assertEquals(0, c.getRow());
+   }
+
+   @Test
+   public void addWorksheetTest()
+   {
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      wbb.onWorksheet("Foo");
+      Workbook wb = wbb.getWorkbook();
+      Assert.assertEquals(1, wb.getWorksheets().size());
+      Assert.assertEquals("Foo", wb.getWorksheets().iterator().next().getName());
+   }
+
+   @Test
+   public void selectWorksheetTest()
+   {
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      wbb.onWorksheet("Foo");
+      wbb.onWorksheet("Foo");
+      Workbook wb = wbb.getWorkbook();
+      Assert.assertEquals(1, wb.getWorksheets().size());
+      Assert.assertEquals("Foo", wb.getWorksheets().iterator().next().getName());
+   }
+
+   @Test
+   public void moveCursorTest()
+   {
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      wbb.at(10, 10);
+      Coordinate c = wbb.getCursor();
+      Assert.assertEquals(10, c.getColumn());
+      Assert.assertEquals(10, c.getRow());
+   }
+
+   @Test
+   public void addWorkbookCommandTest()
+   {
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      wbb.addWorkbookCommand(new ColumnWidthCommand(1, 100));
+      Workbook wb = wbb.getWorkbook();
+      Assert.assertFalse(wb.getCommands().isEmpty());
+   }
+
+   @Test
+   public void addWorksheetCommandTest()
+   {
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      wbb.addWorksheetCommand(new ColumnWidthCommand(1, 100));
+      Workbook wb = wbb.getWorkbook();
+      Assert.assertFalse(wb.getWorksheets().iterator().next().getCommands().isEmpty());
+   }
+
+   @Test
+   public void addWorkbookCellFormatRuleTest()
+   {
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      wbb.addWorkbookCellFormatRule(RangeCellFormatRule.of(new CellFormat(), Range.of(1, 1, 10, 10)));
+      Workbook wb = wbb.getWorkbook();
+      Assert.assertFalse(wb.getCellFormatRules().isEmpty());
+   }
+
+   @Test
+   public void addWorksheetCellFormatRuleTest()
+   {
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      wbb.addWorksheetCellFormatRule(RangeCellFormatRule.of(new CellFormat(), Range.of(1, 1, 10, 10)));
+      Workbook wb = wbb.getWorkbook();
+      Assert.assertFalse(wb.getWorksheets().iterator().next().getCellFormatRules().isEmpty());
+   }
+
+   private List<Person> getPersons()
+   {
+      final Person nik = new Person("Nicklas Karlsson", 35);
+      final Person pete = new Person("Pete Muir", 26);
+      List<Person> persons = new ArrayList<Person>()
+      {
+         {
+            add(nik);
+            add(pete);
+         }
+      };
+      return persons;
+   }
+
+   private List<Cell> getCheckCells(Coordinate coordinate, String[] headers)
+   {
+      int checkColumn = coordinate == null ? 0 : coordinate.getColumn();
+      int checkRow = coordinate == null ? 0 : coordinate.getRow();
+      List<Cell> check = new ArrayList<Cell>();
+      if (headers != null)
+      {
+         for (String header : headers)
+         {
+            check.add(Cell.of(header, Coordinate.of(checkColumn, checkRow)));
+            checkColumn++;
+         }
+         checkRow++;
+      }
+      checkColumn = coordinate == null ? 0 : coordinate.getColumn();
+      check.add(Cell.of("Nicklas Karlsson", Coordinate.of(checkColumn, checkRow)));
+      check.add(Cell.of(35, Coordinate.of(checkColumn + 1, checkRow)));
+      check.add(Cell.of("Pete Muir", Coordinate.of(checkColumn, checkRow + 1)));
+      check.add(Cell.of(26, Coordinate.of(checkColumn + 1, checkRow + 1)));
+      return check;
+   }
+
+   private void addDataAtCoordinate(final Coordinate coordinate, String[] headers)
+   {
+      List<Person> persons = getPersons();
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      if (coordinate != null)
+      {
+         wbb.at(coordinate.getColumn(), coordinate.getRow());
+      }
+      if (headers != null)
+      {
+         wbb.withHeaders(headers);
+      }
+      wbb.place(persons);
+      Workbook wb = wbb.getWorkbook();
+      List<Cell> cells = wb.getWorksheets().iterator().next().getCells();
+      List<Cell> check = getCheckCells(coordinate, headers);
+      Assert.assertEquals(check, cells);
+   }
+
+   @Test
+   public void addDataTest()
+   {
+      addDataAtCoordinate(null, null);
+   }
+
+   @Test
+   public void addHeaderAndDataTest()
+   {
+      addDataAtCoordinate(null, new String[] { "Name", "Age" });
+   }
+
+   @Test
+   public void addDataAtCoordinateTest()
+   {
+      addDataAtCoordinate(Coordinate.of(10, 10), null);
+   }
+
+   @Test
+   public void addHeaderAndDataAtCoordinateTest()
+   {
+      addDataAtCoordinate(Coordinate.of(10, 10), new String[] { "Name", "Age" });
+   }
+
+   private Font getColoredFont(Colour colour)
+   {
+      Font font = new Font();
+      font.setColour(colour);
+      return font;
+   }
+
+   @Test
+   public void formattingTest()
+   {
+      WorkbookBuilder wbb = new WorkbookBuilder();
+      CellFormat headerCellFormat = getCellFormatWithFont(getColoredFont(Colour.BLUE));
+      CellFormat dataCellFormat = getCellFormatWithFont(getColoredFont(Colour.RED));
+      wbb.at(10, 10).withHeaders(new String[] { "Name", "Age" }, headerCellFormat).place(getPersons(), dataCellFormat);
+      Workbook wb = wbb.getWorkbook();
+      Worksheet ws = wb.getWorksheets().iterator().next();
+      Assert.assertEquals(2, ws.getCellFormatRules().size());
+      CellFormatRule headerRule = ws.getCellFormatRules().get(0);
+      Assert.assertEquals(Colour.BLUE, headerRule.getCellFormat().getFont().getColour());
+      Assert.assertFalse(headerRule.appliesTo(Cell.of("", Coordinate.of(9, 10))));
+      Assert.assertFalse(headerRule.appliesTo(Cell.of("", Coordinate.of(10, 9))));
+      Assert.assertTrue(headerRule.appliesTo(Cell.of("", Coordinate.of(10, 10))));
+      Assert.assertTrue(headerRule.appliesTo(Cell.of("", Coordinate.of(11, 10))));
+      Assert.assertFalse(headerRule.appliesTo(Cell.of("", Coordinate.of(12, 10))));
+      Assert.assertFalse(headerRule.appliesTo(Cell.of("", Coordinate.of(13, 10))));
+      Assert.assertFalse(headerRule.appliesTo(Cell.of("", Coordinate.of(10, 11))));
+      CellFormatRule dataRule = ws.getCellFormatRules().get(1);
+      Assert.assertEquals(Colour.RED, dataRule.getCellFormat().getFont().getColour());
+      Assert.assertTrue(dataRule.appliesTo(Cell.of("", Coordinate.of(10, 11))));
+      Assert.assertTrue(dataRule.appliesTo(Cell.of("", Coordinate.of(11, 11))));
+      Assert.assertTrue(dataRule.appliesTo(Cell.of("", Coordinate.of(10, 12))));
+      Assert.assertTrue(dataRule.appliesTo(Cell.of("", Coordinate.of(11, 12))));
+      Assert.assertFalse(dataRule.appliesTo(Cell.of("", Coordinate.of(12, 11))));
+      Assert.assertFalse(dataRule.appliesTo(Cell.of("", Coordinate.of(9, 11))));
+      Assert.assertFalse(dataRule.appliesTo(Cell.of("", Coordinate.of(12, 12))));
+      Assert.assertFalse(dataRule.appliesTo(Cell.of("", Coordinate.of(9, 12))));
+      Assert.assertFalse(dataRule.appliesTo(Cell.of("", Coordinate.of(10, 13))));
+      Assert.assertFalse(dataRule.appliesTo(Cell.of("", Coordinate.of(11, 13))));
+   }
+
+   private CellFormat getCellFormatWithFont(Font font)
+   {
+      CellFormat cellFormat = new CellFormat();
+      cellFormat.setFont(font);
+      return cellFormat;
+   }
+
+   @Test
+   public void complexTest()
+   {
+
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/BackgroundTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/BackgroundTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/BackgroundTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,51 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+import junit.framework.Assert;
+
+import org.jboss.seam.spreadsheet.model.formatting.Background.Pattern;
+import org.junit.Test;
+
+public class BackgroundTest extends SpreadsheetTest
+{
+
+   @Test
+   public void mergeTest() {
+      Background a = new Background();
+      Background b = getSampleBackground();
+      a.merge(b);
+      Assert.assertEquals(Colour.RED, a.getColour());
+      Assert.assertEquals(Pattern.GRAY_50, a.getPattern());
+   }
+   
+   @Test
+   public void inverseMergeTest() {
+      Background a = getSampleBackground();
+      Background b = new Background();
+      a.merge(b);
+      Assert.assertEquals(Colour.RED, a.getColour());
+      Assert.assertEquals(Pattern.GRAY_50, a.getPattern());
+   }
+   
+   @Test
+   public void equalsOKTest() {
+      Background a = getSampleBackground();
+      Background b = getSampleBackground();
+      Assert.assertTrue(a.equals(b));
+   }
+   
+   @Test
+   public void equalsFailsOnColourTest() {
+      Background a = getSampleBackground();
+      Background b = getSampleBackground();
+      b.setColour(Colour.BLACK);
+      Assert.assertFalse(a.equals(b));
+   }
+
+   @Test
+   public void equalsFailsOnPatternTest() {
+      Background a = getSampleBackground();
+      Background b = getSampleBackground();
+      b.setPattern(Pattern.SOLID);
+      Assert.assertFalse(a.equals(b));
+   }
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/BorderTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/BorderTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/BorderTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,121 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.jboss.seam.spreadsheet.model.formatting.Border.BorderLineStyle;
+import org.jboss.seam.spreadsheet.model.formatting.Border.BorderType;
+import org.junit.Test;
+
+public class BorderTest extends SpreadsheetTest
+{
+
+   @Test
+   public void mergeTest()
+   {
+      Border a = new Border(BorderType.ALL);
+      Border b = getSampleBorder();
+      a.merge(b);
+      Assert.assertEquals(Colour.RED, a.getColour());
+      Assert.assertEquals(BorderType.ALL, a.getBorderType());
+      Assert.assertEquals(BorderLineStyle.DOUBLE, a.getLineStyle());
+   }
+
+   @Test
+   public void multipleBorderMergeTest()
+   {
+      Border a = new Border(BorderType.TOP);
+      a.setColour(Colour.RED);
+      CellFormat cfa = new CellFormat();
+      cfa.getBorders().add(a);
+
+      Border b = new Border(BorderType.LEFT);
+      b.setColour(Colour.GREEN);
+      CellFormat cfb = new CellFormat();
+      cfb.getBorders().add(b);
+
+      Border c = new Border(BorderType.RIGHT);
+      c.setColour(Colour.BLUE);
+      CellFormat cfc = new CellFormat();
+      cfc.getBorders().add(c);
+
+      Border d = new Border(BorderType.BOTTOM);
+      d.setColour(Colour.WHITE);
+      CellFormat cfd = new CellFormat();
+      cfd.getBorders().add(d);
+
+      Border e = new Border(BorderType.ALL);
+      e.setLineStyle(BorderLineStyle.DOTTED);
+      CellFormat cfe = new CellFormat();
+      cfe.getBorders().add(e);
+
+      cfa.merge(cfb).merge(cfc).merge(cfd).merge(cfe);
+      Assert.assertEquals(Colour.RED, getBorder(BorderType.TOP, cfa.getBorders()).getColour());
+      Assert.assertEquals(Colour.GREEN, getBorder(BorderType.LEFT, cfa.getBorders()).getColour());
+      Assert.assertEquals(Colour.BLUE, getBorder(BorderType.RIGHT, cfa.getBorders()).getColour());
+      Assert.assertEquals(Colour.WHITE, getBorder(BorderType.BOTTOM, cfa.getBorders()).getColour());
+      Assert.assertEquals(BorderLineStyle.DOTTED, getBorder(BorderType.TOP, cfa.getBorders()).getLineStyle());
+      Assert.assertEquals(BorderLineStyle.DOTTED, getBorder(BorderType.LEFT, cfa.getBorders()).getLineStyle());
+      Assert.assertEquals(BorderLineStyle.DOTTED, getBorder(BorderType.RIGHT, cfa.getBorders()).getLineStyle());
+      Assert.assertEquals(BorderLineStyle.DOTTED, getBorder(BorderType.BOTTOM, cfa.getBorders()).getLineStyle());
+   }
+
+   private Border getBorder(BorderType type, List<Border> borders)
+   {
+      for (Border border : borders)
+      {
+         if (border.getBorderType().equals(type))
+         {
+            return border;
+         }
+      }
+      return null;
+   }
+
+   @Test
+   public void inverseMergeTest()
+   {
+      Border a = getSampleBorder();
+      Border b = new Border(BorderType.ALL);
+      a.merge(b);
+      Assert.assertEquals(Colour.RED, a.getColour());
+      Assert.assertEquals(BorderType.ALL, a.getBorderType());
+      Assert.assertEquals(BorderLineStyle.DOUBLE, a.getLineStyle());
+   }
+
+   @Test
+   public void equalsOKTest()
+   {
+      Border a = getSampleBorder();
+      Border b = getSampleBorder();
+      Assert.assertTrue(a.equals(b));
+   }
+
+   @Test
+   public void equalsFailsOnColourTest()
+   {
+      Border a = getSampleBorder();
+      Border b = getSampleBorder();
+      b.setColour(Colour.BLACK);
+      Assert.assertFalse(a.equals(b));
+   }
+
+   @Test
+   public void equalsFailsOnLineStyleTest()
+   {
+      Border a = getSampleBorder();
+      Border b = getSampleBorder();
+      b.setLineStyle(BorderLineStyle.DASH_DOT);
+      Assert.assertFalse(a.equals(b));
+   }
+
+   @Test
+   public void equalsFailsOnBorderTypeTest()
+   {
+      Border a = getSampleBorder();
+      Border b = getSampleBorder();
+      b.setBorderType(BorderType.LEFT);
+      Assert.assertFalse(a.equals(b));
+   }
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/CellFormatRuleTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/CellFormatRuleTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/CellFormatRuleTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,44 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.Coordinate;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class CellFormatRuleTest extends SpreadsheetTest
+{
+   @Test
+   public void testHit()
+   {
+      Cell cell = Cell.of("foo", Coordinate.of(15, 15));
+      Assert.assertTrue(getSampleCellFormatRule().appliesTo(cell));
+   }
+
+   @Test
+   public void testHit2()
+   {
+      Cell cell = Cell.of("foo", Coordinate.of(10, 10));
+      Assert.assertTrue(getSampleCellFormatRule().appliesTo(cell));
+   }
+
+   @Test
+   public void testHit3()
+   {
+      Cell cell = Cell.of("foo", Coordinate.of(20, 20));
+      Assert.assertTrue(getSampleCellFormatRule().appliesTo(cell));
+   }
+
+   @Test
+   public void testHit4()
+   {
+      Cell cell = Cell.of("foo", Coordinate.of(20, 21));
+      Assert.assertFalse(getSampleCellFormatRule().appliesTo(cell));
+   }
+
+   @Test
+   public void miss()
+   {
+      Cell cell = Cell.of("foo", Coordinate.of(0, 0));
+      Assert.assertFalse(getSampleCellFormatRule().appliesTo(cell));
+   }
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/CellFormatTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/CellFormatTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/CellFormatTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,83 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+import junit.framework.Assert;
+
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.Alignment;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.Orientation;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.Type;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.VerticalAlignment;
+import org.junit.Test;
+
+public class CellFormatTest extends SpreadsheetTest
+{
+
+   @Test
+   public void mergeOKTest()
+   {
+      CellFormat a = new CellFormat();
+      CellFormat b = getSampleCellFormat();
+      a.merge(b);
+      Assert.assertEquals(Alignment.LEFT, a.getAlignment());
+      Assert.assertEquals(getSampleBackground(), a.getBackground());
+      Assert.assertEquals(getSampleBorders(), a.getBorders());
+      Assert.assertEquals(getSampleFont(), a.getFont());
+      Assert.assertEquals(new Integer(1), a.getIndentation());
+      Assert.assertTrue(a.getLocked());
+      Assert.assertEquals("ACCOUNTING", a.getMask());
+      Assert.assertEquals(Orientation.MINUS_45, a.getOrientation());
+      Assert.assertTrue(a.getShrinkToFit());
+      Assert.assertEquals(VerticalAlignment.TOP, a.getVerticalAlignment());
+      Assert.assertTrue(a.getWrap());
+   }
+
+   @Test
+   public void inverseMergeOKTest()
+   {
+      CellFormat a = getSampleCellFormat();
+      CellFormat b = new CellFormat();
+      a.merge(b);
+      Assert.assertEquals(Alignment.LEFT, a.getAlignment());
+      Assert.assertEquals(getSampleBackground(), a.getBackground());
+      Assert.assertEquals(getSampleBorders(), a.getBorders());
+      Assert.assertEquals(getSampleFont(), a.getFont());
+      Assert.assertEquals(new Integer(1), a.getIndentation());
+      Assert.assertTrue(a.getLocked());
+      Assert.assertEquals("ACCOUNTING", a.getMask());
+      Assert.assertEquals(Orientation.MINUS_45, a.getOrientation());
+      Assert.assertTrue(a.getShrinkToFit());
+      Assert.assertEquals(VerticalAlignment.TOP, a.getVerticalAlignment());
+      Assert.assertTrue(a.getWrap());
+   }
+   
+   @Test
+   public void equalsOKTest() {
+      CellFormat a = getSampleCellFormat();
+      CellFormat b = getSampleCellFormat();
+      Assert.assertTrue(a.equals(b));
+   }
+   
+   @Test
+   public void equalsOKTest2() {
+      CellFormat a = getSampleCellFormat();
+      a.setType(Type.ABSOLUTE);
+      CellFormat b = getSampleCellFormat();
+      Assert.assertTrue(a.equals(b));
+   }
+   
+   @Test
+   public void equalsFailsOnFontTest() {
+      CellFormat a = getSampleCellFormat();
+      a.setFont(null);
+      CellFormat b = getSampleCellFormat();
+      Assert.assertFalse(a.equals(b));
+   }
+
+   @Test
+   public void equalsFailsOnFontTest2() {
+      CellFormat a = getSampleCellFormat();
+      CellFormat b = getSampleCellFormat();
+      b.setFont(null);
+      Assert.assertFalse(a.equals(b));
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/FontTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/FontTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/FontTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,120 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+import org.jboss.seam.spreadsheet.model.formatting.Font.ScriptStyle;
+import org.jboss.seam.spreadsheet.model.formatting.Font.UnderlineStyle;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class FontTest extends SpreadsheetTest
+{
+   @Test
+   public void mergeTest()
+   {
+      Font a = new Font();
+      Font b = getSampleFont();
+      a.merge(b);
+      Assert.assertEquals("Times New Roman", a.getFontName());
+      Assert.assertEquals(true, a.getBold());
+      Assert.assertEquals(Colour.RED, a.getColour());
+      Assert.assertEquals((Integer) 100, a.getPointSize());
+      Assert.assertEquals(ScriptStyle.SUBSCRIPT, a.getScriptStyle());
+      Assert.assertEquals(true, a.getStruckOut());
+      Assert.assertEquals(UnderlineStyle.DOUBLE, a.getUnderlineStyle());
+   }
+   
+   @Test
+   public void inverseMergeTest()
+   {
+      Font a = getSampleFont();
+      Font b = new Font();
+      a.merge(b);
+      Assert.assertEquals("Times New Roman", a.getFontName());
+      Assert.assertEquals(true, a.getBold());
+      Assert.assertEquals(Colour.RED, a.getColour());
+      Assert.assertEquals((Integer) 100, a.getPointSize());
+      Assert.assertEquals(ScriptStyle.SUBSCRIPT, a.getScriptStyle());
+      Assert.assertEquals(true, a.getStruckOut());
+      Assert.assertEquals(UnderlineStyle.DOUBLE, a.getUnderlineStyle());
+   }
+   
+
+   @Test
+   public void equalsOKTest()
+   {
+      Font f1 = getSampleFont();
+      Font f2 = getSampleFont();
+      Assert.assertEquals(f1, f2);
+   }
+
+   @Test
+   public void equalsFontNameFailsTest()
+   {
+      Font f1 = getSampleFont();
+      Font f2 = getSampleFont();
+      f2.setFontName("Arial");
+      Assert.assertFalse(f1.equals(f2));
+   }
+
+   @Test
+   public void equalsBoldFailsTest()
+   {
+      Font f1 = getSampleFont();
+      Font f2 = getSampleFont();
+      f2.setBold(false);
+      Assert.assertFalse(f1.equals(f2));
+   }
+
+   @Test
+   public void equalsColorFailsTest()
+   {
+      Font f1 = getSampleFont();
+      Font f2 = getSampleFont();
+      f2.setColour(Colour.GOLD);
+      Assert.assertFalse(f1.equals(f2));
+   }
+
+   @Test
+   public void equalsItalicFailsTest()
+   {
+      Font f1 = getSampleFont();
+      Font f2 = getSampleFont();
+      f2.setItalic(false);
+      Assert.assertFalse(f1.equals(f2));
+   }
+
+   @Test
+   public void equalsPointSizeFailsTest()
+   {
+      Font f1 = getSampleFont();
+      Font f2 = getSampleFont();
+      f2.setPointSize(1);
+      Assert.assertFalse(f1.equals(f2));
+   }
+
+   @Test
+   public void equalsScriptStyleFailsTest()
+   {
+      Font f1 = getSampleFont();
+      Font f2 = getSampleFont();
+      f2.setScriptStyle(ScriptStyle.SUPERSCRIPT);
+      Assert.assertFalse(f1.equals(f2));
+   }
+
+   @Test
+   public void equalsStructOutFailsTest()
+   {
+      Font f1 = getSampleFont();
+      Font f2 = getSampleFont();
+      f2.setStruckOut(false);
+      Assert.assertFalse(f1.equals(f2));
+   }
+
+   @Test
+   public void equalsUnderlineStyleFailsTest()
+   {
+      Font f1 = getSampleFont();
+      Font f2 = getSampleFont();
+      f2.setUnderlineStyle(UnderlineStyle.SINGLE);
+      Assert.assertFalse(f1.equals(f2));
+   }
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/SpreadsheetTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/SpreadsheetTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/model/formatting/SpreadsheetTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,115 @@
+package org.jboss.seam.spreadsheet.model.formatting;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import jxl.read.biff.BiffException;
+
+import org.jboss.seam.spreadsheet.jxl.JXLSpreadsheetWriter;
+import org.jboss.seam.spreadsheet.model.Cell;
+import org.jboss.seam.spreadsheet.model.Coordinate;
+import org.jboss.seam.spreadsheet.model.Range;
+import org.jboss.seam.spreadsheet.model.Workbook;
+import org.jboss.seam.spreadsheet.model.formatting.Background.Pattern;
+import org.jboss.seam.spreadsheet.model.formatting.Border.BorderLineStyle;
+import org.jboss.seam.spreadsheet.model.formatting.Border.BorderType;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.Alignment;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.Orientation;
+import org.jboss.seam.spreadsheet.model.formatting.CellFormat.VerticalAlignment;
+import org.jboss.seam.spreadsheet.model.formatting.Font.ScriptStyle;
+import org.jboss.seam.spreadsheet.model.formatting.Font.UnderlineStyle;
+
+public abstract class SpreadsheetTest
+{
+
+   protected jxl.Workbook getWorkbook(Workbook workbook)
+   {
+      try
+      {
+         JXLSpreadsheetWriter writer = new JXLSpreadsheetWriter();
+         byte[] data = writer.writeWorkbook(workbook);
+         return jxl.Workbook.getWorkbook(new ByteArrayInputStream(data));
+      }
+      catch (BiffException e)
+      {
+         e.printStackTrace();
+      }
+      catch (IOException e)
+      {
+         e.printStackTrace();
+      }
+      return null;
+   }
+
+   protected Cell getTestCell()
+   {
+      Cell cell = new Cell();
+      cell.setCoordinate(Coordinate.of(1, 1));
+      cell.setValue("foo");
+      cell.setCellFormat(new CellFormat());
+      return cell;
+   }
+
+   protected CellFormat getSampleCellFormat()
+   {
+      CellFormat cellFormat = new CellFormat();
+      cellFormat.setAlignment(Alignment.LEFT);
+      cellFormat.setBackground(getSampleBackground());
+      List<Border> borders = new ArrayList<Border>();
+      borders.add(getSampleBorder());
+      cellFormat.setBorders(borders);
+      cellFormat.setFont(getSampleFont());
+      cellFormat.setIndentation(1);
+      cellFormat.setLocked(true);
+      cellFormat.setMask("ACCOUNTING");
+      cellFormat.setOrientation(Orientation.MINUS_45);
+      cellFormat.setShrinkToFit(true);
+      cellFormat.setVerticalAlignment(VerticalAlignment.TOP);
+      cellFormat.setWrap(true);
+      return cellFormat;
+   }
+
+   protected List<Border> getSampleBorders()
+   {
+      List<Border> borders = new ArrayList<Border>();
+      borders.add(getSampleBorder());
+      return borders;
+   }
+
+   protected Border getSampleBorder()
+   {
+      Border border = new Border(BorderType.ALL);
+      border.setColour(Colour.RED);
+      border.setLineStyle(BorderLineStyle.DOUBLE);
+      return border;
+   }
+
+   protected Font getSampleFont()
+   {
+      Font font = new Font();
+      font.setFontName("Times New Roman");
+      font.setBold(true);
+      font.setColour(Colour.RED);
+      font.setItalic(true);
+      font.setPointSize(100);
+      font.setScriptStyle(ScriptStyle.SUBSCRIPT);
+      font.setStruckOut(true);
+      font.setUnderlineStyle(UnderlineStyle.DOUBLE);
+      return font;
+   }
+
+   protected Background getSampleBackground()
+   {
+      Background background = new Background();
+      background.setColour(Colour.RED);
+      background.setPattern(Pattern.GRAY_50);
+      return background;
+   }
+
+   protected CellFormatRule getSampleCellFormatRule()
+   {
+      return new RangeCellFormatRule(new CellFormat(), Range.of(10, 10, 20, 20));
+   }
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/HashUtilTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/HashUtilTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/HashUtilTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,69 @@
+package org.jboss.seam.spreadsheet.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class HashUtilTest
+{
+
+   @Test
+   public void testEquals()
+   {
+      Assert.assertTrue(HashUtil.same(null, null));
+   }
+
+   @Test
+   public void testEquals2()
+   {
+      Person person = new Person("Nicklas Karlsson", 35);
+      Assert.assertTrue(HashUtil.same(person, person));
+   }
+
+   @Test
+   public void testEquals3()
+   {
+      Person person = new Person("Nicklas Karlsson", 35);
+      Person person2 = new Person("Nicklas Karlsson", 35);
+      Assert.assertTrue(HashUtil.same(person, person2));
+   }
+
+   @Test
+   public void testNonEqual()
+   {
+      Person person = new Person("Nicklas Karlsson", 35);
+      Assert.assertFalse(HashUtil.same(person, null));
+   }
+
+   @Test
+   public void testNonEqual2()
+   {
+      Person person = new Person("Nicklas Karlsson", 35);
+      Assert.assertFalse(HashUtil.same(null, person));
+   }
+
+   @Test
+   public void testNonEqual3()
+   {
+      Person person = new Person("Nicklas Karlsson", 35);
+      Person person2 = new Person("Nicklas Karlsson", 36);
+      Assert.assertFalse(HashUtil.same(person, person2));
+   }
+
+   @Test
+   public void testCollectionHashcode()
+   {
+      final Person person = new Person("Nicklas Karlsson", 35);
+      List<Person> persons = new ArrayList<Person>()
+      {
+         {
+            add(person);
+         }
+      };
+      Assert.assertEquals(-788329001, HashUtil.collectionHashCode(persons));
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/Person.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/Person.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/Person.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,37 @@
+package org.jboss.seam.spreadsheet.util;
+
+public class Person
+{
+   private String name;
+   private int age;
+
+   public Person(String name, int age)
+   {
+      this.name = name;
+      this.age = age;
+   }
+
+   public String getName()
+   {
+      return name;
+   }
+
+   @Override
+   public boolean equals(Object other)
+   {
+      Person otherPerson = (Person) other;
+      return name.equals(otherPerson.getName()) && age == otherPerson.getAge();
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return name.hashCode() + age;
+   }
+
+   public int getAge()
+   {
+      return age;
+   }
+
+}

Added: sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/ReflectionUtilTest.java
===================================================================
--- sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/ReflectionUtilTest.java	                        (rev 0)
+++ sandbox/modules/spreadsheet/src/test/java/org/jboss/seam/spreadsheet/util/ReflectionUtilTest.java	2010-07-21 10:18:59 UTC (rev 13456)
@@ -0,0 +1,45 @@
+package org.jboss.seam.spreadsheet.util;
+
+
+
+import junit.framework.Assert;
+
+import org.jboss.seam.spreadsheet.SpreadsheetException;
+import org.jboss.seam.spreadsheet.util.ReflectionUtil.AccessType;
+import org.junit.Test;
+
+public class ReflectionUtilTest
+{
+   @Test
+   public void testFieldAccess()
+   {
+      ReflectionUtil reflectionUtil = ReflectionUtil.of(Person.class);
+      Person person = new Person("Nicklas Karlsson", 35);
+      Assert.assertEquals(35, reflectionUtil.readValue(person, "age"));
+   }
+
+   @Test(expected=SpreadsheetException.class)
+   public void testMissingFieldAccess()
+   {
+      ReflectionUtil reflectionUtil = ReflectionUtil.of(Person.class);
+      Person person = new Person("Nicklas Karlsson", 35);
+      Assert.assertEquals(35, reflectionUtil.readValue(person, "foo"));
+   }
+
+   @Test()
+   public void testGetterAccess() {
+      ReflectionUtil reflectionUtil = ReflectionUtil.of(Person.class);
+      reflectionUtil.setAccessType(AccessType.METHOD);
+      Person person = new Person("Nicklas Karlsson", 35);
+      Assert.assertEquals("Nicklas Karlsson", reflectionUtil.readValue(person, "name"));
+   }
+   
+   @Test(expected=SpreadsheetException.class)
+   public void testMissinGetterAccess() {
+      ReflectionUtil reflectionUtil = ReflectionUtil.of(Person.class);
+      reflectionUtil.setAccessType(AccessType.METHOD);
+      Person person = new Person("Nicklas Karlsson", 35);
+      Assert.assertEquals("Nicklas Karlsson", reflectionUtil.readValue(person, "foo"));
+   }
+   
+}



More information about the seam-commits mailing list