    View Javadoc
    1   /*
    2    * Copyright (c) 2003
    3    * Information Desire GmbH
    4    * All rights reserved.
    5    */
    6   package com.infodesire.infobit.external.impl;
    7
    8   import org.apache.commons.logging.Log;
    9   import org.apache.commons.logging.LogFactory;
    10
    11  import java.io.IOException;
    12  import java.io.Writer;
    13
    14  import java.util.HashMap;
    15  import java.util.Map;
    16
    17  /***
    18   * This class resolves predifined general entity references within an assumed
    19   * XML document.
    20   *
    21   * @author    peter2
    22   * @created   1. September 2003
    23   * @version   $Revision: 1.1 $
    24   */
    25  class EntityReferenceDecoder {
    26
    27      private final static Log _log =
    28          LogFactory.getLog(EntityReferenceDecoder.class);
    29
    30      /***
    31       * Maximum length of entities to be resolved
    32       */
    33      private final static int MAX_ENT_NAME = 10;
    34
    35      /***
    36       * Scanning state: waiting for an entity reference to start
    37       */
    38      private final static int SS_TEXT = 0;
    39
    40      /***
    41       * Scanning state: scanning a referenced entity name
    42       */
    43      private final static int SS_ENT_NAME = 1;
    44
    45      /***
    46       * Maps (default) entities to their content
    47       */
    48      private final static Map DEFAULT_ENTITIES = new HashMap();
    49
    50      /***
    51       * The destination of decoded text
    52       */
    53      private Writer  _destination;
    54
    55      /***
    56       * The current scanning state, either {@link #SS_TEXT or {@link
    57       * #SS_ENT_NAME}
    58       */
    59      private int     _state = SS_TEXT;
    60
    61      /***
    62       * Buffer to collect entity references
    63       */
    64      private StringBuffer _nameBuffer = new StringBuffer();
    65
    66
    67      /***
    68       * Initializes an instance ready for setup. The instance is in state waiting
    69       * for entity references to occure.
    70       */
    71      EntityReferenceDecoder() {
    72          //  null;
    73      }
    74
    75
    76      /***
    77       * Defines the destination of decoded input. The read methods access the
    78       * destination and will block if the input blocks. Single character write
    79       * operations on the provided writer should not be expensive (else wrap it
    80       * with a <code>BufferedWriter</code>).
    81       *
    82       * @param dest  Where to write decoded data to
    83       */
    84      void setDestination(Writer dest) {
    85          _destination = dest;
    86      }
    87
    88
    89      /***
    90       * Adds the specified characters to the data to be decoded.
    91       *
    92       * @param b                Contains the character chunk to be decoded
    93       * @param offset           Index of the first character to be decoded in
    94       *      <code>b</code>
    95       * @param length           Number of subsequent characters from <code>b</code>
    96       *      to be decoded
    97       * @exception IOException  Description of Exception
    98       */
    99      void decodeChunk(char[] b, int offset, int length)
    100          throws IOException {
    101
    102         for (int i = offset; i < offset + length; ++i) {
    103             char c = b[i];
    104
    105             switch (_state) {
    106                 case SS_TEXT:
    107                     //  In unescaped text
    108                     switch (c) {
    109                         case '&':
    110                             _state = SS_ENT_NAME;
    111                             break;
    112                         default:
    113                             _destination.write(c);
    114                     }
    115                     break;
    116                 case SS_ENT_NAME:
    117                     //  In entity name
    118                     switch (c) {
    119                         case ';':
    120                             String name = _nameBuffer.toString();
    121                             String value = (String) DEFAULT_ENTITIES.get(name);
    122                             if (value != null) {
    123                                 _destination.write(value);
    124                             }
    125                             else {
    126                                 _destination.write('&');
    127                                 _destination.write(name);
    128                                 _destination.write(';');
    129                             }
    130                             _nameBuffer.delete(0, _nameBuffer.length());
    131                             _state = SS_TEXT;
    132                             break;
    133                         default:
    134                             //  NOTE: no check for proper entity name
    135                             //  syntax
    136                             if (_nameBuffer.length() == MAX_ENT_NAME) {
    137                                 _destination.write('&');
    138                                 _destination.write(_nameBuffer.toString());
    139                                 _state = SS_TEXT;
    140                             }
    141                             else {
    142                                 _nameBuffer.append(c);
    143                             }
    144                     }
    145                 default:
    146                     String m = "failed assertion: _state: " + _state;
    147                     _log.error(m);
    148                     throw new RuntimeException(m);
    149             }
    150         }
    151
    152     }
    153
    154
    155     /***
    156      * Signals end-of-text of the input source.
    157      *
    158      * @exception IOException  Description of Exception
    159      */
    160     void endOfText() throws IOException {
    161         switch (_state) {
    162             case SS_TEXT:
    163                 break;
    164             case SS_ENT_NAME:
    165                 _destination.write("&");
    166                 _destination.write(_nameBuffer.toString());
    167                 break;
    168         }
    169
    170         _destination.flush();
    171     }
    172
    173     static {
    174         Map m = DEFAULT_ENTITIES;
    175         m.put("lt", "<");
    176         m.put("gl", ">");
    177         m.put("amp", "&");
    178         m.put("quot", "\"");
    179         m.put("apos", "'");
    180     }
    181
    182 }

This page was automatically generated by Maven