001: /*
002: Copyright (C) 2003 Know Gate S.L. All rights reserved.
003: C/Oņa, 107 1š2 28050 Madrid (Spain)
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions
007: are met:
008:
009: 1. Redistributions of source code must retain the above copyright
010: notice, this list of conditions and the following disclaimer.
011:
012: 2. The end-user documentation included with the redistribution,
013: if any, must include the following acknowledgment:
014: "This product includes software parts from hipergate
015: (http://www.hipergate.org/)."
016: Alternately, this acknowledgment may appear in the software itself,
017: if and wherever such third-party acknowledgments normally appear.
018:
019: 3. The name hipergate must not be used to endorse or promote products
020: derived from this software without prior written permission.
021: Products derived from this software may not be called hipergate,
022: nor may hipergate appear in their name, without prior written
023: permission.
024:
025: This library is distributed in the hope that it will be useful,
026: but WITHOUT ANY WARRANTY; without even the implied warranty of
027: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
028:
029: You should have received a copy of hipergate License with this code;
030: if not, visit http://www.hipergate.org or mail to info@hipergate.org
031: */
032:
033: package com.knowgate.dataxslt;
034:
035: import java.io.StringBufferInputStream;
036: import java.io.BufferedInputStream;
037: import java.io.IOException;
038: import java.io.InputStream;
039: import java.io.FileInputStream;
040:
041: import java.util.HashMap;
042:
043: import java.util.Date;
044:
045: import com.knowgate.debug.DebugFile;
046:
047: /**
048: * Search and Replace a set of substrings with another substrings.
049: * <p>This class is a single-pass fast no wildcards replacer for a given set of substrings.</p>
050: * <p>It is primarily designed for mail merge document personalization routines, where a small
051: * number of substrings have to be replaced at a master document with data retrieved from a list
052: * or database.</p>
053: * @author Sergio Montoro Ten
054: * @version 2.1
055: */
056:
057: public class FastStreamReplacer {
058: int BufferSize;
059: int iReplacements;
060: StringBuffer oOutStream;
061:
062: // ----------------------------------------------------------
063:
064: public FastStreamReplacer() {
065: BufferSize = 32767;
066: oOutStream = new StringBuffer(BufferSize);
067: }
068:
069: // ----------------------------------------------------------
070:
071: public FastStreamReplacer(int iBufferSize) {
072: BufferSize = iBufferSize;
073: oOutStream = new StringBuffer(BufferSize);
074: }
075:
076: // ----------------------------------------------------------
077: /**
078: * Replace subtrings from a Stream.
079: * @param oInStream Input Stream containing substrings to be replaced.
080: * @param oMap Map with values to be replaced.<br>
081: * Each map key will be replaced by its value.<br>
082: * Map keys must appear in stream text as {#<i>key</i>}<br>
083: * For example: InputStream "Today is {#System.Date}" will be replaced with "Today is 2002-02-21 11:32:44"<br>
084: * No wildcards are accepted.<br>
085: * Map keys must not contain {# } key markers.
086: * @return String Replacements Result
087: * @throws IOException
088: */
089:
090: public String replace(InputStream oFileInStream, HashMap oMap)
091: throws IOException {
092:
093: if (DebugFile.trace) {
094: DebugFile
095: .writeln("Begin FastStreamReplacer.replace([InputStream],[HashMap])");
096: DebugFile.incIdent();
097: }
098:
099: int iChr;
100: String sKey;
101: Object oValue;
102:
103: Date dtToday = new Date();
104: String sToday = String.valueOf(dtToday.getYear() + 1900) + "-"
105: + String.valueOf(dtToday.getMonth() + 1) + "-"
106: + String.valueOf(dtToday.getDate());
107:
108: oMap.put("Sistema.Fecha", sToday);
109: oMap.put("System.Date", sToday);
110:
111: iReplacements = 0;
112:
113: BufferedInputStream oInStream = new BufferedInputStream(
114: oFileInStream, BufferSize);
115:
116: oOutStream.setLength(0);
117:
118: do {
119: iChr = oInStream.read();
120:
121: if (-1 == iChr)
122: break;
123:
124: else {
125:
126: if (123 == iChr) {
127: // Se encontro el caracter '{'
128: iChr = oInStream.read();
129: if (35 == iChr) {
130: // Se encontro el caracter '#'
131:
132: iReplacements++;
133:
134: sKey = "";
135:
136: do {
137:
138: iChr = oInStream.read();
139: if (-1 == iChr || 125 == iChr)
140: break;
141: sKey += (char) iChr;
142:
143: } while (true);
144:
145: oValue = oMap.get(sKey);
146:
147: if (null != oValue)
148: oOutStream.append(((String) oValue));
149: } // fi ('#')
150:
151: else {
152: oOutStream.append((char) 123);
153: oOutStream.append((char) iChr);
154: }
155:
156: } // fi ('{')
157:
158: else
159: oOutStream.append((char) iChr);
160: } // fi (!eof)
161:
162: } while (true);
163:
164: oInStream.close();
165:
166: if (DebugFile.trace) {
167: DebugFile.decIdent();
168: DebugFile.writeln("End FastStreamReplacer.replace() : "
169: + String.valueOf(oOutStream.length()));
170: }
171:
172: return oOutStream.toString();
173: } // replace()
174:
175: // ----------------------------------------------------------
176: /**
177: * Replace subtrings from a Stream.
178: * @param oInStream Input Stream containing substrings to be replaced.
179: * @param oMap Map with values to be replaced.<br>
180: * Each map key will be replaced by its value.<br>
181: * Map keys must appear in stream text as {#<i>key</i>}<br>
182: * For example: InputStream "Today is {#System.Date}" will be replaced with "Today is 2002-02-21 11:32:44"<br>
183: * No wildcards are accepted.<br>
184: * Map keys must not contain {# } key markers.
185: * @return String Replacements Result
186: * @throws IOException
187: * @throws IndexOutOfBoundsException
188: */
189:
190: public String replace(StringBuffer oStrBuff, HashMap oMap)
191: throws IOException, IndexOutOfBoundsException {
192:
193: if (DebugFile.trace) {
194: DebugFile
195: .writeln("Begin FastStreamReplacer.replace([StringBuffer],[HashMap])");
196: DebugFile.incIdent();
197: }
198:
199: int iChr;
200: String sKey;
201: Object oValue;
202:
203: Date dtToday = new Date();
204: String sToday = String.valueOf(dtToday.getYear() + 1900) + "-"
205: + String.valueOf(dtToday.getMonth() + 1) + "-"
206: + String.valueOf(dtToday.getDate());
207:
208: oMap.put("Sistema.Fecha", sToday);
209: oMap.put("System.Date", sToday);
210:
211: iReplacements = 0;
212:
213: oOutStream.setLength(0);
214:
215: int iAt = 0;
216: final int iLen = oStrBuff.length();
217:
218: while (iAt < iLen) {
219: iChr = oStrBuff.charAt(iAt++);
220:
221: if (123 == iChr) {
222: // Se encontro el caracter '{'
223: iChr = oStrBuff.charAt(iAt++);
224: if (35 == iChr) {
225: // Se encontro el caracter '#'
226: iReplacements++;
227:
228: sKey = "";
229:
230: while (iAt < iLen) {
231: iChr = oStrBuff.charAt(iAt++);
232: if (125 == iChr)
233: break;
234: sKey += (char) iChr;
235: } // wend
236:
237: oValue = oMap.get(sKey);
238:
239: if (null != oValue)
240: oOutStream.append(((String) oValue));
241: } // fi ('#')
242:
243: else {
244: oOutStream.append((char) 123);
245: oOutStream.append((char) iChr);
246: }
247:
248: } // fi ('{')
249:
250: else
251: oOutStream.append((char) iChr);
252:
253: } // wend
254:
255: if (DebugFile.trace) {
256: DebugFile.decIdent();
257: DebugFile.writeln("End FastStreamReplacer.replace() : "
258: + String.valueOf(oOutStream.length()));
259: }
260:
261: return oOutStream.toString();
262: } // replace()
263:
264: // ----------------------------------------------------------
265:
266: /**
267: * Replace substrings from a Text File.
268: * @param sFilePath File containing text to be replaced.
269: * @param oMap Map with values to be replaced.<br>
270: * Each map key will be replaced by its value.<br>
271: * Map keys must appear in stream text as {#<i>key</i>}<br>
272: * For example: InputStream "Today is {#System.Date}" will be replaced with "Today is 2002-02-21 11:32:44"<br>
273: * No wildcards are accepted.<br>
274: * Map keys must not contain {# } key markers.
275: * @return String Replacements Result.
276: * @throws IOException
277: */
278:
279: public String replace(String sFilePath, HashMap oMap)
280: throws IOException {
281:
282: FileInputStream oStrm = new FileInputStream(sFilePath);
283: String sRetVal = replace(oStrm, oMap);
284: oStrm.close();
285:
286: return sRetVal;
287: }
288:
289: // ----------------------------------------------------------
290:
291: /**
292: * Number of replacements done in last call to replace() method.
293: */
294: public int lastReplacements() {
295: return iReplacements;
296: }
297:
298: // ----------------------------------------------------------
299:
300: /**
301: * <p>Create a HashMap for a couple of String Arrays</p>
302: * This method is just a convenient shortcut for creating input HashMap for
303: * replace methods from this class
304: * @param aKeys An array of Strings to be used as keys
305: * @param aValues An array of Strings that will be the actual values for the keys
306: * @return A HashMap with the given keys and values
307: */
308: public static HashMap createMap(String[] aKeys, String[] aValues) {
309:
310: HashMap oRetVal = new HashMap(5 + ((aKeys.length * 100) / 60));
311:
312: for (int k = 0; k < aKeys.length; k++)
313: oRetVal.put(aKeys[k], aValues[k]);
314:
315: return oRetVal;
316: } // createMap
317:
318: // ----------------------------------------------------------
319:
320: } // FastStreamReplacer
|