]> source.dussan.org Git - poi.git/commitdiff
More FeatRecord support
authorNick Burch <nick@apache.org>
Sun, 3 Jan 2010 21:51:25 +0000 (21:51 +0000)
committerNick Burch <nick@apache.org>
Sun, 3 Jan 2010 21:51:25 +0000 (21:51 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@895487 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/FeatRecord.java
src/java/org/apache/poi/hssf/record/common/FeatFormulaErr2.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/common/FeatProtection.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/common/FeatSmartTag.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/common/SharedFeature.java [new file with mode: 0644]
src/java/org/apache/poi/util/StringUtil.java
src/testcases/org/apache/poi/hssf/record/TestFeatRecord.java

index fd27f0226cc2cb7b7da41ed7c6ba92df3b446e22..c9fed7d40d6534954b4c703994d42b599fc8c756 100644 (file)
 
 package org.apache.poi.hssf.record;
 
+import org.apache.poi.hssf.record.common.FeatFormulaErr2;
+import org.apache.poi.hssf.record.common.FeatProtection;
+import org.apache.poi.hssf.record.common.FeatSmartTag;
 import org.apache.poi.hssf.record.common.FtrHeader;
+import org.apache.poi.hssf.record.common.SharedFeature;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -49,7 +53,7 @@ public final class FeatRecord extends StandardRecord  {
         *  ISFFEC2       -> FeatFormulaErr2
         *  ISFFACTOID    -> FeatSmartTag
         */
-       private byte[] rgbFeat
+       private SharedFeature sharedFeature
        
        public FeatRecord() {
                futureHeader = new FtrHeader();
@@ -75,7 +79,19 @@ public final class FeatRecord extends StandardRecord  {
                        cellRefs[i] = new CellRangeAddress(in);
                }
                
-               rgbFeat = in.readRemainder();
+               switch(isf_sharedFeatureType) {
+               case FeatHdrRecord.SHAREDFEATURES_ISFPROTECTION:
+                       sharedFeature = new FeatProtection(in);
+                       break;
+               case FeatHdrRecord.SHAREDFEATURES_ISFFEC2:
+                       sharedFeature = new FeatFormulaErr2(in);
+                       break;
+               case FeatHdrRecord.SHAREDFEATURES_ISFFACTOID:
+                       sharedFeature = new FeatSmartTag(in);
+                       break;
+               default:
+                       System.err.println("Unknown Shared Feature " + isf_sharedFeatureType + " found!");
+               }
        }
 
        public String toString() {
@@ -102,21 +118,18 @@ public final class FeatRecord extends StandardRecord  {
                        cellRefs[i].serialize(out);
                }
                
-               out.write(rgbFeat);
+               sharedFeature.serialize(out);
        }
 
        protected int getDataSize() {
                return 12 + 2+1+4+2+4+2+
                        (cellRefs.length * CellRangeAddress.ENCODED_SIZE)
-                       +rgbFeat.length;
+                       +sharedFeature.getDataSize();
        }
 
        public int getIsf_sharedFeatureType() {
                return isf_sharedFeatureType;
        }
-       public void setIsf_sharedFeatureType(int isfSharedFeatureType) {
-               isf_sharedFeatureType = isfSharedFeatureType;
-       }
 
        public long getCbFeatData() {
                return cbFeatData;
@@ -132,14 +145,24 @@ public final class FeatRecord extends StandardRecord  {
                this.cellRefs = cellRefs;
        }
 
-       public byte[] getRgbFeat() {
-               return rgbFeat;
+       public SharedFeature getSharedFeature() {
+               return sharedFeature;
        }
-       public void setRgbFeat(byte[] rgbFeat) {
-               this.rgbFeat = rgbFeat;
+       public void setSharedFeature(SharedFeature feature) {
+               this.sharedFeature = feature;
+               
+               if(feature instanceof FeatProtection) {
+                       isf_sharedFeatureType = FeatHdrRecord.SHAREDFEATURES_ISFPROTECTION;
+               }
+               if(feature instanceof FeatFormulaErr2) {
+                       isf_sharedFeatureType = FeatHdrRecord.SHAREDFEATURES_ISFFEC2;
+               }
+               if(feature instanceof FeatSmartTag) {
+                       isf_sharedFeatureType = FeatHdrRecord.SHAREDFEATURES_ISFFACTOID;
+               }
                
                if(isf_sharedFeatureType == FeatHdrRecord.SHAREDFEATURES_ISFFEC2) {
-                       cbFeatData = rgbFeat.length;
+                       cbFeatData = sharedFeature.getDataSize();
                } else {
                        cbFeatData = 0;
                }
diff --git a/src/java/org/apache/poi/hssf/record/common/FeatFormulaErr2.java b/src/java/org/apache/poi/hssf/record/common/FeatFormulaErr2.java
new file mode 100644 (file)
index 0000000..adf1b88
--- /dev/null
@@ -0,0 +1,159 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.common;
+
+import org.apache.poi.hssf.record.FeatRecord;
+//import org.apache.poi.hssf.record.Feat11Record;
+//import org.apache.poi.hssf.record.Feat12Record;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: FeatFormulaErr2 (Formula Evaluation Shared Feature) common record part
+ * <P>
+ * This record part specifies Formula Evaluation & Error Ignoring data 
+ *  for a sheet, stored as part of a Shared Feature. It can be found in 
+ *  records such as {@link FeatRecord}, {@link Feat11Record} or
+ *  {@link Feat12Record}.
+ * For the full meanings of the flags, see pages 669 and 670
+ *  of the Excel binary file format documentation.
+ */
+public final class FeatFormulaErr2 implements SharedFeature {
+       static BitField checkCalculationErrors =
+               BitFieldFactory.getInstance(0x01);
+       static BitField checkEmptyCellRef =
+               BitFieldFactory.getInstance(0x02);
+       static BitField checkNumbersAsText =
+               BitFieldFactory.getInstance(0x04);
+       static BitField checkInconsistentRanges =
+               BitFieldFactory.getInstance(0x08);
+       static BitField checkInconsistentFormulas =
+               BitFieldFactory.getInstance(0x10);
+       static BitField checkDateTimeFormats =
+               BitFieldFactory.getInstance(0x20);
+       static BitField checkUnprotectedFormulas =
+               BitFieldFactory.getInstance(0x40);
+       static BitField performDataValidation =
+               BitFieldFactory.getInstance(0x80);
+       
+       /**
+        * What errors we should ignore
+        */
+       private int errorCheck;
+       
+       
+       public FeatFormulaErr2() {}
+
+       public FeatFormulaErr2(RecordInputStream in) {
+               errorCheck = in.readInt();
+       }
+
+       public String toString() {
+               StringBuffer buffer = new StringBuffer();
+               buffer.append(" [FEATURE FORMULA ERRORS]\n");
+               buffer.append("  checkCalculationErrors    = "); 
+               buffer.append("  checkEmptyCellRef         = "); 
+               buffer.append("  checkNumbersAsText        = "); 
+               buffer.append("  checkInconsistentRanges   = "); 
+               buffer.append("  checkInconsistentFormulas = "); 
+               buffer.append("  checkDateTimeFormats      = "); 
+               buffer.append("  checkUnprotectedFormulas  = "); 
+               buffer.append("  performDataValidation     = "); 
+               buffer.append(" [/FEATURE FORMULA ERRORS]\n");
+               return buffer.toString();
+       }
+
+       public void serialize(LittleEndianOutput out) {
+               out.writeInt(errorCheck);
+       }
+
+       public int getDataSize() {
+               return 4;
+       }
+       
+       public int _getRawErrorCheckValue() {
+               return errorCheck;
+       }
+
+       public boolean getCheckCalculationErrors() {
+               return checkCalculationErrors.isSet(errorCheck);
+       }
+       public void setCheckCalculationErrors(boolean checkCalculationErrors) {
+               FeatFormulaErr2.checkCalculationErrors.setBoolean(
+                               errorCheck, checkCalculationErrors);
+       }
+
+       public boolean getCheckEmptyCellRef() {
+               return checkEmptyCellRef.isSet(errorCheck);
+       }
+       public void setCheckEmptyCellRef(boolean checkEmptyCellRef) {
+               FeatFormulaErr2.checkEmptyCellRef.setBoolean(
+                               errorCheck, checkEmptyCellRef);
+       }
+
+       public boolean getCheckNumbersAsText() {
+               return checkNumbersAsText.isSet(errorCheck);
+       }
+       public void setCheckNumbersAsText(boolean checkNumbersAsText) {
+               FeatFormulaErr2.checkNumbersAsText.setBoolean(
+                               errorCheck, checkNumbersAsText);
+       }
+
+       public boolean getCheckInconsistentRanges() {
+               return checkInconsistentRanges.isSet(errorCheck);
+       }
+       public void setCheckInconsistentRanges(boolean checkInconsistentRanges) {
+               FeatFormulaErr2.checkInconsistentRanges.setBoolean(
+                               errorCheck, checkInconsistentRanges);
+       }
+
+       public boolean getCheckInconsistentFormulas() {
+               return checkInconsistentFormulas.isSet(errorCheck);
+       }
+       public void setCheckInconsistentFormulas(
+                       boolean checkInconsistentFormulas) {
+               FeatFormulaErr2.checkInconsistentFormulas.setBoolean(
+                               errorCheck, checkInconsistentFormulas);
+       }
+
+       public boolean getCheckDateTimeFormats() {
+               return checkDateTimeFormats.isSet(errorCheck);
+       }
+       public void setCheckDateTimeFormats(boolean checkDateTimeFormats) {
+               FeatFormulaErr2.checkDateTimeFormats.setBoolean(
+                               errorCheck, checkDateTimeFormats);
+       }
+
+       public boolean getCheckUnprotectedFormulas() {
+               return checkUnprotectedFormulas.isSet(errorCheck);
+       }
+       public void setCheckUnprotectedFormulas(boolean checkUnprotectedFormulas) {
+               FeatFormulaErr2.checkUnprotectedFormulas.setBoolean(
+                               errorCheck, checkUnprotectedFormulas);
+       }
+
+       public boolean getPerformDataValidation() {
+               return performDataValidation.isSet(errorCheck);
+       }
+       public void setPerformDataValidation(boolean performDataValidation) {
+               FeatFormulaErr2.performDataValidation.setBoolean(
+                               errorCheck, performDataValidation);
+       }
+}
diff --git a/src/java/org/apache/poi/hssf/record/common/FeatProtection.java b/src/java/org/apache/poi/hssf/record/common/FeatProtection.java
new file mode 100644 (file)
index 0000000..bab65e6
--- /dev/null
@@ -0,0 +1,106 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.common;
+
+import org.apache.poi.hssf.record.FeatRecord;
+import org.apache.poi.hssf.record.PasswordRecord;
+import org.apache.poi.hssf.record.PasswordRev4Record;
+//import org.apache.poi.hssf.record.Feat11Record;
+//import org.apache.poi.hssf.record.Feat12Record;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * Title: FeatProtection (Protection Shared Feature) common record part
+ * <P>
+ * This record part specifies Protection data for a sheet, stored
+ *  as part of a Shared Feature. It can be found in records such
+ *  as {@link FeatRecord}, {@link Feat11Record} or
+ *  {@link Feat12Record}  
+ */
+public final class FeatProtection implements SharedFeature {
+       public static long NO_SELF_RELATIVE_SECURITY_FEATURE = 0;
+       public static long HAS_SELF_RELATIVE_SECURITY_FEATURE = 1;
+
+       private int fSD;
+       
+       /**
+        * 0 means no password. Otherwise indicates the
+        *  password verifier algorithm (same kind as 
+        *   {@link PasswordRecord} and
+        *   {@link PasswordRev4Record})
+        */
+       private int passwordVerifier;
+       
+       private String title;
+       private byte[] securityDescriptor;
+       
+       public FeatProtection() {
+               securityDescriptor = new byte[0];
+       }
+
+       public FeatProtection(RecordInputStream in) {
+               fSD = in.readInt();
+               passwordVerifier = in.readInt();
+               
+               title = StringUtil.readUnicodeString(in);
+               
+               securityDescriptor = in.readRemainder();
+       }
+
+       public String toString() {
+               StringBuffer buffer = new StringBuffer();
+               buffer.append(" [FEATURE PROTECTION]\n");
+               buffer.append("   Self Relative = " + fSD); 
+               buffer.append("   Password Verifier = " + passwordVerifier);
+               buffer.append("   Title = " + title);
+               buffer.append("   Security Descriptor Size = " + securityDescriptor.length);
+               buffer.append(" [/FEATURE PROTECTION]\n");
+               return buffer.toString();
+       }
+
+       public void serialize(LittleEndianOutput out) {
+               out.writeInt(fSD);
+               out.writeInt(passwordVerifier);
+               StringUtil.writeUnicodeString(out, title);
+               out.write(securityDescriptor);
+       }
+
+       public int getDataSize() {
+               return 4 + 4 + StringUtil.getEncodedSize(title) + securityDescriptor.length;
+       }
+
+       public int getPasswordVerifier() {
+               return passwordVerifier;
+       }
+       public void setPasswordVerifier(int passwordVerifier) {
+               this.passwordVerifier = passwordVerifier;
+       }
+
+       public String getTitle() {
+               return title;
+       }
+       public void setTitle(String title) {
+               this.title = title;
+       }
+
+       public int getFSD() {
+               return fSD;
+       }
+}
\ No newline at end of file
diff --git a/src/java/org/apache/poi/hssf/record/common/FeatSmartTag.java b/src/java/org/apache/poi/hssf/record/common/FeatSmartTag.java
new file mode 100644 (file)
index 0000000..2fc53e2
--- /dev/null
@@ -0,0 +1,63 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.common;
+
+import org.apache.poi.hssf.record.FeatRecord;
+//import org.apache.poi.hssf.record.Feat11Record;
+//import org.apache.poi.hssf.record.Feat12Record;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: FeatSmartTag (Smart Tag Shared Feature) common record part
+ * <P>
+ * This record part specifies Smart Tag data for a sheet, stored as part
+ *  of a Shared Feature. It can be found in records such as 
+ *  {@link FeatRecord}, {@link Feat11Record} or {@link Feat12Record}.
+ * It is made up of a hash, and a set of Factoid Data that makes up
+ *  the smart tags.
+ * For more details, see page 669 of the Excel binary file
+ *  format documentation.
+ */
+public final class FeatSmartTag implements SharedFeature {
+       // TODO - process
+       private byte[] data;
+       
+       public FeatSmartTag() {
+               data = new byte[0];
+       }
+
+       public FeatSmartTag(RecordInputStream in) {
+               data = in.readRemainder();
+       }
+
+       public String toString() {
+               StringBuffer buffer = new StringBuffer();
+               buffer.append(" [FEATURE SMART TAGS]\n");
+               buffer.append(" [/FEATURE SMART TAGS]\n");
+               return buffer.toString();
+       }
+
+       public int getDataSize() {
+               return data.length;
+       }
+
+       public void serialize(LittleEndianOutput out) {
+               out.write(data);
+       }
+}
diff --git a/src/java/org/apache/poi/hssf/record/common/SharedFeature.java b/src/java/org/apache/poi/hssf/record/common/SharedFeature.java
new file mode 100644 (file)
index 0000000..1ce8bce
--- /dev/null
@@ -0,0 +1,29 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.common;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Common Interface for all Shared Features
+ */
+public interface SharedFeature {
+       public String toString();
+       public void serialize(LittleEndianOutput out);
+       public int getDataSize();
+}
index 4a2cbabc72c39c20bfce7f29deb4049ee0635e76..b08a979fa4a6ba7b2d95a26163a732dd8500c77c 100644 (file)
@@ -130,6 +130,8 @@ public class StringUtil {
         * <li>byte[]/char[] characterData</li>
         * </ol>
         * For this encoding, the is16BitFlag is always present even if nChars==0.
+        * 
+        * This structure is also known as a XLUnicodeString.
         */
        public static String readUnicodeString(LittleEndianInput in) {
 
index 7fe7c3bae04d9cd8651df1f112ede8136e6d9e9d..288c7ea94432089ef941858eba952a22ddc7c5ef 100644 (file)
@@ -20,6 +20,7 @@ package org.apache.poi.hssf.record;
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.model.InternalSheet;
 import org.apache.poi.hssf.model.InternalWorkbook;
+import org.apache.poi.hssf.record.common.FeatFormulaErr2;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFTestHelper;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@@ -152,8 +153,21 @@ public final class TestFeatRecord extends TestCase {
                assertEquals(0, fr.getCellRefs()[0].getFirstColumn());
                assertEquals(0, fr.getCellRefs()[0].getLastColumn());
                
-               // TODO - more checking of shared features stuff
+               // More checking of shared features stuff
                assertEquals(4, fr.getCbFeatData());
-               assertEquals(4, fr.getRgbFeat().length);
+               assertEquals(4, fr.getSharedFeature().getDataSize());
+               assertEquals(FeatFormulaErr2.class, fr.getSharedFeature().getClass());
+               
+               FeatFormulaErr2 fferr2 = (FeatFormulaErr2)fr.getSharedFeature();
+               assertEquals(0x04, fferr2._getRawErrorCheckValue());
+               
+               assertFalse(fferr2.getCheckCalculationErrors());
+               assertFalse(fferr2.getCheckDateTimeFormats());
+               assertFalse(fferr2.getCheckEmptyCellRef());
+               assertFalse(fferr2.getCheckInconsistentFormulas());
+               assertFalse(fferr2.getCheckInconsistentRanges());
+               assertTrue(fferr2.getCheckNumbersAsText());
+               assertFalse(fferr2.getCheckUnprotectedFormulas());
+               assertFalse(fferr2.getPerformDataValidation());
        }
 }