/* * Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com) * Licensed under the Apache License, Version 2.0 (the "License") * $Id: TriggerListEncoder.java 3918 2008-04-14 17:35:35Z gbevin $ */ package com.uwyn.rife.engine; import java.util.*; import com.uwyn.rife.tools.ArrayUtils; import com.uwyn.rife.tools.Base64; import com.uwyn.rife.tools.IntegerUtils; import com.uwyn.rife.tools.StringUtils; class TriggerListEncoder { private static final String SEP_DATAPART = "d\000"; private static final byte[] SEP_DATAPART_BYTES = SEP_DATAPART.getBytes(); private static final String SEP_DECLARATION_NAME = "x\000"; private static final byte[] SEP_DECLARATION_NAME_BYTES = SEP_DECLARATION_NAME.getBytes(); private static final String SEP_TRIGGER_NAME = "t\000"; private static final byte[] SEP_TRIGGER_NAME_BYTES = SEP_TRIGGER_NAME.getBytes(); private static final String SEP_PARAMETER_NAME = "n\000"; private static final byte[] SEP_PARAMETER_NAME_BYTES = SEP_PARAMETER_NAME.getBytes(); private static final String SEP_PARAMETER_NAMES = "s\000"; private static final byte[] SEP_PARAMETER_NAMES_BYTES = SEP_PARAMETER_NAMES.getBytes(); private static final String SEP_VALUE = "v\000"; private static final byte[] SEP_VALUE_BYTES = SEP_VALUE.getBytes(); private static final String SEP_VALUEARRAY = "a\000"; private static final byte[] SEP_VALUEARRAY_BYTES = SEP_VALUEARRAY.getBytes(); private static final String SEP_VALUEARRAYS = "y\000"; private static final byte[] SEP_VALUEARRAYS_BYTES = SEP_VALUEARRAYS.getBytes(); static String encode(List<TriggerContext> triggerList) { assert triggerList != null; if (0 == triggerList.size()) { return ""; } else { byte[] trigger_list = new byte[4+triggerList.size()*4]; Iterator<TriggerContext> trigger_it = null; TriggerContext trigger_context = null; byte[] hashcode_bytes = new byte[4]; int counter = 0; // store the number of elements that activated a child hashcode_bytes = IntegerUtils.intToBytes(triggerList.size()); trigger_list[counter++] = hashcode_bytes[0]; trigger_list[counter++] = hashcode_bytes[1]; trigger_list[counter++] = hashcode_bytes[2]; trigger_list[counter++] = hashcode_bytes[3]; // store the trigger type ids trigger_it = triggerList.iterator(); while (trigger_it.hasNext()) { trigger_context = trigger_it.next(); hashcode_bytes = IntegerUtils.intToBytes(trigger_context.getType()); trigger_list[counter++] = hashcode_bytes[0]; trigger_list[counter++] = hashcode_bytes[1]; trigger_list[counter++] = hashcode_bytes[2]; trigger_list[counter++] = hashcode_bytes[3]; } // store the element info xml filenames byte[] xmlfile_names_encoded = new byte[0]; trigger_it = triggerList.iterator(); while (trigger_it.hasNext()) { trigger_context = trigger_it.next(); xmlfile_names_encoded = ArrayUtils.join(xmlfile_names_encoded, (trigger_context.getDeclarationName()).getBytes()); // add seperator between element info xml filenames if (trigger_it.hasNext()) { xmlfile_names_encoded = ArrayUtils.join(xmlfile_names_encoded, SEP_DECLARATION_NAME_BYTES); } } // store the trigger names that were activated byte[] trigger_names_encoded = new byte[0]; trigger_it = triggerList.iterator(); while (trigger_it.hasNext()) { trigger_context = trigger_it.next(); trigger_names_encoded = ArrayUtils.join(trigger_names_encoded, (trigger_context.getTriggerName()).getBytes()); // add seperator between trigger names if (trigger_it.hasNext()) { trigger_names_encoded = ArrayUtils.join(trigger_names_encoded, SEP_TRIGGER_NAME_BYTES); } } // store the trigger values String[] trigger_values = null; byte[] trigger_values_encoded = new byte[0]; trigger_it = triggerList.iterator(); while (trigger_it.hasNext()) { trigger_context = trigger_it.next(); trigger_values = trigger_context.getTriggerValues(); // store the parameter values for (int i = 0; i < trigger_values.length; i++) { trigger_values_encoded = ArrayUtils.join(trigger_values_encoded, (trigger_values[i]).getBytes()); // add seperator between different values if (i < trigger_values.length-1) { trigger_list = ArrayUtils.join(trigger_list, SEP_VALUE_BYTES); } } // add seperator between different triggers if (trigger_it.hasNext()) { trigger_values_encoded = ArrayUtils.join(trigger_values_encoded, SEP_VALUEARRAY_BYTES); } } // process the parameter entries Set<Map.Entry<String, String[]>> parameter_entries = null; Iterator<Map.Entry<String, String[]>> parameter_entries_it = null; Map.Entry<String, String[]> parameter_entry = null; String[] parameter_values = null; byte[] parameter_names_encoded = new byte[0]; byte[] parameter_values_encoded = new byte[0]; trigger_it = triggerList.iterator(); while (trigger_it.hasNext()) { trigger_context = trigger_it.next(); parameter_entries = trigger_context.getParameters().entrySet(); parameter_entries_it = parameter_entries.iterator(); while (parameter_entries_it.hasNext()) { parameter_entry = parameter_entries_it.next(); // store the parameter name parameter_names_encoded = ArrayUtils.join(parameter_names_encoded, parameter_entry.getKey().getBytes()); parameter_values = parameter_entry.getValue(); // store the parameter values for (int i = 0; i < parameter_values.length; i++) { parameter_values_encoded = ArrayUtils.join(parameter_values_encoded, (parameter_values[i]).getBytes()); // add seperator between different values if (i < parameter_values.length-1) { trigger_list = ArrayUtils.join(trigger_list, SEP_VALUE_BYTES); } } // add seperator between different names and values if (parameter_entries_it.hasNext()) { parameter_names_encoded = ArrayUtils.join(parameter_names_encoded, SEP_PARAMETER_NAME_BYTES); parameter_values_encoded = ArrayUtils.join(parameter_values_encoded, SEP_VALUEARRAY_BYTES); } } // add seperator between different triggers if (trigger_it.hasNext()) { parameter_names_encoded = ArrayUtils.join(parameter_names_encoded, SEP_PARAMETER_NAMES_BYTES); parameter_values_encoded = ArrayUtils.join(parameter_values_encoded, SEP_VALUEARRAYS_BYTES); } } trigger_list = ArrayUtils.join(trigger_list, xmlfile_names_encoded); trigger_list = ArrayUtils.join(trigger_list, SEP_DATAPART_BYTES); trigger_list = ArrayUtils.join(trigger_list, trigger_names_encoded); trigger_list = ArrayUtils.join(trigger_list, SEP_DATAPART_BYTES); trigger_list = ArrayUtils.join(trigger_list, trigger_values_encoded); trigger_list = ArrayUtils.join(trigger_list, SEP_DATAPART_BYTES); trigger_list = ArrayUtils.join(trigger_list, parameter_names_encoded); trigger_list = ArrayUtils.join(trigger_list, SEP_DATAPART_BYTES); trigger_list = ArrayUtils.join(trigger_list, parameter_values_encoded); return Base64.encodeToString(trigger_list, false); } } static List<TriggerContext> decode(String[] triggerListValues) { if (triggerListValues != null && triggerListValues.length > 0 && triggerListValues[0] != null && triggerListValues[0].length() > 0) { TriggerContext[] trigger_list = null; byte[] hashcode_bytes = new byte[4]; byte[] decoded_bytes = null; decoded_bytes = Base64.decode(triggerListValues[0]); if (null == decoded_bytes) { return new ArrayList<TriggerContext>(); } // obtain the number of triggers System.arraycopy(decoded_bytes, 0, hashcode_bytes, 0, 4); int number_of_triggers = IntegerUtils.bytesToInt(hashcode_bytes); trigger_list = new TriggerContext[number_of_triggers]; // obtain the trigger type ids int triggers_types_offset = 4; for (int i = 0; i < number_of_triggers; i++) { System.arraycopy(decoded_bytes, triggers_types_offset+i*4, hashcode_bytes, 0, 4); trigger_list[i] = new TriggerContext(); trigger_list[i].setType(IntegerUtils.bytesToInt(hashcode_bytes)); } // obtain the data section int triggers_names_offset = 4+number_of_triggers*4; String triggers_data = new String(decoded_bytes, triggers_names_offset, decoded_bytes.length-triggers_names_offset); // split the data into five parts, a section with the element info xml filenames, // a section with the trigger names, a section with the trigger values, // a section with the parameter values and another section with the associated values List<String> triggers_data_parts = StringUtils.split(triggers_data, SEP_DATAPART); // obtain the element info xml filenames List<String> elementinfo_names = StringUtils.split(triggers_data_parts.get(0), SEP_DECLARATION_NAME); for (int i = 0; i < number_of_triggers; i++) { trigger_list[i].setDeclarationName(elementinfo_names.get(i)); } // obtain the trigger names List<String> triggers_names = StringUtils.split(triggers_data_parts.get(1), SEP_TRIGGER_NAME); for (int i = 0; i < number_of_triggers; i++) { trigger_list[i].setTriggerName(triggers_names.get(i)); } // obtains the trigger values List<String> trigger_values_list = StringUtils.split(triggers_data_parts.get(2), SEP_VALUEARRAY); List<String> trigger_values = null; String[] trigger_values_array = null; for (int i = 0; i < number_of_triggers; i++) { trigger_values = StringUtils.split(trigger_values_list.get(i), SEP_VALUE); trigger_values_array = new String[trigger_values.size()]; trigger_values_array = trigger_values.toArray(trigger_values_array); trigger_list[i].setTriggerValues(trigger_values_array); } // obtain the parameter names and their values List<String> parameter_names_list = StringUtils.split(triggers_data_parts.get(3), SEP_PARAMETER_NAMES); List<String> parameter_values_list = StringUtils.split(triggers_data_parts.get(4), SEP_VALUEARRAYS); List<String> parameter_names = null; List<String> parameter_valuearrays = null; List<String> parameter_values = null; String[] parameter_values_array = null; Map<String, String[]> parameters = null; for (int i = 0; i < number_of_triggers; i++) { parameters = new HashMap<String, String[]>(); if (parameter_names_list.get(i).length() > 0) { parameter_names = StringUtils.split(parameter_names_list.get(i), SEP_PARAMETER_NAME); parameter_valuearrays = StringUtils.split(parameter_values_list.get(i), SEP_VALUEARRAY); for (int j = 0; j < parameter_names.size(); j++) { parameter_values = StringUtils.split(parameter_valuearrays.get(j), SEP_VALUE); parameter_values_array = new String[parameter_values.size()]; parameter_values_array = parameter_values.toArray(parameter_values_array); parameters.put(parameter_names.get(j), parameter_values_array); } } trigger_list[i].setParameters(parameters); } return new ArrayList<TriggerContext>(Arrays.asList(trigger_list)); } else { return new ArrayList<TriggerContext>(); } } }