001: /*
002: * JDynamiTe - Dynamic Template in Java
003: * Copyright (C) 2001 Christophe Bouleau
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package cb.jdynamite.analyser;
021:
022: import java.io.*;
023: import gnu.regexp.*;
024: import cb.jdynamite.*;
025:
026: /**
027: * This class analyses the input template document and builds the JDynamiTe document structure,
028: * which is made up of "ITemplateElements".<br>
029: * A JDynamiTe document is structurally a tree where the nodes are "DynamicElement" objects,
030: * and where the leaves are the other objects.<br>
031: * An analyser is attached to an "ITemplateDocument" (JDynamiTe object),
032: * which is the "root" Dynamic Element of the tree.
033: *
034: * @see cb.jdynamite.JDynamiTe
035: */
036: public class DefaultAnalyser implements ITemplateAnalyser {
037: private ITemplateDocument rootDoc;
038: private BufferedReader input;
039: private RE varRegExp;
040: private RE dynBeginRegExp;
041: private RE dynEndRegExp;
042: private RE ignBeginRegExp;
043: private RE ignEndRegExp;
044: private boolean debug = false;
045:
046: /**
047: HTML default "Variable" tag.
048: This is the regular expression for a word (within brackets) made up of alplanumeric (and '.', '_', ':', '-') character(s).
049: Examples : "Table2.name" or "page-title".<br>
050: "[\w._:-]+" is the regular expression for a word made up of alplanumeric (and '.', '_', ':', '-') character(s).
051: <br>Important: the variable name (the key) is this word wich matches the first "regexp" subexpression.
052: That's why this word should be enclosed within brackets.
053: <br>See GNU regexp package documentation for more details on regular expressions.
054: */
055: public static String HTML_VARIABLE_TAG = "\\{([\\w._:-]+)\\}";
056: /**
057: HTML default "Begin Dynamic Element" tag.
058: This regular expression is : <pre>
059: "<!-- *BEGIN *DYNAMIC.*: *([\w._:-]+) *-->".
060: </pre>For example:<pre>
061: "<-- BEGIN DYNAMIC : myList -->".
062: </pre>or<pre>
063: "<-- BEGIN DYNAMIC BLOCK: myList -->".
064: </pre>Important: the element name is this word wich matches the first "regexp" subexpression.
065: That's why this word should be enclosed within brackets.
066: <br>See GNU regexp package documentation.
067: */
068: public static String HTML_BEGIN_DYNAMIC_TAG = "<!-- *BEGIN *DYNAMIC.*: *([\\w._:-]+) *-->";
069: /**
070: HTML default "End Dynamic Element" tag.
071: This regular expression is : <pre>
072: "<-- *END *DYNAMIC.*-->".
073: </pre>For example:<pre>
074: "<-- END DYNAMIC : myList -->".
075: </pre>or<pre>
076: "<-- END DYNAMIC BLOCK: myList -->".
077: </pre>See GNU regexp package documentation.
078: */
079: public static String HTML_END_DYNAMIC_TAG = "<!-- *END *DYNAMIC.*-->";
080: /**
081: * HTML default "Begin Ignored Element" tag.
082: * This regular expression is : <pre>
083: * "<!-- *BEGIN *IGNORED.*: *([\w._:-]+) *-->".
084: * </pre>For example:<pre>
085: * "<-- BEGIN IGNORED : myLinesExample -->".
086: * </pre>See GNU regexp package documentation.
087: *
088: * @since JDynamiTe 1.1
089: */
090: public static String HTML_BEGIN_IGNORED_TAG = "<!-- *BEGIN *IGNORED.*: *([\\w._:-]+) *-->";
091: /**
092: * HTML default "End Ignored Element" tag.
093: * This regular expression is : <pre>
094: * "<-- *END *IGNORED.*-->".
095: * </pre>For example:<pre>
096: * "<-- END IGNORED : myList -->".
097: * </pre>See GNU regexp package documentation.
098: *
099: * @since JDynamiTe 1.1
100: */
101: public static String HTML_END_IGNORED_TAG = "<!-- *END *IGNORED.*-->";
102:
103: public static String XML_VARIABLE_TAG = "\\{([\\w._:-]+)\\}";
104: public static String XML_BEGIN_DYNAMIC_TAG = "<!-- *BEGIN *DYNAMIC.*: *([\\w._:-]+) *-->";
105: public static String XML_END_DYNAMIC_TAG = "<!-- *END *DYNAMIC.*-->";
106: public static String SCRIPT_VARIABLE_TAG = "\\$([\\w._:-]+)";
107: public static String SCRIPT_BEGIN_DYNAMIC_TAG = "#+ *BEGIN *DYNAMIC.*: *([\\w._:-]+) *";
108: public static String SCRIPT_END_DYNAMIC_TAG = "#+ *END *DYNAMIC.*";
109:
110: public void DefaultAnalyser() {
111: }
112:
113: public void analyse(ITemplateDocument rootDocument,
114: IDynamicElement rootElem, BufferedReader inputText)
115: throws IOException {
116: rootDoc = rootDocument;
117: input = inputText;
118: initRegExp();
119: doAnalyse(rootElem, 0);
120: }
121:
122: public RE getVariableRegExp() {
123: return varRegExp;
124: }
125:
126: public void setVariableRegExp(String variableRegExp)
127: throws REException {
128: varRegExp = new RE(variableRegExp);
129: }
130:
131: public RE getDynamicBeginRegExp() {
132: return dynBeginRegExp;
133: }
134:
135: public void setDynamicBeginRegExp(String dynamicBeginRegExp)
136: throws REException {
137: dynBeginRegExp = new RE(dynamicBeginRegExp);
138: }
139:
140: public RE getDynamicEndRegExp() {
141: return dynEndRegExp;
142: }
143:
144: public void setDynamicEndRegExp(String dynamicEndRegExp)
145: throws REException {
146: dynEndRegExp = new RE(dynamicEndRegExp);
147: }
148:
149: public RE getIgnoredBeginRegExp() {
150: return ignBeginRegExp;
151: }
152:
153: public void setIgnoredBeginRegExp(String ignoredBeginRegExp)
154: throws REException {
155: ignBeginRegExp = new RE(ignoredBeginRegExp);
156: }
157:
158: public RE getIgnoredEndRegExp() {
159: return ignEndRegExp;
160: }
161:
162: public void setIgnoredEndRegExp(String ignoredEndRegExp)
163: throws REException {
164: ignEndRegExp = new RE(ignoredEndRegExp);
165: }
166:
167: public boolean getDebug() {
168: return debug;
169: }
170:
171: public void setDebug(boolean debugMode) {
172: debug = debugMode;
173: }
174:
175: private void initRegExp() {
176: varRegExp = null;
177: dynBeginRegExp = null;
178: dynEndRegExp = null;
179: ignBeginRegExp = null;
180: ignEndRegExp = null;
181: try {
182: setVariableRegExp(DefaultAnalyser.HTML_VARIABLE_TAG);
183: setDynamicBeginRegExp(DefaultAnalyser.HTML_BEGIN_DYNAMIC_TAG);
184: setDynamicEndRegExp(DefaultAnalyser.HTML_END_DYNAMIC_TAG);
185: setIgnoredBeginRegExp(DefaultAnalyser.HTML_BEGIN_IGNORED_TAG);
186: setIgnoredEndRegExp(DefaultAnalyser.HTML_END_IGNORED_TAG);
187: } catch (REException e) {
188: e.printStackTrace();
189: }
190: }
191:
192: private void addMixed(IDynamicElement dynElem, StringBuffer content) {
193: REMatchEnumeration matchEnum = varRegExp
194: .getMatchEnumeration(content);
195: int constantStart = 0;
196: int endMatch;
197: while (matchEnum.hasMoreElements()) {
198: REMatch match = matchEnum.nextMatch();
199: if (constantStart < match.getStartIndex()) {
200: ConstantElement constElem = new ConstantElement(
201: content.substring(constantStart, match
202: .getStartIndex()));
203: dynElem.addElement(constElem);
204: }
205: constantStart = match.getEndIndex();
206: // Important: the variable name (the key) is this word wich matches the first
207: // "regexp" subexpression. That's why this word should be enclosed within brackets in varRegExp.
208: String key = match.toString(1);
209: // Equivalent : match.substituteInto("$1");
210: if (key == null) {
211: System.err
212: .println("Can not get Variable element name from this string: "
213: + match.toString());
214: key = "___Undefined Name___";
215: }
216: VariableElement varElem = new VariableElement(key);
217: dynElem.addElement(varElem);
218: // Add this variable to the root document hashtable
219: rootDoc.setVariable(key, "");
220: }
221: if (constantStart < content.length()) {
222: ConstantElement constElem = new ConstantElement(content
223: .substring(constantStart));
224: dynElem.addElement(constElem);
225: }
226:
227: content.delete(0, content.length());
228: /***
229: if (content.length() != 0) {
230: MixedElement mixedElem = new MixedElement(content.toString());
231: dynElem.addElement(mixedElem);
232: }
233: ***/
234: }
235:
236: /*
237: private String getDynamicElementNameFromString(String line) {
238: int startIndex = line.lastIndexOf(':');
239: if (startIndex != -1) {
240: int lastIndex = line.lastIndexOf("-->");
241: if (lastIndex != -1) {
242: return (line.substring(startIndex + 1, lastIndex)).trim();
243: }
244: }
245: System.err.println("Can not get element name from this line: " + line);
246: return "___Undefined Name___";
247: }
248: */
249:
250: protected void doAnalyse(IDynamicElement dynElem, int depth) {
251: StringBuffer mixed = new StringBuffer();
252: boolean inIgnoredElement = false;
253: boolean theEnd = false;
254: while (!theEnd) {
255: String line = null;
256: try {
257: line = input.readLine();
258: } catch (IOException e) {
259: System.err.println(e.getMessage());
260: break;
261: }
262: if (line == null) {
263: addMixed(dynElem, mixed);
264: break;
265: }
266: REMatch match;
267: if (inIgnoredElement) {
268: match = ignEndRegExp.getMatch(line);
269: if (match != null) {
270: // end of an ignored element
271: inIgnoredElement = false;
272: if (debug) {
273: System.err.println("<<End Ignore\n");
274: }
275: } else if (debug) {
276: System.err.println("ignore[" + line + "]\n");
277: }
278: continue;
279: }
280: match = dynBeginRegExp.getMatch(line);
281: if (match != null) {
282: // begin of a dynamic element.
283: // first add the current mixed element
284: addMixed(dynElem, mixed);
285: // then build a new dynamic element
286: String name = match.toString(1); // first subexpression
287: if (name == null) {
288: System.err
289: .println("Can not get dynamic element name from this line: "
290: + line);
291: name = "___Undefined Name___";
292: }
293: DefaultDynamicElement newDyn = new DefaultDynamicElement(
294: name);
295: dynElem.addElement(newDyn);
296: rootDoc.recordDynElem(name, newDyn); // record it in ITemplateDocument root document
297: doAnalyse(newDyn, depth + 1); // recursively analyse this new bloc
298: } else {
299: match = dynEndRegExp.getMatch(line);
300: if (match != null) {
301: // end of the dynamic element
302: addMixed(dynElem, mixed);
303: theEnd = true;
304: } else {
305: match = ignBeginRegExp.getMatch(line);
306: if (match != null) {
307: // begin of an ignored element
308: inIgnoredElement = true;
309: if (debug) {
310: System.err.println("Begin Ignore>>\n");
311: }
312: } else {
313: // just a line in the dynamic element
314: mixed.append(line + '\n');
315: }
316: }
317: }
318: }
319: }
320: }
|