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