]> source.dussan.org Git - poi.git/commitdiff
Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-63924...
authorNick Burch <nick@apache.org>
Mon, 9 Jun 2008 13:30:17 +0000 (13:30 +0000)
committerNick Burch <nick@apache.org>
Mon, 9 Jun 2008 13:30:17 +0000 (13:30 +0000)
https://svn.apache.org:443/repos/asf/poi/trunk

........
  r664220 | josh | 2008-06-07 01:53:01 +0100 (Sat, 07 Jun 2008) | 1 line

  Fix for bug 45091 - serialization of RefN~ tokens. Simplified Ptg class hierarchy
........
  r664490 | yegor | 2008-06-08 13:30:25 +0100 (Sun, 08 Jun 2008) | 1 line

  Correctly increment the reference count of a blip when a picture is inserted
........
  r664491 | yegor | 2008-06-08 13:31:19 +0100 (Sun, 08 Jun 2008) | 1 line

  Support custom image renderers
........
  r664492 | yegor | 2008-06-08 13:32:10 +0100 (Sun, 08 Jun 2008) | 1 line

  Fixed TextShape.resizeToFitText() to properly resize TextShape. See patch#45140
........
  r664493 | yegor | 2008-06-08 13:37:39 +0100 (Sun, 08 Jun 2008) | 1 line

  expose access to OEPlaceholderAtom  so that users can determine whether a shape represents ppt placeholder (date/time, footer or slide number)
........
  r664515 | yegor | 2008-06-08 16:31:05 +0100 (Sun, 08 Jun 2008) | 1 line

  bug#44692 - Fixed HSSFPicture.resize() to properly resize pictures if the underlying columns/rows have modified size
........

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@664700 13f79535-47bb-0310-9956-ffa450edef68

99 files changed:
src/documentation/content/xdocs/changes.xml
src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/ddf/EscherDggRecord.java
src/java/org/apache/poi/hssf/model/FormulaParser.java
src/java/org/apache/poi/hssf/record/FormulaRecord.java
src/java/org/apache/poi/hssf/record/NameRecord.java
src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java
src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java
src/java/org/apache/poi/hssf/record/formula/AddPtg.java
src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
src/java/org/apache/poi/hssf/record/formula/AreaAPtg.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java
src/java/org/apache/poi/hssf/record/formula/AreaNAPtg.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java
src/java/org/apache/poi/hssf/record/formula/AreaNVPtg.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/AreaPtg.java [changed mode: 0644->0755]
src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/AreaVPtg.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java
src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/BoolPtg.java
src/java/org/apache/poi/hssf/record/formula/ConcatPtg.java
src/java/org/apache/poi/hssf/record/formula/DividePtg.java
src/java/org/apache/poi/hssf/record/formula/EqualPtg.java
src/java/org/apache/poi/hssf/record/formula/ErrPtg.java
src/java/org/apache/poi/hssf/record/formula/ExpPtg.java
src/java/org/apache/poi/hssf/record/formula/FuncPtg.java
src/java/org/apache/poi/hssf/record/formula/FuncVarPtg.java
src/java/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java
src/java/org/apache/poi/hssf/record/formula/GreaterThanPtg.java
src/java/org/apache/poi/hssf/record/formula/IntPtg.java
src/java/org/apache/poi/hssf/record/formula/IntersectionPtg.java
src/java/org/apache/poi/hssf/record/formula/LessEqualPtg.java
src/java/org/apache/poi/hssf/record/formula/LessThanPtg.java
src/java/org/apache/poi/hssf/record/formula/MemAreaPtg.java
src/java/org/apache/poi/hssf/record/formula/MemErrPtg.java
src/java/org/apache/poi/hssf/record/formula/MemFuncPtg.java
src/java/org/apache/poi/hssf/record/formula/MissingArgPtg.java
src/java/org/apache/poi/hssf/record/formula/MultiplyPtg.java
src/java/org/apache/poi/hssf/record/formula/NamePtg.java
src/java/org/apache/poi/hssf/record/formula/NameXPtg.java
src/java/org/apache/poi/hssf/record/formula/NotEqualPtg.java
src/java/org/apache/poi/hssf/record/formula/NumberPtg.java
src/java/org/apache/poi/hssf/record/formula/OperationPtg.java
src/java/org/apache/poi/hssf/record/formula/ParenthesisPtg.java
src/java/org/apache/poi/hssf/record/formula/PercentPtg.java
src/java/org/apache/poi/hssf/record/formula/PowerPtg.java
src/java/org/apache/poi/hssf/record/formula/Ptg.java
src/java/org/apache/poi/hssf/record/formula/RangePtg.java
src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java
src/java/org/apache/poi/hssf/record/formula/RefAPtg.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/RefErrorPtg.java
src/java/org/apache/poi/hssf/record/formula/RefNAPtg.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/RefNPtg.java
src/java/org/apache/poi/hssf/record/formula/RefNVPtg.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/RefPtg.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/RefPtgBase.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/RefVPtg.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/ReferencePtg.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java
src/java/org/apache/poi/hssf/record/formula/StringPtg.java
src/java/org/apache/poi/hssf/record/formula/SubtractPtg.java
src/java/org/apache/poi/hssf/record/formula/UnaryMinusPtg.java
src/java/org/apache/poi/hssf/record/formula/UnaryPlusPtg.java
src/java/org/apache/poi/hssf/record/formula/UnionPtg.java
src/java/org/apache/poi/hssf/record/formula/ValueOperatorPtg.java
src/java/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java
src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java
src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java
src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java [new file with mode: 0755]
src/scratchpad/src/org/apache/poi/hslf/blip/ImagePainter.java [new file with mode: 0755]
src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java
src/scratchpad/src/org/apache/poi/hslf/model/Picture.java
src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java
src/scratchpad/src/org/apache/poi/hslf/model/Slide.java
src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java
src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java
src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestImagePainter.java [new file with mode: 0755]
src/scratchpad/testcases/org/apache/poi/hslf/model/TestPicture.java [new file with mode: 0755]
src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
src/testcases/org/apache/poi/hssf/model/TestFormulaParserIf.java
src/testcases/org/apache/poi/hssf/model/TestRVA.java
src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java
src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java
src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java
src/testcases/org/apache/poi/hssf/record/formula/TestReferencePtg.java
src/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java
src/testcases/org/apache/poi/hssf/record/formula/eval/TestUnaryPlusEval.java
src/testcases/org/apache/poi/hssf/record/formula/functions/EvalFactory.java
src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java
src/testcases/org/apache/poi/hssf/record/formula/functions/TestMid.java
src/testcases/org/apache/poi/hssf/record/formula/functions/TestSumproduct.java
src/testcases/org/apache/poi/hssf/record/formula/functions/TestTFunc.java

index 267811d78aacffe4544a8687c0261ff8b00f6502..43b373d04d227cb37e1b27360eb7b1fad373ca8e 100644 (file)
            <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
         </release>
         <release version="3.1-final" date="2008-06-??">
+           <action dev="POI-DEVELOPERS" type="fix">44692 - Fixed HSSFPicture.resize() to properly resize pictures if the underlying columns/rows have modified size</action>
+           <action dev="POI-DEVELOPERS" type="add">Support custom image renderers in HSLF</action>
+           <action dev="POI-DEVELOPERS" type="fix">Correctly increment the reference count of a blip when a picture is inserted</action>
+           <action dev="POI-DEVELOPERS" type="fix">45110 - Fixed TextShape.resizeToFitText() to properly resize TextShape</action>
+           <action dev="POI-DEVELOPERS" type="fix">45091 - Fixed serialization of RefN~ tokens.  Simplified Ptg class hierarchy</action>
            <action dev="POI-DEVELOPERS" type="fix">45133 - Fixed OBJ Record (5Dh) to pad the sub-record data to a 4-byte boundary</action>
            <action dev="POI-DEVELOPERS" type="fix">45145 - Fixed Sheet to always enforce RowRecordsAggregate before ValueRecordsAggregate</action>
            <action dev="POI-DEVELOPERS" type="fix">45123 - Fixed SharedFormulaRecord.convertSharedFormulas() to propagate token operand classes</action>
index 115db4e1037cc03a38dab1d46b193c93314a6196..3ad07a2162690ea09e9ab9208536049a04d23928 100644 (file)
            <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
         </release>
         <release version="3.1-final" date="2008-06-??">
+           <action dev="POI-DEVELOPERS" type="fix">44692 - Fixed HSSFPicture.resize() to properly resize pictures if the underlying columns/rows have modified size</action>
+           <action dev="POI-DEVELOPERS" type="add">Support custom image renderers in HSLF</action>
+           <action dev="POI-DEVELOPERS" type="fix">Correctly increment the reference count of a blip when a picture is inserted</action>
+           <action dev="POI-DEVELOPERS" type="fix">45110 - Fixed TextShape.resizeToFitText() to properly resize TextShape</action>
+           <action dev="POI-DEVELOPERS" type="fix">45091 - Fixed serialization of RefN~ tokens.  Simplified Ptg class hierarchy</action>
            <action dev="POI-DEVELOPERS" type="fix">45133 - Fixed OBJ Record (5Dh) to pad the sub-record data to a 4-byte boundary</action>
            <action dev="POI-DEVELOPERS" type="fix">45145 - Fixed Sheet to always enforce RowRecordsAggregate before ValueRecordsAggregate</action>
            <action dev="POI-DEVELOPERS" type="fix">45123 - Fixed SharedFormulaRecord.convertSharedFormulas() to propagate token operand classes</action>
index 0ff00016d506a00d5b03284f84b00fc6ce517ed0..cdc9281a8e4eef3c915ed8b02d4193bf28667e2d 100644 (file)
@@ -238,6 +238,10 @@ public class EscherDggRecord
         return maxDgId;
     }
 
+    public void setMaxDrawingGroupId(int id){
+        maxDgId = id;
+    }
+
      public FileIdCluster[] getFileIdClusters()
     {
         return field_5_fileIdClusters;
index d45e8741ba101112061396f2bac5b0e1f41060c2..501b030ecc7810484591f618e8d1ba4c08ee5f8e 100644 (file)
@@ -97,7 +97,7 @@ public final class FormulaParser {
      *  parse results.
      * This class is recommended only for single threaded use.
      *
-     * If you only have a usermodel.HSSFWorkbook, and not a
+     * If you only have a usermodel.Workbook, and not a
      *  model.Workbook, then use the convenience method on
      *  usermodel.HSSFFormulaEvaluator
      */
@@ -274,7 +274,7 @@ public final class FormulaParser {
         boolean cellRef = CELL_REFERENCE_PATTERN.matcher(name).matches();
 
         if (cellRef) {
-            return new ReferencePtg(name);
+            return new RefPtg(name);
         }
 
         for(int i = 0; i < book.getNumberOfNames(); i++) {
@@ -324,9 +324,9 @@ public final class FormulaParser {
         FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByName(name.toUpperCase());
         int numArgs = args.length;
         if(fm == null) {
-               if (namePtg == null) {
-                       throw new IllegalStateException("NamePtg must be supplied for external functions");
-               }
+            if (namePtg == null) {
+                throw new IllegalStateException("NamePtg must be supplied for external functions");
+            }
             // must be external function
             ParseNode[] allArgs = new ParseNode[numArgs+1];
             allArgs[0] = new ParseNode(namePtg);
@@ -335,8 +335,8 @@ public final class FormulaParser {
         }
 
         if (namePtg != null) {
-               throw new IllegalStateException("NamePtg no applicable to internal functions");
-       }
+            throw new IllegalStateException("NamePtg no applicable to internal functions");
+        }
         boolean isVarArgs = !fm.hasFixedArgsLength();
         int funcIx = fm.getIndex();
         validateNumArgs(args.length, fm);
@@ -392,7 +392,7 @@ public final class FormulaParser {
             SkipWhite();
             if (isArgumentDelimiter(look)) {
                 if (missedPrevArg) {
-                       temp.add(new ParseNode(new MissingArgPtg()));
+                    temp.add(new ParseNode(MissingArgPtg.instance));
                     numArgs++;
                 }
                 if (look == ')') {
@@ -417,7 +417,7 @@ public final class FormulaParser {
 
    /** Parse and Translate a Math Factor  */
     private ParseNode powerFactor() {
-       ParseNode result = percentFactor();
+        ParseNode result = percentFactor();
         while(true) {
             SkipWhite();
             if(look != '^') {
@@ -425,19 +425,19 @@ public final class FormulaParser {
             }
             Match('^');
             ParseNode other = percentFactor();
-            result = new ParseNode(new PowerPtg(), result, other);
+            result = new ParseNode(PowerPtg.instance, result, other);
         }
     }
 
     private ParseNode percentFactor() {
-       ParseNode result = parseSimpleFactor();
+        ParseNode result = parseSimpleFactor();
         while(true) {
             SkipWhite();
             if(look != '%') {
                 return result;
             }
             Match('%');
-            result = new ParseNode(new PercentPtg(), result);
+            result = new ParseNode(PercentPtg.instance, result);
         }
     }
 
@@ -452,15 +452,15 @@ public final class FormulaParser {
                 return new ParseNode(parseErrorLiteral());
             case '-':
                 Match('-');
-                return new ParseNode(new UnaryMinusPtg(), powerFactor());
+                return new ParseNode(UnaryMinusPtg.instance, powerFactor());
             case '+':
                 Match('+');
-                return new ParseNode(new UnaryPlusPtg(), powerFactor());
+                return new ParseNode(UnaryPlusPtg.instance, powerFactor());
             case '(':
                 Match('(');
                 ParseNode inside = comparisonExpression();
                 Match(')');
-                return new ParseNode(new ParenthesisPtg(), inside);
+                return new ParseNode(ParenthesisPtg.instance, inside);
             case '"':
                 return new ParseNode(parseStringLiteral());
         }
@@ -625,18 +625,18 @@ public final class FormulaParser {
 
     /** Parse and Translate a Math Term */
     private ParseNode  Term() {
-       ParseNode result = powerFactor();
+        ParseNode result = powerFactor();
         while(true) {
             SkipWhite();
             Ptg operator;
             switch(look) {
                 case '*':
                     Match('*');
-                    operator = new MultiplyPtg();
+                    operator = MultiplyPtg.instance;
                     break;
                 case '/':
                     Match('/');
-                    operator = new DividePtg();
+                    operator = DividePtg.instance;
                     break;
                 default:
                     return result; // finished with Term
@@ -647,7 +647,7 @@ public final class FormulaParser {
     }
 
     private ParseNode comparisonExpression() {
-       ParseNode result = concatExpression();
+        ParseNode result = concatExpression();
         while (true) {
             SkipWhite();
             switch(look) {
@@ -666,26 +666,26 @@ public final class FormulaParser {
     private Ptg getComparisonToken() {
         if(look == '=') {
             Match(look);
-            return new EqualPtg();
+            return EqualPtg.instance;
         }
         boolean isGreater = look == '>';
         Match(look);
         if(isGreater) {
             if(look == '=') {
                 Match('=');
-                return new GreaterEqualPtg();
+                return GreaterEqualPtg.instance;
             }
-            return new GreaterThanPtg();
+            return GreaterThanPtg.instance;
         }
         switch(look) {
             case '=':
                 Match('=');
-                return new LessEqualPtg();
+                return LessEqualPtg.instance;
             case '>':
                 Match('>');
-                return new NotEqualPtg();
+                return NotEqualPtg.instance;
         }
-        return new LessThanPtg();
+        return LessThanPtg.instance;
     }
 
 
@@ -698,7 +698,7 @@ public final class FormulaParser {
             }
             Match('&');
             ParseNode other = additiveExpression();
-            result = new ParseNode(new ConcatPtg(), result, other);
+            result = new ParseNode(ConcatPtg.instance, result, other);
         }
         return result;
     }
@@ -706,18 +706,18 @@ public final class FormulaParser {
 
     /** Parse and Translate an Expression */
     private ParseNode additiveExpression() {
-       ParseNode result = Term();
+        ParseNode result = Term();
         while (true) {
             SkipWhite();
             Ptg operator;
             switch(look) {
                 case '+':
                     Match('+');
-                    operator = new AddPtg();
+                    operator = AddPtg.instance;
                     break;
                 case '-':
                     Match('-');
-                    operator = new SubtractPtg();
+                    operator = SubtractPtg.instance;
                     break;
                 default:
                     return result; // finished with additive expression
@@ -743,7 +743,7 @@ end;
 
     /**
      *  API call to execute the parsing of the formula
-     * @deprecated use Ptg[] FormulaParser.parse(String, HSSFWorkbook) directly
+     * @deprecated use Ptg[] FormulaParser.parse(String, Workbook) directly
      */
     public void parse() {
         pointer=0;
@@ -771,9 +771,9 @@ end;
     }
 
     public Ptg[] getRPNPtg(int formulaType) {
-       OperandClassTransformer oct = new OperandClassTransformer(formulaType);
+        OperandClassTransformer oct = new OperandClassTransformer(formulaType);
         // RVA is for 'operand class': 'reference', 'value', 'array'
-       oct.transformFormula(_rootNode);
+        oct.transformFormula(_rootNode);
         return ParseNode.toTokenArray(_rootNode);
     }
 
index c20f5e6d32f3070a9c9616b00eeb43cb20b41776..1583aa039b11613a15ca18810cf128a854a7c6cd 100644 (file)
@@ -557,7 +557,7 @@ public final class FormulaRecord
       if (field_8_parsed_expr != null)
         size = field_8_parsed_expr.size();
       for (int i=0; i< size; i++) {
-        Ptg ptg = (Ptg)((Ptg)field_8_parsed_expr.get(i)).clone();        
+        Ptg ptg = ((Ptg)field_8_parsed_expr.get(i)).copy();        
         rec.field_8_parsed_expr.add(i, ptg);
       }
       rec.value_data = value_data;
index 23af4b17cc8a0bb4418f92aee8403acea4472087..786c0b3d6ba3a6586694562f627de48be48a4787 100644 (file)
@@ -737,7 +737,7 @@ public class NameRecord extends Record {
                }
                // And then a union if we had more than one area
                if(refs.length > 1) {
-                       ptg = new UnionPtg();
+                       ptg = UnionPtg.instance;
                 field_13_name_definition.push(ptg);
                    this.setDefinitionTextLength( (short)(getDefinitionLength() + ptg.getSize()) );
                }
index e4c0f28ea48ba047abce5957787d2a6f5d683765..a8aeed0dae8d5f802e6bf0e95ab2d586e4c82901 100755 (executable)
@@ -207,22 +207,10 @@ public final class SharedFormulaRecord extends Record {
             }
             if (ptg instanceof RefNPtg) {
               RefNPtg refNPtg = (RefNPtg)ptg;
-              ptg = new ReferencePtg(fixupRelativeRow(formulaRow,refNPtg.getRow(),refNPtg.isRowRelative()),
+              ptg = new RefPtg(fixupRelativeRow(formulaRow,refNPtg.getRow(),refNPtg.isRowRelative()),
                                      fixupRelativeColumn(formulaColumn,refNPtg.getColumn(),refNPtg.isColRelative()),
                                      refNPtg.isRowRelative(),
                                      refNPtg.isColRelative());
-            } else if (ptg instanceof RefNVPtg) {
-              RefNVPtg refNVPtg = (RefNVPtg)ptg;
-              ptg = new RefVPtg(fixupRelativeRow(formulaRow,refNVPtg.getRow(),refNVPtg.isRowRelative()),
-                                fixupRelativeColumn(formulaColumn,refNVPtg.getColumn(),refNVPtg.isColRelative()),
-                                refNVPtg.isRowRelative(),
-                                refNVPtg.isColRelative());
-            } else if (ptg instanceof RefNAPtg) {
-              RefNAPtg refNAPtg = (RefNAPtg)ptg;
-              ptg = new RefAPtg( fixupRelativeRow(formulaRow,refNAPtg.getRow(),refNAPtg.isRowRelative()),
-                                 fixupRelativeColumn(formulaColumn,refNAPtg.getColumn(),refNAPtg.isColRelative()),
-                                 refNAPtg.isRowRelative(),
-                                 refNAPtg.isColRelative());
             } else if (ptg instanceof AreaNPtg) {
               AreaNPtg areaNPtg = (AreaNPtg)ptg;
               ptg = new AreaPtg(fixupRelativeRow(formulaRow,areaNPtg.getFirstRow(),areaNPtg.isFirstRowRelative()),
@@ -233,26 +221,6 @@ public final class SharedFormulaRecord extends Record {
                                 areaNPtg.isLastRowRelative(),
                                 areaNPtg.isFirstColRelative(),
                                 areaNPtg.isLastColRelative());
-            } else if (ptg instanceof AreaNVPtg) {
-              AreaNVPtg areaNVPtg = (AreaNVPtg)ptg;
-              ptg = new AreaVPtg(fixupRelativeRow(formulaRow,areaNVPtg.getFirstRow(),areaNVPtg.isFirstRowRelative()),
-                                fixupRelativeRow(formulaRow,areaNVPtg.getLastRow(),areaNVPtg.isLastRowRelative()),
-                                fixupRelativeColumn(formulaColumn,areaNVPtg.getFirstColumn(),areaNVPtg.isFirstColRelative()),
-                                fixupRelativeColumn(formulaColumn,areaNVPtg.getLastColumn(),areaNVPtg.isLastColRelative()),
-                                areaNVPtg.isFirstRowRelative(),
-                                areaNVPtg.isLastRowRelative(),
-                                areaNVPtg.isFirstColRelative(),
-                                areaNVPtg.isLastColRelative());
-            } else if (ptg instanceof AreaNAPtg) {
-              AreaNAPtg areaNAPtg = (AreaNAPtg)ptg;
-              ptg = new AreaAPtg(fixupRelativeRow(formulaRow,areaNAPtg.getFirstRow(),areaNAPtg.isFirstRowRelative()),
-                                fixupRelativeRow(formulaRow,areaNAPtg.getLastRow(),areaNAPtg.isLastRowRelative()),
-                                fixupRelativeColumn(formulaColumn,areaNAPtg.getFirstColumn(),areaNAPtg.isFirstColRelative()),
-                                fixupRelativeColumn(formulaColumn,areaNAPtg.getLastColumn(),areaNAPtg.isLastColRelative()),
-                                areaNAPtg.isFirstRowRelative(),
-                                areaNAPtg.isLastRowRelative(),
-                                areaNAPtg.isFirstColRelative(),
-                                areaNAPtg.isLastColRelative());
             }
             if (!ptg.isBaseToken()) {
                 ptg.setClass(originalOperandClass);
index bda9950667cc2d84c0a341b4c3933e16ce65baa7..fabc85ce52bad6a2a958cba06960c8ca49c273d6 100644 (file)
@@ -56,12 +56,6 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
         return sb.toString();
     }
 
-    public int getType() {
-        return -1;
-    }
-
-
-
     public short getFunctionIndex() {
         return field_2_fnc_index;
     }
index 20f609c56b3992a4399322bbd191a9e32dbb2a9a..db2d9d104411c692c41f17cac53bd609f004241c 100644 (file)
@@ -17,9 +17,6 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  * Addition operator PTG the "+" binomial operator.  If you need more 
  * explanation than that then well...We really can't help you here.
@@ -27,49 +24,23 @@ import org.apache.poi.hssf.record.RecordInputStream;
  * @author Jason Height (jheight at chariot dot net dot au)
  */
 public final class AddPtg extends ValueOperatorPtg {
-    public final static int  SIZE = 1;
     public final static byte sid  = 0x03;
     
     private final static String ADD = "+";
 
-    /** Creates new AddPtg */
-
-    public AddPtg()
-    {
-    }
-
-    public AddPtg(RecordInputStream in)
-    {
+    public static final ValueOperatorPtg instance = new AddPtg();
 
-        // doesn't need anything
+    private AddPtg() {
+       // enforce singleton
     }
     
-   
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
-
-    public int getSize()
-    {
-        return SIZE;
+    protected byte getSid() {
+       return sid;
     }
 
-    public int getType()
-    {
-        return TYPE_BINARY;
-    }
-
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
-    
-    /** Implementation of method from Ptg */
-    public String toFormulaString(Workbook book)
-    {
-        return "+";
-    }
        
    /** implementation of method from OperationsPtg*/  
     public String toFormulaString(String[] operands) {
@@ -80,9 +51,4 @@ public final class AddPtg extends ValueOperatorPtg {
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }
-           
-    public Object clone() {
-      return new AddPtg();
-    }
-
 }
index e0411cd35ee692a89ecc744de7523bb21851c9b1..dab9cf3ceae5731357c9a1c71ac24cdf040aa948 100644 (file)
@@ -18,9 +18,9 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.hssf.util.AreaReference;
-import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
 import org.apache.poi.util.LittleEndian;
@@ -95,7 +95,7 @@ public class Area3DPtg extends OperandPtg implements AreaI {
 
        public void writeBytes( byte[] array, int offset )
        {
-               array[0 + offset] = (byte) ( sid + ptgClass );
+               array[0 + offset] = (byte) ( sid + getPtgClass() );
                LittleEndian.putShort( array, 1 + offset, getExternSheetIndex() );
                LittleEndian.putShort( array, 3 + offset, (short)getFirstRow() );
                LittleEndian.putShort( array, 5 + offset, (short)getLastRow() );
@@ -280,24 +280,10 @@ public class Area3DPtg extends OperandPtg implements AreaI {
                return retval.toString();
        }
 
-       public byte getDefaultOperandClass()
-       {
+       public byte getDefaultOperandClass() {
                return Ptg.CLASS_REF;
        }
-
-       public Object clone()
-       {
-               Area3DPtg ptg = new Area3DPtg();
-               ptg.field_1_index_extern_sheet = field_1_index_extern_sheet;
-               ptg.field_2_first_row = field_2_first_row;
-               ptg.field_3_last_row = field_3_last_row;
-               ptg.field_4_first_column = field_4_first_column;
-               ptg.field_5_last_column = field_5_last_column;
-               ptg.setClass(ptgClass);
-               return ptg;
-       }
-
-
+       // TODO - one junit relies on this. remove
        public boolean equals( Object o )
        {
                if ( this == o ) return true;
@@ -313,18 +299,4 @@ public class Area3DPtg extends OperandPtg implements AreaI {
 
                return true;
        }
-
-       public int hashCode()
-       {
-               // TODO - hashCode seems to be unused
-               int result;
-               result = (int) field_1_index_extern_sheet;
-               result = 29 * result + (int) field_2_first_row;
-               result = 29 * result + (int) field_3_last_row;
-               result = 29 * result + (int) field_4_first_column;
-               result = 29 * result + (int) field_5_last_column;
-               return result;
-       }
-
-
 }
diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaAPtg.java b/src/java/org/apache/poi/hssf/record/formula/AreaAPtg.java
deleted file mode 100644 (file)
index e984b69..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-
-/* ====================================================================
-   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.
-==================================================================== */
-
-/*
- * AreaPtg.java
- *
- * Created on November 17, 2001, 9:30 PM
- */
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.util.AreaReference;
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * Specifies a rectangular area of cells A1:A4 for instance.
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-
-public final class AreaAPtg extends AreaPtg {
-    public final static short sid  = 0x65;
-
-    protected AreaAPtg() {
-      //Required for clone methods
-    }
-
-    public AreaAPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
-      super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
-    }
-
-    public AreaAPtg(RecordInputStream in)
-    {
-      super(in);
-    }
-
-    public String getAreaPtgName() {
-      return "AreaAPtg";
-    }
-
-    public Object clone() {
-      AreaAPtg ptg = new AreaAPtg();
-      ptg.setFirstRow(getFirstRow());
-      ptg.setLastRow(getLastRow());
-      ptg.setFirstColumnRaw(getFirstColumnRaw());
-      ptg.setLastColumnRaw(getLastColumnRaw());
-      ptg.setClass(ptgClass);
-      return ptg;
-    }
-}
index 182b8b43e3c10ea041d26e47fc0f20085b8bdea7..f1af9b68d1bf6c4d6a2d1986068bb1635fea168a 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * AreaErr - handles deleted cell area references.
  *
  * @author Daniel Noll (daniel at nuix dot com dot au)
  */
-public class AreaErrPtg extends AreaPtg
-{
+public final class AreaErrPtg extends OperandPtg {
     public final static byte sid  = 0x2b;
 
-    private AreaErrPtg()
-    {
-        //Required for clone methods
-        super();
-    }
-    
-    public AreaErrPtg(RecordInputStream in)
-    {
-        super(in);
-    }
-
-    public String toString()
-    {
-        StringBuffer buffer = new StringBuffer();
-
-        buffer.append("AreaErrPtg\n");
-        buffer.append("firstRow = " + getFirstRow()).append("\n");
-        buffer.append("lastRow  = " + getLastRow()).append("\n");
-        buffer.append("firstCol = " + getFirstColumn()).append("\n");
-        buffer.append("lastCol  = " + getLastColumn()).append("\n");
-        buffer.append("firstColRowRel= "
-                      + isFirstRowRelative()).append("\n");
-        buffer.append("lastColRowRel = "
-                      + isLastRowRelative()).append("\n");
-        buffer.append("firstColRel   = " + isFirstColRelative()).append("\n");
-        buffer.append("lastColRel    = " + isLastColRelative()).append("\n");
-        return buffer.toString();
+    public AreaErrPtg(RecordInputStream in) {
+       // 8 bytes unused:
+        in.readInt();
+        in.readInt();
     }
 
     public void writeBytes(byte [] array, int offset) {
-        super.writeBytes(array, offset);
-        array[offset] = (byte) (sid + ptgClass);
+        array[offset] = (byte) (sid + getPtgClass());
+        LittleEndian.putInt(array, offset+1, 0);
+        LittleEndian.putInt(array, offset+5, 0);
     }
 
-    public String toFormulaString(Workbook book)
-    {
+    public String toFormulaString(Workbook book) {
         return "#REF!";
     }
-    
-    public Object clone()
-    {
-        AreaErrPtg ptg = new AreaErrPtg();
-        ptg.setFirstRow(getFirstRow());
-        ptg.setFirstColumn(getFirstColumn());
-        ptg.setLastRow(getLastRow());
-        ptg.setLastColumn(getLastColumn());
-        ptg.setFirstColRelative(isFirstColRelative());
-        ptg.setLastColRelative(isLastColRelative());
-        ptg.setFirstRowRelative(isFirstRowRelative());
-        ptg.setLastRowRelative(isLastRowRelative());
-        ptg.setClass(ptgClass);
-        return ptg;
-    }
+
+       public byte getDefaultOperandClass() {
+               return Ptg.CLASS_REF;
+       }
+
+       public int getSize() {
+               return 9;
+       }
 }
 
diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaNAPtg.java b/src/java/org/apache/poi/hssf/record/formula/AreaNAPtg.java
deleted file mode 100644 (file)
index 7667f65..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* ====================================================================
-   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.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * Specifies a rectangular area of cells A1:A4 for instance.
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-
-public final class AreaNAPtg extends AreaPtg
-{
-    public final static short sid  = 0x6D;
-
-    protected AreaNAPtg() {
-      //Required for clone methods
-    }
-
-    public AreaNAPtg(RecordInputStream in)
-    {
-      super(in);
-    }
-
-    public String getAreaPtgName() {
-      return "AreaNAPtg";
-    }
-
-    public String toFormulaString(Workbook book)
-    {
-      throw notImplemented();
-    }
-
-    public Object clone() {
-      throw notImplemented();
-    }
-}
index ee939a7fca1a055e0eb9def56062406027f84f64..bf013838b2c0213b3245fbb3e79de400a5ca28e9 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    limitations under the License.
 ==================================================================== */
 
-/*
- * AreaPtg.java
- *
- * Created on November 17, 2001, 9:30 PM
- */
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.util.AreaReference;
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
 
 /**
  * Specifies a rectangular area of cells A1:A4 for instance.
  * @author Jason Height (jheight at chariot dot net dot au)
  */
+public final class AreaNPtg extends AreaPtgBase {
+       public final static short sid = 0x2D;
 
-public final class AreaNPtg extends AreaPtg
-{
-  public final static short sid  = 0x2D;
-
-  protected AreaNPtg() {
-    //Required for clone methods
-  }
-
-  public AreaNPtg(RecordInputStream in)
-  {
-    super(in);
-  }
-
-  public String getAreaPtgName() {
-    return "AreaNPtg";
-  }
-
-  public String toFormulaString(Workbook book)
-  {
-    throw notImplemented();
-  }
+       public AreaNPtg(RecordInputStream in) {
+               super(in);
+       }
 
-  public Object clone() {
-    throw notImplemented();
-  }
+       protected byte getSid() {
+               return sid;
+       }
 }
diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaNVPtg.java b/src/java/org/apache/poi/hssf/record/formula/AreaNVPtg.java
deleted file mode 100644 (file)
index f24745f..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* ====================================================================
-   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.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * Specifies a rectangular area of cells A1:A4 for instance.
- * @author  andy
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public final class AreaNVPtg extends AreaPtg {
-  public final static short sid  = 0x4D;
-
-  protected AreaNVPtg() {
-    //Required for clone methods
-  }
-
-  public AreaNVPtg(RecordInputStream in)
-  {
-    super(in);
-  }
-
-  public String getAreaPtgName() {
-    return "AreaNVPtg";
-  }
-
-  public String toFormulaString(Workbook book)
-  {
-    throw notImplemented();
-  }
-
-  public Object clone() {
-    throw notImplemented();
-  }
-}
old mode 100644 (file)
new mode 100755 (executable)
index f5f43e6..0839e55
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-import org.apache.poi.util.BitFieldFactory;
-
-import org.apache.poi.hssf.util.AreaReference;
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordInputStream;
 
 /**
  * Specifies a rectangular area of cells A1:A4 for instance.
- * @author  andy
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-public class AreaPtg extends OperandPtg implements AreaI {
-    /**
-     * TODO - (May-2008) fix subclasses of AreaPtg 'AreaN~' which are used in shared formulas.
-     * see similar comment in ReferencePtg
-     */
-    protected final RuntimeException notImplemented() {
-          return new RuntimeException("Coding Error: This method should never be called. This ptg should be converted");
-    }
-
+public final class AreaPtg extends AreaPtgBase {
     public final static short sid  = 0x25;
-    private final static int  SIZE = 9;
-    /** zero based, unsigned 16 bit */
-    private int             field_1_first_row;
-    /** zero based, unsigned 16 bit */
-    private int             field_2_last_row;
-    /** zero based, unsigned 8 bit */
-    private int             field_3_first_column;
-    /** zero based, unsigned 8 bit */
-    private int             field_4_last_column;
-    
-    private final static BitField   rowRelative = BitFieldFactory.getInstance(0x8000);
-    private final static BitField   colRelative = BitFieldFactory.getInstance(0x4000);
-    private final static BitField   columnMask      = BitFieldFactory.getInstance(0x3FFF);
-
-    protected AreaPtg() {
-      //Required for clone methods
-    }
-   
-    public AreaPtg(String arearef) {
-        AreaReference ar = new AreaReference(arearef);
-        CellReference firstCell = ar.getFirstCell();
-        CellReference lastCell = ar.getLastCell();
-        setFirstRow(firstCell.getRow());
-        setFirstColumn(firstCell.getCol());
-        setLastRow(lastCell.getRow());
-        setLastColumn(lastCell.getCol());
-        setFirstColRelative(!firstCell.isColAbsolute());
-        setLastColRelative(!lastCell.isColAbsolute());
-        setFirstRowRelative(!firstCell.isRowAbsolute());
-        setLastRowRelative(!lastCell.isRowAbsolute());        
-    }
-    
-    public AreaPtg(int firstRow, int lastRow, int firstColumn, int lastColumn,
-            boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
-        
-        checkColumnBounds(firstColumn);
-        checkColumnBounds(lastColumn);
-        checkRowBounds(firstRow);
-        checkRowBounds(lastRow);
-      setFirstRow(firstRow);
-      setLastRow(lastRow);
-      setFirstColumn(firstColumn);
-      setLastColumn(lastColumn);
-      setFirstRowRelative(firstRowRelative);
-      setLastRowRelative(lastRowRelative);
-      setFirstColRelative(firstColRelative);
-      setLastColRelative(lastColRelative);
-    }    
 
-    private static void checkColumnBounds(int colIx) {
-        if((colIx & 0x0FF) != colIx) {
-            throw new IllegalArgumentException("colIx (" + colIx + ") is out of range");
-        }
-    }
-    private static void checkRowBounds(int rowIx) {
-        if((rowIx & 0x0FFFF) != rowIx) {
-            throw new IllegalArgumentException("rowIx (" + rowIx + ") is out of range");
-        }
+    public AreaPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+      super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
     }
-
-    public AreaPtg(RecordInputStream in)
-    {
-        field_1_first_row    = in.readUShort();
-        field_2_last_row     = in.readUShort();
-        field_3_first_column = in.readUShort();
-        field_4_last_column  = in.readUShort();
-        //System.out.println(toString());
-    }
-    
-    public String getAreaPtgName() {
-      return "AreaPtg";
-    }    
-
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        sb.append(getClass().getName());
-        sb.append(" [");
-        sb.append(AreaReference.formatAsString(this));
-        sb.append("]");
-        return sb.toString();
-    }
-
-    public void writeBytes(byte [] array, int offset) {
-        array[offset] = (byte) (sid + ptgClass);
-        LittleEndian.putShort(array,offset+1,(short)field_1_first_row);
-        LittleEndian.putShort(array,offset+3,(short)field_2_last_row);
-        LittleEndian.putShort(array,offset+5,(short)field_3_first_column);
-        LittleEndian.putShort(array,offset+7,(short)field_4_last_column);        
-    }
-
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    /**
-     * @return the first row in the area
-     */
-    public int getFirstRow()
-    {
-        return field_1_first_row;
-    }
-
-    /**
-     * sets the first row
-     * @param rowIx number (0-based)
-     */
-    public void setFirstRow(int rowIx) {
-        checkRowBounds(rowIx);
-        field_1_first_row = rowIx;
-    }
-
-    /**
-     * @return last row in the range (x2 in x1,y1-x2,y2)
-     */
-    public int getLastRow()
-    {
-        return field_2_last_row;
-    }
-
-    /**
-     * @param rowIx last row number in the area 
-     */
-    public void setLastRow(int rowIx) {
-        checkRowBounds(rowIx);
-        field_2_last_row = rowIx;
-    }
-
-    /**
-     * @return the first column number in the area.
-     */
-    public int getFirstColumn()
-    {
-        return columnMask.getValue(field_3_first_column);
-    }
-
-    /**
-     * @return the first column number + the options bit settings unstripped
-     */
-    public short getFirstColumnRaw()
-    {
-        return (short) field_3_first_column; // TODO
-    }
-
-    /**
-     * @return whether or not the first row is a relative reference or not.
-     */
-    public boolean isFirstRowRelative()
-    {
-        return rowRelative.isSet(field_3_first_column);
+    public AreaPtg(RecordInputStream in) {
+      super(in);
     }
-    
-    /**
-     * sets the first row to relative or not
-     * @param rel is relative or not.
-     */
-    public void setFirstRowRelative(boolean rel) {
-        field_3_first_column=rowRelative.setBoolean(field_3_first_column,rel);
-    }
-
-    /**
-     * @return isrelative first column to relative or not
-     */
-    public boolean isFirstColRelative()
-    {
-        return colRelative.isSet(field_3_first_column);
-    }
-    
-    /**
-     * set whether the first column is relative 
-     */
-    public void setFirstColRelative(boolean rel) {
-        field_3_first_column=colRelative.setBoolean(field_3_first_column,rel);
-    }
-
-    /**
-     * set the first column in the area
-     */
-    public void setFirstColumn(int colIx) {
-        checkColumnBounds(colIx);
-       field_3_first_column=columnMask.setValue(field_3_first_column, colIx);
-    }
-
-    /**
-     * set the first column irespective of the bitmasks
-     */
-    public void setFirstColumnRaw(int column)
-    {
-        field_3_first_column = column;
-    }
-
-    /**
-     * @return lastcolumn in the area
-     */
-    public int getLastColumn()
-    {
-        return columnMask.getValue(field_4_last_column);
-    }
-
-    /**
-     * @return last column and bitmask (the raw field)
-     */
-    public short getLastColumnRaw()
-    {
-        return (short) field_4_last_column;
-    }
-
-    /**
-     * @return last row relative or not
-     */
-    public boolean isLastRowRelative()
-    {
-        return rowRelative.isSet(field_4_last_column);
-    }
-    
-    /**
-     * set whether the last row is relative or not
-     * @param rel <code>true</code> if the last row relative, else
-     * <code>false</code>
-     */
-    public void setLastRowRelative(boolean rel) {
-        field_4_last_column=rowRelative.setBoolean(field_4_last_column,rel);
-    }
-
-    /**
-     * @return lastcol relative or not
-     */
-    public boolean isLastColRelative()
-    {
-        return colRelative.isSet(field_4_last_column);
-    }
-    
-    /**
-     * set whether the last column should be relative or not
-     */
-    public void setLastColRelative(boolean rel) {
-        field_4_last_column=colRelative.setBoolean(field_4_last_column,rel);
-    }
-    
-
-    /**
-     * set the last column in the area
-     */
-    public void setLastColumn(int colIx) {
-        checkColumnBounds(colIx);
-       field_4_last_column=columnMask.setValue(field_4_last_column, colIx);
-    }
-
-    /**
-     * set the last column irrespective of the bitmasks
-     */
-    public void setLastColumnRaw(short column)
-    {
-        field_4_last_column = column;
-    }
-    
-    public String toFormulaString(Workbook book) {
-        return AreaReference.formatAsString(this);
-    }
-
-    public byte getDefaultOperandClass() {
-        return Ptg.CLASS_REF;
-    }
-    
-    public Object clone() {
-      AreaPtg ptg = new AreaPtg();
-      ptg.field_1_first_row = field_1_first_row;
-      ptg.field_2_last_row = field_2_last_row;
-      ptg.field_3_first_column = field_3_first_column;
-      ptg.field_4_last_column = field_4_last_column;
-      ptg.setClass(ptgClass);
-      return ptg;
-    }
-
+    public AreaPtg(String arearef) {
+               super(arearef);
+       }
+       protected byte getSid() {
+               return sid;
+       }
 }
diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java b/src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java
new file mode 100644 (file)
index 0000000..9ac406b
--- /dev/null
@@ -0,0 +1,286 @@
+/* ====================================================================
+   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.formula;
+
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.hssf.util.AreaReference;
+import org.apache.poi.hssf.record.RecordInputStream;
+
+/**
+ * Specifies a rectangular area of cells A1:A4 for instance.
+ * @author  andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public abstract class AreaPtgBase extends OperandPtg implements AreaI {
+    /**
+     * TODO - (May-2008) fix subclasses of AreaPtg 'AreaN~' which are used in shared formulas.
+     * see similar comment in ReferencePtg
+     */
+    protected final RuntimeException notImplemented() {
+          return new RuntimeException("Coding Error: This method should never be called. This ptg should be converted");
+    }
+
+    public final static short sid  = 0x25;
+    private final static int  SIZE = 9;
+    /** zero based, unsigned 16 bit */
+    private int             field_1_first_row;
+    /** zero based, unsigned 16 bit */
+    private int             field_2_last_row;
+    /** zero based, unsigned 8 bit */
+    private int             field_3_first_column;
+    /** zero based, unsigned 8 bit */
+    private int             field_4_last_column;
+    
+    private final static BitField   rowRelative = BitFieldFactory.getInstance(0x8000);
+    private final static BitField   colRelative = BitFieldFactory.getInstance(0x4000);
+    private final static BitField   columnMask      = BitFieldFactory.getInstance(0x3FFF);
+
+    protected AreaPtgBase(String arearef) {
+        AreaReference ar = new AreaReference(arearef);
+        CellReference firstCell = ar.getFirstCell();
+        CellReference lastCell = ar.getLastCell();
+        setFirstRow(firstCell.getRow());
+        setFirstColumn(firstCell.getCol());
+        setLastRow(lastCell.getRow());
+        setLastColumn(lastCell.getCol());
+        setFirstColRelative(!firstCell.isColAbsolute());
+        setLastColRelative(!lastCell.isColAbsolute());
+        setFirstRowRelative(!firstCell.isRowAbsolute());
+        setLastRowRelative(!lastCell.isRowAbsolute());        
+    }
+    
+    protected AreaPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn,
+            boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+        
+        checkColumnBounds(firstColumn);
+        checkColumnBounds(lastColumn);
+        checkRowBounds(firstRow);
+        checkRowBounds(lastRow);
+      setFirstRow(firstRow);
+      setLastRow(lastRow);
+      setFirstColumn(firstColumn);
+      setLastColumn(lastColumn);
+      setFirstRowRelative(firstRowRelative);
+      setLastRowRelative(lastRowRelative);
+      setFirstColRelative(firstColRelative);
+      setLastColRelative(lastColRelative);
+    }    
+
+    private static void checkColumnBounds(int colIx) {
+        if((colIx & 0x0FF) != colIx) {
+            throw new IllegalArgumentException("colIx (" + colIx + ") is out of range");
+        }
+    }
+    private static void checkRowBounds(int rowIx) {
+        if((rowIx & 0x0FFFF) != rowIx) {
+            throw new IllegalArgumentException("rowIx (" + rowIx + ") is out of range");
+        }
+    }
+
+    protected AreaPtgBase(RecordInputStream in)
+    {
+        field_1_first_row    = in.readUShort();
+        field_2_last_row     = in.readUShort();
+        field_3_first_column = in.readUShort();
+        field_4_last_column  = in.readUShort();
+    }
+
+    public final String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName());
+        sb.append(" [");
+        sb.append(AreaReference.formatAsString(this));
+        sb.append("]");
+        return sb.toString();
+    }
+    protected abstract byte getSid();
+
+    public final void writeBytes(byte [] array, int offset) {
+        array[offset] = (byte) (getSid() + getPtgClass());
+        LittleEndian.putShort(array,offset+1,(short)field_1_first_row);
+        LittleEndian.putShort(array,offset+3,(short)field_2_last_row);
+        LittleEndian.putShort(array,offset+5,(short)field_3_first_column);
+        LittleEndian.putShort(array,offset+7,(short)field_4_last_column);        
+    }
+
+    
+    public final int getSize() {
+        return SIZE;
+    }
+
+    /**
+     * @return the first row in the area
+     */
+    public final int getFirstRow() {
+        return field_1_first_row;
+    }
+
+    /**
+     * sets the first row
+     * @param rowIx number (0-based)
+     */
+    public final void setFirstRow(int rowIx) {
+        checkRowBounds(rowIx);
+        field_1_first_row = rowIx;
+    }
+
+    /**
+     * @return last row in the range (x2 in x1,y1-x2,y2)
+     */
+    public final int getLastRow() {
+        return field_2_last_row;
+    }
+
+    /**
+     * @param rowIx last row number in the area 
+     */
+    public final void setLastRow(int rowIx) {
+        checkRowBounds(rowIx);
+        field_2_last_row = rowIx;
+    }
+
+    /**
+     * @return the first column number in the area.
+     */
+    public final int getFirstColumn() {
+        return columnMask.getValue(field_3_first_column);
+    }
+
+    /**
+     * @return the first column number + the options bit settings unstripped
+     */
+    public final short getFirstColumnRaw() {
+        return (short) field_3_first_column; // TODO
+    }
+
+    /**
+     * @return whether or not the first row is a relative reference or not.
+     */
+    public final boolean isFirstRowRelative() {
+        return rowRelative.isSet(field_3_first_column);
+    }
+    
+    /**
+     * sets the first row to relative or not
+     * @param rel is relative or not.
+     */
+    public final void setFirstRowRelative(boolean rel) {
+        field_3_first_column=rowRelative.setBoolean(field_3_first_column,rel);
+    }
+
+    /**
+     * @return isrelative first column to relative or not
+     */
+    public final boolean isFirstColRelative() {
+        return colRelative.isSet(field_3_first_column);
+    }
+    
+    /**
+     * set whether the first column is relative 
+     */
+    public final void setFirstColRelative(boolean rel) {
+        field_3_first_column=colRelative.setBoolean(field_3_first_column,rel);
+    }
+
+    /**
+     * set the first column in the area
+     */
+    public final void setFirstColumn(int colIx) {
+        checkColumnBounds(colIx);
+       field_3_first_column=columnMask.setValue(field_3_first_column, colIx);
+    }
+
+    /**
+     * set the first column irrespective of the bitmasks
+     */
+    public final void setFirstColumnRaw(int column) {
+        field_3_first_column = column;
+    }
+
+    /**
+     * @return lastcolumn in the area
+     */
+    public final int getLastColumn() {
+        return columnMask.getValue(field_4_last_column);
+    }
+
+    /**
+     * @return last column and bitmask (the raw field)
+     */
+    public final short getLastColumnRaw() {
+        return (short) field_4_last_column;
+    }
+
+    /**
+     * @return last row relative or not
+     */
+    public final boolean isLastRowRelative() {
+        return rowRelative.isSet(field_4_last_column);
+    }
+    
+    /**
+     * set whether the last row is relative or not
+     * @param rel <code>true</code> if the last row relative, else
+     * <code>false</code>
+     */
+    public final void setLastRowRelative(boolean rel) {
+        field_4_last_column=rowRelative.setBoolean(field_4_last_column,rel);
+    }
+
+    /**
+     * @return lastcol relative or not
+     */
+    public final boolean isLastColRelative() {
+        return colRelative.isSet(field_4_last_column);
+    }
+    
+    /**
+     * set whether the last column should be relative or not
+     */
+    public final void setLastColRelative(boolean rel) {
+        field_4_last_column=colRelative.setBoolean(field_4_last_column,rel);
+    }
+    
+    /**
+     * set the last column in the area
+     */
+    public final void setLastColumn(int colIx) {
+        checkColumnBounds(colIx);
+       field_4_last_column=columnMask.setValue(field_4_last_column, colIx);
+    }
+
+    /**
+     * set the last column irrespective of the bitmasks
+     */
+    public final void setLastColumnRaw(short column) {
+        field_4_last_column = column;
+    }
+    
+    public String toFormulaString(Workbook book) {
+        return AreaReference.formatAsString(this);
+    }
+
+    public byte getDefaultOperandClass() {
+        return Ptg.CLASS_REF;
+    }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaVPtg.java b/src/java/org/apache/poi/hssf/record/formula/AreaVPtg.java
deleted file mode 100644 (file)
index 77c02bf..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-
-/* ====================================================================
-   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.
-==================================================================== */
-
-/*
- * AreaPtg.java
- *
- * Created on November 17, 2001, 9:30 PM
- */
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.util.AreaReference;
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * Specifies a rectangular area of cells A1:A4 for instance.
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-
-public final class AreaVPtg
-    extends AreaPtg
-{
-    public final static short sid  = 0x45;
-
-    protected AreaVPtg() {
-      //Required for clone methods
-    }
-
-    public AreaVPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
-      super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
-    }
-
-
-    public AreaVPtg(RecordInputStream in)
-    {
-      super(in);
-    }
-
-    public String getAreaPtgName() {
-      return "AreaVPtg";
-    }
-
-    public Object clone() {
-      AreaVPtg ptg = new AreaVPtg();
-      ptg.setFirstRow(getFirstRow());
-      ptg.setLastRow(getLastRow());
-      ptg.setFirstColumnRaw(getFirstColumnRaw());
-      ptg.setLastColumnRaw(getLastColumnRaw());
-      ptg.setClass(ptgClass);
-      return ptg;
-    }
-}
index cacce0485857d4f81b17cf45e5fd7e64b7195e56..371753007933db3ac9053bd1474eaf9b53ab51ee 100644 (file)
@@ -35,29 +35,28 @@ import org.apache.poi.util.LittleEndian;
  *  
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-public class ArrayPtg extends Ptg {
+public final class ArrayPtg extends Ptg {
        public static final byte sid  = 0x20;
 
        private static final int RESERVED_FIELD_LEN = 7;
        // TODO - fix up field visibility and subclasses
-       protected byte[] field_1_reserved;
+       private byte[] field_1_reserved;
+       
        // data from these fields comes after the Ptg data of all tokens in current formula
-       protected short  token_1_columns;
-       protected short token_2_rows;
-       protected Object[] token_3_arrayValues;
-
-       protected ArrayPtg() {
-         //Required for clone methods
-       }
+       private short  token_1_columns;
+       private short token_2_rows;
+       private Object[] token_3_arrayValues;
 
-       public ArrayPtg(RecordInputStream in)
-       {
+       public ArrayPtg(RecordInputStream in) {
                field_1_reserved = new byte[RESERVED_FIELD_LEN];
                // TODO - add readFully method to RecordInputStream
                for(int i=0; i< RESERVED_FIELD_LEN; i++) {
                        field_1_reserved[i] = in.readByte();
                }
        }
+       public Object[] getTokenArrayValues() {
+               return (Object[]) token_3_arrayValues.clone();
+       }
        
        public boolean isBaseToken() {
                return false;
@@ -117,7 +116,7 @@ public class ArrayPtg extends Ptg {
 
        public void writeBytes(byte[] data, int offset) {
                
-               LittleEndian.putByte(data, offset + 0, sid + ptgClass);
+               LittleEndian.putByte(data, offset + 0, sid + getPtgClass());
                System.arraycopy(field_1_reserved, 0, data, offset+1, RESERVED_FIELD_LEN);
        }
 
@@ -190,13 +189,9 @@ public class ArrayPtg extends Ptg {
        }
        
        public Object clone() {
-         ArrayPtg ptg = new ArrayPtg();
+         ArrayPtg ptg = (ArrayPtg) super.clone();
          ptg.field_1_reserved = (byte[]) field_1_reserved.clone();
-         
-         ptg.token_1_columns = token_1_columns;
-         ptg.token_2_rows = token_2_rows;
          ptg.token_3_arrayValues = (Object[]) token_3_arrayValues.clone();
-         ptg.setClass(ptgClass);
          return ptg;
        }
 }
diff --git a/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java b/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java
deleted file mode 100644 (file)
index 5be866e..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ====================================================================
-   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.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * ArrayPtgA - handles arrays
- *  
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public final class ArrayPtgA extends ArrayPtg {
-    public final static byte sid  = 0x60;
-
-    private ArrayPtgA() {
-      //Required for clone methods
-    }
-
-    public ArrayPtgA(RecordInputStream in) {
-       super(in);
-    }
-        
-    public Object clone() {
-      ArrayPtgA ptg = new ArrayPtgA();
-      ptg.field_1_reserved = (byte[]) field_1_reserved.clone();
-      
-      ptg.token_1_columns = token_1_columns;
-      ptg.token_2_rows = token_2_rows;
-      ptg.token_3_arrayValues = (Object[]) token_3_arrayValues.clone();
-      ptg.setClass(ptgClass);
-      return ptg;
-    }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java b/src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java
deleted file mode 100644 (file)
index ba95565..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ====================================================================
-   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.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * ArrayPtg - handles arrays
- * 
- * The ArrayPtg is a little weird, the size of the Ptg when parsing initially only
- * includes the Ptg sid and the reserved bytes. The next Ptg in the expression then follows.
- * It is only after the "size" of all the Ptgs is met, that the ArrayPtg data is actually
- * held after this. So Ptg.createParsedExpression keeps track of the number of 
- * ArrayPtg elements and need to parse the data upto the FORMULA record size.
- *  
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public final class ArrayPtgV extends ArrayPtg {
-    public final static byte sid  = 0x40;
-
-    private ArrayPtgV() {
-      //Required for clone methods
-    }
-
-    public ArrayPtgV(RecordInputStream in) {
-       super(in);
-    }
-    
-    public Object clone() {
-      ArrayPtgV ptg = new ArrayPtgV();
-      ptg.field_1_reserved = (byte[]) field_1_reserved.clone();
-      
-      ptg.token_1_columns = token_1_columns;
-      ptg.token_2_rows = token_2_rows;
-      ptg.token_3_arrayValues = (Object[]) token_3_arrayValues.clone();
-      ptg.setClass(ptgClass);
-      return ptg;
-    }
-}
index 401bf4df0256a61b37a22438575f639b8986946f..3d9c496604ed3bf7920cc06ffd1b16a3dd649d0c 100644 (file)
@@ -30,11 +30,7 @@ import org.apache.poi.hssf.record.RecordInputStream;
 public final class BoolPtg extends ScalarConstantPtg {
     public final static int  SIZE = 2;
     public final static byte sid  = 0x1d;
-    private boolean          field_1_value;
-
-    private BoolPtg() {
-      //Required for clone methods
-    }
+    private final boolean field_1_value;
 
     public BoolPtg(RecordInputStream in)
     {
@@ -46,11 +42,6 @@ public final class BoolPtg extends ScalarConstantPtg {
         field_1_value = (formulaToken.equals("TRUE"));
     }
 
-    public void setValue(boolean value)
-    {
-        field_1_value = value;
-    }
-
     public boolean getValue()
     {
         return field_1_value;
@@ -71,10 +62,4 @@ public final class BoolPtg extends ScalarConstantPtg {
     {
         return field_1_value ? "TRUE" : "FALSE";
     }
-
-    public Object clone() {
-        BoolPtg ptg = new BoolPtg();
-        ptg.field_1_value = field_1_value;
-        return ptg;
-    }
 }
index 6473c7f989817d8504885d28ccabee238851b2c4..28cca4f2e98d06829998ab53cbf8c78db0d94fa4 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  *
  * @author  andy
  * @author Jason Height (jheight at chariot dot net dot au)
  */
 public final class ConcatPtg extends ValueOperatorPtg {
-    public final static int  SIZE = 1;
     public final static byte sid  = 0x08;
     
     private final static String CONCAT = "&";
     
-    public ConcatPtg(RecordInputStream in)
-    {
-       // No contents
-    }
-    
-    public ConcatPtg() {
-        
-    }
-
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
+    public static final ValueOperatorPtg instance = new ConcatPtg();
 
-    public int getSize()
-    {
-        return SIZE;
+    private ConcatPtg() {
+       // enforce singleton
     }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
+    
+    protected byte getSid() {
+       return sid;
     }
 
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
-
-    public String toFormulaString(Workbook book)
-    {
-        return CONCAT;
-    }    
-
        
     public String toFormulaString(String[] operands) {
         StringBuffer buffer = new StringBuffer();
@@ -74,9 +49,4 @@ public final class ConcatPtg extends ValueOperatorPtg {
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }
-           
-    public Object clone() {
-      return new ConcatPtg();
-    }
-
 }
index 960ff90320ae3f1bf7d9e1f0fdbc17d93653ace5..fd5f86aabea0ac7145bf760efc05f40c73d16fd4 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  * This PTG implements the standard binomial divide "/"
  * @author  Andrew C. Oliver acoliver at apache dot org
  * @author Jason Height (jheight at chariot dot net dot au)
  */
 public final class DividePtg extends ValueOperatorPtg {
-    public final static int  SIZE = 1;
     public final static byte sid  = 0x06;
 
-    /** Creates new AddPtg */
-
-    public DividePtg()
-    {
-    }
-
-    public DividePtg(RecordInputStream in)
-    {
+    public static final ValueOperatorPtg instance = new DividePtg();
 
-        // doesn't need anything
+    private DividePtg() {
+       // enforce singleton
     }
-
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
-
-    public int getSize()
-    {
-        return SIZE;
+    
+    protected byte getSid() {
+       return sid;
     }
 
-    public int getType()
-    {
-        return TYPE_BINARY;
-    }
-
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
 
-    public String toFormulaString(Workbook book)
-    {
-        return "/";
-    }
-
      public String toFormulaString(String[] operands) {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append(operands[ 0 ]);
-        buffer.append(toFormulaString((Workbook)null));
+        buffer.append("/");
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }      
-
-    public Object clone() {
-      DividePtg ptg = new DividePtg();
-      return ptg;
-    }
 }
index 9ae08426b22d3801cc9fb5a960463d5babdeca63..7fbd17330de35063e74dcb9672ad2eb3ecdd7541 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  *
  * @author  andy
  */
 public final class EqualPtg extends ValueOperatorPtg {
-    public final static int  SIZE = 1;
     public final static byte sid  = 0x0b;
 
-    /** Creates new AddPtg */
-
-   public EqualPtg()
-    {
-    }
-
-    public EqualPtg(RecordInputStream in)
-    {
+    public static final ValueOperatorPtg instance = new EqualPtg();
 
-        // doesn't need anything
+    private EqualPtg() {
+       // enforce singleton
     }
-
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
-
-    public int getSize()
-    {
-        return SIZE;
+    
+    protected byte getSid() {
+       return sid;
     }
 
-    public int getType()
-    {
-        return TYPE_BINARY;
-    }
-
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
-
-    public String toFormulaString(Workbook book)
-    {
-        return "=";
-    }
  
     public String toFormulaString(String[] operands) {
          StringBuffer buffer = new StringBuffer();
 
         
         buffer.append(operands[ 0 ]);
-        buffer.append(toFormulaString((Workbook)null));
+        buffer.append("=");
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }       
-
-    public Object clone() {
-      return new EqualPtg();
-    }
-
-
 }
index 9d81e3bc24f0a2f9e323d71b522c64ec42cca822..27a2b29de52cb3bb5ae2cb101fe4e5382e7ea57d 100644 (file)
@@ -47,7 +47,7 @@ public final class ErrPtg extends ScalarConstantPtg {
     
     public static final short sid  = 0x1c;
     private static final int  SIZE = 2;
-    private int              field_1_error_code;
+    private final int field_1_error_code;
 
     /** Creates new ErrPtg */
 
@@ -64,7 +64,7 @@ public final class ErrPtg extends ScalarConstantPtg {
 
     public void writeBytes(byte [] array, int offset)
     {
-        array[offset] = (byte) (sid + ptgClass);
+        array[offset] = (byte) (sid + getPtgClass());
         array[offset + 1] = (byte)field_1_error_code;
     }
 
@@ -76,10 +76,6 @@ public final class ErrPtg extends ScalarConstantPtg {
         return SIZE;
     }
 
-    public Object clone() {
-        return new ErrPtg(field_1_error_code);
-    }
-
     public int getErrorCode() {
         return field_1_error_code;
     }
index 91f4baf3b125d898e77ebc75cb64d96a71515565..62a8878508565b21e823cb592c0fa5cf3d37b139 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -30,20 +29,11 @@ import org.apache.poi.util.LittleEndian;
  * @author Jason Height (jheight at chariot dot net dot au)
  * @author dmui (save existing implementation)
  */
-
 public final class ExpPtg extends ControlPtg {
     private final static int  SIZE = 5;
     public final static short sid  = 0x1;
-    private short            field_1_first_row;
-    private short            field_2_first_col;
-
-    /** Creates new ExpPtg */
-
-    public ExpPtg()
-    {
-    }
-
-    /** Creates new ExpPtg */
+    private final short            field_1_first_row;
+    private final short            field_2_first_col;
 
     public ExpPtg(RecordInputStream in)
     {
@@ -83,12 +73,4 @@ public final class ExpPtg extends ControlPtg {
         buffer.append("col = ").append(getColumn()).append("\n");
         return buffer.toString();
     }    
-    
-    public Object clone() {
-       ExpPtg result = new ExpPtg();
-        result.field_1_first_row = field_1_first_row;
-        result.field_2_first_col = field_2_first_col;        
-        return result;
-    }
-
 }
index cea44ed430d7bcd40cb8c154dca037f2460aff3b..c0034b24fb29a4b62bba2e7fb2b652cd017f0ba3 100644 (file)
@@ -56,7 +56,7 @@ public final class FuncPtg extends AbstractFunctionPtg {
     }
 
     public void writeBytes(byte[] array, int offset) {
-        array[offset+0]= (byte) (sid + ptgClass);
+        array[offset+0]= (byte) (sid + getPtgClass());
         LittleEndian.putShort(array,offset+1,field_2_fnc_index);
     }
 
@@ -64,12 +64,6 @@ public final class FuncPtg extends AbstractFunctionPtg {
         return numParams;
     }
 
-    public Object clone() {
-        FuncPtg ptg = new FuncPtg(field_2_fnc_index);
-        ptg.setClass(ptgClass);
-        return ptg;
-    }
-
     public int getSize() {
         return SIZE;
     }
index e3d2e77310bbb0c8f6b0456671f58d28a30cabc8..fd3546250a9029cee0f909e16033cf7e5321f64f 100644 (file)
@@ -30,11 +30,7 @@ public final class FuncVarPtg extends AbstractFunctionPtg{
     public final static byte sid  = 0x22;
     private final static int  SIZE = 4;
 
-    private FuncVarPtg() {
-      //Required for clone methods
-    }
-
- /**Creates new function pointer from a byte array
+    /**Creates new function pointer from a byte array
      * usually called while reading an excel file.
      */
     public FuncVarPtg(RecordInputStream in) {
@@ -69,7 +65,7 @@ public final class FuncVarPtg extends AbstractFunctionPtg{
     }
 
      public void writeBytes(byte[] array, int offset) {
-        array[offset+0]=(byte) (sid + ptgClass);
+        array[offset+0]=(byte) (sid + getPtgClass());
         array[offset+1]=field_1_num_args;
         LittleEndian.putShort(array,offset+2,field_2_fnc_index);
     }
@@ -78,14 +74,6 @@ public final class FuncVarPtg extends AbstractFunctionPtg{
         return field_1_num_args;
     }
 
-    public Object clone() {
-      FuncVarPtg ptg = new FuncVarPtg();
-      ptg.field_1_num_args = field_1_num_args;
-      ptg.field_2_fnc_index = field_2_fnc_index;
-      ptg.setClass(ptgClass);
-      return ptg;
-    }
-
     public int getSize() {
         return SIZE;
     }
index 91b9713a84889c82bbbd1d9808609322f67ba40a..f46191ed849dd9d3d801c08343e53f93b4fc1726 100755 (executable)
@@ -17,8 +17,6 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
 
 /**
  * PTG class to implement greater or equal to
@@ -29,56 +27,28 @@ public final class GreaterEqualPtg extends ValueOperatorPtg {
     public final static int  SIZE = 1;
     public final static byte sid  = 0x0c;
 
-    /** Creates new GreaterEqualPtg */
+    public static final ValueOperatorPtg instance = new GreaterEqualPtg();
 
-   public GreaterEqualPtg()
-    {
+    private GreaterEqualPtg() {
+       // enforce singleton
     }
-
-    public GreaterEqualPtg(RecordInputStream in)
-    {
-
-        // doesn't need anything
-    }
-
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
+    
+    protected byte getSid() {
+       return sid;
     }
 
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
-    }
-
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
 
-    public String toFormulaString(Workbook book)
-    {
-        return ">=";
-    }
-
     public String toFormulaString(String[] operands) {
          StringBuffer buffer = new StringBuffer();
 
         buffer.append(operands[ 0 ]);
 
-        buffer.append(toFormulaString((Workbook)null));
+        buffer.append(">=");
         buffer.append(operands[ 1 ]);
 
         return buffer.toString();
     }
-
-    public Object clone() {
-      return new GreaterEqualPtg();
-    }
-
 }
index 9bc83e569005cd39f476a34512ae9fbba9a97d6c..248cf6ff4a0f367f516eac98eca17c9f5984f1ce 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
 
 /**
  * Greater than operator PTG ">"
  * @author  Cameron Riley (criley at ekmail.com)
  */
 public final class GreaterThanPtg extends ValueOperatorPtg {
-    public final static int  SIZE = 1;
     public final static byte sid  = 0x0D;    
     private final static String GREATERTHAN = ">";
 
-    /** 
-     * Constructor. Creates new GreaterThanPtg 
-     */
-    public GreaterThanPtg()
-    {
-        //deliberately empty
-    }
+    public static final ValueOperatorPtg instance = new GreaterThanPtg();
 
-    /**
-     * Constructor. Create a new GreaterThanPtg.
-     * @param in the RecordInputstream to read the record from
-     */
-    public GreaterThanPtg(RecordInputStream in)
-    {
-        //deliberately empty
+    private GreaterThanPtg() {
+       // enforce singleton
     }
     
-    /**
-     * Write the sid to an array
-     * @param array the array of bytes to write the sid to
-     * @param offset the offset to add the sid to
-     */
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
-
-    /**
-     * Get the size of the sid
-     * @return int the size of the sid in terms of byte additions to an array
-     */
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    /**
-     * Get the type of PTG for Greater Than
-     * @return int the identifier for the type
-     */
-    public int getType()
-    {
-        return TYPE_BINARY;
+    protected byte getSid() {
+       return sid;
     }
 
     /**
      * Get the number of operands for the Less than operator
      * @return int the number of operands
      */
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
     
-    /** 
-     * Implementation of method from Ptg 
-     * @param book the Sheet References
-     */
-    public String toFormulaString(Workbook book)
-    {
-        return this.GREATERTHAN;
-    }
-      
     /** 
      * Implementation of method from OperationsPtg
      * @param operands a String array of operands
@@ -102,17 +54,8 @@ public final class GreaterThanPtg extends ValueOperatorPtg {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append(operands[ 0 ]);
-        buffer.append(this.GREATERTHAN);
+        buffer.append(GREATERTHAN);
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }
-    
-    /**
-     * Implementation of clone method from Object
-     * @return Object a clone of this class as an Object
-     */ 
-    public Object clone() 
-    {
-        return new GreaterThanPtg();
-    }
 }
index 673ce4fade0522189163a87e4dab992147f3b053..609b3ea451a99988687b402a89bd10660a57639e 100644 (file)
@@ -43,13 +43,12 @@ public final class IntPtg extends ScalarConstantPtg {
 
     public final static int  SIZE = 3;
     public final static byte sid  = 0x1e;
-    private int            field_1_value;
+    private final int field_1_value;
   
     public IntPtg(RecordInputStream in) {
         this(in.readUShort());
     }
 
-
     public IntPtg(int value) {
         if(!isInRange(value)) {
             throw new IllegalArgumentException("value is out of range: " + value);
@@ -61,7 +60,6 @@ public final class IntPtg extends ScalarConstantPtg {
         return field_1_value;
     }
 
-
     public void writeBytes(byte [] array, int offset)
     {
         array[ offset + 0 ] = sid;
@@ -76,9 +74,6 @@ public final class IntPtg extends ScalarConstantPtg {
         return String.valueOf(getValue());
     }
 
-    public Object clone() {
-     return new IntPtg(field_1_value);
-    }
     public String toString() {
         StringBuffer sb = new StringBuffer(64);
         sb.append(getClass().getName()).append(" [");
index e7a0ea7ce59f8dcf2c6952d25812335bbff99023..d939e057026288b1a2348d9b6bef91916d0edab8 100644 (file)
@@ -18,7 +18,6 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
 
 /**
  * @author Daniel Noll (daniel at nuix dot com dot au)
@@ -26,14 +25,10 @@ import org.apache.poi.hssf.record.RecordInputStream;
 public final class IntersectionPtg extends OperationPtg {
     public final static byte sid  = 0x0f;
 
+    public static final OperationPtg instance = new IntersectionPtg();
 
-    public IntersectionPtg()
-    {
-    }
-
-    public IntersectionPtg(RecordInputStream in)
-    {
-        // doesn't need anything
+    private IntersectionPtg() {
+       // enforce singleton
     }
 
     public final boolean isBaseToken() {
@@ -50,16 +45,6 @@ public final class IntersectionPtg extends OperationPtg {
         array[ offset + 0 ] = sid;
     }
 
-    public Object clone()
-    {
-        return new IntersectionPtg();
-    }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
-    }
-
     /** Implementation of method from Ptg */
     public String toFormulaString(Workbook book)
     {
index f6e4919c45b20f22219751d0eada075f39136030..99070e192fb000bd3cacf520e5ba4588dd6fe376 100755 (executable)
@@ -19,8 +19,6 @@
 package org.apache.poi.hssf.record.formula;
 
 
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
 
 
 /**
@@ -29,58 +27,27 @@ import org.apache.poi.hssf.record.RecordInputStream;
  * @author fred at stsci dot edu
  */
 public final class LessEqualPtg extends ValueOperatorPtg {
-    public final static int SIZE = 1;
     public final static byte sid = 0x0a;
 
-    /**
-     * Creates new LessEqualPtg
-     */
-    public LessEqualPtg()
-    {
+    public static final ValueOperatorPtg instance = new LessEqualPtg();
 
+    private LessEqualPtg() {
+       // enforce singleton
     }
-
-    public LessEqualPtg( RecordInputStream in )
-    {
-        // doesn't need anything
-    }
-
-    public void writeBytes( byte[] array, int offset )
-    {
-        array[offset + 0] = sid;
+    
+    protected byte getSid() {
+       return sid;
     }
 
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
-    }
-
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
 
-    public String toFormulaString( Workbook book )
-    {
-        return "<=";
-    }
-
-    public String toFormulaString( String[] operands )
-    {
+    public String toFormulaString(String[] operands) {
         StringBuffer buffer = new StringBuffer();
         buffer.append( operands[0] );
-        buffer.append( toFormulaString( (Workbook) null ) );
+        buffer.append("<=");
         buffer.append( operands[1] );
         return buffer.toString();
     }
-
-    public Object clone()
-    {
-        return new LessEqualPtg();
-    }
 }
index 03241ef37e00cdee60909a8d031ed6f566ebbf3c..f2fd06fe2bdf6bf702aad5270c8d95263601721d 100644 (file)
@@ -17,9 +17,6 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  * Less than operator PTG "<". The SID is taken from the 
  * Openoffice.orgs Documentation of the Excel File Format,
@@ -27,79 +24,31 @@ import org.apache.poi.hssf.record.RecordInputStream;
  * @author Cameron Riley (criley at ekmail.com)
  */
 public final class LessThanPtg extends ValueOperatorPtg {
-    /** the size of the Ptg  */
-    public final static int SIZE = 1;
-
     /** the sid for the less than operator as hex */
     public final static byte sid  = 0x09;    
 
     /** identifier for LESS THAN char */
     private final static String LESSTHAN = "<";
 
-    /** 
-     * Constructor. Creates new LessThanPtg 
-     */
-    public LessThanPtg()
-    {
-        //deliberately empty
-    }
+    public static final ValueOperatorPtg instance = new LessThanPtg();
 
-    /**
-     * Constructor. Create a new LessThanPtg.
-     * @param in the RecordInputstream to read the record from
-     */
-    public LessThanPtg(RecordInputStream in)
-    {
-        //deliberately empty
+    private LessThanPtg() {
+       // enforce singleton
     }
     
-    /**
-     * Write the sid to an array
-     * @param array the array of bytes to write the sid to
-     * @param offset the offset to add the sid to
-     */
-    public void writeBytes(byte[] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
-
-    /**
-     * Get the size of the sid
-     * @return int the size of the sid in terms of byte additions to an array
-     */
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    /**
-     * Get the type of PTG for Less Than
-     * @return int the identifier for the type
-     */
-    public int getType()
-    {
-        return TYPE_BINARY;
+    protected byte getSid() {
+       return sid;
     }
 
     /**
      * Get the number of operands for the Less than operator
      * @return int the number of operands
      */
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
     
-    /** 
-     * Implementation of method from Ptg 
-     * @param book the Sheet References
-     */
-    public String toFormulaString(Workbook book)
-    {
-        return this.LESSTHAN;
-    }
-       
-    /** 
+     /** 
      * Implementation of method from OperationsPtg
      * @param operands a String array of operands
      * @return String the Formula as a String
@@ -108,18 +57,8 @@ public final class LessThanPtg extends ValueOperatorPtg {
     {
         StringBuffer buffer = new StringBuffer();
         buffer.append(operands[ 0 ]);
-        buffer.append(this.LESSTHAN);
+        buffer.append(LESSTHAN);
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }
-    
-    /**
-     * Implementation of clone method from Object
-     * @return Object a clone of this class as an Object
-     */       
-    public Object clone() 
-    {
-        return new LessThanPtg();
-    }
-
 }
index a2e075c2285bc1013f39a97d4600ef4336a154af..10ce43789a781f83291509640c8fed6acaf674f1 100644 (file)
@@ -64,7 +64,7 @@ public class MemAreaPtg extends OperandPtg {
 
     public void writeBytes(byte [] array, int offset)
     {
-        array[offset] = (byte) (sid + ptgClass);
+        array[offset] = (byte) (sid + getPtgClass());
         LittleEndian.putInt(array, offset + 1, field_1_reserved);
         LittleEndian.putShort(array, offset + 5, field_2_subex_len);
     }
@@ -79,12 +79,7 @@ public class MemAreaPtg extends OperandPtg {
         return ""; // TODO: Not sure how to format this. -- DN
     }
 
-    public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
-
-    public Object clone() {
-      MemAreaPtg ptg = new MemAreaPtg();
-      ptg.field_1_reserved = field_1_reserved;
-      ptg.field_2_subex_len = field_2_subex_len;
-      return ptg;
+    public byte getDefaultOperandClass() {
+       return Ptg.CLASS_VALUE;
     }
 }
index 4c9156a904194e7cb96cec9fec84855fbaf8dc0b..e6afeae958c9cf8ea7a8b9c9318701f686ff8519 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    limitations under the License.
 ==================================================================== */
 
-
-/*
- * MemErrPtg.java
- *
- * Created on November 21, 2001, 8:46 AM
- */
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.usermodel.Workbook;
 
 /**
  *
@@ -35,9 +27,7 @@ import org.apache.poi.hssf.record.RecordInputStream;
  * @author Daniel Noll (daniel at nuix dot com dot au)
  */
 
-public class MemErrPtg
-    extends MemAreaPtg
-{
+public final class MemErrPtg extends MemAreaPtg {
     public final static short sid  = 0x27;
 
     /** Creates new MemErrPtg */
@@ -46,26 +36,17 @@ public class MemErrPtg
     {
     }
 
-    public MemErrPtg(RecordInputStream in)
-    {
+    public MemErrPtg(RecordInputStream in) {
         super(in);
     }
 
-    public void writeBytes(byte [] array, int offset)
-    {
+    public void writeBytes(byte [] array, int offset) {
         super.writeBytes(array, offset);
-        array[offset] = (byte) (sid + ptgClass);
+        array[offset] = (byte) (sid + getPtgClass());
     }
 
     public String toFormulaString(Workbook book)
     {
         return "ERR#";
     }
-
-    public Object clone() {
-      MemErrPtg ptg = new MemErrPtg();
-      ptg.setReserved(getReserved());
-      ptg.setSubexpressionLength(getSubexpressionLength());
-      return ptg;
-    }
 }
index a351cbc9ad3c1c52f0695a3989da6736962ac875..26fe637baedb51b08e1c15b231f3e355d68ad9c7 100644 (file)
    limitations under the License.
 ==================================================================== */
 
-
-/*
- * Ptg.java
- *
- * Created on October 28, 2001, 6:30 PM
- */
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.util.LittleEndian;
@@ -30,25 +24,23 @@ import org.apache.poi.hssf.record.RecordInputStream;
 /**
  * @author Glen Stampoultzis (glens at apache.org)
  */
-public class MemFuncPtg extends OperandPtg {
+public final class MemFuncPtg extends OperandPtg {
 
     public final static byte sid = 0x29;
-    private short field_1_len_ref_subexpression = 0;
-
-    public MemFuncPtg()
-    {
-        //Required for clone methods
-    }
+    private final int field_1_len_ref_subexpression;
 
     /**Creates new function pointer from a byte array
      * usually called while reading an excel file.
      */
-    public MemFuncPtg( RecordInputStream in )
-    {
-        field_1_len_ref_subexpression = in.readShort();
+    public MemFuncPtg(RecordInputStream in) {
+        this(in.readUShort());
     }
 
-    public int getSize()
+    public MemFuncPtg(int subExprLen) {
+       field_1_len_ref_subexpression = subExprLen;
+       }
+
+       public int getSize()
     {
         return 3;
     }
@@ -56,7 +48,7 @@ public class MemFuncPtg extends OperandPtg {
     public void writeBytes( byte[] array, int offset )
     {
         array[offset + 0] =  sid ;
-        LittleEndian.putShort( array, offset + 1, (short)field_1_len_ref_subexpression );
+        LittleEndian.putUShort( array, offset + 1, field_1_len_ref_subexpression );
     }
 
     public String toFormulaString(Workbook book)
@@ -66,7 +58,7 @@ public class MemFuncPtg extends OperandPtg {
 
     public byte getDefaultOperandClass()
     {
-        return 0;
+        return Ptg.CLASS_REF;
     }
 
     public int getNumberOfOperands()
@@ -74,21 +66,8 @@ public class MemFuncPtg extends OperandPtg {
         return field_1_len_ref_subexpression;
     }
 
-    public Object clone()
-    {
-        MemFuncPtg ptg = new MemFuncPtg();
-        ptg.field_1_len_ref_subexpression = this.field_1_len_ref_subexpression;
-        return ptg;
-    }
-
     public int getLenRefSubexpression()
     {
         return field_1_len_ref_subexpression;
     }
-
-    public void setLenRefSubexpression(int len)
-    {
-        field_1_len_ref_subexpression = (short)len;
-    }
-
 }
\ No newline at end of file
index 890f9e895f2ae85b4c3140ef7406200638d68a67..19f56cff741df4613f2ba98dfa1319453ea04336 100644 (file)
@@ -18,7 +18,6 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
 
 /**
  * Missing Function Arguments
@@ -31,16 +30,10 @@ public final class MissingArgPtg extends ScalarConstantPtg {
     private final static int SIZE = 1;
     public final static byte sid  = 0x16;
    
-    public MissingArgPtg()
+    public static final Ptg instance = new MissingArgPtg();
+    private MissingArgPtg()
     {
     }
-
-    public MissingArgPtg(RecordInputStream in)
-    {
-       // doesn't need anything
-    }
-    
-  
      
     public void writeBytes(byte [] array, int offset)
     {
@@ -51,15 +44,9 @@ public final class MissingArgPtg extends ScalarConstantPtg {
     {
         return SIZE;
     }
-
    
     public String toFormulaString(Workbook book)
     {
         return " ";
     }
-        
-    public Object clone() {
-      return new MissingArgPtg();
-    }
-
 }
index 1c5c80eab1a985eb991a0c89ce859159c4f13cd3..f627a91903e6adf998abc9bfaf28bdaedd1ad44f 100644 (file)
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
+package org.apache.poi.hssf.record.formula;
 
 /**
  * Implements the standard mathmatical multiplication - *
  * @author  Andrew C. Oliver (acoliver at apache dot org)
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-
 public final class MultiplyPtg extends ValueOperatorPtg {
-    public final static int  SIZE = 1;
     public final static byte sid  = 0x05;
 
-    /** Creates new AddPtg */
-
-    public MultiplyPtg()
-    {
-    }
-
-    public MultiplyPtg(RecordInputStream in)
-    {
+    public static final ValueOperatorPtg instance = new MultiplyPtg();
 
-        // doesn't need anything
+    private MultiplyPtg() {
+       // enforce singleton
     }
     
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
+    protected byte getSid() {
+       return sid;
     }
 
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
-    }
-
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
-
-    public int getStringLength() {
-        return 1;
-    }
-    
-
-    public String toFormulaString(Workbook book)
-    {
-        return "*";
-    }
-
-    public String toFormulaString(Ptg [] operands)
-    {
-        StringBuffer buffer = new StringBuffer();
-
-        buffer.append(operands[ 0 ].toFormulaString((Workbook)null));
-        buffer.append("*");
-        buffer.append(operands[ 1 ].toFormulaString((Workbook)null));
-        return buffer.toString();
-    }
     
     public String toFormulaString(String[] operands) {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append(operands[ 0 ]);
-        buffer.append(toFormulaString((Workbook)null));
+        buffer.append("*");
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }                  
-
-    public Object clone() {
-      return new MultiplyPtg();
-    }
 }
index 22215e2ec6921561e9f22452dfd270b14572ccd3..a29ae5541df643f007faf47b60192a2af2207ad6 100644 (file)
@@ -33,12 +33,6 @@ public final class NamePtg extends OperandPtg {
     /** one-based index to defined name record */
     private short             field_1_label_index;
     private short             field_2_zero;   // reserved must be 0
-    boolean xtra=false;
-
-
-    private NamePtg() {
-      //Required for clone methods
-    }
 
     /**
      * Creates new NamePtg and sets its name index to that of the corresponding defined name record
@@ -68,12 +62,9 @@ public final class NamePtg extends OperandPtg {
 
     /** Creates new NamePtg */
 
-    public NamePtg(RecordInputStream in)
-    {
-        //field_1_ixti        = LittleEndian.getShort(data, offset);
+    public NamePtg(RecordInputStream in) {
         field_1_label_index = in.readShort();
         field_2_zero        = in.readShort();
-        //if (data[offset+6]==0) xtra=true;
     }
     
     /**
@@ -83,15 +74,13 @@ public final class NamePtg extends OperandPtg {
         return field_1_label_index-1; // convert to zero based
     }
 
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[offset+0]= (byte) (sid + ptgClass);
+    public void writeBytes(byte [] array, int offset) {
+        array[offset+0]= (byte) (sid + getPtgClass());
         LittleEndian.putShort(array,offset+1,field_1_label_index);
         LittleEndian.putShort(array,offset+3, field_2_zero);
     }
 
-    public int getSize()
-    {
+    public int getSize() {
         return SIZE;
     }
 
@@ -100,12 +89,7 @@ public final class NamePtg extends OperandPtg {
        return book.getNameName(field_1_label_index - 1);
     }
     
-    public byte getDefaultOperandClass() {return Ptg.CLASS_REF;}
-
-    public Object clone() {
-      NamePtg ptg = new NamePtg();
-      ptg.field_1_label_index = field_1_label_index;
-      ptg.field_2_zero = field_2_zero;
-      return ptg;
-    }
+    public byte getDefaultOperandClass() {
+               return Ptg.CLASS_REF;
+       }
 }
index 6d98ef2eb4def35c59e3d7d430e122365bdc36fb..0a99ff140e51a9ea21d2800e604d1d34285d06f9 100644 (file)
@@ -33,31 +33,20 @@ public final class NameXPtg extends OperandPtg {
     private short            field_3_reserved;   // reserved must be 0
 
 
-    private NameXPtg() {
-      //Required for clone methods
-    }
-
-    /** Creates new NamePtg */
-
-    public NameXPtg(RecordInputStream in)
-    {
+    public NameXPtg(RecordInputStream in) {
         field_1_ixals        = in.readShort();
         field_2_ilbl        = in.readShort();
         field_3_reserved = in.readShort();
-        
-        //field_2_reserved = LittleEndian.getByteArray(data, offset + 12,12);
     }
 
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = (byte)(sid + ptgClass);
+    public void writeBytes(byte [] array, int offset) {
+        array[ offset + 0 ] = (byte)(sid + getPtgClass());
         LittleEndian.putShort(array, offset + 1, field_1_ixals);
         LittleEndian.putShort(array,offset+3, field_2_ilbl);
         LittleEndian.putShort(array, offset + 5, field_3_reserved);
     }
 
-    public int getSize()
-    {
+    public int getSize() {
         return SIZE;
     }
 
@@ -67,14 +56,7 @@ public final class NameXPtg extends OperandPtg {
         return book.resolveNameXText(field_1_ixals, field_2_ilbl-1); 
     }
     
-    public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
-
-    public Object clone() {
-      NameXPtg ptg = new NameXPtg();
-      ptg.field_1_ixals = field_1_ixals;
-      ptg.field_3_reserved = field_3_reserved;
-      ptg.field_2_ilbl = field_2_ilbl;
-      ptg.setClass(ptgClass);
-      return ptg;
-    }
+    public byte getDefaultOperandClass() {
+               return Ptg.CLASS_VALUE;
+       }
 }
index 95b68e87daaa4ceca0999d2840f108046dcb6a8d..62739dbd70045f7e2a560ef2e05555d05cc146d3 100755 (executable)
@@ -1,4 +1,3 @@
-        
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  * Ptg class to implement not equal
  *
  * @author fred at stsci dot edu
  */
 public final class NotEqualPtg extends ValueOperatorPtg {
-    public final static int SIZE = 1;
     public final static byte sid = 0x0e;
 
-    /**
-     * Creates new NotEqualPtg
-     */
-    public NotEqualPtg()
-    {
-    }
-
-    public NotEqualPtg( RecordInputStream in )
-    {
-        // doesn't need anything
-    }
-
-    public void writeBytes( byte[] array, int offset )
-    {
-        array[offset + 0] = sid;
-    }
+    public static final ValueOperatorPtg instance = new NotEqualPtg();
 
-    public int getSize()
-    {
-        return SIZE;
+    private NotEqualPtg() {
+       // enforce singleton
     }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
+    
+    protected byte getSid() {
+       return sid;
     }
 
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
 
-    public String toFormulaString( Workbook book )
-    {
-        return "<>";
-    }
-
-    public String toFormulaString( String[] operands )
-    {
+    public String toFormulaString(String[] operands) {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append( operands[0] );
 
-        buffer.append( toFormulaString( (Workbook) null ) );
+        buffer.append("<>");
         buffer.append( operands[1] );
 
         return buffer.toString();
     }
-
-    public Object clone()
-    {
-        return new NotEqualPtg();
-    }
-
 }
index a6d9e9259770e7a65d03e4a081679bcebab925a9..dc28e705ad903c8fea5bc0f7d0eb64b134d83dfb 100644 (file)
@@ -31,16 +31,12 @@ import org.apache.poi.hssf.record.RecordInputStream;
 public final class NumberPtg extends ScalarConstantPtg {
     public final static int  SIZE = 9;
     public final static byte sid  = 0x1f;
-    private double            field_1_value;
-
-    private NumberPtg() {
-      //Required for clone methods
-    }
+    private final double field_1_value;
         
     /** Create a NumberPtg from a byte array read from disk */
     public NumberPtg(RecordInputStream in)
     {
-        setValue(in.readDouble());
+        field_1_value = in.readDouble();
     }
     
     /** Create a NumberPtg from a string representation of  the number
@@ -49,13 +45,7 @@ public final class NumberPtg extends ScalarConstantPtg {
      *  @param value : String representation of a floating point number
      */
     public NumberPtg(String value) {
-        setValue(Double.parseDouble(value));
-    }
-    
-    
-    public void setValue(double value)
-    {
-        field_1_value = value;
+        field_1_value = Double.parseDouble(value);
     }
     
     
@@ -79,10 +69,4 @@ public final class NumberPtg extends ScalarConstantPtg {
     {
         return "" + getValue();
     }
-
-    public Object clone() {
-      NumberPtg ptg = new NumberPtg();
-      ptg.field_1_value = field_1_value;
-      return ptg;
-    }
 }
index 77df6b3b019d7a65392cc17ce4e01b6710d2ace1..085fa1e16b9567d1b8071b71fbc0725b164db7d5 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-
-
 /**
  * defines a Ptg that is an operation instead of an operand
  * @author  andy
  */
-
-public abstract class OperationPtg extends Ptg
-{
+public abstract class OperationPtg extends Ptg {
     public final static int TYPE_UNARY    = 0;
     public final static int TYPE_BINARY   = 1;
     public final static int TYPE_FUNCTION = 2;
 
-    public abstract int getType();
-    
     /**
      *  returns a string representation of the operations
      *  the length of the input array should equal the number returned by 
@@ -45,6 +39,12 @@ public abstract class OperationPtg extends Ptg
      */
     public abstract int getNumberOfOperands();
     
-    public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
+    public byte getDefaultOperandClass() {
+               return Ptg.CLASS_VALUE;
+       }
+    public final int getType() {
+       // TODO remove "int getType();" from Eval hierarchy
+       throw new RuntimeException("remove this method");
+    }
     
 }
index 7781d061ce2d84a0957d4291114cc37632452c3d..67bb85bfedcac8b8bfc98180d4d60c90e7b15376 100644 (file)
@@ -37,18 +37,11 @@ public final class ParenthesisPtg extends ControlPtg {
     private final static int SIZE = 1;
     public final static byte sid  = 0x15;
    
-    public ParenthesisPtg()
-    {
-    }
-
-    public ParenthesisPtg(RecordInputStream in)
-    {
-
-        // doesn't need anything
+    public static final ControlPtg instance = new ParenthesisPtg();
+    private ParenthesisPtg() {
+       // enforce singleton
     }
     
-  
-    
     public void writeBytes(byte [] array, int offset)
     {
         array[ offset + 0 ] = sid;
@@ -68,9 +61,4 @@ public final class ParenthesisPtg extends ControlPtg {
     public String toFormulaString(String[] operands) {
         return "("+operands[0]+")";
     }  
-        
-    public Object clone() {
-      return new ParenthesisPtg();
-    }
-
 }
index a8d6450b4e09f1f1e5d75595587b0280b7709ba7..9dd7bd2be91801f539cc42380ea35b7043dacffe 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    limitations under the License.
 ==================================================================== */
 
-/*
- * PercentPtg.java
- *
- * Created on March 29, 2006, 9:23 PM
- */
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  * Percent PTG.
  *
  * @author Daniel Noll (daniel at nuix.com.au)
  */
-
 public final class PercentPtg extends ValueOperatorPtg {
     public final static int  SIZE = 1;
     public final static byte sid  = 0x14;
     
     private final static String PERCENT = "%";
 
-    /** Creates new PercentPtg */
+    public static final ValueOperatorPtg instance = new PercentPtg();
 
-    public PercentPtg()
-    {
-    }
-
-    public PercentPtg(RecordInputStream in)
-    {
-
-        // doesn't need anything
+    private PercentPtg() {
+       // enforce singleton
     }
     
-   
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
+    protected byte getSid() {
+       return sid;
     }
 
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    public int getType()
-    {
-        return TYPE_UNARY;
-    }
-
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 1;
     }
-    
-    /** Implementation of method from Ptg */
-    public String toFormulaString(Workbook book)
-    {
-        return "%";
-    }
        
-   /** implementation of method from OperationsPtg*/  
     public String toFormulaString(String[] operands) {
         StringBuffer buffer = new StringBuffer();
 
@@ -85,9 +49,4 @@ public final class PercentPtg extends ValueOperatorPtg {
         buffer.append(PERCENT);
         return buffer.toString();
     }
-    
-    public Object clone() {
-      return new PercentPtg();
-    }
-
 }
index dbd0f28581da16fdaaca8304cac60e8d63e3e285..478b12fac35b3ea4a70464b68a6dd6eae8d2dc4b 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  *
  * @author  andy
  * @author Jason Height (jheight at chariot dot net dot au)
  */
 public final class PowerPtg extends ValueOperatorPtg {
-    public final static int  SIZE = 1;
     public final static byte sid  = 0x07;
 
-    /** Creates new AddPtg */
-
-   public PowerPtg()
-    {
-    }
-
-    public PowerPtg(RecordInputStream in)
-    {
-
-        // doesn't need anything
-    }
-
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
-
-    public int getSize()
-    {
-        return SIZE;
-    }
+    public static final ValueOperatorPtg instance = new PowerPtg();
 
-    public int getType()
-    {
-        return TYPE_BINARY;
+    private PowerPtg() {
+       // enforce singleton
     }
-
-    public int getNumberOfOperands()
-    {
-        return 2;
+    
+    protected byte getSid() {
+       return sid;
     }
 
-    public String toFormulaString(Workbook book)
-    {
-        return "^";
+    public int getNumberOfOperands() {
+        return 2; // TODO - 2 seems wrong (Jun 2008).  Maybe this method is not relevant
     }
  
     public String toFormulaString(String[] operands) {
@@ -71,13 +44,8 @@ public final class PowerPtg extends ValueOperatorPtg {
 
         
         buffer.append(operands[ 0 ]);
-        buffer.append(toFormulaString((Workbook)null));
+        buffer.append("^");
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }       
-
-    public Object clone() {
-      return new PowerPtg();
-    }
-
 }
index 7819c35bc8f6e10fe3e21bd15cdf18266e392dc4..666b83cfa758630ff30a5fb9392471d7c4570ebc 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import java.util.List;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Stack;
 
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.usermodel.Workbook;
 
 /**
+ * <tt>Ptg</tt> represents a syntactic token in a formula.  'PTG' is an acronym for 
+ * '<b>p</b>arse <b>t</b>hin<b>g</b>'.  Originally, the name referred to the single 
+ * byte identifier at the start of the token, but in POI, <tt>Ptg</tt> encapsulates
+ * the whole formula token (initial byte + value data).
+ * <p/>
+ * 
+ * <tt>Ptg</tt>s are logically arranged in a tree representing the structure of the
+ * parsed formula.  However, in BIFF files <tt>Ptg</tt>s are written/read in 
+ * <em>Reverse-Polish Notation</em> order. The RPN ordering also simplifies formula
+ * evaluation logic, so POI mostly accesses <tt>Ptg</tt>s in the same way.
  *
  * @author  andy
  * @author avik
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-public abstract class Ptg
-{
-
-
-    /* convert infix order ptg list to rpn order ptg list
-     * @return List ptgs in RPN order
-     * @param infixPtgs List of ptgs in infix order
-     */
-
-    /* DO NOT REMOVE
-     *we keep this method in case we wish to change the way we parse
-     *It needs a getPrecedence in OperationsPtg
-
-    public static List ptgsToRpn(List infixPtgs) {
-        java.util.Stack operands = new java.util.Stack();
-        java.util.List retval = new java.util.Stack();
-
-        java.util.ListIterator i = infixPtgs.listIterator();
-        Object p;
-        OperationPtg o ;
-        boolean weHaveABracket = false;
-        while (i.hasNext()) {
-            p=i.next();
-            if (p instanceof OperationPtg) {
-                if (p instanceof ParenthesisPtg) {
-                    if (!weHaveABracket) {
-                        operands.push(p);
-                        weHaveABracket = true;
-                    } else {
-                        o = (OperationPtg) operands.pop();
-                        while (!(o instanceof ParenthesisPtg)) {
-                            retval.add(o);
-                        }
-                        weHaveABracket = false;
-                    }
-                } else {
-
-                    while  (!operands.isEmpty() && ((OperationPtg) operands.peek()).getPrecedence() >= ((OperationPtg) p).getPrecedence() ) { //TODO handle ^ since it is right associative
-                        retval.add(operands.pop());
-                    }
-                    operands.push(p);
-                }
-            } else {
-                retval.add(p);
-            }
-        }
-        while (!operands.isEmpty()) {
-            if (operands.peek() instanceof ParenthesisPtg ){
-                //throw some error
-            } else {
-                retval.add(operands.pop());
-            }
-        }
-        return retval;
-    }
-    */
-
-    /**
-     * Reads <tt>size</tt> bytes of the input stream, to create an array of <tt>Ptg</tt>s.
-     * Extra data (beyond <tt>size</tt>) may be read if and <tt>ArrayPtg</tt>s are present.
-     */
-    public static Stack createParsedExpressionTokens(short size,  RecordInputStream in )
-    {
-        Stack stack = new Stack();
-        int pos = 0;
-        List arrayPtgs = null;
-        while ( pos < size )
-        {
-            Ptg ptg = Ptg.createPtg( in );
-            if (ptg instanceof ArrayPtg) {
-                if (arrayPtgs == null)
-                    arrayPtgs = new ArrayList(5);
-                arrayPtgs.add(ptg);
-                pos += 8;
-            } else pos += ptg.getSize();
-            stack.push( ptg );
-        }
-        if(pos != size) {
-            throw new RuntimeException("Ptg array size mismatch");
-        }
-        if (arrayPtgs != null) {
-            for (int i=0;i<arrayPtgs.size();i++) {
-                ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
-                p.readTokenValues(in);
-            }
-        }
-        return stack;
-    }
-
-    public static Ptg createPtg(RecordInputStream in) {
-        byte id = in.readByte();
-        
-        if (id < 0x20) {
-               return createBasePtg(id, in);
-        }
-        
-        Ptg  retval = createClassifiedPtg(id, in);
-
-        if (id > 0x60) {
-            retval.setClass(CLASS_ARRAY);
-        } else if (id > 0x40) {
-            retval.setClass(CLASS_VALUE);
-        } else {
-            retval.setClass(CLASS_REF);
-        }
-
-       return retval;
-
-    }
+public abstract class Ptg implements Cloneable {
+
+       /* convert infix order ptg list to rpn order ptg list
+        * @return List ptgs in RPN order
+        * @param infixPtgs List of ptgs in infix order
+        */
+
+       /* DO NOT REMOVE
+        *we keep this method in case we wish to change the way we parse
+        *It needs a getPrecedence in OperationsPtg
+
+       public static List ptgsToRpn(List infixPtgs) {
+               java.util.Stack operands = new java.util.Stack();
+               java.util.List retval = new java.util.Stack();
+
+               java.util.ListIterator i = infixPtgs.listIterator();
+               Object p;
+               OperationPtg o ;
+               boolean weHaveABracket = false;
+               while (i.hasNext()) {
+                       p=i.next();
+                       if (p instanceof OperationPtg) {
+                               if (p instanceof ParenthesisPtg) {
+                                       if (!weHaveABracket) {
+                                               operands.push(p);
+                                               weHaveABracket = true;
+                                       } else {
+                                               o = (OperationPtg) operands.pop();
+                                               while (!(o instanceof ParenthesisPtg)) {
+                                                       retval.add(o);
+                                               }
+                                               weHaveABracket = false;
+                                       }
+                               } else {
+
+                                       while  (!operands.isEmpty() && ((OperationPtg) operands.peek()).getPrecedence() >= ((OperationPtg) p).getPrecedence() ) { //TODO handle ^ since it is right associative
+                                               retval.add(operands.pop());
+                                       }
+                                       operands.push(p);
+                               }
+                       } else {
+                               retval.add(p);
+                       }
+               }
+               while (!operands.isEmpty()) {
+                       if (operands.peek() instanceof ParenthesisPtg ){
+                               //throw some error
+                       } else {
+                               retval.add(operands.pop());
+                       }
+               }
+               return retval;
+       }
+       */
+       
+       /**
+        * Reads <tt>size</tt> bytes of the input stream, to create an array of <tt>Ptg</tt>s.
+        * Extra data (beyond <tt>size</tt>) may be read if and <tt>ArrayPtg</tt>s are present.
+        */
+       public static Ptg[] readTokens(int size, RecordInputStream in) {
+               Stack temp = createParsedExpressionTokens((short)size, in);
+               return toPtgArray(temp);
+       }
+
+       /**
+        * @deprecated - use readTokens()
+        */
+       public static Stack createParsedExpressionTokens(short size, RecordInputStream in)
+       {
+               Stack stack = new Stack();
+               int pos = 0;
+               List arrayPtgs = null;
+               while ( pos < size )
+               {
+                       Ptg ptg = Ptg.createPtg( in );
+                       if (ptg instanceof ArrayPtg) {
+                               if (arrayPtgs == null)
+                                       arrayPtgs = new ArrayList(5);
+                               arrayPtgs.add(ptg);
+                               pos += 8;
+                       } else pos += ptg.getSize();
+                       stack.push( ptg );
+               }
+               if(pos != size) {
+                       throw new RuntimeException("Ptg array size mismatch");
+               }
+               if (arrayPtgs != null) {
+                       for (int i=0;i<arrayPtgs.size();i++) {
+                               ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
+                               p.readTokenValues(in);
+                       }
+               }
+               return stack;
+       }
+
+       public static Ptg createPtg(RecordInputStream in) {
+               byte id = in.readByte();
+               
+               if (id < 0x20) {
+                       return createBasePtg(id, in);
+               }
+               
+               Ptg  retval = createClassifiedPtg(id, in);
+
+               if (id > 0x60) {
+                       retval.setClass(CLASS_ARRAY);
+               } else if (id > 0x40) {
+                       retval.setClass(CLASS_VALUE);
+               } else {
+                       retval.setClass(CLASS_REF);
+               }
+
+          return retval;
+       }
 
        private static Ptg createClassifiedPtg(byte id, RecordInputStream in) {
                
                int baseId = id & 0x1F | 0x20;
                
-        switch (baseId) {
-             case FuncPtg.sid:     return new FuncPtg(in);     // 0x21, 0x41, 0x61
-             case FuncVarPtg.sid:  return new FuncVarPtg(in);  // 0x22, 0x42, 0x62
-             case NamePtg.sid:     return new NamePtg(in);     // 0x23, 0x43, 0x63
-
-             case MemAreaPtg.sid:  return new MemAreaPtg(in);  // 0x26, 0x46, 0x66
-             case MemErrPtg.sid:   return new MemErrPtg(in);   // 0x27, 0x47, 0x67
-             case MemFuncPtg.sid:  return new MemFuncPtg(in);  // 0x29, 0x49, 0x69
-             case RefErrorPtg.sid: return  new RefErrorPtg(in);// 0x2a, 0x4a, 0x6a
-             case AreaErrPtg.sid:  return new AreaErrPtg(in);  // 0x2b, 0x4b, 0x6b
-
-             case NameXPtg.sid:    return new NameXPtg(in);    // 0x39, 0x49, 0x79
-             case Ref3DPtg.sid:    return  new Ref3DPtg(in);   // 0x3a, 0x5a, 0x7a
-             case Area3DPtg.sid:   return new Area3DPtg(in);   // 0x3b, 0x5b, 0x7b
-             case DeletedRef3DPtg.sid:  return new DeletedRef3DPtg(in);   // 0x3c, 0x5c, 0x7c
-             case DeletedArea3DPtg.sid: return  new DeletedArea3DPtg(in); // 0x3d, 0x5d, 0x7d
-        }
-        
-        
-        switch (id) {
-        // TODO - why are specific subclasses needed for these Ptgs?
-            case ArrayPtg.sid:     return new ArrayPtg(in);    // 0x20
-            case ArrayPtgV.sid:    return new ArrayPtgV(in);   // 0x40
-            case ArrayPtgA.sid:    return new ArrayPtgA(in);   // 0x60
-
-            case ReferencePtg.sid: return new ReferencePtg(in);// 0x24
-            case RefAPtg.sid:      return new RefAPtg(in);     // 0x64
-            case RefVPtg.sid:      return new RefVPtg(in);     // 0x44
-
-            case RefNAPtg.sid:     return new RefNAPtg(in);    // 0x6C
-            case RefNPtg.sid:      return new RefNPtg(in);     // 0x2C
-            case RefNVPtg.sid:     return new RefNVPtg(in);    // 0x4C
-
-            case AreaPtg.sid:      return new AreaPtg(in);     // 0x25
-            case AreaVPtg.sid:      return new AreaVPtg(in);   // 0x45
-            case AreaAPtg.sid:      return new AreaAPtg(in);   // 0x65
-
-            case AreaNAPtg.sid:    return new AreaNAPtg(in);   // 0x6D
-            case AreaNPtg.sid:     return new AreaNPtg(in);    // 0x2D
-            case AreaNVPtg.sid:    return new AreaNVPtg(in);   // 0x4D
-        
-        }
-        throw new UnsupportedOperationException(" Unknown Ptg in Formula: 0x"+
-                   Integer.toHexString(id) + " (" + ( int ) id + ")");
+               switch (baseId) {
+                       case ArrayPtg.sid:     return new ArrayPtg(in);    // 0x20, 0x40, 0x60
+                        case FuncPtg.sid:     return new FuncPtg(in);     // 0x21, 0x41, 0x61
+                        case FuncVarPtg.sid:  return new FuncVarPtg(in);  // 0x22, 0x42, 0x62
+                        case NamePtg.sid:     return new NamePtg(in);     // 0x23, 0x43, 0x63
+                        case RefPtg.sid:      return new RefPtg(in);      // 0x24, 0x44, 0x64
+                        case AreaPtg.sid:     return new AreaPtg(in);     // 0x25, 0x45, 0x65
+                        case MemAreaPtg.sid:  return new MemAreaPtg(in);  // 0x26, 0x46, 0x66
+                        case MemErrPtg.sid:   return new MemErrPtg(in);   // 0x27, 0x47, 0x67
+                        case MemFuncPtg.sid:  return new MemFuncPtg(in);  // 0x29, 0x49, 0x69
+                        case RefErrorPtg.sid: return  new RefErrorPtg(in);// 0x2a, 0x4a, 0x6a
+                        case AreaErrPtg.sid:  return new AreaErrPtg(in);  // 0x2b, 0x4b, 0x6b
+                        case RefNPtg.sid:     return new RefNPtg(in);     // 0x2c, 0x4c, 0x6c
+                        case AreaNPtg.sid:    return new AreaNPtg(in);    // 0x2d, 0x4d, 0x6d
+
+                        case NameXPtg.sid:    return new NameXPtg(in);    // 0x39, 0x49, 0x79
+                        case Ref3DPtg.sid:    return  new Ref3DPtg(in);   // 0x3a, 0x5a, 0x7a
+                        case Area3DPtg.sid:   return new Area3DPtg(in);   // 0x3b, 0x5b, 0x7b
+                        case DeletedRef3DPtg.sid:  return new DeletedRef3DPtg(in);   // 0x3c, 0x5c, 0x7c
+                        case DeletedArea3DPtg.sid: return  new DeletedArea3DPtg(in); // 0x3d, 0x5d, 0x7d
+               }
+               throw new UnsupportedOperationException(" Unknown Ptg in Formula: 0x"+
+                                  Integer.toHexString(id) + " (" + ( int ) id + ")");
        }
 
        private static Ptg createBasePtg(byte id, RecordInputStream in) {
                switch(id) {
-                   case 0x00:                return new UnknownPtg(); // TODO - not a real Ptg
-               case ExpPtg.sid:          return new ExpPtg(in);         // 0x01
-               case AddPtg.sid:          return new AddPtg(in);         // 0x03
-               case SubtractPtg.sid:     return new SubtractPtg(in);    // 0x04
-               case MultiplyPtg.sid:     return new MultiplyPtg(in);    // 0x05
-               case DividePtg.sid:       return new DividePtg(in);      // 0x06
-               case PowerPtg.sid:        return new PowerPtg(in);       // 0x07
-               case ConcatPtg.sid:       return new ConcatPtg(in);      // 0x08
-               case LessThanPtg.sid:     return new LessThanPtg(in);    // 0x09
-               case LessEqualPtg.sid:    return new LessEqualPtg(in);   // 0x0a
-               case EqualPtg.sid:        return new EqualPtg(in);       // 0x0b
-               case GreaterEqualPtg.sid: return new GreaterEqualPtg(in);// 0x0c
-               case GreaterThanPtg.sid:  return new GreaterThanPtg(in); // 0x0d
-               case NotEqualPtg.sid:     return new NotEqualPtg(in);    // 0x0e
-               case IntersectionPtg.sid: return new IntersectionPtg(in);// 0x0f
-               case UnionPtg.sid:        return new UnionPtg(in);       // 0x10
-               case RangePtg.sid:        return new RangePtg(in);       // 0x11
-               case UnaryPlusPtg.sid:    return new UnaryPlusPtg(in);   // 0x12
-               case UnaryMinusPtg.sid:   return new UnaryMinusPtg(in);  // 0x13
-               case PercentPtg.sid:      return new PercentPtg(in);     // 0x14
-               case ParenthesisPtg.sid:  return new ParenthesisPtg(in); // 0x15
-               case MissingArgPtg.sid:   return new MissingArgPtg(in);  // 0x16
-               case StringPtg.sid:       return new StringPtg(in);      // 0x17
-               case AttrPtg.sid:                
-               case 0x1a:        return new AttrPtg(in); // 0x19
-               case ErrPtg.sid:          return new ErrPtg(in);         // 0x1c
-               case BoolPtg.sid:         return new BoolPtg(in);        // 0x1d
-               case IntPtg.sid:          return new IntPtg(in);         // 0x1e
-               case NumberPtg.sid:       return new NumberPtg(in);      // 0x1f
+                       case 0x00:                return new UnknownPtg(); // TODO - not a real Ptg
+                       case ExpPtg.sid:          return new ExpPtg(in);          // 0x01
+                       case AddPtg.sid:          return AddPtg.instance;         // 0x03
+                       case SubtractPtg.sid:     return SubtractPtg.instance;    // 0x04
+                       case MultiplyPtg.sid:     return MultiplyPtg.instance;    // 0x05
+                       case DividePtg.sid:       return DividePtg.instance;      // 0x06
+                       case PowerPtg.sid:        return PowerPtg.instance;       // 0x07
+                       case ConcatPtg.sid:       return ConcatPtg.instance;      // 0x08
+                       case LessThanPtg.sid:     return LessThanPtg.instance;    // 0x09
+                       case LessEqualPtg.sid:    return LessEqualPtg.instance;   // 0x0a
+                       case EqualPtg.sid:        return EqualPtg.instance;       // 0x0b
+                       case GreaterEqualPtg.sid: return GreaterEqualPtg.instance;// 0x0c
+                       case GreaterThanPtg.sid:  return GreaterThanPtg.instance; // 0x0d
+                       case NotEqualPtg.sid:     return NotEqualPtg.instance;    // 0x0e
+                       case IntersectionPtg.sid: return IntersectionPtg.instance;// 0x0f
+                       case UnionPtg.sid:        return UnionPtg.instance;       // 0x10
+                       case RangePtg.sid:        return RangePtg.instance;       // 0x11
+                       case UnaryPlusPtg.sid:    return UnaryPlusPtg.instance;   // 0x12
+                       case UnaryMinusPtg.sid:   return UnaryMinusPtg.instance;  // 0x13
+                       case PercentPtg.sid:      return PercentPtg.instance;     // 0x14
+                       case ParenthesisPtg.sid:  return ParenthesisPtg.instance; // 0x15
+                       case MissingArgPtg.sid:   return MissingArgPtg.instance;  // 0x16
+
+                       case StringPtg.sid:       return new StringPtg(in);       // 0x17
+                       case AttrPtg.sid:                
+                       case 0x1a:        return new AttrPtg(in); // 0x19
+                       case ErrPtg.sid:          return new ErrPtg(in);          // 0x1c
+                       case BoolPtg.sid:         return new BoolPtg(in);         // 0x1d
+                       case IntPtg.sid:          return new IntPtg(in);          // 0x1e
+                       case NumberPtg.sid:       return new NumberPtg(in);       // 0x1f
                }
                throw new RuntimeException("Unexpected base token id (" + id + ")");
        }
-    /**
-     * 
-     * 
-     */
+       /**
+        
+        
+        */
        public static int getEncodedSize(Stack ptgs) {
                return getEncodedSize(toPtgArray(ptgs));
        }
+       /**
+        * @return a distinct copy of this <tt>Ptg</tt> if the class is mutable, or the same instance
+        * if the class is immutable.
+        */
+       public final Ptg copy() {
+               // TODO - all base tokens are logically immutable, but AttrPtg needs some clean-up 
+               if (this instanceof ValueOperatorPtg) {
+                       return this;
+               }
+               if (this instanceof ScalarConstantPtg) {
+                       return this;
+               }
+               return (Ptg) clone();
+       }
+
+       protected Object clone() {
+               try {
+                       return super.clone();
+               } catch (CloneNotSupportedException e) {
+                       throw new RuntimeException(e);
+               }
+       }
        private static Ptg[] toPtgArray(List l) {
                Ptg[] result = new Ptg[l.size()];
                l.toArray(result);
                return result;
        }
-    private static Stack createStack(Ptg[] formulaTokens) {
+       private static Stack createStack(Ptg[] formulaTokens) {
                Stack result = new Stack();
                for (int i = 0; i < formulaTokens.length; i++) {
                        result.add(formulaTokens[i]);
@@ -251,110 +268,120 @@ public abstract class Ptg
                }
                return result;
        }
+       /**
+        * Writes the ptgs to the data buffer, starting at the specified offset.  
+        *
+        * <br/>
+        * The 2 byte encode length field is <b>not</b> written by this method.
+        * @return number of bytes written
+        */
+       public static int serializePtgs(Ptg[] ptgs, byte[] data, int offset) {
+               return serializePtgStack(createStack(ptgs), data, offset);
+       }
+
+       /**
+        * @deprecated use serializePtgs()
+        */
+       public static int serializePtgStack(Stack expression, byte[] array, int offset) {
+               int pos = 0;
+               int size = 0;
+               if (expression != null)
+                       size = expression.size();
+
+               List arrayPtgs = null;
+
+               for (int k = 0; k < size; k++) {
+                       Ptg ptg = ( Ptg ) expression.get(k);
+
+                       ptg.writeBytes(array, pos + offset);
+                       if (ptg instanceof ArrayPtg) {
+                         if (arrayPtgs == null)
+                                 arrayPtgs = new ArrayList(5);
+                         arrayPtgs.add(ptg);
+                         pos += 8;
+                       } else pos += ptg.getSize();
+               }
+               if (arrayPtgs != null) {
+                       for (int i=0;i<arrayPtgs.size();i++) {
+                               ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
+                               pos += p.writeTokenValueBytes(array, pos + offset);
+                       }
+               }
+               return pos;
+       }
 
-    public static int serializePtgStack(Stack expression, byte[] array, int offset) {
-        int pos = 0;
-        int size = 0;
-        if (expression != null)
-            size = expression.size();
-
-        List arrayPtgs = null;
-
-        for (int k = 0; k < size; k++) {
-            Ptg ptg = ( Ptg ) expression.get(k);
-
-            ptg.writeBytes(array, pos + offset);
-            if (ptg instanceof ArrayPtg) {
-              if (arrayPtgs == null)
-                  arrayPtgs = new ArrayList(5);
-              arrayPtgs.add(ptg);
-              pos += 8;
-            } else pos += ptg.getSize();
-        }
-        if (arrayPtgs != null) {
-            for (int i=0;i<arrayPtgs.size();i++) {
-                ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
-                pos += p.writeTokenValueBytes(array, pos + offset);
-            }
-        }
-        return pos;
-    }
-
-    /**
-     * @return the encoded length of this Ptg, including the initial Ptg type identifier byte. 
-     */
-    public abstract int getSize();
-    
-    /**
-     * @return the encoded length of this Ptg, not including the initial Ptg type identifier byte. 
-     */
+       /**
+        * @return the encoded length of this Ptg, including the initial Ptg type identifier byte. 
+        */
+       public abstract int getSize();
+       
+       /**
+        * @return the encoded length of this Ptg, not including the initial Ptg type identifier byte. 
+        */
 //    public abstract int getDataSize();
 
-    public final byte [] getBytes()
-    {
-        int    size  = getSize();
-        byte[] bytes = new byte[ size ];
-
-        writeBytes(bytes, 0);
-        return bytes;
-    }
-    /** write this Ptg to a byte array*/
-    public abstract void writeBytes(byte [] array, int offset);
-
-    /**
-     * return a string representation of this token alone
-     */
-    public abstract String toFormulaString(Workbook book);
-    /**
-     * dump a debug representation (hexdump) to a string
-     */
-    public String toDebugString() {
-        byte[] ba = new byte[getSize()];
-        String retval=null;
-        writeBytes(ba,0);
-        try {
-            retval = org.apache.poi.util.HexDump.dump(ba,0,0);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        return retval;
-    }
-
-    /** Overridden toString method to ensure object hash is not printed.
-     * This helps get rid of gratuitous diffs when comparing two dumps
-     * Subclasses may output more relevant information by overriding this method
-     **/
-    public String toString(){
-        return this.getClass().toString();
-    }
-
-    public static final byte CLASS_REF = 0x00;
-    public static final byte CLASS_VALUE = 0x20;
-    public static final byte CLASS_ARRAY = 0x40;
-
-    protected byte ptgClass = CLASS_REF; //base ptg
-
-    public void setClass(byte thePtgClass) {
-       if (isBaseToken()) {
-               throw new RuntimeException("setClass should not be called on a base token");
-       }
-        ptgClass = thePtgClass;
-    }
-
-    /**
-     *  @return the 'operand class' (REF/VALUE/ARRAY) for this Ptg
-     */
-    public byte getPtgClass() {
-        return ptgClass;
-    }
-
-    public abstract byte getDefaultOperandClass();
-
-    public abstract Object clone();
-
-
-    /**
-     * @return <code>false</code> if this token is classified as 'reference', 'value', or 'array'
-     */
-    public abstract boolean isBaseToken();
+       public final byte [] getBytes()
+       {
+               int    size  = getSize();
+               byte[] bytes = new byte[ size ];
+
+               writeBytes(bytes, 0);
+               return bytes;
+       }
+       /** write this Ptg to a byte array*/
+       public abstract void writeBytes(byte [] array, int offset);
+
+       /**
+        * return a string representation of this token alone
+        */
+       public abstract String toFormulaString(Workbook book);
+       /**
+        * dump a debug representation (hexdump) to a string
+        */
+       public final String toDebugString() {
+               byte[] ba = new byte[getSize()];
+               String retval=null;
+               writeBytes(ba,0);
+               try {
+                       retval = org.apache.poi.util.HexDump.dump(ba,0,0);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+               return retval;
+       }
+
+       /** Overridden toString method to ensure object hash is not printed.
+        * This helps get rid of gratuitous diffs when comparing two dumps
+        * Subclasses may output more relevant information by overriding this method
+        **/
+       public String toString(){
+               return this.getClass().toString();
+       }
+
+       public static final byte CLASS_REF = 0x00;
+       public static final byte CLASS_VALUE = 0x20;
+       public static final byte CLASS_ARRAY = 0x40;
+
+       private byte ptgClass = CLASS_REF; //base ptg
+
+       public final void setClass(byte thePtgClass) {
+               if (isBaseToken()) {
+                       throw new RuntimeException("setClass should not be called on a base token");
+               }
+               ptgClass = thePtgClass;
+       }
+
+       /**
+        *  @return the 'operand class' (REF/VALUE/ARRAY) for this Ptg
+        */
+       public final byte getPtgClass() {
+               return ptgClass;
+       }
+
+       public abstract byte getDefaultOperandClass();
+
+       /**
+        * @return <code>false</code> if this token is classified as 'reference', 'value', or 'array'
+        */
+       public abstract boolean isBaseToken();
 }
index 05cb6defe14aba43a42c140186dd10635c3279ab..d6076f2baf2b31d46163961e8e99d108e2ac48bb 100644 (file)
@@ -18,7 +18,6 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
 
 /**
  * @author Daniel Noll (daniel at nuix dot com dot au)
@@ -27,20 +26,16 @@ public final class RangePtg  extends OperationPtg {
     public final static int  SIZE = 1;
     public final static byte sid  = 0x11;
 
-    public RangePtg()
-    {
-    }
+    public static final OperationPtg instance = new RangePtg();
 
-    public RangePtg(RecordInputStream in)
-    {
-       // No contents
+    private RangePtg() {
+       // enforce singleton
     }
 
     public final boolean isBaseToken() {
         return true;
     }
 
-
     public int getSize()
     {
         return SIZE;
@@ -51,17 +46,6 @@ public final class RangePtg  extends OperationPtg {
         array[ offset + 0 ] = sid;
     }
 
-    public Object clone()
-    {
-        return new RangePtg();
-    }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
-    }
-
-    /** Implementation of method from Ptg */
     public String toFormulaString(Workbook book)
     {
         return ":";
index fa1563c040b68a6494ab74a9489631b60a8f1cfd..8a4311dba013b0d4f40eb318fa8e9f660fdccfd9 100644 (file)
@@ -82,7 +82,7 @@ public class Ref3DPtg extends OperandPtg {
     }
 
     public void writeBytes(byte [] array, int offset) {
-        array[ 0 + offset ] = (byte) (sid + ptgClass);
+        array[ 0 + offset ] = (byte) (sid + getPtgClass());
         LittleEndian.putShort(array, 1 + offset , getExternSheetIndex());
         LittleEndian.putShort(array, 3 + offset , (short)getRow());
         LittleEndian.putShort(array, 5 + offset , (short)getColumnRaw());
@@ -190,14 +190,7 @@ public class Ref3DPtg extends OperandPtg {
         return retval.toString();
     }
 
-   public byte getDefaultOperandClass() {return Ptg.CLASS_REF;}
-
-   public Object clone() {
-     Ref3DPtg ptg = new Ref3DPtg();
-     ptg.field_1_index_extern_sheet = field_1_index_extern_sheet;
-     ptg.field_2_row = field_2_row;
-     ptg.field_3_column = field_3_column;
-     ptg.setClass(ptgClass);
-     return ptg;
-   }
+   public byte getDefaultOperandClass() {
+               return Ptg.CLASS_REF;
+       }
 }
diff --git a/src/java/org/apache/poi/hssf/record/formula/RefAPtg.java b/src/java/org/apache/poi/hssf/record/formula/RefAPtg.java
deleted file mode 100644 (file)
index 596b386..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* ====================================================================
-   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.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * RefNAPtg
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-
-public final class RefAPtg extends ReferencePtg {
-    public final static byte sid  = 0x64;
-
-    protected RefAPtg() {
-      super();
-    }
-
-    public RefAPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
-      super(row, column, isRowRelative, isColumnRelative);
-    }
-
-    public RefAPtg(RecordInputStream in)
-    {
-      super(in);
-    }
-
-
-    public String getRefPtgName() {
-      return "RefAPtg";
-    }
-
-    public Object clone() {
-      RefAPtg ptg = new RefAPtg();
-      ptg.setRow(getRow());
-      ptg.setColumnRaw(getColumnRaw());
-      ptg.setClass(ptgClass);
-      return ptg;
-    }
-}
index fed32ddade5fedcd892e434f1a2aacbf97d8b1fd..6adbe43c51999634a3921ed90a215548592491be 100755 (executable)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * RefError - handles deleted cell reference
@@ -34,10 +31,6 @@ public final class RefErrorPtg extends OperandPtg {
     public final static byte sid  = 0x2a;
     private int              field_1_reserved;
 
-    private RefErrorPtg() {
-      //Required for clone methods
-    }
-    
     public RefErrorPtg(RecordInputStream in)
     {
         field_1_reserved = in.readInt();
@@ -54,7 +47,7 @@ public final class RefErrorPtg extends OperandPtg {
 
     public void writeBytes(byte [] array, int offset)
     {
-        array[offset] = (byte) (sid + ptgClass);
+        array[offset] = (byte) (sid + getPtgClass());
         LittleEndian.putInt(array,offset+1,field_1_reserved);
     }
 
@@ -82,11 +75,4 @@ public final class RefErrorPtg extends OperandPtg {
     public byte getDefaultOperandClass() {
         return Ptg.CLASS_REF;
     }
-    
-    public Object clone() {
-      RefErrorPtg ptg = new RefErrorPtg();
-      ptg.field_1_reserved = field_1_reserved;
-      ptg.setClass(ptgClass);
-      return ptg;
-    }
 }
diff --git a/src/java/org/apache/poi/hssf/record/formula/RefNAPtg.java b/src/java/org/apache/poi/hssf/record/formula/RefNAPtg.java
deleted file mode 100644 (file)
index 4a9b85b..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* ====================================================================
-   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.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * RefNAPtg
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public final class RefNAPtg extends ReferencePtg
-{
-    public final static byte sid  = 0x6C;
-
-    protected RefNAPtg() {
-      //Required for clone methods
-    }
-
-    public RefNAPtg(RecordInputStream in)
-    {
-      super(in);
-    }
-
-    public String getRefPtgName() {
-      return "RefNAPtg";
-    }
-
-    public String toFormulaString(Workbook book)
-    {
-      throw notImplemented();
-    }
-
-    public Object clone() {
-        throw notImplemented();
-    }
-}
index 5c8d93c79e019f70fb41110411a44c004406c004..5ef4a413b31ac125e1346a6f824ae72b642508f5 100644 (file)
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
 
 /**
  * RefNPtg
  * @author Jason Height (jheight at apache dot com)
  */
-public final class RefNPtg extends ReferencePtg
-{
+public final class RefNPtg extends RefPtgBase {
     public final static byte sid  = 0x2C;
 
-    protected RefNPtg() {
-      //Required for clone methods
-    }
-
     /** Creates new ValueReferencePtg */
 
-    public RefNPtg(RecordInputStream in)
-    {
+    public RefNPtg(RecordInputStream in) {
       super(in);
     }
-
-    public String getRefPtgName() {
-      return "RefNPtg";
-    }
-
-    public String toFormulaString(Workbook book)
-    {
-        throw notImplemented();
-    }
-
-    public Object clone() {
-        throw notImplemented();
+    
+    protected byte getSid() {
+       return sid;
     }
 }
diff --git a/src/java/org/apache/poi/hssf/record/formula/RefNVPtg.java b/src/java/org/apache/poi/hssf/record/formula/RefNVPtg.java
deleted file mode 100644 (file)
index cb2f663..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ====================================================================
-   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.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * RefNVPtg
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-
-public final class RefNVPtg extends ReferencePtg {
-  public final static byte sid  = 0x4C;
-
-  protected RefNVPtg() {
-    //Required for clone methods
-  }
-
-  /** Creates new ValueReferencePtg */
-
-  public RefNVPtg(RecordInputStream in)
-  {
-    super(in);
-  }
-
-  public String getRefPtgName() {
-    return "RefNVPtg";
-  }
-
-  public String toFormulaString(Workbook book)
-  {
-      throw notImplemented();
-  }
-
-  public Object clone() {
-      throw notImplemented();
-  }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/RefPtg.java b/src/java/org/apache/poi/hssf/record/formula/RefPtg.java
new file mode 100644 (file)
index 0000000..a324ce7
--- /dev/null
@@ -0,0 +1,53 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.hssf.record.formula;\r
+\r
+import org.apache.poi.hssf.record.RecordInputStream;\r
+\r
+/**\r
+ * ReferencePtg - handles references (such as A1, A2, IA4)\r
+ * @author  Andrew C. Oliver (acoliver@apache.org)\r
+ * @author Jason Height (jheight at chariot dot net dot au)\r
+ */\r
+public final class RefPtg extends RefPtgBase {\r
+    public final static byte sid  = 0x24;\r
+\r
+    /**\r
+     * Takes in a String representation of a cell reference and fills out the\r
+     * numeric fields.\r
+     */\r
+    public RefPtg(String cellref) {\r
+       super(cellref);\r
+    }\r
+\r
+    public RefPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {\r
+      setRow(row);\r
+      setColumn(column);\r
+      setRowRelative(isRowRelative);\r
+      setColRelative(isColumnRelative);\r
+    }\r
+\r
+    public RefPtg(RecordInputStream in) {\r
+        super(in);\r
+    }\r
+\r
+       protected byte getSid() {\r
+               return sid;\r
+       }\r
+    \r
+}\r
diff --git a/src/java/org/apache/poi/hssf/record/formula/RefPtgBase.java b/src/java/org/apache/poi/hssf/record/formula/RefPtgBase.java
new file mode 100644 (file)
index 0000000..87207f6
--- /dev/null
@@ -0,0 +1,165 @@
+/* ====================================================================
+   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.formula;
+
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.hssf.record.RecordInputStream;
+
+/**
+ * ReferencePtgBase - handles references (such as A1, A2, IA4)
+ * @author  Andrew C. Oliver (acoliver@apache.org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public abstract class RefPtgBase extends OperandPtg {
+
+    private final static int SIZE = 5;
+    private final static int MAX_ROW_NUMBER = 65536;
+
+   /** The row index - zero based unsigned 16 bit value */
+    private int            field_1_row;
+    /** Field 2
+     * - lower 8 bits is the zero based unsigned byte column index
+     * - bit 16 - isRowRelative
+     * - bit 15 - isColumnRelative
+     */
+    private int            field_2_col;
+    private static final BitField         rowRelative = BitFieldFactory.getInstance(0x8000);
+    private static final BitField         colRelative = BitFieldFactory.getInstance(0x4000);
+    private static final BitField         column      = BitFieldFactory.getInstance(0x00FF);
+
+    protected RefPtgBase() {
+      //Required for clone methods
+    }
+
+    /**
+     * Takes in a String representation of a cell reference and fills out the
+     * numeric fields.
+     */
+    protected RefPtgBase(String cellref) {
+        CellReference c= new CellReference(cellref);
+        setRow(c.getRow());
+        setColumn(c.getCol());
+        setColRelative(!c.isColAbsolute());
+        setRowRelative(!c.isRowAbsolute());
+    }
+
+    protected RefPtgBase(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
+      setRow(row);
+      setColumn(column);
+      setRowRelative(isRowRelative);
+      setColRelative(isColumnRelative);
+    }
+
+    protected RefPtgBase(RecordInputStream in) {
+        field_1_row = in.readUShort();
+        field_2_col = in.readUShort();
+    }
+
+    public final String toString() {
+        CellReference cr = new CellReference(getRow(), getColumn(), !isRowRelative(),!isColRelative());
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName());
+        sb.append(" [");
+        sb.append(cr.formatAsString());
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public final void writeBytes(byte [] array, int offset) {
+        array[offset] = (byte) (getSid() + getPtgClass());
+
+        LittleEndian.putShort(array, offset+1, (short)field_1_row);
+        LittleEndian.putShort(array, offset+3, (short)field_2_col);
+    }
+    
+    protected abstract byte getSid();
+
+    public final void setRow(int row) {
+        if(row < 0 || row >= MAX_ROW_NUMBER) {
+           throw new IllegalArgumentException("The row number, when specified as an integer, must be between 0 and " + MAX_ROW_NUMBER);
+        }
+        field_1_row = row;
+    }
+
+    /**
+     * Returns the row number as a short, which will be
+     *  wrapped (negative) for values between 32769 and 65535
+     */
+    public final int getRow(){
+        return field_1_row;
+    }
+    /**
+     * Returns the row number as an int, between 0 and 65535
+     */
+    public final int getRowAsInt() {
+        return field_1_row;
+    }
+
+    public final boolean isRowRelative() {
+        return rowRelative.isSet(field_2_col);
+    }
+
+    public final void setRowRelative(boolean rel) {
+        field_2_col=rowRelative.setBoolean(field_2_col,rel);
+    }
+
+    public final boolean isColRelative() {
+        return colRelative.isSet(field_2_col);
+    }
+
+    public final void setColRelative(boolean rel) {
+        field_2_col=colRelative.setBoolean(field_2_col,rel);
+    }
+
+    public final void setColumnRawX(int col) { // TODO
+        field_2_col = col;
+    }
+
+    public int getColumnRawX() { // TODO
+        return field_2_col;
+    }
+
+    public final void setColumn(int col) {
+        if(col < 0 || col >= 0x100) {
+            throw new IllegalArgumentException("Specified colIx (" + col + ") is out of range");
+        }
+       field_2_col = column.setValue(field_2_col, col);
+    }
+
+    public final int getColumn() {
+       return column.getValue(field_2_col);
+    }
+
+    public final int getSize() {
+        return SIZE;
+    }
+
+    public final String toFormulaString(Workbook book) {
+        //TODO -- should we store a cellreference instance in this ptg?? but .. memory is an issue, i believe!
+        return (new CellReference(getRowAsInt(),getColumn(),!isRowRelative(),!isColRelative())).formatAsString();
+    }
+
+    public final byte getDefaultOperandClass() {
+        return Ptg.CLASS_REF;
+    }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/RefVPtg.java b/src/java/org/apache/poi/hssf/record/formula/RefVPtg.java
deleted file mode 100644 (file)
index 75c6348..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ====================================================================
-   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.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * RefVPtg
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public final class RefVPtg extends ReferencePtg {
-  public final static byte sid  = 0x44;
-
-  protected RefVPtg() {
-    super();
-  }
-
-  public RefVPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
-    super(row, column, isRowRelative, isColumnRelative);
-    setClass(CLASS_VALUE);
-  }
-
-
-  /** Creates new ValueReferencePtg */
-
-  public RefVPtg(RecordInputStream in)
-  {
-    super(in);
-  }
-
-  public String getRefPtgName() {
-    return "RefVPtg";
-  }
-
-  public Object clone() {
-    RefVPtg ptg = new RefVPtg();
-    ptg.setRow(getRow());
-    ptg.setColumnRaw(getColumnRaw());
-    ptg.setClass(ptgClass);
-    return ptg;
-  }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/ReferencePtg.java b/src/java/org/apache/poi/hssf/record/formula/ReferencePtg.java
deleted file mode 100644 (file)
index d06507e..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/* ====================================================================
-   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.formula;
-
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-import org.apache.poi.util.BitFieldFactory;
-
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * ReferencePtg - handles references (such as A1, A2, IA4)
- * @author  Andrew C. Oliver (acoliver@apache.org)
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public class ReferencePtg extends OperandPtg {
-    /**
-     * TODO - (May-2008) fix subclasses of ReferencePtg 'RefN~' which are used in shared formulas.
-     * (See bugzilla 44921)
-     * The 'RefN~' instances do not work properly, and are expected to be converted by
-     * SharedFormulaRecord.convertSharedFormulas().
-     * This conversion currently does not take place for formulas of named ranges, conditional
-     * format rules and data validation rules.
-     * Furthermore, conversion is probably not appropriate in those instances.
-     */
-    protected final RuntimeException notImplemented() {
-        return new RuntimeException("Coding Error: This method should never be called. This ptg should be converted");
-    }
-
-    private final static int SIZE = 5;
-    public final static byte sid  = 0x24;
-    private final static int MAX_ROW_NUMBER = 65536;
-
-   /** The row index - zero based unsigned 16 bit value */
-    private int            field_1_row;
-    /** Field 2
-     * - lower 8 bits is the zero based unsigned byte column index
-     * - bit 16 - isRowRelative
-     * - bit 15 - isColumnRelative
-     */
-    private int            field_2_col;
-    private static final BitField         rowRelative = BitFieldFactory.getInstance(0x8000);
-    private static final BitField         colRelative = BitFieldFactory.getInstance(0x4000);
-    private static final BitField         column      = BitFieldFactory.getInstance(0x00FF);
-
-    protected ReferencePtg() {
-      //Required for clone methods
-    }
-
-    /**
-     * Takes in a String represnetation of a cell reference and fills out the
-     * numeric fields.
-     */
-    public ReferencePtg(String cellref) {
-        CellReference c= new CellReference(cellref);
-        setRow(c.getRow());
-        setColumn(c.getCol());
-        setColRelative(!c.isColAbsolute());
-        setRowRelative(!c.isRowAbsolute());
-    }
-
-    public ReferencePtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
-      setRow(row);
-      setColumn(column);
-      setRowRelative(isRowRelative);
-      setColRelative(isColumnRelative);
-    }
-
-    /** Creates new ValueReferencePtg */
-
-    public ReferencePtg(RecordInputStream in)
-    {
-        field_1_row = in.readUShort();
-        field_2_col = in.readUShort();
-    }
-
-    public String getRefPtgName() {
-      return "ReferencePtg";
-    }
-
-    public String toString() {
-        CellReference cr = new CellReference(getRow(), getColumn(), !isRowRelative(),!isColRelative());
-        StringBuffer sb = new StringBuffer();
-        sb.append(getClass().getName());
-        sb.append(" [");
-        sb.append(cr.formatAsString());
-        sb.append("]");
-        return sb.toString();
-    }
-
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[offset] = (byte) (sid + ptgClass);
-
-        LittleEndian.putShort(array, offset+1, (short)field_1_row);
-        LittleEndian.putShort(array, offset+3, (short)field_2_col);
-    }
-
-    public void setRow(int row)
-    {
-        if(row < 0 || row >= MAX_ROW_NUMBER) {
-           throw new IllegalArgumentException("The row number, when specified as an integer, must be between 0 and " + MAX_ROW_NUMBER);
-        }
-        field_1_row = row;
-    }
-
-    /**
-     * Returns the row number as a short, which will be
-     *  wrapped (negative) for values between 32769 and 65535
-     */
-    public int getRow()
-    {
-        return field_1_row;
-    }
-    /**
-     * Returns the row number as an int, between 0 and 65535
-     */
-    public int getRowAsInt()
-    {
-       if(field_1_row < 0) {
-               return field_1_row + MAX_ROW_NUMBER;
-       }
-        return field_1_row;
-    }
-
-    public boolean isRowRelative()
-    {
-        return rowRelative.isSet(field_2_col);
-    }
-
-    public void setRowRelative(boolean rel) {
-        field_2_col=rowRelative.setBoolean(field_2_col,rel);
-    }
-
-    public boolean isColRelative()
-    {
-        return colRelative.isSet(field_2_col);
-    }
-
-    public void setColRelative(boolean rel) {
-        field_2_col=colRelative.setBoolean(field_2_col,rel);
-    }
-
-    public void setColumnRaw(int col)
-    {
-        field_2_col = col;
-    }
-
-    public int getColumnRaw()
-    {
-        return field_2_col;
-    }
-
-    public void setColumn(int col)
-    {
-        if(col < 0 || col > 0x100) {
-            throw new IllegalArgumentException("Specified colIx (" + col + ") is out of range");
-        }
-       field_2_col = column.setValue(field_2_col, col);
-    }
-
-    public int getColumn() {
-       return column.getValue(field_2_col);
-    }
-
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    public String toFormulaString(Workbook book)
-    {
-        //TODO -- should we store a cellreference instance in this ptg?? but .. memory is an issue, i believe!
-        return (new CellReference(getRowAsInt(),getColumn(),!isRowRelative(),!isColRelative())).formatAsString();
-    }
-
-    public byte getDefaultOperandClass() {
-        return Ptg.CLASS_REF;
-    }
-
-    public Object clone() {
-      ReferencePtg ptg = new ReferencePtg();
-      ptg.field_1_row = field_1_row;
-      ptg.field_2_col = field_2_col;
-      ptg.setClass(ptgClass);
-      return ptg;
-    }
-}
index 43b8c13920588d5f2cab8b0d61f35ab9b9ec3483..8b00d327fccdfe525fa01015125396e0168a108c 100644 (file)
@@ -27,5 +27,4 @@ abstract class ScalarConstantPtg extends Ptg {
     public final byte getDefaultOperandClass() {\r
         return Ptg.CLASS_VALUE;\r
     }\r
-       \r
 }\r
index 6cd65005e223a2d2b25268d93dbf155d57c885ad..88b4d9843d59852aa05ca2654f4e5b4c9f5d09a1 100644 (file)
@@ -42,15 +42,11 @@ public final class StringPtg extends ScalarConstantPtg {
      * NOTE: OO doc says 16bit length, but BiffViewer says 8 Book says something
      * totally different, so don't look there!
      */
-    private int field_1_length;
-    private byte field_2_options;
-    private String field_3_string;
+    private final int field_1_length;
+    private final byte field_2_options;
+    private final String field_3_string;
 
-    private StringPtg() {
-        // Required for clone methods
-    }
-
-    /** Create a StringPtg from a byte array read from disk */
+    /** Create a StringPtg from a stream */
     public StringPtg(RecordInputStream in) {
         field_1_length = in.readUByte();
         field_2_options = in.readByte();
@@ -76,9 +72,7 @@ public final class StringPtg extends ScalarConstantPtg {
             throw new IllegalArgumentException(
                     "String literals in formulas can't be bigger than 255 characters ASCII");
         }
-        field_2_options = 0;
-        field_2_options = (byte) fHighByte.setBoolean(field_2_options, StringUtil
-                .hasMultibyte(value));
+        field_2_options = (byte) fHighByte.setBoolean(0, StringUtil.hasMultibyte(value));
         field_3_string = value;
         field_1_length = value.length(); // for the moment, we support only ASCII strings in formulas we create
     }
@@ -124,14 +118,6 @@ public final class StringPtg extends ScalarConstantPtg {
         return sb.toString();
     }
 
-    public Object clone() {
-        StringPtg ptg = new StringPtg();
-        ptg.field_1_length = field_1_length;
-        ptg.field_2_options = field_2_options;
-        ptg.field_3_string = field_3_string;
-        return ptg;
-    }
-
     public String toString() {
         StringBuffer sb = new StringBuffer(64);
         sb.append(getClass().getName()).append(" [");
index fc99293fdcad8ccb1b7c1fd8ba0e85f7b626536c..46fa4cca6eb4755641ecded5ff4ea05330b99da9 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import java.util.List;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  *
  * @author  andy
  * @author Jason Height (jheight at chariot dot net dot au)
  */
 public final class SubtractPtg extends ValueOperatorPtg {
-    public final static int  SIZE = 1;
     public final static byte sid  = 0x04;
 
-    public SubtractPtg()
-    {
-    }
-
-    public SubtractPtg(RecordInputStream in)
-    {
+    public static final ValueOperatorPtg instance = new SubtractPtg();
 
-        // doesn't need anything
+    private SubtractPtg() {
+       // enforce singleton
     }
-
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
+    
+    protected byte getSid() {
+       return sid;
     }
 
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
-    }
-
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
-
-    public String toFormulaString(Workbook book)
-    {
-        return "-";
-    }
-
        
     public String toFormulaString(String[] operands) {
         StringBuffer buffer = new StringBuffer();
@@ -74,8 +47,4 @@ public final class SubtractPtg extends ValueOperatorPtg {
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }
-
-    public Object clone() {
-      return new SubtractPtg();
-    }
 }
index 296cf25c592343a9e66f98465df7bee927d12955..b8f28ec3952115c6f18febb650d91a56b5c861d8 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import java.util.List;
-
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  * Unary Plus operator
  * does not have any effect on the operand
  * @author Avik Sengupta
  */
-
 public final class UnaryMinusPtg extends ValueOperatorPtg {
-    public final static int  SIZE = 1;
     public final static byte sid  = 0x13;
     
     private final static String MINUS = "-";
 
-    /** Creates new AddPtg */
+    public static final ValueOperatorPtg instance = new UnaryMinusPtg();
 
-    public UnaryMinusPtg()
-    {
-    }
-
-    public UnaryMinusPtg(RecordInputStream in)
-    {
-
-        // doesn't need anything
+    private UnaryMinusPtg() {
+       // enforce singleton
     }
     
-   
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
-
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    public int getType()
-    {
-        return this.TYPE_UNARY;
+    protected byte getSid() {
+       return sid;
     }
 
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 1;
     }
     
-    /** Implementation of method from Ptg */
-    public String toFormulaString(Workbook book)
-    {
-        return "+";
-    }
-       
    /** implementation of method from OperationsPtg*/  
     public String toFormulaString(String[] operands) {
         StringBuffer buffer = new StringBuffer();
@@ -80,9 +48,4 @@ public final class UnaryMinusPtg extends ValueOperatorPtg {
         buffer.append(operands[ 0]);
         return buffer.toString();
     }
-    
-    public Object clone() {
-      return new UnaryPlusPtg();
-    }
-
 }
index eef161e4411d6fb7aa778ab57e79a1e5e0016008..0b050fd5311767ad68a02a1903d810eb78c247f2 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import java.util.List;
-
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  * Unary Plus operator
  * does not have any effect on the operand
  * @author Avik Sengupta
  */
-
 public final class UnaryPlusPtg extends ValueOperatorPtg {
-    public final static int  SIZE = 1;
     public final static byte sid  = 0x12;
     
     private final static String ADD = "+";
 
-    /** Creates new AddPtg */
+    public static final ValueOperatorPtg instance = new UnaryPlusPtg();
 
-    public UnaryPlusPtg()
-    {
-    }
-
-    public UnaryPlusPtg(RecordInputStream in)
-    {
-
-        // doesn't need anything
+    private UnaryPlusPtg() {
+       // enforce singleton
     }
     
-   
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
-
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    public int getType()
-    {
-        return this.TYPE_UNARY;
+    protected byte getSid() {
+       return sid;
     }
 
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 1;
     }
     
-    /** Implementation of method from Ptg */
-    public String toFormulaString(Workbook book)
-    {
-        return "+";
-    }
-       
    /** implementation of method from OperationsPtg*/  
     public String toFormulaString(String[] operands) {
         StringBuffer buffer = new StringBuffer();
@@ -80,9 +48,4 @@ public final class UnaryPlusPtg extends ValueOperatorPtg {
         buffer.append(operands[ 0]);
         return buffer.toString();
     }
-    
-    public Object clone() {
-      return new UnaryPlusPtg();
-    }
-
 }
index 4abc33b86869366ad9eeba57e7917fc906176440..266f7decabd63ef192a43955d8f775222bba9d82 100644 (file)
@@ -18,7 +18,6 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
 
 /**
  * @author Glen Stampoultzis (glens at apache.org)
@@ -26,14 +25,10 @@ import org.apache.poi.hssf.record.RecordInputStream;
 public final class UnionPtg extends OperationPtg {
     public final static byte sid  = 0x10;
 
+    public static final OperationPtg instance = new UnionPtg();
 
-    public UnionPtg()
-    {
-    }
-
-    public UnionPtg(RecordInputStream in)
-    {
-        // doesn't need anything
+    private UnionPtg() {
+       // enforce singleton
     }
 
     public final boolean isBaseToken() {
@@ -50,17 +45,6 @@ public final class UnionPtg extends OperationPtg {
         array[ offset + 0 ] = sid;
     }
 
-    public Object clone()
-    {
-        return new UnionPtg();
-    }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
-    }
-
-    /** Implementation of method from Ptg */
     public String toFormulaString(Workbook book)
     {
         return ",";
index 4ef6ab595dc965659d09d5b29e6c15d35c1ba4f9..7f5d86cac1eb00623cb384516a7a83e8cd086182 100644 (file)
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hssf.record.formula;
 
+import org.apache.poi.ss.usermodel.Workbook;
+
 /**
  * Common superclass of all value operators.
  * Subclasses include all unary and binary operators except for the reference operators (IntersectionPtg, RangePtg, UnionPtg) 
@@ -26,12 +28,27 @@ package org.apache.poi.hssf.record.formula;
 public abstract class ValueOperatorPtg extends OperationPtg {
 
        /**
-        * All Operator <tt>Ptg</tt>s are base tokens (i.e. are not RVA classifed)  
+        * All Operator <tt>Ptg</tt>s are base tokens (i.e. are not RVA classified)  
         */
        public final boolean isBaseToken() {
                return true;
        }
+
        public final byte getDefaultOperandClass() {
                return Ptg.CLASS_VALUE;
        }
+
+       public final void writeBytes(byte[] array, int offset) {
+               array[offset + 0] = getSid();
+       }
+
+       protected abstract byte getSid();
+
+       public final int getSize() {
+               return 1;
+       }
+    public final String toFormulaString(Workbook book) {
+       // TODO - prune this method out of the hierarchy
+       throw new RuntimeException("toFormulaString(String[] operands) should be used for subclasses of OperationPtgs");
+       }
 }
index 898d7a86186640d7c60b06dffd61d50ba1dd369d..033ecc1f862cef5068e3bc3bc76aa89e0922376b 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hssf.record.formula.eval;
 
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 
 /**
  * @author adeshmukh
@@ -26,9 +26,9 @@ import org.apache.poi.hssf.record.formula.ReferencePtg;
 public final class Ref2DEval implements RefEval {
 
     private final ValueEval value;
-    private final ReferencePtg delegate;
+    private final RefPtg delegate;
     
-    public Ref2DEval(ReferencePtg ptg, ValueEval ve) {
+    public Ref2DEval(RefPtg ptg, ValueEval ve) {
         if(ve == null) {
             throw new IllegalArgumentException("ve must not be null");
         }
index 9aa0e966d1e5d58120d18efd00b9d5d988e8aee8..7327fc1833acd7e0f3008eb1e35d8843c6f29994 100644 (file)
@@ -26,6 +26,7 @@ import javax.imageio.ImageIO;
 import javax.imageio.ImageReader;
 import javax.imageio.stream.ImageInputStream;
 import java.awt.image.BufferedImage;
+import java.awt.*;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.util.Iterator;
@@ -46,6 +47,20 @@ public class HSSFPicture
     public static final int PICTURE_TYPE_PNG = HSSFWorkbook.PICTURE_TYPE_PNG;                // PNG
     public static final int PICTURE_TYPE_DIB = HSSFWorkbook.PICTURE_TYPE_DIB;                // Windows DIB
 
+    /**
+     * width of 1px in columns with default width in units of 1/256 of a character width
+     */
+    private static final float PX_DEFAULT = 32.00f;
+    /**
+     * width of 1px in columns with overridden width in units of 1/256 of a character width
+     */
+    private static final float PX_MODIFIED = 36.56f;
+
+    /**
+     * Height of 1px of a row
+     */
+    private static final int PX_ROW = 15;
+
     int pictureIndex;
     HSSFPatriarch patriarch;
 
@@ -100,59 +115,77 @@ public class HSSFPicture
      * @since POI 3.0.2
      */
     public HSSFClientAnchor getPreferredSize(){
-        HSSFClientAnchor anchor = new HSSFClientAnchor();
-
-        EscherBSERecord bse = (EscherBSERecord)patriarch.sheet.book.getBSERecord(pictureIndex);
-        byte[] data = bse.getBlipRecord().getPicturedata();
-        int type = bse.getBlipTypeWin32();
-        switch (type){
-            //we can calculate the preferred size only for JPEG and PNG
-            //other formats like WMF, EMF and PICT are not supported in Java
-            case HSSFWorkbook.PICTURE_TYPE_JPEG:
-            case HSSFWorkbook.PICTURE_TYPE_PNG:
-                BufferedImage img = null;
-                ImageReader r = null;
-                try {
-                    //read the image using javax.imageio.*
-                    ImageInputStream iis = ImageIO.createImageInputStream( new ByteArrayInputStream(data) );
-                    Iterator i = ImageIO.getImageReaders( iis );
-                    r = (ImageReader) i.next();
-                    r.setInput( iis );
-                    img = r.read(0);
-
-                    int[] dpi = getResolution(r);
-                    int imgWidth = img.getWidth()*96/dpi[0];
-                    int imgHeight = img.getHeight()*96/dpi[1];
+        HSSFClientAnchor anchor = (HSSFClientAnchor)getAnchor();
 
-                    //Excel measures cells in units of 1/256th of a character width.
-                    //The cell width calculated based on this info is always "off".
-                    //A better approach seems to be to use empirically obtained cell width and row height
-                    int cellwidth = 64;
-                    int rowheight = 17;
+        Dimension size = getImageDimension();
 
-                    int col2 = imgWidth/cellwidth;
-                    int row2 = imgHeight/rowheight;
+        float w = 0;
 
-                    int dx2 = (int)((float)(imgWidth % cellwidth)/cellwidth * 1024);
-                    int dy2 = (int)((float)(imgHeight % rowheight)/rowheight * 256);
+        //space in the leftmost cell
+        w += getColumnWidthInPixels(anchor.col1)*(1 - anchor.dx1/1024);
+        short col2 = (short)(anchor.col1 + 1);
+        int dx2 = 0;
 
-                    anchor.setCol2((short)col2);
-                    anchor.setDx2(dx2);
+        while(w < size.width){
+            w += getColumnWidthInPixels(col2++);
+        }
 
-                    anchor.setRow2(row2);
-                    anchor.setDy2(dy2);
+        if(w > size.width) {
+            //calculate dx2, offset in the rightmost cell
+            col2--;
+            float cw = getColumnWidthInPixels(col2);
+            float delta = w - size.width;
+            dx2 = (int)((cw-delta)/cw*1024);
+        }
+        anchor.col2 = col2;
+        anchor.dx2 = dx2;
 
-                } catch (IOException e){
-                    //silently return if ImageIO failed to read the image
-                    log.log(POILogger.WARN, e);
-                    img = null;
-                }
+        float h = 0;
+        h += (1 - anchor.dy1/256)* getRowHeightInPixels(anchor.row1);
+        int row2 = anchor.row1 + 1;
+        int dy2 = 0;
 
-                break;
+        while(h < size.height){
+            h += getRowHeightInPixels(row2++);
+        }
+        if(h > size.height) {
+            row2--;
+            float ch = getRowHeightInPixels(row2);
+            float delta = h - size.height;
+            dy2 = (int)((ch-delta)/ch*256);
         }
+        anchor.row2 = row2;
+        anchor.dy2 = dy2;
+
         return anchor;
     }
 
+    private float getColumnWidthInPixels(short column){
+
+        short cw = patriarch.sheet.getColumnWidth(column);
+        float px = getPixelWidth(column);
+
+        return cw/px;
+    }
+
+    private float getRowHeightInPixels(int i){
+
+        HSSFRow row = patriarch.sheet.getRow(i);
+        float height;
+        if(row != null) height = row.getHeight();
+        else height = patriarch.sheet.getDefaultRowHeight();
+
+        return height/PX_ROW;
+    }
+
+    private float getPixelWidth(short column){
+
+        int def = patriarch.sheet.getDefaultColumnWidth()*256;
+        short cw = patriarch.sheet.getColumnWidth(column);
+
+        return cw == def ? PX_DEFAULT : PX_MODIFIED;
+    }
+
     /**
      * The metadata of PNG and JPEG can contain the width of a pixel in millimeters.
      * Return the the "effective" dpi calculated as <code>25.4/HorizontalPixelSize</code>
@@ -176,4 +209,42 @@ public class HSSFPicture
         return new int[]{hdpi, vdpi};
     }
 
+    /**
+     * Return the dimension of this image
+     *
+     * @return image dimension
+     */
+    public Dimension getImageDimension(){
+        EscherBSERecord bse = patriarch.sheet.book.getBSERecord(pictureIndex);
+        byte[] data = bse.getBlipRecord().getPicturedata();
+        int type = bse.getBlipTypeWin32();
+        Dimension size = new Dimension();
+
+        switch (type){
+            //we can calculate the preferred size only for JPEG and PNG
+            //other formats like WMF, EMF and PICT are not supported in Java
+            case HSSFWorkbook.PICTURE_TYPE_JPEG:
+            case HSSFWorkbook.PICTURE_TYPE_PNG:
+            case HSSFWorkbook.PICTURE_TYPE_DIB:
+                try {
+                    //read the image using javax.imageio.*
+                    ImageInputStream iis = ImageIO.createImageInputStream( new ByteArrayInputStream(data) );
+                    Iterator i = ImageIO.getImageReaders( iis );
+                    ImageReader r = (ImageReader) i.next();
+                    r.setInput( iis );
+                    BufferedImage img = r.read(0);
+
+                    int[] dpi = getResolution(r);
+                    size.width = img.getWidth()*96/dpi[0];
+                    size.height = img.getHeight()*96/dpi[1];
+
+                } catch (IOException e){
+                    //silently return if ImageIO failed to read the image
+                    log.log(POILogger.WARN, e);
+                }
+
+                break;
+        }
+        return size;
+    }
 }
index f33570c10cb57dfb7111b2fa7df681bf178cc867..23ce6120a9b3e0bfa62b01fd11c57c997d511a00 100644 (file)
@@ -50,7 +50,7 @@ import org.apache.poi.hssf.record.VCenterRecord;
 import org.apache.poi.hssf.record.WSBoolRecord;
 import org.apache.poi.hssf.record.WindowTwoRecord;
 import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.util.HSSFCellRangeAddress;
 import org.apache.poi.hssf.util.HSSFDataValidation;
 import org.apache.poi.hssf.util.PaneInformation;
@@ -1322,8 +1322,8 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
                     Ptg[] ptgs = fp.getRPNPtg();
                     boolean changed = false;
                     for(int i=0; i<ptgs.length; i++) {
-                        if(ptgs[i] instanceof ReferencePtg) {
-                            ReferencePtg rptg = (ReferencePtg)ptgs[i];
+                        if(ptgs[i] instanceof RefPtg) {
+                            RefPtg rptg = (RefPtg)ptgs[i];
                             if(startRow <= rptg.getRowAsInt() &&
                                     rptg.getRowAsInt() <= endRow) {
                                 // References a row that moved
index c059b028aff583e32d4a9bc64f535ee71fbd9d2c..3aac4b599216fbbc85186786fba42283a3ad2638 100644 (file)
@@ -930,9 +930,7 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
 
         if (settingRowAndColumn)
         {
-            MemFuncPtg memFuncPtg = new MemFuncPtg();
-            memFuncPtg.setLenRefSubexpression(23);
-            ptgs.add(memFuncPtg);
+            ptgs.add(new MemFuncPtg(23)); // TODO - where did constant '23' come from?
         }
         if (startColumn >= 0)
         {
@@ -956,8 +954,7 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
         }
         if (settingRowAndColumn)
         {
-            UnionPtg unionPtg = new UnionPtg();
-            ptgs.add(unionPtg);
+            ptgs.add(UnionPtg.instance);
         }
         nameRecord.setNameDefinition(ptgs);
 
index 88d8dcecddf96d5406da344c5206df8d3bcb90f8..4fcc0ffe1081aa6e11bbd47fba2bf2740c976679 100644 (file)
@@ -39,7 +39,7 @@ import org.apache.poi.hssf.record.formula.OperationPtg;
 import org.apache.poi.hssf.record.formula.ParenthesisPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.record.formula.Ref3DPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.StringPtg;
 import org.apache.poi.hssf.record.formula.UnionPtg;
 import org.apache.poi.hssf.record.formula.UnknownPtg;
@@ -337,17 +337,10 @@ public class FormulaEvaluator {
 
             // since we don't know how to handle these yet :(
             Ptg ptg = ptgs[i];
-<<<<<<< .mine
             if (ptg instanceof ControlPtg) {
                // skip Parentheses, Attr, etc
                continue;
                        }
-=======
-            if (ptg instanceof ControlPtg) {
-                // skip Parentheses, Attr, etc
-                continue;
-            }
->>>>>>> .r663896
             if (ptg instanceof MemErrPtg) { continue; }
             if (ptg instanceof MissingArgPtg) { continue; }
             if (ptg instanceof NamePtg) { 
@@ -380,8 +373,8 @@ public class FormulaEvaluator {
                 Eval opresult = invokeOperation(operation, ops, srcRowNum, srcColNum, workbook, sheet);
                 stack.push(opresult);
             }
-            else if (ptg instanceof ReferencePtg) {
-                ReferencePtg refPtg = (ReferencePtg) ptg;
+            else if (ptg instanceof RefPtg) {
+                RefPtg refPtg = (RefPtg) ptg;
                 int colIx = refPtg.getColumn();
                 int rowIx = refPtg.getRow();
                 Row row = sheet.getRow(rowIx);
@@ -526,7 +519,7 @@ public class FormulaEvaluator {
 
     /**
      * returns an appropriate Eval impl instance for the Ptg. The Ptg must be
-     * one of: Area3DPtg, AreaPtg, ReferencePtg, Ref3DPtg, IntPtg, NumberPtg,
+     * one of: Area3DPtg, AreaPtg, RefPtg, Ref3DPtg, IntPtg, NumberPtg,
      * StringPtg, BoolPtg <br/>special Note: OperationPtg subtypes cannot be
      * passed here!
      * 
@@ -545,7 +538,7 @@ public class FormulaEvaluator {
                 Constructor constructor = clazz.getConstructor(AREA3D_CONSTRUCTOR_CLASS_ARRAY);
                 retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
             }
-            else if (ptg instanceof ReferencePtg) {
+            else if (ptg instanceof RefPtg) {
                 Constructor constructor = clazz.getConstructor(REFERENCE_CONSTRUCTOR_CLASS_ARRAY);
                 retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
             }
@@ -600,10 +593,10 @@ public class FormulaEvaluator {
     }
 
     /**
-     * Creates a Ref2DEval for ReferencePtg.
+     * Creates a Ref2DEval for RefPtg.
      * Non existent cells are treated as RefEvals containing BlankEval.
      */
-    private static Ref2DEval createRef2DEval(ReferencePtg ptg, Cell cell, 
+    private static Ref2DEval createRef2DEval(RefPtg ptg, Cell cell, 
             Row row, Sheet sheet, Workbook workbook) {
         if (cell == null) {
             return new Ref2DEval(ptg, BlankEval.INSTANCE);
diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java b/src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java
new file mode 100755 (executable)
index 0000000..ab6d645
--- /dev/null
@@ -0,0 +1,51 @@
+package org.apache.poi.hslf.blip;\r
+\r
+import org.apache.poi.hslf.usermodel.PictureData;\r
+import org.apache.poi.hslf.model.Picture;\r
+import org.apache.poi.util.POILogger;\r
+import org.apache.poi.util.POILogFactory;\r
+\r
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+import javax.imageio.ImageIO;\r
+import java.awt.*;\r
+import java.awt.image.BufferedImage;\r
+import java.io.ByteArrayInputStream;\r
+\r
+/**\r
+ * Creates BufferedImage using javax.imageio.ImageIO and draws it in the specified graphics.\r
+ *\r
+ * @author  Yegor Kozlov.\r
+ */\r
+public class BitmapPainter implements ImagePainter {\r
+    protected POILogger logger = POILogFactory.getLogger(this.getClass());\r
+\r
+    public void paint(Graphics2D graphics, PictureData pict, Picture parent) {\r
+        BufferedImage img;\r
+        try {\r
+               img = ImageIO.read(new ByteArrayInputStream(pict.getData()));\r
+        }\r
+        catch (Exception e){\r
+            logger.log(POILogger.WARN, "ImageIO failed to create image. image.type: " + pict.getType());\r
+            return;\r
+        }\r
+        Rectangle anchor = parent.getAnchor();\r
+        Image scaledImg = img.getScaledInstance(anchor.width, anchor.height, Image.SCALE_SMOOTH);\r
+        graphics.drawImage(scaledImg, anchor.x, anchor.y, null);\r
+    }\r
+\r
+}\r
diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/ImagePainter.java b/src/scratchpad/src/org/apache/poi/hslf/blip/ImagePainter.java
new file mode 100755 (executable)
index 0000000..8849a31
--- /dev/null
@@ -0,0 +1,71 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.hslf.blip;\r
+\r
+import org.apache.poi.hslf.model.Picture;\r
+import org.apache.poi.hslf.usermodel.PictureData;\r
+\r
+import java.awt.*;\r
+\r
+/**\r
+ * A common interface for objects that can render ppt picture data.\r
+ * <p>\r
+ * Subclasses can redefine it and use third-party libraries for actual rendering,\r
+ * for example, Bitmaps can be rendered using javax.imageio.* , WMF can be rendered using Apache Batik,\r
+ * PICT can be rendered using Apple QuickTime API for Java, etc.\r
+ * </p>\r
+ *\r
+ * A typical usage is as follows:\r
+ * <code>\r
+ * public WMFPaiter implements ImagePainter{\r
+ *   public void paint(Graphics2D graphics, PictureData pict, Picture parent){\r
+ *       DataInputStream is = new DataInputStream(new ByteArrayInputStream(pict.getData()));\r
+ *       org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore wmfStore =\r
+ *               new org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore();\r
+ *       try {\r
+ *           wmfStore.read(is);\r
+ *       } catch (IOException e){\r
+ *           return;\r
+ *       }\r
+ *\r
+ *       Rectangle anchor = parent.getAnchor();\r
+ *       float scale = (float)anchor.width/wmfStore.getWidthPixels();\r
+ *\r
+ *       org.apache.batik.transcoder.wmf.tosvg.WMFPainter painter =\r
+ *               new org.apache.batik.transcoder.wmf.tosvg.WMFPainter(wmfStore, 0, 0, scale);\r
+ *       graphics.translate(anchor.x, anchor.y);\r
+ *       painter.paint(graphics);\r
+ *   }\r
+ * }\r
+ * PictureData.setImagePainter(Picture.WMF, new WMFPaiter());\r
+ * ...\r
+ * </code>\r
+ * Subsequent calls of Slide.draw(Graphics gr) will use WMFPaiter for WMF images.\r
+ *\r
+ * @author  Yegor Kozlov.\r
+ */\r
+public interface ImagePainter {\r
+\r
+    /**\r
+     * Paints the specified picture data\r
+     *\r
+     * @param graphics  the graphics to paintb into\r
+     * @param pict      the data to paint\r
+     * @param parent    the shapes that owns the picture data\r
+     */\r
+    public void paint(Graphics2D graphics, PictureData pict, Picture parent);\r
+}\r
index d01136d87ee90ee876453ea6239ed168b035a7ab..17c1d1c23f49e6f622c8bdaecfd92870a364e7fc 100644 (file)
@@ -51,21 +51,7 @@ public abstract class MasterSheet extends Sheet {
         if(!(shape instanceof TextShape)) return false;
 
         TextShape tx = (TextShape)shape;
-        TextRun run = tx.getTextRun();
-        if(run == null) return false;
-
-        Record[] records = run._records;
-        for (int i = 0; i < records.length; i++) {
-            int type = (int)records[i].getRecordType();
-            if (type == RecordTypes.BaseTextPropAtom.typeID ||
-                type == RecordTypes.DateTimeMCAtom.typeID ||
-                type == RecordTypes.GenericDateMCAtom.typeID ||
-                type == RecordTypes.FooterMCAtom.typeID ||
-                type == RecordTypes.SlideNumberMCAtom.typeID
-                    ) return true;
-
-        }
-        return false;
+        return tx.getPlaceholderAtom() != null;
     }
 
     /**
index 375249b519c79b15f82068a5eba0901fc1193d8d..34b1fd89bcf2e1875143d49047f2308b07c6ded8 100644 (file)
@@ -176,16 +176,11 @@ public class Picture extends SimpleShape {
     public PictureData getPictureData(){
         SlideShow ppt = getSheet().getSlideShow();
         PictureData[] pict = ppt.getPictureData();
-        Document doc = ppt.getDocumentRecord();
-        EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
-        EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
 
-        List lst = bstore.getChildRecords();
-        int idx = getPictureIndex();
-        if (idx == 0){
+        EscherBSERecord bse = getEscherBSERecord();
+        if (bse == null){
             logger.log(POILogger.ERROR, "no reference to picture data found ");
         } else {
-            EscherBSERecord bse = (EscherBSERecord)lst.get(idx-1);
             for ( int i = 0; i < pict.length; i++ ) {
                 if (pict[i].getOffset() ==  bse.getOffset()){
                     return pict[i];
@@ -196,6 +191,21 @@ public class Picture extends SimpleShape {
         return null;
     }
 
+    protected EscherBSERecord getEscherBSERecord(){
+        SlideShow ppt = getSheet().getSlideShow();
+        Document doc = ppt.getDocumentRecord();
+        EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
+        EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+
+        List lst = bstore.getChildRecords();
+        int idx = getPictureIndex();
+        if (idx == 0){
+            return null;
+        } else {
+            return (EscherBSERecord)lst.get(idx-1);
+        }
+    }
+
     /**
      * Name of this picture.
      *
@@ -238,6 +248,10 @@ public class Picture extends SimpleShape {
      */
     protected void afterInsert(Sheet sh){
         super.afterInsert(sh);
+
+        EscherBSERecord bse = getEscherBSERecord();
+        bse.setRef(bse.getRef() + 1);
+
         java.awt.Rectangle anchor = getAnchor();
         if (anchor.equals(new java.awt.Rectangle())){
             setDefaultSize();
@@ -249,21 +263,8 @@ public class Picture extends SimpleShape {
         ShapePainter.paint(this, graphics);
 
         PictureData data = getPictureData();
-        if (data  instanceof Bitmap){
-            BufferedImage img = null;
-            try {
-                       img = ImageIO.read(new ByteArrayInputStream(data.getData()));
-            }
-            catch (Exception e){
-                logger.log(POILogger.WARN, "ImageIO failed to create image. image.type: " + data.getType());
-                return;
-            }
-            Rectangle anchor = getAnchor();
-            Image scaledImg = img.getScaledInstance(anchor.width, anchor.height, Image.SCALE_SMOOTH);
-            graphics.drawImage(scaledImg, anchor.x, anchor.y, null);
-        } else {
-            logger.log(POILogger.WARN, "Rendering of metafiles is not yet supported. image.type: " + (data == null ? "NA" : data.getClass().getName()));
-        }
+        data.draw(graphics, this);
+
         graphics.setTransform(at);
     }
 }
index e15454d651c90148bc077f88136efde5da8f66c8..d336cb3f3ffbef268dd210a2f75419dc395d5d58 100644 (file)
@@ -20,10 +20,12 @@ package org.apache.poi.hslf.model;
 import org.apache.poi.ddf.*;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.hslf.record.ColorSchemeAtom;
+import org.apache.poi.hslf.record.Record;
 
 import java.awt.*;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Rectangle2D;
+import java.util.Iterator;
 
 /**
  *  An abstract simple (non-group) shape.
@@ -284,4 +286,28 @@ public class SimpleShape extends Shape {
         ShapePainter.paint(this, graphics);
         graphics.setTransform(at);
     }
+
+    /**
+     *  Find a record in the underlying EscherClientDataRecord
+     *
+     * @param recordType type of the record to search
+     */
+    protected Record getClientDataRecord(int recordType) {
+        Record oep = null;
+        EscherContainerRecord spContainer = getSpContainer();
+        for (Iterator it = spContainer.getChildRecords().iterator(); it.hasNext();) {
+            EscherRecord obj = (EscherRecord) it.next();
+            if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
+                byte[] data = obj.serialize();
+                Record[] records = Record.findChildRecords(data, 8, data.length - 8);
+                for (int j = 0; j < records.length; j++) {
+                    if (records[j].getRecordType() == recordType) {
+                        return records[j];
+                    }
+                }
+            }
+        }
+        return oep;
+    }
+
 }
index bb99c1bcadecabfdbbe612949742275507a5a7c8..ee32868eb6353020659d5c889f7013ffcbdf41a2 100644 (file)
@@ -147,6 +147,7 @@ public class Slide extends Sheet
         int dgId = dgg.getMaxDrawingGroupId() + 1;
         dg.setOptions((short)(dgId << 4));
         dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1);
+        dgg.setMaxDrawingGroupId(dgId);
 
         for (Iterator it = dgContainer.getChildContainers().iterator(); it.hasNext(); ) {
             EscherContainerRecord c = (EscherContainerRecord)it.next();
index 4030ddc0c281a571bd3f54c5c379e970fde10166..27dbe1b2d573f0c50bf5fb7bd3f5bf2d8deeb1be 100644 (file)
@@ -683,4 +683,13 @@ public class TextRun
         String ns = s.replaceAll("\\r?\\n", "\r");
         return ns;
     }
+
+    /**
+     * Returns records that make up this text run
+     *
+     * @return text run records
+     */
+    public Record[] getRecords(){
+        return _records;
+    }
 }
index 53f8ef97d57cf91c6f359946d6ea1f6ca3c76b7e..d1a84a5e44416f130975697e268d71ddc5c2d8bd 100755 (executable)
-\r
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.hslf.model;\r
-\r
-import org.apache.poi.ddf.*;\r
-import org.apache.poi.hslf.record.*;\r
-import org.apache.poi.hslf.usermodel.RichTextRun;\r
-import org.apache.poi.hslf.exceptions.HSLFException;\r
-import org.apache.poi.util.POILogger;\r
-\r
-import java.awt.*;\r
-import java.awt.geom.Rectangle2D;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.font.FontRenderContext;\r
-import java.awt.font.TextLayout;\r
-import java.io.IOException;\r
-\r
-/**\r
- * A common superclass of all shapes that can hold text.\r
- *\r
- * @author Yegor Kozlov\r
- */\r
-public abstract class TextShape extends SimpleShape {\r
-\r
-    /**\r
-     * How to anchor the text\r
-     */\r
-    public static final int AnchorTop = 0;\r
-    public static final int AnchorMiddle = 1;\r
-    public static final int AnchorBottom = 2;\r
-    public static final int AnchorTopCentered = 3;\r
-    public static final int AnchorMiddleCentered = 4;\r
-    public static final int AnchorBottomCentered = 5;\r
-    public static final int AnchorTopBaseline = 6;\r
-    public static final int AnchorBottomBaseline = 7;\r
-    public static final int AnchorTopCenteredBaseline = 8;\r
-    public static final int AnchorBottomCenteredBaseline = 9;\r
-\r
-    /**\r
-     * How to wrap the text\r
-     */\r
-    public static final int WrapSquare = 0;\r
-    public static final int WrapByPoints = 1;\r
-    public static final int WrapNone = 2;\r
-    public static final int WrapTopBottom = 3;\r
-    public static final int WrapThrough = 4;\r
-\r
-    /**\r
-     * How to align the text\r
-     */\r
-    public static final int AlignLeft = 0;\r
-    public static final int AlignCenter = 1;\r
-    public static final int AlignRight = 2;\r
-    public static final int AlignJustify = 3;\r
-\r
-    /**\r
-     * TextRun object which holds actual text and format data\r
-     */\r
-    protected TextRun _txtrun;\r
-\r
-    /**\r
-     * Escher container which holds text attributes such as\r
-     * TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc.\r
-     */\r
-    protected EscherTextboxWrapper _txtbox;\r
-\r
-    /**\r
-     * Used to calculate text bounds\r
-     */\r
-    protected static final FontRenderContext _frc = new FontRenderContext(null, true, true);\r
-\r
-    /**\r
-     * Create a TextBox object and initialize it from the supplied Record container.\r
-     * \r
-     * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape\r
-     * @param parent    the parent of the shape\r
-     */\r
-   protected TextShape(EscherContainerRecord escherRecord, Shape parent){\r
-        super(escherRecord, parent);\r
-\r
-    }\r
-\r
-    /**\r
-     * Create a new TextBox. This constructor is used when a new shape is created.\r
-     *\r
-     * @param parent    the parent of this Shape. For example, if this text box is a cell\r
-     * in a table then the parent is Table.\r
-     */\r
-    public TextShape(Shape parent){\r
-        super(null, parent);\r
-        _escherContainer = createSpContainer(parent instanceof ShapeGroup);\r
-    }\r
-\r
-    /**\r
-     * Create a new TextBox. This constructor is used when a new shape is created.\r
-     *\r
-     */\r
-    public TextShape(){\r
-        this(null);\r
-    }\r
-\r
-    public TextRun createTextRun(){\r
-        _txtbox = getEscherTextboxWrapper();\r
-        if(_txtbox == null) _txtbox = new EscherTextboxWrapper();\r
-\r
-        _txtrun = getTextRun();\r
-        if(_txtrun == null){\r
-            TextHeaderAtom tha = new TextHeaderAtom();\r
-            tha.setParentRecord(_txtbox);\r
-            _txtbox.appendChildRecord(tha);\r
-\r
-            TextCharsAtom tca = new TextCharsAtom();\r
-            _txtbox.appendChildRecord(tca);\r
-\r
-            StyleTextPropAtom sta = new StyleTextPropAtom(0);\r
-            _txtbox.appendChildRecord(sta);\r
-\r
-            _txtrun = new TextRun(tha,tca,sta);\r
-            _txtrun.setText("");\r
-\r
-            _escherContainer.addChildRecord(_txtbox.getEscherRecord());\r
-\r
-            setDefaultTextProperties(_txtrun);\r
-        }\r
-\r
-        return _txtrun;\r
-    }\r
-\r
-    /**\r
-     * Set default properties for the  TextRun.\r
-     * Depending on the text and shape type the defaults are different:\r
-     *   TextBox: align=left, valign=top\r
-     *   AutoShape: align=center, valign=middle\r
-     *\r
-     */\r
-    protected void setDefaultTextProperties(TextRun _txtrun){\r
-\r
-    }\r
-\r
-    /**\r
-     * Returns the text contained in this text frame.\r
-     *\r
-     * @return the text string for this textbox.\r
-     */\r
-     public String getText(){\r
-        TextRun tx = getTextRun();\r
-        return tx == null ? null : tx.getText();\r
-    }\r
-\r
-    /**\r
-     * Sets the text contained in this text frame.\r
-     *\r
-     * @param text the text string used by this object.\r
-     */\r
-    public void setText(String text){\r
-        TextRun tx = getTextRun();\r
-        if(tx == null){\r
-            tx = createTextRun();\r
-        }\r
-        tx.setText(text);\r
-        setTextId(text.hashCode());\r
-    }\r
-\r
-    /**\r
-     * When a textbox is added to  a sheet we need to tell upper-level\r
-     * <code>PPDrawing</code> about it.\r
-     *\r
-     * @param sh the sheet we are adding to\r
-     */\r
-    protected void afterInsert(Sheet sh){\r
-        super.afterInsert(sh);\r
-\r
-        EscherTextboxWrapper _txtbox = getEscherTextboxWrapper();\r
-        if(_txtbox != null){\r
-            PPDrawing ppdrawing = sh.getPPDrawing();\r
-            ppdrawing.addTextboxWrapper(_txtbox);\r
-            // Ensure the escher layer knows about the added records\r
-            try {\r
-                _txtbox.writeOut(null);\r
-            } catch (IOException e){\r
-                throw new HSLFException(e);\r
-            }\r
-            if(getAnchor().equals(new Rectangle()) && !"".equals(getText())) resizeToFitText();\r
-        }\r
-    }\r
-\r
-    protected EscherTextboxWrapper getEscherTextboxWrapper(){\r
-        if(_txtbox == null){\r
-            EscherTextboxRecord textRecord = (EscherTextboxRecord)Shape.getEscherChild(_escherContainer, EscherTextboxRecord.RECORD_ID);\r
-            if(textRecord != null) _txtbox = new EscherTextboxWrapper(textRecord);\r
-        }\r
-        return _txtbox;\r
-    }\r
-    /**\r
-     * Adjust the size of the TextShape so it encompasses the text inside it.\r
-     *\r
-     * @return a <code>Rectangle2D</code> that is the bounds of this <code>TextShape</code>.\r
-     */\r
-    public Rectangle2D resizeToFitText(){\r
-        String txt = getText();\r
-        if(txt == null || txt.length() == 0) return new Rectangle2D.Float();\r
-\r
-        RichTextRun rt = getTextRun().getRichTextRuns()[0];\r
-        int size = rt.getFontSize();\r
-        int style = 0;\r
-        if (rt.isBold()) style |= Font.BOLD;\r
-        if (rt.isItalic()) style |= Font.ITALIC;\r
-        String fntname = rt.getFontName();\r
-        Font font = new Font(fntname, style, size);\r
-\r
-        float width = 0, height = 0;\r
-        String[] lines = txt.split("\r");\r
-        for (int i = 0; i < lines.length; i++) {\r
-            if(lines[i].length() == 0) continue;\r
-\r
-            TextLayout layout = new TextLayout(lines[i], font, _frc);\r
-\r
-            width = Math.max(width, layout.getAdvance());\r
-\r
-            /**\r
-             * Even if top and bottom margins are set to 0 PowerPoint\r
-             * always sets extra space between the text and its bounding box.\r
-             *\r
-             * The approximation height = ascent*2 works good enough in most cases\r
-             */\r
-            height = Math.max(height, 2*layout.getAscent());\r
-        }\r
-\r
-        width += getMarginLeft() + getMarginRight();\r
-        height += getMarginTop() + getMarginBottom();\r
-\r
-        Rectangle2D anchor = getAnchor2D();\r
-        anchor.setRect(anchor.getX(), anchor.getY(), width, height);\r
-        setAnchor(anchor);\r
-\r
-        return anchor;\r
-    }\r
-\r
-    /**\r
-     * Returns the type of vertical alignment for the text.\r
-     * One of the <code>Anchor*</code> constants defined in this class.\r
-     *\r
-     * @return the type of alignment\r
-     */\r
-    public int getVerticalAlignment(){\r
-        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
-        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT);\r
-        int valign = TextShape.AnchorTop;\r
-        if (prop == null){\r
-            /**\r
-             * If vertical alignment was not found in the shape properties then try to\r
-             * fetch the master shape and search for the align property there.\r
-             */\r
-            int type = getTextRun().getRunType();\r
-            MasterSheet master = getSheet().getMasterSheet();\r
-            if(master != null){\r
-                TextShape masterShape = master.getPlaceholder(type);\r
-                if(masterShape != null) valign = masterShape.getVerticalAlignment();\r
-            } else {\r
-                //not found in the master sheet. Use the hardcoded defaults.\r
-                switch (type){\r
-                     case TextHeaderAtom.TITLE_TYPE:\r
-                     case TextHeaderAtom.CENTER_TITLE_TYPE:\r
-                         valign = TextShape.AnchorMiddle;\r
-                         break;\r
-                     default:\r
-                         valign = TextShape.AnchorTop;\r
-                         break;\r
-                 }\r
-            }\r
-        } else {\r
-            valign = prop.getPropertyValue();\r
-        }\r
-        return valign;\r
-    }\r
-\r
-    /**\r
-     * Sets the type of vertical alignment for the text.\r
-     * One of the <code>Anchor*</code> constants defined in this class.\r
-     *\r
-     * @param align - the type of alignment\r
-     */\r
-    public void setVerticalAlignment(int align){\r
-        setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, align);\r
-    }\r
-\r
-    /**\r
-     * Sets the type of horizontal alignment for the text.\r
-     * One of the <code>Align*</code> constants defined in this class.\r
-     *\r
-     * @param align - the type of horizontal alignment\r
-     */\r
-    public void setHorizontalAlignment(int align){\r
-        TextRun tx = getTextRun();\r
-        if(tx != null) tx.getRichTextRuns()[0].setAlignment(align);\r
-    }\r
-\r
-    /**\r
-     * Gets the type of horizontal alignment for the text.\r
-     * One of the <code>Align*</code> constants defined in this class.\r
-     *\r
-     * @return align - the type of horizontal alignment\r
-     */\r
-    public int getHorizontalAlignment(){\r
-        TextRun tx = getTextRun();\r
-        return tx == null ? -1 : tx.getRichTextRuns()[0].getAlignment();\r
-    }\r
-\r
-    /**\r
-     * Returns the distance (in points) between the bottom of the text frame\r
-     * and the bottom of the inscribed rectangle of the shape that contains the text.\r
-     * Default value is 1/20 inch.\r
-     *\r
-     * @return the botom margin\r
-     */\r
-    public float getMarginBottom(){\r
-        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
-        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);\r
-        int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();\r
-        return (float)val/EMU_PER_POINT;\r
-    }\r
-\r
-    /**\r
-     * Sets the botom margin.\r
-     * @see #getMarginBottom()\r
-     *\r
-     * @param margin    the bottom margin\r
-     */\r
-    public void setMarginBottom(float margin){\r
-        setEscherProperty(EscherProperties.TEXT__TEXTBOTTOM, (int)(margin*EMU_PER_POINT));\r
-    }\r
-\r
-    /**\r
-     *  Returns the distance (in points) between the left edge of the text frame\r
-     *  and the left edge of the inscribed rectangle of the shape that contains\r
-     *  the text.\r
-     *  Default value is 1/10 inch.\r
-     *\r
-     * @return the left margin\r
-     */\r
-    public float getMarginLeft(){\r
-        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
-        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);\r
-        int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();\r
-        return (float)val/EMU_PER_POINT;\r
-    }\r
-\r
-    /**\r
-     * Sets the left margin.\r
-     * @see #getMarginLeft()\r
-     *\r
-     * @param margin    the left margin\r
-     */\r
-    public void setMarginLeft(float margin){\r
-        setEscherProperty(EscherProperties.TEXT__TEXTLEFT, (int)(margin*EMU_PER_POINT));\r
-    }\r
-\r
-    /**\r
-     *  Returns the distance (in points) between the right edge of the\r
-     *  text frame and the right edge of the inscribed rectangle of the shape\r
-     *  that contains the text.\r
-     *  Default value is 1/10 inch.\r
-     *\r
-     * @return the right margin\r
-     */\r
-    public float getMarginRight(){\r
-        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
-        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT);\r
-        int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();\r
-        return (float)val/EMU_PER_POINT;\r
-    }\r
-\r
-    /**\r
-     * Sets the right margin.\r
-     * @see #getMarginRight()\r
-     *\r
-     * @param margin    the right margin\r
-     */\r
-    public void setMarginRight(float margin){\r
-        setEscherProperty(EscherProperties.TEXT__TEXTRIGHT, (int)(margin*EMU_PER_POINT));\r
-    }\r
-\r
-     /**\r
-     *  Returns the distance (in points) between the top of the text frame\r
-     *  and the top of the inscribed rectangle of the shape that contains the text.\r
-     *  Default value is 1/20 inch.\r
-     *\r
-     * @return the top margin\r
-     */\r
-    public float getMarginTop(){\r
-        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
-        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTTOP);\r
-        int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();\r
-        return (float)val/EMU_PER_POINT;\r
-    }\r
-\r
-   /**\r
-     * Sets the top margin.\r
-     * @see #getMarginTop()\r
-     *\r
-     * @param margin    the top margin\r
-     */\r
-    public void setMarginTop(float margin){\r
-        setEscherProperty(EscherProperties.TEXT__TEXTTOP, (int)(margin*EMU_PER_POINT));\r
-    }\r
-\r
-\r
-    /**\r
-     * Returns the value indicating word wrap.\r
-     *\r
-     * @return the value indicating word wrap.\r
-     *  Must be one of the <code>Wrap*</code> constants defined in this class.\r
-     */\r
-    public int getWordWrap(){\r
-        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
-        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT);\r
-        return prop == null ? WrapSquare : prop.getPropertyValue();\r
-    }\r
-\r
-    /**\r
-     *  Specifies how the text should be wrapped\r
-     *\r
-     * @param wrap  the value indicating how the text should be wrapped.\r
-     *  Must be one of the <code>Wrap*</code> constants defined in this class.\r
-     */\r
-    public void setWordWrap(int wrap){\r
-        setEscherProperty(EscherProperties.TEXT__WRAPTEXT, wrap);\r
-    }\r
-\r
-    /**\r
-     * @return id for the text.\r
-     */\r
-    public int getTextId(){\r
-        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
-        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTID);\r
-        return prop == null ? 0 : prop.getPropertyValue();\r
-    }\r
-\r
-    /**\r
-     * Sets text ID\r
-     *\r
-     * @param id of the text\r
-     */\r
-    public void setTextId(int id){\r
-        setEscherProperty(EscherProperties.TEXT__TEXTID, id);\r
-    }\r
-\r
-    /**\r
-      * @return the TextRun object for this text box\r
-      */\r
-     public TextRun getTextRun(){\r
-         if(_txtrun == null) initTextRun();\r
-         return _txtrun;\r
-     }\r
-\r
-    public void setSheet(Sheet sheet) {\r
-        _sheet = sheet;\r
-\r
-        // Initialize _txtrun object.\r
-        // (We can't do it in the constructor because the sheet\r
-        //  is not assigned then, it's only built once we have\r
-        //  all the records)\r
-        TextRun tx = getTextRun();\r
-        if (tx != null) {\r
-            // Supply the sheet to our child RichTextRuns\r
-            tx.setSheet(_sheet);\r
-            RichTextRun[] rt = tx.getRichTextRuns();\r
-            for (int i = 0; i < rt.length; i++) {\r
-                rt[i].supplySlideShow(_sheet.getSlideShow());\r
-            }\r
-        }\r
-\r
-    }\r
-\r
-    protected void initTextRun(){\r
-        EscherTextboxWrapper txtbox = getEscherTextboxWrapper();\r
-        Sheet sheet = getSheet();\r
-\r
-        if(sheet == null || txtbox == null) return;\r
-\r
-        OutlineTextRefAtom ota = null;\r
-\r
-        Record[] child = txtbox.getChildRecords();\r
-        for (int i = 0; i < child.length; i++) {\r
-            if (child[i] instanceof OutlineTextRefAtom) {\r
-                ota = (OutlineTextRefAtom)child[i];\r
-                break;\r
-            }\r
-        }\r
-\r
-        TextRun[] runs = _sheet.getTextRuns();\r
-        if (ota != null) {\r
-            int idx = ota.getTextIndex();\r
-            for (int i = 0; i < runs.length; i++) {\r
-                if(runs[i].getIndex() == idx){\r
-                    _txtrun = runs[i];\r
-                    break;\r
-                }\r
-            }\r
-            if(_txtrun == null) {\r
-                logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);\r
-            }\r
-        } else {\r
-            int shapeId = _escherContainer.getChildById(EscherSpRecord.RECORD_ID).getShapeId();\r
-            if(runs != null) for (int i = 0; i < runs.length; i++) {\r
-                if(runs[i].getShapeId() == shapeId){\r
-                    _txtrun = runs[i];\r
-                    break;\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    public void draw(Graphics2D graphics){\r
-        AffineTransform at = graphics.getTransform();\r
-        ShapePainter.paint(this, graphics);\r
-        new TextPainter(this).paint(graphics);\r
-        graphics.setTransform(at);\r
-    }\r
-\r
-}\r
+
+/* ====================================================================
+   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.hslf.model;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.usermodel.RichTextRun;
+import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.util.POILogger;
+
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.AffineTransform;
+import java.awt.font.FontRenderContext;
+import java.awt.font.TextLayout;
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ * A common superclass of all shapes that can hold text.
+ *
+ * @author Yegor Kozlov
+ */
+public abstract class TextShape extends SimpleShape {
+
+    /**
+     * How to anchor the text
+     */
+    public static final int AnchorTop = 0;
+    public static final int AnchorMiddle = 1;
+    public static final int AnchorBottom = 2;
+    public static final int AnchorTopCentered = 3;
+    public static final int AnchorMiddleCentered = 4;
+    public static final int AnchorBottomCentered = 5;
+    public static final int AnchorTopBaseline = 6;
+    public static final int AnchorBottomBaseline = 7;
+    public static final int AnchorTopCenteredBaseline = 8;
+    public static final int AnchorBottomCenteredBaseline = 9;
+
+    /**
+     * How to wrap the text
+     */
+    public static final int WrapSquare = 0;
+    public static final int WrapByPoints = 1;
+    public static final int WrapNone = 2;
+    public static final int WrapTopBottom = 3;
+    public static final int WrapThrough = 4;
+
+    /**
+     * How to align the text
+     */
+    public static final int AlignLeft = 0;
+    public static final int AlignCenter = 1;
+    public static final int AlignRight = 2;
+    public static final int AlignJustify = 3;
+
+    /**
+     * TextRun object which holds actual text and format data
+     */
+    protected TextRun _txtrun;
+
+    /**
+     * Escher container which holds text attributes such as
+     * TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc.
+     */
+    protected EscherTextboxWrapper _txtbox;
+
+    /**
+     * Used to calculate text bounds
+     */
+    protected static final FontRenderContext _frc = new FontRenderContext(null, true, true);
+
+    /**
+     * Create a TextBox object and initialize it from the supplied Record container.
+     * 
+     * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape
+     * @param parent    the parent of the shape
+     */
+   protected TextShape(EscherContainerRecord escherRecord, Shape parent){
+        super(escherRecord, parent);
+
+    }
+
+    /**
+     * Create a new TextBox. This constructor is used when a new shape is created.
+     *
+     * @param parent    the parent of this Shape. For example, if this text box is a cell
+     * in a table then the parent is Table.
+     */
+    public TextShape(Shape parent){
+        super(null, parent);
+        _escherContainer = createSpContainer(parent instanceof ShapeGroup);
+    }
+
+    /**
+     * Create a new TextBox. This constructor is used when a new shape is created.
+     *
+     */
+    public TextShape(){
+        this(null);
+    }
+
+    public TextRun createTextRun(){
+        _txtbox = getEscherTextboxWrapper();
+        if(_txtbox == null) _txtbox = new EscherTextboxWrapper();
+
+        _txtrun = getTextRun();
+        if(_txtrun == null){
+            TextHeaderAtom tha = new TextHeaderAtom();
+            tha.setParentRecord(_txtbox);
+            _txtbox.appendChildRecord(tha);
+
+            TextCharsAtom tca = new TextCharsAtom();
+            _txtbox.appendChildRecord(tca);
+
+            StyleTextPropAtom sta = new StyleTextPropAtom(0);
+            _txtbox.appendChildRecord(sta);
+
+            _txtrun = new TextRun(tha,tca,sta);
+            _txtrun.setText("");
+
+            _escherContainer.addChildRecord(_txtbox.getEscherRecord());
+
+            setDefaultTextProperties(_txtrun);
+        }
+
+        return _txtrun;
+    }
+
+    /**
+     * Set default properties for the  TextRun.
+     * Depending on the text and shape type the defaults are different:
+     *   TextBox: align=left, valign=top
+     *   AutoShape: align=center, valign=middle
+     *
+     */
+    protected void setDefaultTextProperties(TextRun _txtrun){
+
+    }
+
+    /**
+     * Returns the text contained in this text frame.
+     *
+     * @return the text string for this textbox.
+     */
+     public String getText(){
+        TextRun tx = getTextRun();
+        return tx == null ? null : tx.getText();
+    }
+
+    /**
+     * Sets the text contained in this text frame.
+     *
+     * @param text the text string used by this object.
+     */
+    public void setText(String text){
+        TextRun tx = getTextRun();
+        if(tx == null){
+            tx = createTextRun();
+        }
+        tx.setText(text);
+        setTextId(text.hashCode());
+    }
+
+    /**
+     * When a textbox is added to  a sheet we need to tell upper-level
+     * <code>PPDrawing</code> about it.
+     *
+     * @param sh the sheet we are adding to
+     */
+    protected void afterInsert(Sheet sh){
+        super.afterInsert(sh);
+
+        EscherTextboxWrapper _txtbox = getEscherTextboxWrapper();
+        if(_txtbox != null){
+            PPDrawing ppdrawing = sh.getPPDrawing();
+            ppdrawing.addTextboxWrapper(_txtbox);
+            // Ensure the escher layer knows about the added records
+            try {
+                _txtbox.writeOut(null);
+            } catch (IOException e){
+                throw new HSLFException(e);
+            }
+            if(getAnchor().equals(new Rectangle()) && !"".equals(getText())) resizeToFitText();
+        }
+    }
+
+    protected EscherTextboxWrapper getEscherTextboxWrapper(){
+        if(_txtbox == null){
+            EscherTextboxRecord textRecord = (EscherTextboxRecord)Shape.getEscherChild(_escherContainer, EscherTextboxRecord.RECORD_ID);
+            if(textRecord != null) _txtbox = new EscherTextboxWrapper(textRecord);
+        }
+        return _txtbox;
+    }
+    /**
+     * Adjust the size of the TextShape so it encompasses the text inside it.
+     *
+     * @return a <code>Rectangle2D</code> that is the bounds of this <code>TextShape</code>.
+     */
+    public Rectangle2D resizeToFitText(){
+        String txt = getText();
+        if(txt == null || txt.length() == 0) return new Rectangle2D.Float();
+
+        RichTextRun rt = getTextRun().getRichTextRuns()[0];
+        int size = rt.getFontSize();
+        int style = 0;
+        if (rt.isBold()) style |= Font.BOLD;
+        if (rt.isItalic()) style |= Font.ITALIC;
+        String fntname = rt.getFontName();
+        Font font = new Font(fntname, style, size);
+
+        float width = 0, height = 0, leading = 0;        
+        String[] lines = txt.split("\n");        
+        for (int i = 0; i < lines.length; i++) {
+            if(lines[i].length() == 0) continue;
+            
+            TextLayout layout = new TextLayout(lines[i], font, _frc);
+            
+            leading = Math.max(leading, layout.getLeading());           
+            width = Math.max(width, layout.getAdvance());
+            height = Math.max(height, (height + (layout.getDescent() + layout.getAscent())));
+        }      
+       
+        // add one character to width
+        Rectangle2D charBounds = font.getMaxCharBounds(_frc);                
+        width += getMarginLeft() + getMarginRight() + charBounds.getWidth();
+        
+        // add leading to height        
+        height += getMarginTop() + getMarginBottom() + leading;
+
+        Rectangle2D anchor = getAnchor2D();
+        anchor.setRect(anchor.getX(), anchor.getY(), width, height);
+        setAnchor(anchor);
+
+        return anchor;
+    }
+
+    /**
+     * Returns the type of vertical alignment for the text.
+     * One of the <code>Anchor*</code> constants defined in this class.
+     *
+     * @return the type of alignment
+     */
+    public int getVerticalAlignment(){
+        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT);
+        int valign = TextShape.AnchorTop;
+        if (prop == null){
+            /**
+             * If vertical alignment was not found in the shape properties then try to
+             * fetch the master shape and search for the align property there.
+             */
+            int type = getTextRun().getRunType();
+            MasterSheet master = getSheet().getMasterSheet();
+            if(master != null){
+                TextShape masterShape = master.getPlaceholder(type);
+                if(masterShape != null) valign = masterShape.getVerticalAlignment();
+            } else {
+                //not found in the master sheet. Use the hardcoded defaults.
+                switch (type){
+                     case TextHeaderAtom.TITLE_TYPE:
+                     case TextHeaderAtom.CENTER_TITLE_TYPE:
+                         valign = TextShape.AnchorMiddle;
+                         break;
+                     default:
+                         valign = TextShape.AnchorTop;
+                         break;
+                 }
+            }
+        } else {
+            valign = prop.getPropertyValue();
+        }
+        return valign;
+    }
+
+    /**
+     * Sets the type of vertical alignment for the text.
+     * One of the <code>Anchor*</code> constants defined in this class.
+     *
+     * @param align - the type of alignment
+     */
+    public void setVerticalAlignment(int align){
+        setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, align);
+    }
+
+    /**
+     * Sets the type of horizontal alignment for the text.
+     * One of the <code>Align*</code> constants defined in this class.
+     *
+     * @param align - the type of horizontal alignment
+     */
+    public void setHorizontalAlignment(int align){
+        TextRun tx = getTextRun();
+        if(tx != null) tx.getRichTextRuns()[0].setAlignment(align);
+    }
+
+    /**
+     * Gets the type of horizontal alignment for the text.
+     * One of the <code>Align*</code> constants defined in this class.
+     *
+     * @return align - the type of horizontal alignment
+     */
+    public int getHorizontalAlignment(){
+        TextRun tx = getTextRun();
+        return tx == null ? -1 : tx.getRichTextRuns()[0].getAlignment();
+    }
+
+    /**
+     * Returns the distance (in points) between the bottom of the text frame
+     * and the bottom of the inscribed rectangle of the shape that contains the text.
+     * Default value is 1/20 inch.
+     *
+     * @return the botom margin
+     */
+    public float getMarginBottom(){
+        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);
+        int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();
+        return (float)val/EMU_PER_POINT;
+    }
+
+    /**
+     * Sets the botom margin.
+     * @see #getMarginBottom()
+     *
+     * @param margin    the bottom margin
+     */
+    public void setMarginBottom(float margin){
+        setEscherProperty(EscherProperties.TEXT__TEXTBOTTOM, (int)(margin*EMU_PER_POINT));
+    }
+
+    /**
+     *  Returns the distance (in points) between the left edge of the text frame
+     *  and the left edge of the inscribed rectangle of the shape that contains
+     *  the text.
+     *  Default value is 1/10 inch.
+     *
+     * @return the left margin
+     */
+    public float getMarginLeft(){
+        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);
+        int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
+        return (float)val/EMU_PER_POINT;
+    }
+
+    /**
+     * Sets the left margin.
+     * @see #getMarginLeft()
+     *
+     * @param margin    the left margin
+     */
+    public void setMarginLeft(float margin){
+        setEscherProperty(EscherProperties.TEXT__TEXTLEFT, (int)(margin*EMU_PER_POINT));
+    }
+
+    /**
+     *  Returns the distance (in points) between the right edge of the
+     *  text frame and the right edge of the inscribed rectangle of the shape
+     *  that contains the text.
+     *  Default value is 1/10 inch.
+     *
+     * @return the right margin
+     */
+    public float getMarginRight(){
+        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT);
+        int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
+        return (float)val/EMU_PER_POINT;
+    }
+
+    /**
+     * Sets the right margin.
+     * @see #getMarginRight()
+     *
+     * @param margin    the right margin
+     */
+    public void setMarginRight(float margin){
+        setEscherProperty(EscherProperties.TEXT__TEXTRIGHT, (int)(margin*EMU_PER_POINT));
+    }
+
+     /**
+     *  Returns the distance (in points) between the top of the text frame
+     *  and the top of the inscribed rectangle of the shape that contains the text.
+     *  Default value is 1/20 inch.
+     *
+     * @return the top margin
+     */
+    public float getMarginTop(){
+        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTTOP);
+        int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();
+        return (float)val/EMU_PER_POINT;
+    }
+
+   /**
+     * Sets the top margin.
+     * @see #getMarginTop()
+     *
+     * @param margin    the top margin
+     */
+    public void setMarginTop(float margin){
+        setEscherProperty(EscherProperties.TEXT__TEXTTOP, (int)(margin*EMU_PER_POINT));
+    }
+
+
+    /**
+     * Returns the value indicating word wrap.
+     *
+     * @return the value indicating word wrap.
+     *  Must be one of the <code>Wrap*</code> constants defined in this class.
+     */
+    public int getWordWrap(){
+        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT);
+        return prop == null ? WrapSquare : prop.getPropertyValue();
+    }
+
+    /**
+     *  Specifies how the text should be wrapped
+     *
+     * @param wrap  the value indicating how the text should be wrapped.
+     *  Must be one of the <code>Wrap*</code> constants defined in this class.
+     */
+    public void setWordWrap(int wrap){
+        setEscherProperty(EscherProperties.TEXT__WRAPTEXT, wrap);
+    }
+
+    /**
+     * @return id for the text.
+     */
+    public int getTextId(){
+        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+        EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTID);
+        return prop == null ? 0 : prop.getPropertyValue();
+    }
+
+    /**
+     * Sets text ID
+     *
+     * @param id of the text
+     */
+    public void setTextId(int id){
+        setEscherProperty(EscherProperties.TEXT__TEXTID, id);
+    }
+
+    /**
+      * @return the TextRun object for this text box
+      */
+     public TextRun getTextRun(){
+         if(_txtrun == null) initTextRun();
+         return _txtrun;
+     }
+
+    public void setSheet(Sheet sheet) {
+        _sheet = sheet;
+
+        // Initialize _txtrun object.
+        // (We can't do it in the constructor because the sheet
+        //  is not assigned then, it's only built once we have
+        //  all the records)
+        TextRun tx = getTextRun();
+        if (tx != null) {
+            // Supply the sheet to our child RichTextRuns
+            tx.setSheet(_sheet);
+            RichTextRun[] rt = tx.getRichTextRuns();
+            for (int i = 0; i < rt.length; i++) {
+                rt[i].supplySlideShow(_sheet.getSlideShow());
+            }
+        }
+
+    }
+
+    protected void initTextRun(){
+        EscherTextboxWrapper txtbox = getEscherTextboxWrapper();
+        Sheet sheet = getSheet();
+
+        if(sheet == null || txtbox == null) return;
+
+        OutlineTextRefAtom ota = null;
+
+        Record[] child = txtbox.getChildRecords();
+        for (int i = 0; i < child.length; i++) {
+            if (child[i] instanceof OutlineTextRefAtom) {
+                ota = (OutlineTextRefAtom)child[i];
+                break;
+            }
+        }
+
+        TextRun[] runs = _sheet.getTextRuns();
+        if (ota != null) {
+            int idx = ota.getTextIndex();
+            for (int i = 0; i < runs.length; i++) {
+                if(runs[i].getIndex() == idx){
+                    _txtrun = runs[i];
+                    break;
+                }
+            }
+            if(_txtrun == null) {
+                logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
+            }
+        } else {
+            int shapeId = _escherContainer.getChildById(EscherSpRecord.RECORD_ID).getShapeId();
+            if(runs != null) for (int i = 0; i < runs.length; i++) {
+                if(runs[i].getShapeId() == shapeId){
+                    _txtrun = runs[i];
+                    break;
+                }
+            }
+        }
+    }
+
+    public void draw(Graphics2D graphics){
+        AffineTransform at = graphics.getTransform();
+        ShapePainter.paint(this, graphics);
+        new TextPainter(this).paint(graphics);
+        graphics.setTransform(at);
+    }
+
+    /**
+     * Return <code>OEPlaceholderAtom</code>, the atom that describes a placeholder.
+     *
+     * @return <code>OEPlaceholderAtom</code> or <code>null</code> if not found
+     */
+    public OEPlaceholderAtom getPlaceholderAtom(){
+        return (OEPlaceholderAtom)getClientDataRecord(RecordTypes.OEPlaceholderAtom.typeID);
+    }
+
+}
index 2f3b898a7d1ac7c65ad96526cb412950c2dda11a..969e9036afffda7aa03f11be0c8b77617e9b9bd8 100644 (file)
@@ -138,7 +138,7 @@ public class StyleTextPropAtom extends RecordAtom
                                new TextProp(2, 0x4000, "spaceafter"),
                                new TextProp(2, 0x8000, "para_unknown_4"),
                                new TextProp(2, 0x10000, "para_unknown_5"),
-                               new TextProp(2, 0xE0000, "para_unknown_6"),
+                               new TextProp(2, 0xA0000, "para_unknown_6"),
                                new TextProp(2, 0x200000, "para_unknown_7")
        };
        /** All the different kinds of character properties we might handle */
@@ -167,7 +167,7 @@ public class StyleTextPropAtom extends RecordAtom
        /** 
         * For the Text Style Properties (StyleTextProp) Atom
         */
-       protected StyleTextPropAtom(byte[] source, int start, int len) {
+       public StyleTextPropAtom(byte[] source, int start, int len) {
                // Sanity Checking - we're always at least 8+10 bytes long
                if(len < 18) {
                        len = 18;
index 02ff1d9ad63da5e21cfc3ca0e0ae0a7b8f7ad41a..d21d098c3e54312896f7cca88c1546b883884bdd 100644 (file)
@@ -17,6 +17,8 @@
 package org.apache.poi.hslf.usermodel;
 
 import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.POILogFactory;
 import org.apache.poi.hslf.model.Picture;
 import org.apache.poi.hslf.blip.*;
 import org.apache.poi.hslf.exceptions.HSLFException;
@@ -25,6 +27,7 @@ import java.io.OutputStream;
 import java.io.IOException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.awt.*;
 
 /**
  * A class that represents image data contained in a slide show.
@@ -33,19 +36,21 @@ import java.security.NoSuchAlgorithmException;
  */
 public abstract class PictureData {
 
+    protected POILogger logger = POILogFactory.getLogger(this.getClass());
+
     /**
      * Size of the image checksum calculated using MD5 algorithm.
      */
     protected static final int CHECKSUM_SIZE = 16;
 
-       /**
-       * Binary data of the picture
-       */
+    /**
+    * Binary data of the picture
+    */
     private byte[] rawdata;
-       /**
-        * The offset to the picture in the stream
-        */
-       protected int offset;
+    /**
+     * The offset to the picture in the stream
+     */
+    protected int offset;
 
     /**
      * Returns type of this picture.
@@ -71,6 +76,13 @@ public abstract class PictureData {
      */
     protected abstract int getSignature();
 
+    protected static ImagePainter[] painters = new ImagePainter[8];
+    static {
+        PictureData.setImagePainter(Picture.PNG, new BitmapPainter());
+        PictureData.setImagePainter(Picture.JPEG, new BitmapPainter());
+        PictureData.setImagePainter(Picture.DIB, new BitmapPainter());
+    }
+
     /**
      * Returns the raw binary data of this Picture excluding the first 8 bytes
      * which hold image signature and size of the image data.
@@ -212,4 +224,30 @@ public abstract class PictureData {
         return getData().length;
     }
 
+    public void draw(Graphics2D graphics, Picture parent){
+        ImagePainter painter = painters[getType()];
+        if(painter != null) painter.paint(graphics, this, parent);
+        else logger.log(POILogger.WARN, "Rendering is not supported: " + getClass().getName());
+    }
+
+    /**
+     * Register ImagePainter for the specified image type
+     *
+     * @param type  image type, must be one of the static constants defined in the <code>Picture<code> class.
+     * @param painter   
+     */
+    public static void setImagePainter(int type, ImagePainter painter){
+        painters[type] = painter;
+    }
+
+    /**
+     * Return ImagePainter for the specified image type
+     *
+     * @param type blip type, must be one of the static constants defined in the <code>Picture<code> class.
+     * @return ImagePainter for the specified image type
+     */
+    public static ImagePainter getImagePainter(int type){
+        return painters[type];
+    }
+
 }
index d969c5b8810a41104f58ee86fd039b1319b7c247..56e94431ec1cbbb30aca50d0c23d62134e463333 100644 (file)
@@ -734,7 +734,7 @@ public class SlideShow
         else if (format == Picture.WMF) bse.setBlipTypeMacOS((byte)Picture.PICT);
         else if (format == Picture.PICT) bse.setBlipTypeWin32((byte)Picture.WMF);
 
-        bse.setRef(1);
+        bse.setRef(0);
         bse.setOffset(offset);
 
         bstore.addChildRecord(bse);
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestImagePainter.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestImagePainter.java
new file mode 100755 (executable)
index 0000000..d10dd13
--- /dev/null
@@ -0,0 +1,57 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.hslf.model;\r
+\r
+import junit.framework.*;\r
+\r
+import java.io.FileOutputStream;\r
+import java.io.File;\r
+import java.awt.*;\r
+\r
+import org.apache.poi.hslf.usermodel.SlideShow;\r
+import org.apache.poi.hslf.usermodel.PictureData;\r
+import org.apache.poi.hslf.HSLFSlideShow;\r
+import org.apache.poi.hslf.blip.ImagePainter;\r
+import org.apache.poi.hslf.blip.BitmapPainter;\r
+import org.apache.poi.ddf.EscherBSERecord;\r
+\r
+/**\r
+ * Test Picture shape.\r
+ * \r
+ * @author Yegor Kozlov\r
+ */\r
+public class TestImagePainter extends TestCase {\r
+\r
+    private static class CustomImagePainer implements ImagePainter{\r
+        public void paint(Graphics2D graphics, PictureData pict, Picture parent){\r
+            //do noting\r
+        }\r
+\r
+    }\r
+\r
+    public void testImagePainter() throws Exception {\r
+\r
+        ImagePainter pntr = PictureData.getImagePainter(Picture.PNG);\r
+        assertTrue(PictureData.getImagePainter(Picture.PNG) instanceof BitmapPainter);\r
+        assertTrue(PictureData.getImagePainter(Picture.JPEG) instanceof BitmapPainter);\r
+        assertTrue(PictureData.getImagePainter(Picture.DIB) instanceof BitmapPainter);\r
+\r
+        PictureData.setImagePainter(Picture.WMF, new CustomImagePainer());\r
+        assertTrue(PictureData.getImagePainter(Picture.WMF) instanceof CustomImagePainer);\r
+    }\r
+\r
+}\r
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPicture.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPicture.java
new file mode 100755 (executable)
index 0000000..cec4f19
--- /dev/null
@@ -0,0 +1,73 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.hslf.model;\r
+\r
+import junit.framework.*;\r
+\r
+import java.io.FileOutputStream;\r
+import java.io.File;\r
+import java.awt.*;\r
+\r
+import org.apache.poi.hslf.usermodel.SlideShow;\r
+import org.apache.poi.hslf.HSLFSlideShow;\r
+import org.apache.poi.ddf.EscherBSERecord;\r
+\r
+/**\r
+ * Test Picture shape.\r
+ * \r
+ * @author Yegor Kozlov\r
+ */\r
+public class TestPicture extends TestCase {\r
+\r
+    /**\r
+     * Test that the reference count of a blip is incremented every time the picture is inserted.\r
+     * This is important when the same image appears multiple times in a slide show.\r
+     *\r
+     */\r
+    public void testMultiplePictures() throws Exception {\r
+        String cwd = System.getProperty("HSLF.testdata.path");\r
+        SlideShow ppt = new SlideShow();\r
+\r
+        Slide s = ppt.createSlide();\r
+        Slide s2 = ppt.createSlide();\r
+        Slide s3 = ppt.createSlide();\r
+\r
+        int idx = ppt.addPicture(new File(cwd, "clock.jpg"), Picture.JPEG);\r
+        Picture pict = new Picture(idx);\r
+        Picture pict2 = new Picture(idx);\r
+        Picture pict3 = new Picture(idx);\r
+\r
+        pict.setAnchor(new Rectangle(10,10,100,100));\r
+        s.addShape(pict);\r
+        EscherBSERecord bse1 = pict.getEscherBSERecord();\r
+        assertEquals(1, bse1.getRef());\r
+\r
+        pict2.setAnchor(new Rectangle(10,10,100,100));\r
+        s2.addShape(pict2);\r
+        EscherBSERecord bse2 = pict.getEscherBSERecord();\r
+        assertSame(bse1, bse2);\r
+        assertEquals(2, bse1.getRef());\r
+\r
+        pict3.setAnchor(new Rectangle(10,10,100,100));\r
+        s3.addShape(pict3);\r
+        EscherBSERecord bse3 = pict.getEscherBSERecord();\r
+        assertSame(bse2, bse3);\r
+        assertEquals(3, bse1.getRef());\r
+\r
+    }\r
+\r
+}\r
index 929279a3ce9683ecbf4509e17620acd3f5f4c17a..987ad0b0960f1fbd72309ad9aed0d71e53e6d6df 100644 (file)
@@ -40,7 +40,7 @@ import org.apache.poi.hssf.record.formula.NumberPtg;
 import org.apache.poi.hssf.record.formula.PercentPtg;
 import org.apache.poi.hssf.record.formula.PowerPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.StringPtg;
 import org.apache.poi.hssf.record.formula.SubtractPtg;
 import org.apache.poi.hssf.record.formula.UnaryMinusPtg;
@@ -165,14 +165,14 @@ public final class TestFormulaParser extends TestCase {
        public void testUnaryMinus() {
                Ptg[] ptgs = parseFormula("-A1");
                assertEquals(2, ptgs.length);
-               assertTrue("first ptg is reference",ptgs[0] instanceof ReferencePtg);
+               assertTrue("first ptg is reference",ptgs[0] instanceof RefPtg);
                assertTrue("second ptg is Minus",ptgs[1] instanceof UnaryMinusPtg);
        }
 
        public void testUnaryPlus() {
                Ptg[] ptgs = parseFormula("+A1");
                assertEquals(2, ptgs.length);
-               assertTrue("first ptg is reference",ptgs[0] instanceof ReferencePtg);
+               assertTrue("first ptg is reference",ptgs[0] instanceof RefPtg);
                assertTrue("second ptg is Plus",ptgs[1] instanceof UnaryPlusPtg);
        }
 
@@ -540,11 +540,11 @@ public final class TestFormulaParser extends TestCase {
                Class[] expClss;
 
                expClss = new Class[] { 
-                               ReferencePtg.class, 
+                               RefPtg.class, 
                                AttrPtg.class, // tAttrIf
                                MissingArgPtg.class, 
                                AttrPtg.class, // tAttrSkip
-                               ReferencePtg.class,
+                               RefPtg.class,
                                AttrPtg.class, // tAttrSkip
                                FuncVarPtg.class, 
                };
@@ -696,7 +696,7 @@ public final class TestFormulaParser extends TestCase {
                // FormulaParser strips spaces anyway
                assertEquals("4", formulaString);
 
-               ptgs = new Ptg[] { new IntPtg(3), spacePtg, new IntPtg(4), spacePtg, new AddPtg()};
+               ptgs = new Ptg[] { new IntPtg(3), spacePtg, new IntPtg(4), spacePtg, AddPtg.instance, };
                formulaString = FormulaParser.toFormulaString(null, ptgs);
                assertEquals("3+4", formulaString);
        }
@@ -710,7 +710,7 @@ public final class TestFormulaParser extends TestCase {
                Ptg[] ptgs = {
                                // Excel would probably have put tMissArg here
                                new IntPtg(1),
-                               new DividePtg(),
+                               DividePtg.instance,
                };
                try {
                        FormulaParser.toFormulaString(null, ptgs);
index ba05c16211725bb58e1558e2642045fab21a923a..6f7c4747cfc327d7611718ff1c2230d098b75959 100644 (file)
@@ -31,7 +31,7 @@ import org.apache.poi.hssf.record.formula.LessThanPtg;
 import org.apache.poi.hssf.record.formula.MultiplyPtg;
 import org.apache.poi.hssf.record.formula.NotEqualPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.StringPtg;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
@@ -61,7 +61,7 @@ public final class TestFormulaParserIf extends TestCase {
                Class[] expClss;
 
                expClss = new Class[] {
-                               ReferencePtg.class,
+                               RefPtg.class,
                                AttrPtg.class, // tAttrIf
                                IntPtg.class,
                                AttrPtg.class, // tAttrSkip
@@ -82,9 +82,9 @@ public final class TestFormulaParserIf extends TestCase {
                Class[] expClss;
 
                expClss = new Class[] {
-                               ReferencePtg.class,
+                               RefPtg.class,
                                AttrPtg.class, // tAttrIf
-                               ReferencePtg.class,
+                               RefPtg.class,
                                AttrPtg.class, // tAttrSkip
                                FuncVarPtg.class,
                };
@@ -100,20 +100,20 @@ public final class TestFormulaParserIf extends TestCase {
                Class[] expClss;
 
                expClss = new Class[] {
-                               ReferencePtg.class,
+                               RefPtg.class,
                                AttrPtg.class, // tAttrIf
 
-                               ReferencePtg.class,
+                               RefPtg.class,
                                IntPtg.class,
                                MultiplyPtg.class,
-                               ReferencePtg.class,
+                               RefPtg.class,
                                IntPtg.class,
                                AddPtg.class,
                                FuncPtg.class,
                                AttrPtg.class, // tAttrSkip
                                
-                               ReferencePtg.class,
-                               ReferencePtg.class,
+                               RefPtg.class,
+                               RefPtg.class,
                                FuncPtg.class,
                                
                                AttrPtg.class, // tAttrSkip
@@ -133,9 +133,9 @@ public final class TestFormulaParserIf extends TestCase {
 
                expClss = new Class[] {
 
-                               ReferencePtg.class,
+                               RefPtg.class,
                                AttrPtg.class,    // A tAttrIf
-                               ReferencePtg.class,
+                               RefPtg.class,
                                AttrPtg.class,    //   B tAttrIf
                                IntPtg.class,
                                AttrPtg.class,    //   B tAttrSkip
@@ -143,7 +143,7 @@ public final class TestFormulaParserIf extends TestCase {
                                AttrPtg.class,    //   B tAttrSkip
                                FuncVarPtg.class,
                                AttrPtg.class,    // A tAttrSkip
-                               ReferencePtg.class,
+                               RefPtg.class,
                                AttrPtg.class,    //   C tAttrIf
                                IntPtg.class,
                                AttrPtg.class,    //   C tAttrSkip
index cb51c17bd7075d778888e9e46a1382127acfff11..f8c70eb7b836df346d539b8fd6cfffeb07122969 100644 (file)
@@ -23,7 +23,7 @@ import junit.framework.TestCase;
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.record.formula.AttrPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtgBase;
 import org.apache.poi.hssf.usermodel.FormulaExtractor;
 import org.apache.poi.hssf.usermodel.HSSFCell;
 import org.apache.poi.hssf.usermodel.HSSFRow;
@@ -102,7 +102,7 @@ public final class TestRVA extends TestCase {
                for (int i = 0; i < nExcelTokens; i++) {
                        Ptg poiPtg = poiPtgs[i];
                        Ptg excelPtg = excelPtgs[i];
-                       if (!areTokenClassesSame(poiPtg, excelPtg)) {
+                       if (excelPtg.getClass() != poiPtg.getClass()) {
                                hasMismatch = true;
                                sb.append("  mismatch token type[" + i + "] " + getShortClassName(excelPtg) + " "
                                                + getOperandClassName(excelPtg) + " - " + getShortClassName(poiPtg) + " "
@@ -127,17 +127,6 @@ public final class TestRVA extends TestCase {
                }
        }
 
-       private boolean areTokenClassesSame(Ptg poiPtg, Ptg excelPtg) {
-               if (excelPtg.getClass() == poiPtg.getClass()) {
-                       return true;
-               }
-               if (poiPtg.getClass() == ReferencePtg.class) {
-                       // TODO - remove funny subclasses of ReferencePtg
-                       return excelPtg instanceof ReferencePtg;
-               }
-               return false;
-       }
-
        private String getShortClassName(Object o) {
                String cn = o.getClass().getName();
                int pos = cn.lastIndexOf('.');
index 4f5e390873082dec5276edb73414153127434bf3..3fd2b3cf3ead3443c96d5320628b267061316c42 100644 (file)
@@ -26,7 +26,7 @@ import junit.framework.TestCase;
 import org.apache.poi.hssf.record.formula.AttrPtg;
 import org.apache.poi.hssf.record.formula.FuncVarPtg;
 import org.apache.poi.hssf.record.formula.IntPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 
 /**
  * Tests the serialization and deserialization of the FormulaRecord
@@ -130,11 +130,11 @@ public final class TestFormulaRecord extends TestCase {
                assertEquals(9, ptgs.size());
                assertEquals(IntPtg.class,         ptgs.get(0).getClass());
                assertEquals(AttrPtg.class,       ptgs.get(1).getClass());
-               assertEquals(ReferencePtg.class, ptgs.get(2).getClass());
+               assertEquals(RefPtg.class, ptgs.get(2).getClass());
                assertEquals(AttrPtg.class,       ptgs.get(3).getClass());
-               assertEquals(ReferencePtg.class, ptgs.get(4).getClass());
+               assertEquals(RefPtg.class, ptgs.get(4).getClass());
                assertEquals(AttrPtg.class,       ptgs.get(5).getClass());
-               assertEquals(ReferencePtg.class, ptgs.get(6).getClass());
+               assertEquals(RefPtg.class, ptgs.get(6).getClass());
                assertEquals(AttrPtg.class,       ptgs.get(7).getClass());
                assertEquals(FuncVarPtg.class,   ptgs.get(8).getClass());
                
index cb08edec2a33dcaf819c5c8f99cb912c9e3ef7fe..92dc956189f31ff9e28a6c7aa6956b5b01a7a075 100644 (file)
@@ -25,7 +25,7 @@ import junit.framework.ComparisonFailure;
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.RefAPtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 
 /**
  * @author Josh Micich
@@ -68,7 +68,7 @@ public final class TestSharedFormulaRecord extends TestCase {
                
                Stack convertedFormula = SharedFormulaRecord.convertSharedFormulas(sharedFormula, 100, 200);
                
-               RefAPtg refPtg = (RefAPtg) convertedFormula.get(1);
+               RefPtg refPtg = (RefPtg) convertedFormula.get(1);
                assertEquals("$C101", refPtg.toFormulaString(null));
                if (refPtg.getPtgClass() == Ptg.CLASS_REF) {
                        throw new AssertionFailedError("Identified bug 45123");
index 39464b5e03ab468e0b4ebff6871fc1a9be96b0b8..2ba27e963b34a15bd8a4769809e4ea48d73a200b 100644 (file)
@@ -54,12 +54,12 @@ public final class TestArrayPtg extends TestCase {
         */
        public void testReadWriteTokenValueBytes() {
                
-               ArrayPtg ptg = new ArrayPtgV(new TestcaseRecordInputStream(ArrayPtgV.sid, ENCODED_PTG_DATA));
+               ArrayPtg ptg = new ArrayPtg(new TestcaseRecordInputStream(ArrayPtg.sid, ENCODED_PTG_DATA));
                
                ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
                assertEquals(3, ptg.getColumnCount());
                assertEquals(2, ptg.getRowCount());
-               Object[] values = ptg.token_3_arrayValues;
+               Object[] values = ptg.getTokenArrayValues();
                assertEquals(6, values.length);
                
                
@@ -82,7 +82,7 @@ public final class TestArrayPtg extends TestCase {
         * Excel stores array elements column by column.  This test makes sure POI does the same.
         */
        public void testElementOrdering() {
-               ArrayPtg ptg = new ArrayPtgV(new TestcaseRecordInputStream(ArrayPtgV.sid, ENCODED_PTG_DATA));
+               ArrayPtg ptg = new ArrayPtg(new TestcaseRecordInputStream(ArrayPtg.sid, ENCODED_PTG_DATA));
                ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
                assertEquals(3, ptg.getColumnCount());
                assertEquals(2, ptg.getRowCount());
index 0bddecd3ff559ae51659a6198040578fa3a8bfca..2bc1f42ff3ada4eff003762098cfcaafaa3634fe 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
+import java.util.Arrays;
+import java.util.Stack;
+
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.record.TestcaseRecordInputStream;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
 /**
- * Tests for {@link ReferencePtg}.
+ * Tests for {@link RefPtg}.
  */
 public final class TestReferencePtg extends TestCase {
     /**
@@ -86,5 +90,18 @@ public final class TestReferencePtg extends TestCase {
             throw e;
         }
     }
+    private static final byte[] tRefN_data = {
+       0x2C, 33, 44, 55, 66,
+    };
+    public void testReadWrite_tRefN_bug45091() {
+        TestcaseRecordInputStream in = new TestcaseRecordInputStream(-1, tRefN_data);
+        Stack ptgs = Ptg.createParsedExpressionTokens((short)tRefN_data.length, in);
+        byte[] outData = new byte[5];
+        Ptg.serializePtgStack(ptgs, outData, 0);
+        if (outData[0] == 0x24) {
+            throw new AssertionFailedError("Identified bug 45091");
+        }
+        assertTrue(Arrays.equals(tRefN_data, outData));
+    }
 }
 
index c1daa094ccbc716b19d661ba37d72512ccca1f8b..699e27fc9a15dd875b43d4b4dfd0f24faba40717 100755 (executable)
@@ -41,7 +41,7 @@ public final class TestPercentEval extends TestCase {
                        arg,    
                };
                
-               PercentEval opEval = new PercentEval(new PercentPtg());
+               PercentEval opEval = new PercentEval(PercentPtg.instance);
                double result = NumericFunctionInvoker.invoke(opEval, args, -1, (short)-1);
                
                assertEquals(expectedResult, result, 0);
index 724c54cd903a56a8e4cf854b492ee135d63ab9d2..dc20c0d8e5e7f0436ac13bab863ac7493b9163bb 100755 (executable)
@@ -36,7 +36,7 @@ public final class TestUnaryPlusEval extends TestCase {
         * The code for handling column operands had been copy-pasted from the row handling code. 
         */
        public void testColumnOperand() {
-               
+
                short firstRow = (short)8;
                short lastRow = (short)12;
                short colNum = (short)5;
@@ -52,10 +52,9 @@ public final class TestUnaryPlusEval extends TestCase {
                Eval[] args = { 
                        areaEval,       
                };
-               
-               double result = NumericFunctionInvoker.invoke(new UnaryPlusEval(new UnaryPlusPtg()), args, 10, (short)20);
-               
+
+               double result = NumericFunctionInvoker.invoke(new UnaryPlusEval(UnaryPlusPtg.instance), args, 10, (short)20);
+
                assertEquals(35, result, 0);
        }
-
 }
index a6e262b8682797d9d111613ebbc08dc496ff05a2..9b4a44ea142c4e912a2da731cb9d14ae50d29e35 100755 (executable)
@@ -19,7 +19,7 @@
 package org.apache.poi.hssf.record.formula.functions;
 
 import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.eval.Area2DEval;
 import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.NumberEval;
@@ -58,6 +58,6 @@ final class EvalFactory {
         * Creates a single RefEval (with value zero)
         */
        public static RefEval createRefEval(String refStr) {
-               return new Ref2DEval(new ReferencePtg(refStr), ZERO);
+               return new Ref2DEval(new RefPtg(refStr), ZERO);
        }
 }
index 6d11e5a53a9ce2c23d7839510add3dac5d06aa4b..1ec657dfe2490a410758d80b56ac67060eb921b7 100755 (executable)
@@ -21,7 +21,7 @@ package org.apache.poi.hssf.record.formula.functions;
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.eval.Area2DEval;
 import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.BlankEval;
@@ -124,7 +124,7 @@ public final class TestCountFuncs extends TestCase {
                };
                Area2DEval arg0 = new Area2DEval(new AreaPtg("C1:C6"), values);
                
-               Ref2DEval criteriaArg = new Ref2DEval(new ReferencePtg("A1"), new NumberEval(25));
+               Ref2DEval criteriaArg = new Ref2DEval(new RefPtg("A1"), new NumberEval(25));
                Eval[] args=  { arg0, criteriaArg, };
                
                double actual = NumericFunctionInvoker.invoke(new Countif(), args);
index dc3d595aedd77e993c0caefa10d44c0440d78ff4..87dd470c681b2e0e17bc3f48fb426cfd3c04f944 100755 (executable)
@@ -18,7 +18,7 @@
 package org.apache.poi.hssf.record.formula.functions;
 
 import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.eval.Area2DEval;
 import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.BlankEval;
@@ -77,7 +77,7 @@ public final class TestMid extends TestCase {
                
                // startPos is 1x1 area ref, numChars is cell ref
                AreaEval aeStart = new Area2DEval(new AreaPtg("A1:A1"), new ValueEval[] { new NumberEval(2), } );
-               RefEval reNumChars = new Ref2DEval(new ReferencePtg("B1"), new NumberEval(3));
+               RefEval reNumChars = new Ref2DEval(new RefPtg("B1"), new NumberEval(3));
                confirmMid(new StringEval("galactic"), aeStart, reNumChars, "ala");
 
                confirmMid(new StringEval("galactic"), new NumberEval(3.1), BlankEval.INSTANCE, "");
index 73043911f450aa10b93b705dd058ae3541f9e63a..ea06c5e1b56794e5fe309b4d28fb218e33be5b3a 100755 (executable)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.Eval;
@@ -50,7 +50,7 @@ public final class TestSumproduct extends TestCase {
 
        public void testScalarSimple() {
                
-               RefEval refEval = new Ref2DEval(new ReferencePtg("A1"), new NumberEval(3));
+               RefEval refEval = new Ref2DEval(new RefPtg("A1"), new NumberEval(3));
                Eval[] args = {
                        refEval, 
                        new NumberEval(2),
index 4d63cad1c58d82e7b327b35c04773cb84d13e5dc..c57640eabc9e408dbf6c7f9081c04e3d1081261e 100755 (executable)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.eval.BlankEval;
 import org.apache.poi.hssf.record.formula.eval.BoolEval;
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
@@ -50,7 +50,7 @@ public final class TestTFunc extends TestCase {
         * where cell A1 has the specified innerValue
         */
        private Eval invokeTWithReference(ValueEval innerValue) {
-               Eval arg = new Ref2DEval(new ReferencePtg((short)1, (short)1, false, false), innerValue);
+               Eval arg = new Ref2DEval(new RefPtg((short)1, (short)1, false, false), innerValue);
                return invokeT(arg);
        }