001: package dinamica.parser;
002:
003: import java.util.*;
004:
005: /**
006: * FastTemplateEngine<br>
007: * New fast parser engine, provides high performance
008: * template management. Instances of this class are serializable.
009: * <br><br>
010: * Creation date: 20/06/2004<br>
011: * (c) 2004 Martin Cordova y Asociados<br>
012: * http://www.martincordova.com/fck<br>
013: * @author Martin Cordova dinamica@martincordova.com
014: */
015: public class FastTemplateEngine implements java.io.Serializable {
016:
017: /**
018: *
019: */
020: private static final long serialVersionUID = 1L;
021:
022: /** holds markers and its data values */
023: private HashMap<String, String> markers = new HashMap<String, String>();
024:
025: /** holds static sections of the template */
026: private ArrayList<String> bodyParts = new ArrayList<String>();
027:
028: /** holds static sections of the template */
029: private ArrayList<String> dataParts = new ArrayList<String>();
030:
031: public FastTemplateEngine() {
032: }
033:
034: public FastTemplateEngine(String templateBody) throws Throwable {
035: setTemplate(templateBody);
036: }
037:
038: /**
039: * Set template body
040: * @param body A String that contains the template text
041: * @throws Throwable if body=null
042: */
043: public void setTemplate(String body) throws Throwable {
044:
045: if (body == null)
046: throw new Throwable(
047: "Invalid parameter [body]: cannot be null.");
048:
049: parse(body);
050:
051: }
052:
053: /**
054: * Set data value to be used to replace a certail marker
055: * defined in the template.
056: * @param key Marker name, must be in the form ${markerName}
057: * @param value Data value
058: * @throws Triggers exception if no template has been set with setTemplate()
059: * or if the key does not match any marker.
060: */
061: public void setValue(String key, String value) throws Throwable {
062: if (markers.containsKey(key))
063: markers.put(key, value);
064: else {
065: String logMsg = "Invalid template key: " + key;
066: throw new Throwable(logMsg);
067: }
068: }
069:
070: /**
071: * Parse template body to extract static parts
072: * and data markers; the template will be divided
073: * into several sections in order to assemble the page
074: * using a high performance technique.
075: * @param t Template body
076: * @throws Throwable
077: */
078: private void parse(String t) throws Throwable {
079:
080: int pos = 0;
081: int pos1 = 0;
082: int pos2 = 0;
083: int newPos = 0;
084: String str = "${fld:";
085:
086: /* search markers */
087: while (pos >= 0) {
088:
089: /* find start of marker */
090: pos1 = t.indexOf(str, pos);
091: if (pos1 >= 0) {
092:
093: /* find end of marker */
094: newPos = pos1 + str.length();
095: pos2 = t.indexOf("}", newPos);
096:
097: if (pos2 > 0) {
098: // get marker
099: String marker = t.substring(pos1, pos2 + 1);
100: markers.put(marker, marker);
101: dataParts.add(marker);
102:
103: // get body part before marker
104: String part = t.substring(pos, pos1);
105: bodyParts.add(part);
106: } else {
107: String logMsg = "Invalid template - marker not closed with '}'.";
108: throw new Throwable(logMsg);
109: }
110: pos = pos2 + 1;
111: } else {
112: // get final body part
113: String part = t.substring(pos);
114: bodyParts.add(part);
115: pos = -1;
116: }
117: }
118:
119: }
120:
121: /**
122: * Clear all markers data values, this is specially
123: * useful if you store Template objects in cache
124: * and need to reuse them with another set of data values.
125: */
126: public void resetValues() {
127: Set<String> keys = markers.keySet();
128: Object k[] = keys.toArray();
129: for (int i = 0; i < k.length; i++) {
130: markers.put((String) k[i], (String) k[i]);
131: }
132:
133: }
134:
135: /**
136: * Returns the content of the template with all the markers
137: * replaced by the corresponding value of by an empty string of
138: * no value was defined for a certain marker.
139: * @return Template body
140: */
141: public String toString() {
142:
143: StringBuilder sb = new StringBuilder();
144:
145: int markerCount = dataParts.size();
146: for (int i = 0; i < bodyParts.size(); i++) {
147: sb.append(bodyParts.get(i));
148: if (i < markerCount)
149: sb.append(markers.get(dataParts.get(i)));
150: }
151:
152: return sb.toString();
153:
154: }
155:
156: /**
157: * Returns a list of markers contained in a FastTemplate object
158: * @param prefix The type of marker (fld, lbl, def, inc, seq)
159: * @return ArrayList containing Marker objects
160: * @throws Throwable
161: */
162: public ArrayList<Marker> getMarkers() {
163:
164: String name = "";
165: String format = "";
166:
167: ArrayList<Marker> l = new ArrayList<Marker>();
168:
169: Object k[] = markers.keySet().toArray();
170: for (int i = 0; i < k.length; i++) {
171: String key = (String) k[i];
172: String prefix = key.substring(2, 5);
173:
174: int pos = key.indexOf("@");
175: if (pos > 0) {
176: name = key.substring(6, pos);
177: format = key.substring(pos + 1, key.length() - 1);
178: } else {
179: name = key.substring(6, key.length() - 1);
180: format = null;
181: }
182:
183: Marker m = new Marker(key, prefix, name, format);
184: l.add(m);
185:
186: }
187: return l;
188: }
189:
190: }
|