001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: TriggerListEncoder.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.engine;
009:
010: import java.util.*;
011:
012: import com.uwyn.rife.tools.ArrayUtils;
013: import com.uwyn.rife.tools.Base64;
014: import com.uwyn.rife.tools.IntegerUtils;
015: import com.uwyn.rife.tools.StringUtils;
016:
017: class TriggerListEncoder {
018: private static final String SEP_DATAPART = "d\000";
019: private static final byte[] SEP_DATAPART_BYTES = SEP_DATAPART
020: .getBytes();
021: private static final String SEP_DECLARATION_NAME = "x\000";
022: private static final byte[] SEP_DECLARATION_NAME_BYTES = SEP_DECLARATION_NAME
023: .getBytes();
024: private static final String SEP_TRIGGER_NAME = "t\000";
025: private static final byte[] SEP_TRIGGER_NAME_BYTES = SEP_TRIGGER_NAME
026: .getBytes();
027: private static final String SEP_PARAMETER_NAME = "n\000";
028: private static final byte[] SEP_PARAMETER_NAME_BYTES = SEP_PARAMETER_NAME
029: .getBytes();
030: private static final String SEP_PARAMETER_NAMES = "s\000";
031: private static final byte[] SEP_PARAMETER_NAMES_BYTES = SEP_PARAMETER_NAMES
032: .getBytes();
033: private static final String SEP_VALUE = "v\000";
034: private static final byte[] SEP_VALUE_BYTES = SEP_VALUE.getBytes();
035: private static final String SEP_VALUEARRAY = "a\000";
036: private static final byte[] SEP_VALUEARRAY_BYTES = SEP_VALUEARRAY
037: .getBytes();
038: private static final String SEP_VALUEARRAYS = "y\000";
039: private static final byte[] SEP_VALUEARRAYS_BYTES = SEP_VALUEARRAYS
040: .getBytes();
041:
042: static String encode(List<TriggerContext> triggerList) {
043: assert triggerList != null;
044:
045: if (0 == triggerList.size()) {
046: return "";
047: } else {
048: byte[] trigger_list = new byte[4 + triggerList.size() * 4];
049:
050: Iterator<TriggerContext> trigger_it = null;
051: TriggerContext trigger_context = null;
052: byte[] hashcode_bytes = new byte[4];
053: int counter = 0;
054:
055: // store the number of elements that activated a child
056: hashcode_bytes = IntegerUtils
057: .intToBytes(triggerList.size());
058: trigger_list[counter++] = hashcode_bytes[0];
059: trigger_list[counter++] = hashcode_bytes[1];
060: trigger_list[counter++] = hashcode_bytes[2];
061: trigger_list[counter++] = hashcode_bytes[3];
062:
063: // store the trigger type ids
064: trigger_it = triggerList.iterator();
065: while (trigger_it.hasNext()) {
066: trigger_context = trigger_it.next();
067: hashcode_bytes = IntegerUtils
068: .intToBytes(trigger_context.getType());
069: trigger_list[counter++] = hashcode_bytes[0];
070: trigger_list[counter++] = hashcode_bytes[1];
071: trigger_list[counter++] = hashcode_bytes[2];
072: trigger_list[counter++] = hashcode_bytes[3];
073: }
074:
075: // store the element info xml filenames
076: byte[] xmlfile_names_encoded = new byte[0];
077: trigger_it = triggerList.iterator();
078: while (trigger_it.hasNext()) {
079: trigger_context = trigger_it.next();
080: xmlfile_names_encoded = ArrayUtils.join(
081: xmlfile_names_encoded, (trigger_context
082: .getDeclarationName()).getBytes());
083: // add seperator between element info xml filenames
084: if (trigger_it.hasNext()) {
085: xmlfile_names_encoded = ArrayUtils.join(
086: xmlfile_names_encoded,
087: SEP_DECLARATION_NAME_BYTES);
088: }
089: }
090:
091: // store the trigger names that were activated
092: byte[] trigger_names_encoded = new byte[0];
093: trigger_it = triggerList.iterator();
094: while (trigger_it.hasNext()) {
095: trigger_context = trigger_it.next();
096: trigger_names_encoded = ArrayUtils.join(
097: trigger_names_encoded, (trigger_context
098: .getTriggerName()).getBytes());
099: // add seperator between trigger names
100: if (trigger_it.hasNext()) {
101: trigger_names_encoded = ArrayUtils.join(
102: trigger_names_encoded,
103: SEP_TRIGGER_NAME_BYTES);
104: }
105: }
106:
107: // store the trigger values
108: String[] trigger_values = null;
109: byte[] trigger_values_encoded = new byte[0];
110: trigger_it = triggerList.iterator();
111: while (trigger_it.hasNext()) {
112: trigger_context = trigger_it.next();
113: trigger_values = trigger_context.getTriggerValues();
114:
115: // store the parameter values
116: for (int i = 0; i < trigger_values.length; i++) {
117: trigger_values_encoded = ArrayUtils.join(
118: trigger_values_encoded, (trigger_values[i])
119: .getBytes());
120: // add seperator between different values
121: if (i < trigger_values.length - 1) {
122: trigger_list = ArrayUtils.join(trigger_list,
123: SEP_VALUE_BYTES);
124: }
125: }
126:
127: // add seperator between different triggers
128: if (trigger_it.hasNext()) {
129: trigger_values_encoded = ArrayUtils.join(
130: trigger_values_encoded,
131: SEP_VALUEARRAY_BYTES);
132: }
133: }
134:
135: // process the parameter entries
136: Set<Map.Entry<String, String[]>> parameter_entries = null;
137: Iterator<Map.Entry<String, String[]>> parameter_entries_it = null;
138: Map.Entry<String, String[]> parameter_entry = null;
139: String[] parameter_values = null;
140: byte[] parameter_names_encoded = new byte[0];
141: byte[] parameter_values_encoded = new byte[0];
142:
143: trigger_it = triggerList.iterator();
144: while (trigger_it.hasNext()) {
145: trigger_context = trigger_it.next();
146: parameter_entries = trigger_context.getParameters()
147: .entrySet();
148: parameter_entries_it = parameter_entries.iterator();
149: while (parameter_entries_it.hasNext()) {
150: parameter_entry = parameter_entries_it.next();
151:
152: // store the parameter name
153: parameter_names_encoded = ArrayUtils.join(
154: parameter_names_encoded, parameter_entry
155: .getKey().getBytes());
156: parameter_values = parameter_entry.getValue();
157: // store the parameter values
158: for (int i = 0; i < parameter_values.length; i++) {
159: parameter_values_encoded = ArrayUtils.join(
160: parameter_values_encoded,
161: (parameter_values[i]).getBytes());
162: // add seperator between different values
163: if (i < parameter_values.length - 1) {
164: trigger_list = ArrayUtils.join(
165: trigger_list, SEP_VALUE_BYTES);
166: }
167: }
168:
169: // add seperator between different names and values
170: if (parameter_entries_it.hasNext()) {
171: parameter_names_encoded = ArrayUtils.join(
172: parameter_names_encoded,
173: SEP_PARAMETER_NAME_BYTES);
174: parameter_values_encoded = ArrayUtils.join(
175: parameter_values_encoded,
176: SEP_VALUEARRAY_BYTES);
177: }
178: }
179:
180: // add seperator between different triggers
181: if (trigger_it.hasNext()) {
182: parameter_names_encoded = ArrayUtils.join(
183: parameter_names_encoded,
184: SEP_PARAMETER_NAMES_BYTES);
185: parameter_values_encoded = ArrayUtils.join(
186: parameter_values_encoded,
187: SEP_VALUEARRAYS_BYTES);
188: }
189: }
190:
191: trigger_list = ArrayUtils.join(trigger_list,
192: xmlfile_names_encoded);
193: trigger_list = ArrayUtils.join(trigger_list,
194: SEP_DATAPART_BYTES);
195: trigger_list = ArrayUtils.join(trigger_list,
196: trigger_names_encoded);
197: trigger_list = ArrayUtils.join(trigger_list,
198: SEP_DATAPART_BYTES);
199: trigger_list = ArrayUtils.join(trigger_list,
200: trigger_values_encoded);
201: trigger_list = ArrayUtils.join(trigger_list,
202: SEP_DATAPART_BYTES);
203: trigger_list = ArrayUtils.join(trigger_list,
204: parameter_names_encoded);
205: trigger_list = ArrayUtils.join(trigger_list,
206: SEP_DATAPART_BYTES);
207: trigger_list = ArrayUtils.join(trigger_list,
208: parameter_values_encoded);
209:
210: return Base64.encodeToString(trigger_list, false);
211: }
212: }
213:
214: static List<TriggerContext> decode(String[] triggerListValues) {
215: if (triggerListValues != null && triggerListValues.length > 0
216: && triggerListValues[0] != null
217: && triggerListValues[0].length() > 0) {
218: TriggerContext[] trigger_list = null;
219: byte[] hashcode_bytes = new byte[4];
220: byte[] decoded_bytes = null;
221:
222: decoded_bytes = Base64.decode(triggerListValues[0]);
223: if (null == decoded_bytes) {
224: return new ArrayList<TriggerContext>();
225: }
226:
227: // obtain the number of triggers
228: System.arraycopy(decoded_bytes, 0, hashcode_bytes, 0, 4);
229: int number_of_triggers = IntegerUtils
230: .bytesToInt(hashcode_bytes);
231: trigger_list = new TriggerContext[number_of_triggers];
232:
233: // obtain the trigger type ids
234: int triggers_types_offset = 4;
235: for (int i = 0; i < number_of_triggers; i++) {
236: System.arraycopy(decoded_bytes, triggers_types_offset
237: + i * 4, hashcode_bytes, 0, 4);
238: trigger_list[i] = new TriggerContext();
239: trigger_list[i].setType(IntegerUtils
240: .bytesToInt(hashcode_bytes));
241: }
242:
243: // obtain the data section
244: int triggers_names_offset = 4 + number_of_triggers * 4;
245: String triggers_data = new String(decoded_bytes,
246: triggers_names_offset, decoded_bytes.length
247: - triggers_names_offset);
248:
249: // split the data into five parts, a section with the element info xml filenames,
250: // a section with the trigger names, a section with the trigger values,
251: // a section with the parameter values and another section with the associated values
252: List<String> triggers_data_parts = StringUtils.split(
253: triggers_data, SEP_DATAPART);
254:
255: // obtain the element info xml filenames
256: List<String> elementinfo_names = StringUtils.split(
257: triggers_data_parts.get(0), SEP_DECLARATION_NAME);
258: for (int i = 0; i < number_of_triggers; i++) {
259: trigger_list[i].setDeclarationName(elementinfo_names
260: .get(i));
261: }
262:
263: // obtain the trigger names
264: List<String> triggers_names = StringUtils.split(
265: triggers_data_parts.get(1), SEP_TRIGGER_NAME);
266: for (int i = 0; i < number_of_triggers; i++) {
267: trigger_list[i].setTriggerName(triggers_names.get(i));
268: }
269:
270: // obtains the trigger values
271: List<String> trigger_values_list = StringUtils.split(
272: triggers_data_parts.get(2), SEP_VALUEARRAY);
273: List<String> trigger_values = null;
274: String[] trigger_values_array = null;
275: for (int i = 0; i < number_of_triggers; i++) {
276: trigger_values = StringUtils.split(trigger_values_list
277: .get(i), SEP_VALUE);
278: trigger_values_array = new String[trigger_values.size()];
279: trigger_values_array = trigger_values
280: .toArray(trigger_values_array);
281: trigger_list[i].setTriggerValues(trigger_values_array);
282: }
283:
284: // obtain the parameter names and their values
285: List<String> parameter_names_list = StringUtils.split(
286: triggers_data_parts.get(3), SEP_PARAMETER_NAMES);
287: List<String> parameter_values_list = StringUtils.split(
288: triggers_data_parts.get(4), SEP_VALUEARRAYS);
289: List<String> parameter_names = null;
290: List<String> parameter_valuearrays = null;
291: List<String> parameter_values = null;
292: String[] parameter_values_array = null;
293: Map<String, String[]> parameters = null;
294: for (int i = 0; i < number_of_triggers; i++) {
295: parameters = new HashMap<String, String[]>();
296:
297: if (parameter_names_list.get(i).length() > 0) {
298: parameter_names = StringUtils.split(
299: parameter_names_list.get(i),
300: SEP_PARAMETER_NAME);
301: parameter_valuearrays = StringUtils.split(
302: parameter_values_list.get(i),
303: SEP_VALUEARRAY);
304: for (int j = 0; j < parameter_names.size(); j++) {
305: parameter_values = StringUtils
306: .split(parameter_valuearrays.get(j),
307: SEP_VALUE);
308: parameter_values_array = new String[parameter_values
309: .size()];
310: parameter_values_array = parameter_values
311: .toArray(parameter_values_array);
312: parameters.put(parameter_names.get(j),
313: parameter_values_array);
314: }
315: }
316:
317: trigger_list[i].setParameters(parameters);
318: }
319:
320: return new ArrayList<TriggerContext>(Arrays
321: .asList(trigger_list));
322: } else {
323: return new ArrayList<TriggerContext>();
324: }
325: }
326: }
|