package org.jcon.util.msg;

import org.jcon.util.GenLib;
import java.util.Enumeration;
import java.util.Hashtable;

/**
 * Translates Messages by changing message and/or property
 * names. Designed to allow a mediator to configure the
 * Message a MessageListener processes, so that message
 * sources and listeners are more reusable.
 *
 * @author Jack Harich
 */
public class MessageTranslator {

//---------- Private Fields ------------------------------
private Hashtable translations = new Hashtable();

//---------- Public Methods ------------------------------
/**
 * Adds a translation for a Message with name @param
 * messageName. If newMessageName is not null then
 * the message name will be translated to newMessageName.
 */
public void addTranslation(String messageName,
            String newMessageName) {
    translations.put(messageName, new Translation(messageName, newMessageName));
}
/**
 * Adds a property name change to a translation. The
 * translation must have been already added.
 */
public void addPropertyNameChange(String messageName,
        String oldName, String newName) {
    Translation trans = (Translation)translations.get(messageName);
    if (trans == null) {
        GenLib.error("MessageTranslator.addPropertyNameChange()",
            "Must first addTranslation() for messageName '" + messageName + "'.");
        return;
    }
    trans.addPropertyNameChange(oldName, newName);
}
/**
 * Translates the message to the desired message.
 */
public Message translate(Message message) {
    Translation trans = (Translation)translations.get(message.getName());
    if (trans == null) return message;
    // Create new message, set name
    Message newMessage = (Message)message.clone();
    newMessage.setName(trans.getNewMessageName());
    // Change property names needing translation
    Enumeration enum = trans.getPropertyNameChanges();
    while (enum.hasMoreElements()) {
        String oldName = (String)enum.nextElement();
        String newName = trans.getNewPropertyName(oldName);
        Object property = newMessage.removeKey(oldName);
        newMessage.set(newName, property);
    }
    return newMessage;
}

//---------- Private Methods -----------------------------
//--- Std
private static void print(String text) {
    System.out.println(text);
}
//========== Inner Classes ===============================
class Translation {

private String oldMessageName;
private String newMessageName;
private Hashtable changes = new Hashtable();

Translation(String oldMessageName, String newMessageName) {
    this.oldMessageName = oldMessageName;
    this.newMessageName = newMessageName;
}
void addPropertyNameChange(String oldName, String newName) {
    changes.put(oldName, newName);
}
String getNewMessageName() {
    return (newMessageName == null ? oldMessageName : newMessageName);
}
Enumeration getPropertyNameChanges() {
    return changes.keys();
}
String getNewPropertyName(String oldName) {
    String newName = (String)changes.get(oldName);
    return (newName == null ? oldName : newName);
}


} // End inner class


} // End outer class
