1 /*
2  * $Id$
3  *
4  * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
5  *
6  * The contents of this file are subject to the Mozilla Public License Version 1.1
7  * (the "License"); you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the License.
13  *
14  * The Original Code is 'iText, a free JAVA-PDF library'.
15  *
16  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
17  * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
18  * All Rights Reserved.
19  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
20  * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
21  *
22  * Contributor(s): all the names of the contributors are added in the source code
23  * where applicable.
24  *
25  * Alternatively, the contents of this file may be used under the terms of the
26  * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
27  * provisions of LGPL are applicable instead of those above.  If you wish to
28  * allow use of your version of this file only under the terms of the LGPL
29  * License and not to allow others to use your version of this file under
30  * the MPL, indicate your decision by deleting the provisions above and
31  * replace them with the notice and other provisions required by the LGPL.
32  * If you do not delete the provisions above, a recipient may use your version
33  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
34  *
35  * This library is free software; you can redistribute it and/or modify it
36  * under the terms of the MPL as stated above or under the terms of the GNU
37  * Library General Public License as published by the Free Software Foundation;
38  * either version 2 of the License, or any later version.
39  *
40  * This library is distributed in the hope that it will be useful, but WITHOUT
41  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42  * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
43  * details.
44  *
45  * If you didn't download this code from the following link, you should check if
46  * you aren't using an obsolete version:
47  * http://www.lowagie.com/iText/
48  */
49 
50 package com.lowagie.text.rtf.parser.ctrlwords;
51 
52 import java.io.PushbackInputStream;
53 import java.util.ArrayList;
54 import java.util.Iterator;
55 
56 import com.lowagie.text.rtf.parser.RtfParser;
57 
58 /**
59  * <code>RtfCtrlWordMgr</code> handles the dispatching of control words from
60  * the table of known control words.
61  *
62  * @author Howard Shank (hgshank@yahoo.com)
63  * @since 2.0.8
64  */
65 public final class RtfCtrlWordMgr {
66 	public static final boolean debug = false;
67 	public static final boolean debugFound = false;
68 	public static final boolean debugNotFound = true;
69 	private PushbackInputStream reader = null;
70 	private RtfParser rtfParser = null;
71 	private RtfCtrlWordMap ctrlWordMap = null;
72 
73 	/** The <code>RtfCtrlWordListener</code>. */
74     private ArrayList listeners = new ArrayList();
75 
76 //	// TIMING DEBUG INFO
77 //	private long endTime = 0;
78 //	private Date endDate = null;
79 //	private long endFree = 0;
80 //	private DecimalFormat df = new DecimalFormat("#,##0");
81 //	private Date startDate = new Date();
82 //	private long startTime = System.currentTimeMillis();
83 //	private long startFree = Runtime.getRuntime().freeMemory();
84 
85 	/**
86 	 * Constructor
87 	 * @param rtfParser The parser object this manager works with.
88 	 * @param reader the PushbackReader from the tokeniser.
89 	 */
RtfCtrlWordMgr(RtfParser rtfParser, PushbackInputStream reader)90 	public RtfCtrlWordMgr(RtfParser rtfParser, PushbackInputStream reader) {
91 		this.rtfParser = rtfParser;	// set the parser
92 		this.reader = reader;	// set the reader value
93 		ctrlWordMap = new RtfCtrlWordMap(rtfParser);
94 
95 //		// TIMING DEBUG INFO
96 //		endFree = Runtime.getRuntime().freeMemory();
97 //		endTime = System.currentTimeMillis();
98 //		endDate = new Date();
99 //		System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString());
100 //		System.out.println("RtfCtrlWordMgr end date  : " + endDate.toLocaleString());
101 //		System.out.println("  Elapsed time    : " + Long.toString(endTime - startTime) + " milliseconds.");
102 //		System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k");
103 //		System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k");
104 //        System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k");
105 	}
106 
107 	/**
108 	 * Internal to control word manager class.
109 	 *
110 	 * @param ctrlWordData The <code>RtfCtrlWordData</code> object with control word and param
111 	 * @param groupLevel The current document group parsing level
112 	 * @return errOK if ok, otherwise an error code.
113 	 */
handleKeyword(RtfCtrlWordData ctrlWordData, int groupLevel)114 	public int handleKeyword(RtfCtrlWordData ctrlWordData, int groupLevel) {
115 		//TODO: May be used for event handling.
116 		int result = RtfParser.errOK;
117 
118 		// Call before handler event here
119 		beforeCtrlWord(ctrlWordData);
120 
121 		result = dispatchKeyword(ctrlWordData, groupLevel);
122 
123 		// call after handler event here
124 		afterCtrlWord(ctrlWordData);
125 
126 		return result;
127 	}
128 
129 	/**
130 	 * Dispatch the token to the correct control word handling object.
131 	 *
132 	 * @param ctrlWordData The <code>RtfCtrlWordData</code> object with control word and param
133 	 * @param groupLevel The current document group parsing level
134 	 * @return errOK if ok, otherwise an error code.
135 	 */
dispatchKeyword(RtfCtrlWordData ctrlWordData, int groupLevel)136 	private int dispatchKeyword(RtfCtrlWordData ctrlWordData, int groupLevel) {
137 		int result = RtfParser.errOK;
138 		if(ctrlWordData != null) {
139 			RtfCtrlWordHandler ctrlWord = ctrlWordMap.getCtrlWordHandler(ctrlWordData.ctrlWord);
140 			if(ctrlWord != null) {
141 				ctrlWord.handleControlword(ctrlWordData);
142 				if(debug && debugFound) {
143 					System.out.println("Keyword found:" +
144 						" New:" + ctrlWordData.ctrlWord +
145 						" Param:" + ctrlWordData.param +
146 						" bParam=" + ctrlWordData.hasParam);
147 				}
148 			} else {
149 				result = RtfParser.errCtrlWordNotFound;
150 				//result = RtfParser2.errAssertion;
151 				if(debug && debugNotFound) {
152 					System.out.println("Keyword unknown:" +
153 						" New:" + ctrlWordData.ctrlWord +
154 						" Param:" + ctrlWordData.param +
155 						" bParam=" + ctrlWordData.hasParam);
156 				}
157 			}
158 		}
159 		return result;
160 	}
161 
162 
163     // listener methods
164 
165 	/**
166 	 * Adds a <CODE>RtfCtrlWordListener</CODE> to the <CODE>RtfCtrlWordMgr</CODE>.
167 	 *
168 	 * @param listener
169 	 *            the new RtfCtrlWordListener.
170 	 */
addRtfCtrlWordListener(RtfCtrlWordListener listener)171 	public void addRtfCtrlWordListener(RtfCtrlWordListener listener) {
172 		listeners.add(listener);
173 	}
174 
175 	/**
176 	 * Removes a <CODE>RtfCtrlWordListener</CODE> from the <CODE>RtfCtrlWordMgr</CODE>.
177 	 *
178 	 * @param listener
179 	 *            the RtfCtrlWordListener that has to be removed.
180 	 */
removeRtfCtrlWordListener(RtfCtrlWordListener listener)181 	public void removeRtfCtrlWordListener(RtfCtrlWordListener listener) {
182 		listeners.remove(listener);
183 	}
184 
beforeCtrlWord(RtfCtrlWordData ctrlWordData)185 	private boolean beforeCtrlWord(RtfCtrlWordData ctrlWordData) {
186 		RtfCtrlWordListener listener;
187 		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
188             listener = (RtfCtrlWordListener) iterator.next();
189             listener.beforeCtrlWord(ctrlWordData);
190         }
191 		return true;
192 	}
193 
onCtrlWord(RtfCtrlWordData ctrlWordData)194 	private boolean onCtrlWord(RtfCtrlWordData ctrlWordData) {
195 		RtfCtrlWordListener listener;
196 		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
197             listener = (RtfCtrlWordListener) iterator.next();
198             listener.onCtrlWord(ctrlWordData);
199         }
200 		return true;
201 	}
202 
afterCtrlWord(RtfCtrlWordData ctrlWordData)203 	private boolean afterCtrlWord(RtfCtrlWordData ctrlWordData) {
204 		RtfCtrlWordListener listener;
205 		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
206             listener = (RtfCtrlWordListener) iterator.next();
207             listener.afterCtrlWord(ctrlWordData);
208         }
209 		return true;
210 	}
211 }
212