Fix bug #44201 - support cloning of DVRecord, so validation enabled sheets can be cloned

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@612152 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2008-01-15 16:42:44 +00:00
parent b38caa4cee
commit 83107c9dae
7 changed files with 68 additions and 23 deletions

View File

@ -36,7 +36,8 @@
<!-- Don't forget to update status.xml too! -->
<release version="3.0.2-FINAL" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">44200 - Enable cloning of sheets with notes </action>
<action dev="POI-DEVELOPERS" type="fix">44201 - Enable cloning of sheets with data validation rules</action>
<action dev="POI-DEVELOPERS" type="fix">44200 - Enable cloning of sheets with notes</action>
<action dev="POI-DEVELOPERS" type="add">43008 - Add a moveCell method to HSSFRow, and deprecate setCellNum(), which didn't update things properly</action>
<action dev="POI-DEVELOPERS" type="fix">43058 - Support setting row grouping on files from CR IX, which lack GutsRecords</action>
<action dev="POI-DEVELOPERS" type="fix">31795 - Support cloning of sheets with certain drawing objects on them</action>

View File

@ -33,7 +33,8 @@
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.0.2-FINAL" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">44200 - Enable cloning of sheets with notes </action>
<action dev="POI-DEVELOPERS" type="fix">44201 - Enable cloning of sheets with data validation rules</action>
<action dev="POI-DEVELOPERS" type="fix">44200 - Enable cloning of sheets with notes</action>
<action dev="POI-DEVELOPERS" type="add">43008 - Add a moveCell method to HSSFRow, and deprecate setCellNum(), which didn't update things properly</action>
<action dev="POI-DEVELOPERS" type="fix">43058 - Support setting row grouping on files from CR IX, which lack GutsRecords</action>
<action dev="POI-DEVELOPERS" type="fix">31795 - Support cloning of sheets with certain drawing objects on them</action>

View File

@ -18,7 +18,6 @@
package org.apache.poi.hssf.record;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@ -232,19 +231,7 @@ public abstract class AbstractEscherHolderRecord
public Object clone()
{
// Do it via a re-serialise
// It's a cheat, but it works...
byte[] b = serialize();
RecordInputStream rinp = new RecordInputStream(
new ByteArrayInputStream(b)
);
rinp.nextRecord();
Record[] r = RecordFactory.createRecord(rinp);
if(r.length != 1) {
throw new IllegalStateException("Re-serialised a record to clone it, but got " + r.length + " records back!");
}
return r[0];
return cloneViaReserialise();
}
public void addEscherRecord(int index, EscherRecord element)

View File

@ -16,16 +16,16 @@
package org.apache.poi.hssf.record;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Stack;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.util.HSSFCellRangeAddress;
import org.apache.poi.util.BitField;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.StringUtil;
import org.apache.poi.hssf.util.HSSFCellRangeAddress;
import org.apache.poi.hssf.record.formula.Ptg;
import java.io.IOException;
import java.util.Stack;
import java.util.Hashtable;
import java.util.Enumeration;
/**
* Title: DV Record<P>
@ -503,6 +503,14 @@ public class DVRecord extends Record
return this.sid;
}
/**
* Clones the object. Uses serialisation, as the
* contents are somewhat complex
*/
public Object clone() {
return cloneViaReserialise();
}
/**@todo DVRecord = Serializare */
private class StringHandler

View File

@ -19,6 +19,8 @@
package org.apache.poi.hssf.record;
import java.io.ByteArrayInputStream;
/**
* Title: Record
* Description: All HSSF Records inherit from this class. It
@ -147,4 +149,30 @@ public abstract class Record
public Object clone() {
throw new RuntimeException("The class "+getClass().getName()+" needs to define a clone method");
}
/**
* Clone the current record, via a call to serialise
* it, and another to create a new record from the
* bytes.
* May only be used for classes which don't have
* internal counts / ids in them. For those which
* do, a full record-aware serialise is needed, which
* allocates new ids / counts as needed.
*/
public Record cloneViaReserialise()
{
// Do it via a re-serialise
// It's a cheat, but it works...
byte[] b = serialize();
RecordInputStream rinp = new RecordInputStream(
new ByteArrayInputStream(b)
);
rinp.nextRecord();
Record[] r = RecordFactory.createRecord(rinp);
if(r.length != 1) {
throw new IllegalStateException("Re-serialised a record to clone it, but got " + r.length + " records back!");
}
return r[0];
}
}

Binary file not shown.

View File

@ -934,6 +934,26 @@ extends TestCase {
}
/**
* Bug 44201: Sheet not cloneable when validation added to excel cell
*/
public void test44201() throws Exception {
FileInputStream in = new FileInputStream(new File(cwd, "44201.xls"));
HSSFWorkbook wb = new HSSFWorkbook(in);
in.close();
wb.cloneSheet(0);
assertTrue("No Exceptions while cloning sheet", true);
//serialize and read again
ByteArrayOutputStream out = new ByteArrayOutputStream();
wb.write(out);
out.close();
wb = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray()));
assertTrue("No Exceptions while reading file", true);
}
}