poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ser...@apache.org
Subject svn commit: r1149704 - in /poi/trunk/src/scratchpad/src/org/apache/poi/hwpf: ./ converter/ dev/ model/ usermodel/
Date Fri, 22 Jul 2011 19:38:15 GMT
Author: sergey
Date: Fri Jul 22 19:38:14 2011
New Revision: 1149704

URL: http://svn.apache.org/viewvc?rev=1149704&view=rev
Log:
move Field interface to usermodel and create Fields interface as user-friendly replace for
FieldsTables

Added:
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Field.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/FieldImpl.java
      - copied, changed from r1149034, poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/Field.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Fields.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/FieldsImpl.java
Removed:
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/Field.java
Modified:
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/FieldsTables.java

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java?rev=1149704&r1=1149703&r2=1149704&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java Fri Jul 22 19:38:14
2011
@@ -52,6 +52,9 @@ import org.apache.poi.hwpf.model.io.HWPF
 import org.apache.poi.hwpf.model.io.HWPFOutputStream;
 import org.apache.poi.hwpf.usermodel.Bookmarks;
 import org.apache.poi.hwpf.usermodel.BookmarksImpl;
+import org.apache.poi.hwpf.usermodel.Field;
+import org.apache.poi.hwpf.usermodel.Fields;
+import org.apache.poi.hwpf.usermodel.FieldsImpl;
 import org.apache.poi.hwpf.usermodel.HWPFList;
 import org.apache.poi.hwpf.usermodel.Notes;
 import org.apache.poi.hwpf.usermodel.NotesImpl;
@@ -60,6 +63,7 @@ import org.apache.poi.poifs.common.POIFS
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.Internal;
 
 
 /**
@@ -129,6 +133,9 @@ public final class HWPFDocument extends 
   /** Holds the fields PLCFs */
   protected FieldsTables _fieldsTables;
 
+  /** Holds the fields */
+  protected Fields _fields;
+
   protected HWPFDocument()
   {
      super();
@@ -296,6 +303,7 @@ public final class HWPFDocument extends 
     _footnotes = new NotesImpl( _footnotesTables );
 
     _fieldsTables = new FieldsTables(_tableStream, _fib);
+    _fields = new FieldsImpl(_fieldsTables);
   }
 
   public TextPieceTable getTextTable()
@@ -510,11 +518,24 @@ public final class HWPFDocument extends 
 
   /**
    * @return FieldsTables object, that is able to extract fields descriptors from this document
+   * @deprecated
    */
+    @Deprecated
+    @Internal
   public FieldsTables getFieldsTables() {
       return _fieldsTables;
   }
-  
+
+    /**
+     * Returns user-friendly interface to access document {@link Field}s
+     * 
+     * @return user-friendly interface to access document {@link Field}s
+     */
+    public Fields getFields()
+    {
+        return _fields;
+    }
+
   /**
    * Writes out the word file that is represented by an instance of this class.
    *

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java?rev=1149704&r1=1149703&r2=1149704&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java
Fri Jul 22 19:38:14 2011
@@ -29,12 +29,12 @@ import org.apache.poi.hpsf.SummaryInform
 import org.apache.poi.hwpf.HWPFDocument;
 import org.apache.poi.hwpf.HWPFDocumentCore;
 import org.apache.poi.hwpf.converter.FontReplacer.Triplet;
-import org.apache.poi.hwpf.model.Field;
 import org.apache.poi.hwpf.model.FieldsDocumentPart;
 import org.apache.poi.hwpf.model.ListFormatOverride;
 import org.apache.poi.hwpf.model.ListTables;
 import org.apache.poi.hwpf.usermodel.Bookmark;
 import org.apache.poi.hwpf.usermodel.CharacterRun;
+import org.apache.poi.hwpf.usermodel.Field;
 import org.apache.poi.hwpf.usermodel.Notes;
 import org.apache.poi.hwpf.usermodel.Paragraph;
 import org.apache.poi.hwpf.usermodel.Picture;
@@ -229,9 +229,8 @@ public abstract class AbstractWordConver
             {
                 if ( document instanceof HWPFDocument )
                 {
-                    Field aliveField = ( (HWPFDocument) document )
-                            .getFieldsTables().lookupFieldByStartOffset(
-                                    FieldsDocumentPart.MAIN,
+                    Field aliveField = ( (HWPFDocument) document ).getFields()
+                            .getFieldByStartOffset( FieldsDocumentPart.MAIN,
                                     characterRun.getStartOffset() );
                     if ( aliveField != null )
                     {
@@ -453,7 +452,7 @@ public abstract class AbstractWordConver
             return null;
 
         HWPFDocument hwpfDocument = (HWPFDocument) wordDocument;
-        Field field = hwpfDocument.getFieldsTables().lookupFieldByStartOffset(
+        Field field = hwpfDocument.getFields().getFieldByStartOffset(
                 FieldsDocumentPart.MAIN, startOffset );
         if ( field == null )
             return null;

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java?rev=1149704&r1=1149703&r2=1149704&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java Fri Jul 22 19:38:14
2011
@@ -23,7 +23,6 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -46,6 +45,7 @@ import org.apache.poi.hwpf.model.StyleSh
 import org.apache.poi.hwpf.model.TextPiece;
 import org.apache.poi.hwpf.sprm.SprmIterator;
 import org.apache.poi.hwpf.sprm.SprmOperation;
+import org.apache.poi.hwpf.usermodel.Field;
 import org.apache.poi.hwpf.usermodel.Paragraph;
 import org.apache.poi.hwpf.usermodel.Picture;
 import org.apache.poi.hwpf.usermodel.Range;
@@ -311,7 +311,8 @@ public final class HWPFLister
                 for ( char c : text.toCharArray() )
                 {
                     if ( c < 30 )
-                        stringBuilder.append( "\\0x" + Integer.toHexString( c ) );
+                        stringBuilder
+                                .append( "\\0x" + Integer.toHexString( c ) );
                     else
                         stringBuilder.append( c );
                 }
@@ -340,8 +341,7 @@ public final class HWPFLister
         for ( FieldsDocumentPart part : FieldsDocumentPart.values() )
         {
             System.out.println( "=== Document part: " + part + " ===" );
-            for ( org.apache.poi.hwpf.model.Field field : document
-                    .getFieldsTables().getFields( part ) )
+            for ( Field field : document.getFields().getFields( part ) )
             {
                 System.out.println( field );
             }
@@ -356,7 +356,7 @@ public final class HWPFLister
 
             HWPFDocument doc = (HWPFDocument) _doc;
 
-            Field fMainStream = HWPFDocumentCore.class
+            java.lang.reflect.Field fMainStream = HWPFDocumentCore.class
                     .getDeclaredField( "_mainStream" );
             fMainStream.setAccessible( true );
             byte[] mainStream = (byte[]) fMainStream.get( _doc );

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/FieldsTables.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/FieldsTables.java?rev=1149704&r1=1149703&r2=1149704&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/FieldsTables.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/FieldsTables.java Fri Jul 22 19:38:14
2011
@@ -21,12 +21,7 @@ package org.apache.poi.hwpf.model;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.poi.hwpf.model.io.HWPFOutputStream;
@@ -79,70 +74,13 @@ public class FieldsTables
     @Deprecated
     public static final int PLCFFLDTXBX = 6;
 
-    /**
-     * This is port and adaptation of Arrays.binarySearch from Java 6 (Apache
-     * Harmony).
-     */
-    private static <T> int binarySearch( GenericPropertyNode[] array,
-            int startIndex, int endIndex, int requiredStartOffset )
-    {
-        checkIndexForBinarySearch( array.length, startIndex, endIndex );
-
-        int low = startIndex, mid = -1, high = endIndex - 1, result = 0;
-        while ( low <= high )
-        {
-            mid = ( low + high ) >>> 1;
-            int midStart = array[mid].getStart();
-
-            if ( midStart == requiredStartOffset )
-            {
-                return mid;
-            }
-            else if ( midStart < requiredStartOffset )
-            {
-                low = mid + 1;
-            }
-            else
-            {
-                high = mid - 1;
-            }
-        }
-        if ( mid < 0 )
-        {
-            int insertPoint = endIndex;
-            for ( int index = startIndex; index < endIndex; index++ )
-            {
-                if ( requiredStartOffset < array[index].getStart() )
-                {
-                    insertPoint = index;
-                }
-            }
-            return -insertPoint - 1;
-        }
-        return -mid - ( result >= 0 ? 1 : 2 );
-    }
-
-    private static void checkIndexForBinarySearch( int length, int start,
-            int end )
-    {
-        if ( start > end )
-        {
-            throw new IllegalArgumentException();
-        }
-        if ( length < end || 0 > start )
-        {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-    }
-
     private static ArrayList<PlexOfField> toArrayList( PlexOfCps plexOfCps )
     {
         if ( plexOfCps == null )
             return new ArrayList<PlexOfField>();
 
-        ArrayList<PlexOfField> fields = new ArrayList<PlexOfField>();
-        fields.ensureCapacity( plexOfCps.length() );
-
+        ArrayList<PlexOfField> fields = new ArrayList<PlexOfField>(
+                plexOfCps.length() );
         for ( int i = 0; i < plexOfCps.length(); i++ )
         {
             GenericPropertyNode propNode = plexOfCps.getProperty( i );
@@ -153,37 +91,20 @@ public class FieldsTables
         return fields;
     }
 
-    private Map<FieldsDocumentPart, Map<Integer, Field>> _fieldsByOffset;
-
     private Map<FieldsDocumentPart, PlexOfCps> _tables;
 
-    private GenericPropertyNodeComparator comparator = new GenericPropertyNodeComparator();
-
     public FieldsTables( byte[] tableStream, FileInformationBlock fib )
     {
         _tables = new HashMap<FieldsDocumentPart, PlexOfCps>(
                 FieldsDocumentPart.values().length );
-        _fieldsByOffset = new HashMap<FieldsDocumentPart, Map<Integer, Field>>(
-                FieldsDocumentPart.values().length );
 
         for ( FieldsDocumentPart part : FieldsDocumentPart.values() )
         {
             final PlexOfCps plexOfCps = readPLCF( tableStream, fib, part );
-
-            _fieldsByOffset.put( part, parseFieldStructure( plexOfCps ) );
             _tables.put( part, plexOfCps );
         }
     }
 
-    public Collection<Field> getFields( FieldsDocumentPart part )
-    {
-        Map<Integer, Field> map = _fieldsByOffset.get( part );
-        if ( map == null || map.isEmpty() )
-            return Collections.emptySet();
-
-        return Collections.unmodifiableCollection( map.values() );
-    }
-
     public ArrayList<PlexOfField> getFieldsPLCF( FieldsDocumentPart part )
     {
         return toArrayList( _tables.get( part ) );
@@ -195,146 +116,6 @@ public class FieldsTables
         return getFieldsPLCF( FieldsDocumentPart.values()[partIndex] );
     }
 
-    public Field lookupFieldByStartOffset( FieldsDocumentPart documentPart,
-            int offset )
-    {
-        Map<Integer, Field> map = _fieldsByOffset.get( documentPart );
-        if ( map == null || map.isEmpty() )
-            return null;
-
-        return map.get( Integer.valueOf( offset ) );
-    }
-
-    private Map<Integer, Field> parseFieldStructure( PlexOfCps plexOfCps )
-    {
-        if ( plexOfCps == null )
-            return new HashMap<Integer, Field>();
-
-        GenericPropertyNode[] nodes = plexOfCps.toPropertiesArray();
-        Arrays.sort( nodes, comparator );
-        List<Field> fields = new ArrayList<Field>( nodes.length / 3 + 1 );
-        parseFieldStructureImpl( nodes, 0, nodes.length, fields );
-
-        HashMap<Integer, Field> result = new HashMap<Integer, Field>(
-                fields.size() );
-        for ( Field field : fields )
-        {
-            result.put( Integer.valueOf( field.getFieldStartOffset() ), field );
-        }
-        return result;
-    }
-
-    private void parseFieldStructureImpl( GenericPropertyNode[] nodes,
-            int startOffsetInclusive, int endOffsetExclusive, List<Field> result )
-    {
-        int next = startOffsetInclusive;
-        while ( next < endOffsetExclusive )
-        {
-            GenericPropertyNode startNode = nodes[next];
-            PlexOfField startPlexOfField = new PlexOfField( startNode );
-            if ( startPlexOfField.getFld().getBoundaryType() != FieldDescriptor.FIELD_BEGIN_MARK
)
-            {
-                /* Start mark seems to be missing */
-                next++;
-                continue;
-            }
-
-            /*
-             * we have start node. end offset points to next node, separator or
-             * end
-             */
-            int nextNodePositionInArray = binarySearch( nodes, next + 1,
-                    endOffsetExclusive, startNode.getEnd() );
-            if ( nextNodePositionInArray < 0 )
-            {
-                /*
-                 * too bad, this start field mark doesn't have corresponding end
-                 * field mark or separator field mark in fields table
-                 */
-                next++;
-                continue;
-            }
-            GenericPropertyNode nextNode = nodes[nextNodePositionInArray];
-            PlexOfField nextPlexOfField = new PlexOfField( nextNode );
-
-            switch ( nextPlexOfField.getFld().getBoundaryType() )
-            {
-            case FieldDescriptor.FIELD_SEPARATOR_MARK:
-            {
-                GenericPropertyNode separatorNode = nextNode;
-                PlexOfField separatorPlexOfField = nextPlexOfField;
-
-                int endNodePositionInArray = binarySearch( nodes,
-                        nextNodePositionInArray, endOffsetExclusive,
-                        separatorNode.getEnd() );
-                if ( endNodePositionInArray < 0 )
-                {
-                    /*
-                     * too bad, this separator field mark doesn't have
-                     * corresponding end field mark in fields table
-                     */
-                    next++;
-                    continue;
-                }
-                GenericPropertyNode endNode = nodes[endNodePositionInArray];
-                PlexOfField endPlexOfField = new PlexOfField( endNode );
-
-                if ( endPlexOfField.getFld().getBoundaryType() != FieldDescriptor.FIELD_END_MARK
)
-                {
-                    /* Not and ending mark */
-                    next++;
-                    continue;
-                }
-
-                Field field = new Field( startPlexOfField,
-                        separatorPlexOfField, endPlexOfField );
-                result.add( field );
-
-                // adding included fields
-                if ( startNode.getStart() + 1 < separatorNode.getStart() - 1 )
-                {
-                    parseFieldStructureImpl( nodes, next + 1,
-                            nextNodePositionInArray, result );
-                }
-                if ( separatorNode.getStart() + 1 < endNode.getStart() - 1 )
-                {
-                    parseFieldStructureImpl( nodes,
-                            nextNodePositionInArray + 1,
-                            endNodePositionInArray, result );
-                }
-
-                next = endNodePositionInArray + 1;
-
-                break;
-            }
-            case FieldDescriptor.FIELD_END_MARK:
-            {
-                // we have no separator
-                Field field = new Field( startPlexOfField, null,
-                        nextPlexOfField );
-                result.add( field );
-
-                // adding included fields
-                if ( startNode.getStart() + 1 < nextNode.getStart() - 1 )
-                {
-                    parseFieldStructureImpl( nodes, next + 1,
-                            nextNodePositionInArray, result );
-                }
-
-                next = nextNodePositionInArray + 1;
-                break;
-            }
-            case FieldDescriptor.FIELD_BEGIN_MARK:
-            default:
-            {
-                /* something is wrong, ignoring this mark along with start mark */
-                next++;
-                continue;
-            }
-            }
-        }
-    }
-
     private PlexOfCps readPLCF( byte[] tableStream, FileInformationBlock fib,
             FieldsDocumentPart documentPart )
     {
@@ -377,14 +158,4 @@ public class FieldsTables
         }
     }
 
-    private static final class GenericPropertyNodeComparator implements
-            Comparator<GenericPropertyNode>
-    {
-        public int compare( GenericPropertyNode o1, GenericPropertyNode o2 )
-        {
-            int thisVal = o1.getStart();
-            int anotherVal = o2.getStart();
-            return thisVal < anotherVal ? -1 : thisVal == anotherVal ? 0 : 1;
-        }
-    }
 }

Added: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Field.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Field.java?rev=1149704&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Field.java (added)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Field.java Fri Jul 22 19:38:14
2011
@@ -0,0 +1,55 @@
+package org.apache.poi.hwpf.usermodel;
+
+public interface Field
+{
+
+    Range firstSubrange( Range parent );
+
+    /**
+     * @return character position of first character after field (i.e.
+     *         {@link #getMarkEndOffset()} + 1)
+     */
+    int getFieldEndOffset();
+
+    /**
+     * @return character position of first character in field (i.e.
+     *         {@link #getFieldStartOffset()})
+     */
+    int getFieldStartOffset();
+
+    /**
+     * @return character position of end field mark
+     */
+    int getMarkEndOffset();
+
+    /**
+     * @return character position of separator field mark (if present,
+     *         {@link NullPointerException} otherwise)
+     */
+    int getMarkSeparatorOffset();
+
+    /**
+     * @return character position of start field mark
+     */
+    int getMarkStartOffset();
+
+    int getType();
+
+    boolean hasSeparator();
+
+    boolean isHasSep();
+
+    boolean isLocked();
+
+    boolean isNested();
+
+    boolean isPrivateResult();
+
+    boolean isResultDirty();
+
+    boolean isResultEdited();
+
+    boolean isZombieEmbed();
+
+    Range secondSubrange( Range parent );
+}
\ No newline at end of file

Copied: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/FieldImpl.java (from r1149034,
poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/Field.java)
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/FieldImpl.java?p2=poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/FieldImpl.java&p1=poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/Field.java&r1=1149034&r2=1149704&rev=1149704&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/Field.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/FieldImpl.java Fri Jul 22 19:38:14
2011
@@ -1,14 +1,38 @@
-package org.apache.poi.hwpf.model;
-
-import org.apache.poi.hwpf.usermodel.Range;
-
-public class Field
+/* ====================================================================
+   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.hwpf.usermodel;
+
+import org.apache.poi.hwpf.model.FieldDescriptor;
+import org.apache.poi.hwpf.model.PlexOfField;
+import org.apache.poi.util.Internal;
+
+/**
+ * TODO: document me
+ * 
+ * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
+ */
+@Internal
+class FieldImpl implements Field
 {
     private PlexOfField endPlex;
     private PlexOfField separatorPlex;
     private PlexOfField startPlex;
 
-    public Field( PlexOfField startPlex, PlexOfField separatorPlex,
+    public FieldImpl( PlexOfField startPlex, PlexOfField separatorPlex,
             PlexOfField endPlex )
     {
         if ( startPlex == null )

Added: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Fields.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Fields.java?rev=1149704&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Fields.java (added)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Fields.java Fri Jul 22 19:38:14
2011
@@ -0,0 +1,33 @@
+/* ====================================================================
+   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.hwpf.usermodel;
+
+import java.util.Collection;
+
+import org.apache.poi.hwpf.model.FieldsDocumentPart;
+
+/**
+ * User-friendly interface to access document {@link Field}s
+ * 
+ * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
+ */
+public interface Fields
+{
+    Field getFieldByStartOffset( FieldsDocumentPart documentPart, int offset );
+
+    Collection<Field> getFields( FieldsDocumentPart part );
+}

Added: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/FieldsImpl.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/FieldsImpl.java?rev=1149704&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/FieldsImpl.java (added)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/FieldsImpl.java Fri Jul 22
19:38:14 2011
@@ -0,0 +1,276 @@
+/* ====================================================================
+   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.hwpf.usermodel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.poi.hwpf.model.FieldDescriptor;
+import org.apache.poi.hwpf.model.FieldsDocumentPart;
+import org.apache.poi.hwpf.model.FieldsTables;
+import org.apache.poi.hwpf.model.PlexOfField;
+import org.apache.poi.util.Internal;
+
+/**
+ * Default implementation of {@link Field}
+ * 
+ * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
+ */
+@Internal
+public class FieldsImpl implements Fields
+{
+    /**
+     * This is port and adaptation of Arrays.binarySearch from Java 6 (Apache
+     * Harmony).
+     */
+    private static <T> int binarySearch( List<PlexOfField> list,
+            int startIndex, int endIndex, int requiredStartOffset )
+    {
+        checkIndexForBinarySearch( list.size(), startIndex, endIndex );
+
+        int low = startIndex, mid = -1, high = endIndex - 1, result = 0;
+        while ( low <= high )
+        {
+            mid = ( low + high ) >>> 1;
+            int midStart = list.get( mid ).getFcStart();
+
+            if ( midStart == requiredStartOffset )
+            {
+                return mid;
+            }
+            else if ( midStart < requiredStartOffset )
+            {
+                low = mid + 1;
+            }
+            else
+            {
+                high = mid - 1;
+            }
+        }
+        if ( mid < 0 )
+        {
+            int insertPoint = endIndex;
+            for ( int index = startIndex; index < endIndex; index++ )
+            {
+                if ( requiredStartOffset < list.get( index ).getFcStart() )
+                {
+                    insertPoint = index;
+                }
+            }
+            return -insertPoint - 1;
+        }
+        return -mid - ( result >= 0 ? 1 : 2 );
+    }
+
+    private static void checkIndexForBinarySearch( int length, int start,
+            int end )
+    {
+        if ( start > end )
+        {
+            throw new IllegalArgumentException();
+        }
+        if ( length < end || 0 > start )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+    }
+
+    private Map<FieldsDocumentPart, Map<Integer, FieldImpl>> _fieldsByOffset;
+
+    private PlexOfFieldComparator comparator = new PlexOfFieldComparator();
+
+    public FieldsImpl( FieldsTables fieldsTables )
+    {
+        _fieldsByOffset = new HashMap<FieldsDocumentPart, Map<Integer, FieldImpl>>(
+                FieldsDocumentPart.values().length );
+
+        for ( FieldsDocumentPart part : FieldsDocumentPart.values() )
+        {
+            List<PlexOfField> plexOfCps = fieldsTables.getFieldsPLCF( part );
+            _fieldsByOffset.put( part, parseFieldStructure( plexOfCps ) );
+        }
+    }
+
+    public Collection<Field> getFields( FieldsDocumentPart part )
+    {
+        Map<Integer, FieldImpl> map = _fieldsByOffset.get( part );
+        if ( map == null || map.isEmpty() )
+            return Collections.emptySet();
+
+        return Collections.<Field> unmodifiableCollection( map.values() );
+    }
+
+    public FieldImpl getFieldByStartOffset( FieldsDocumentPart documentPart,
+            int offset )
+    {
+        Map<Integer, FieldImpl> map = _fieldsByOffset.get( documentPart );
+        if ( map == null || map.isEmpty() )
+            return null;
+
+        return map.get( Integer.valueOf( offset ) );
+    }
+
+    private Map<Integer, FieldImpl> parseFieldStructure(
+            List<PlexOfField> plexOfFields )
+    {
+        if ( plexOfFields == null || plexOfFields.isEmpty() )
+            return new HashMap<Integer, FieldImpl>();
+
+        Collections.sort( plexOfFields, comparator );
+        List<FieldImpl> fields = new ArrayList<FieldImpl>(
+                plexOfFields.size() / 3 + 1 );
+        parseFieldStructureImpl( plexOfFields, 0, plexOfFields.size(), fields );
+
+        HashMap<Integer, FieldImpl> result = new HashMap<Integer, FieldImpl>(
+                fields.size() );
+        for ( FieldImpl field : fields )
+        {
+            result.put( Integer.valueOf( field.getFieldStartOffset() ), field );
+        }
+        return result;
+    }
+
+    private void parseFieldStructureImpl( List<PlexOfField> plexOfFields,
+            int startOffsetInclusive, int endOffsetExclusive,
+            List<FieldImpl> result )
+    {
+        int next = startOffsetInclusive;
+        while ( next < endOffsetExclusive )
+        {
+            PlexOfField startPlexOfField = plexOfFields.get( next );
+            if ( startPlexOfField.getFld().getBoundaryType() != FieldDescriptor.FIELD_BEGIN_MARK
)
+            {
+                /* Start mark seems to be missing */
+                next++;
+                continue;
+            }
+
+            /*
+             * we have start node. end offset points to next node, separator or
+             * end
+             */
+            int nextNodePositionInList = binarySearch( plexOfFields, next + 1,
+                    endOffsetExclusive, startPlexOfField.getFcEnd() );
+            if ( nextNodePositionInList < 0 )
+            {
+                /*
+                 * too bad, this start field mark doesn't have corresponding end
+                 * field mark or separator field mark in fields table
+                 */
+                next++;
+                continue;
+            }
+            PlexOfField nextPlexOfField = plexOfFields
+                    .get( nextNodePositionInList );
+
+            switch ( nextPlexOfField.getFld().getBoundaryType() )
+            {
+            case FieldDescriptor.FIELD_SEPARATOR_MARK:
+            {
+                PlexOfField separatorPlexOfField = nextPlexOfField;
+
+                int endNodePositionInList = binarySearch( plexOfFields,
+                        nextNodePositionInList, endOffsetExclusive,
+                        separatorPlexOfField.getFcEnd() );
+                if ( endNodePositionInList < 0 )
+                {
+                    /*
+                     * too bad, this separator field mark doesn't have
+                     * corresponding end field mark in fields table
+                     */
+                    next++;
+                    continue;
+                }
+                PlexOfField endPlexOfField = plexOfFields
+                        .get( endNodePositionInList );
+
+                if ( endPlexOfField.getFld().getBoundaryType() != FieldDescriptor.FIELD_END_MARK
)
+                {
+                    /* Not and ending mark */
+                    next++;
+                    continue;
+                }
+
+                FieldImpl field = new FieldImpl( startPlexOfField,
+                        separatorPlexOfField, endPlexOfField );
+                result.add( field );
+
+                // adding included fields
+                if ( startPlexOfField.getFcStart() + 1 < separatorPlexOfField
+                        .getFcStart() - 1 )
+                {
+                    parseFieldStructureImpl( plexOfFields, next + 1,
+                            nextNodePositionInList, result );
+                }
+                if ( separatorPlexOfField.getFcStart() + 1 < endPlexOfField
+                        .getFcStart() - 1 )
+                {
+                    parseFieldStructureImpl( plexOfFields,
+                            nextNodePositionInList + 1, endNodePositionInList,
+                            result );
+                }
+
+                next = endNodePositionInList + 1;
+
+                break;
+            }
+            case FieldDescriptor.FIELD_END_MARK:
+            {
+                // we have no separator
+                FieldImpl field = new FieldImpl( startPlexOfField, null,
+                        nextPlexOfField );
+                result.add( field );
+
+                // adding included fields
+                if ( startPlexOfField.getFcStart() + 1 < nextPlexOfField
+                        .getFcStart() - 1 )
+                {
+                    parseFieldStructureImpl( plexOfFields, next + 1,
+                            nextNodePositionInList, result );
+                }
+
+                next = nextNodePositionInList + 1;
+                break;
+            }
+            case FieldDescriptor.FIELD_BEGIN_MARK:
+            default:
+            {
+                /* something is wrong, ignoring this mark along with start mark */
+                next++;
+                continue;
+            }
+            }
+        }
+    }
+
+    private static final class PlexOfFieldComparator implements
+            Comparator<PlexOfField>
+    {
+        public int compare( PlexOfField o1, PlexOfField o2 )
+        {
+            int thisVal = o1.getFcStart();
+            int anotherVal = o2.getFcStart();
+            return thisVal < anotherVal ? -1 : thisVal == anotherVal ? 0 : 1;
+        }
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org


Mime
View raw message