MutableMessageElement.java :  » Chat » jYMSG » ymsg » support » Java Open Source

Java Open Source » Chat » jYMSG 
jYMSG » ymsg » support » MutableMessageElement.java
package ymsg.support;

import java.awt.Color;
import java.awt.Font;
import java.util.*;

// *********************************************************************
// A message element structure which can be manipulated to form a
// structure than can ultimately be expressed as a Yahoo message.
//
// FIX: Yahoo appears to be in the process of changing over its escape
// based encoding scheme to something a little like SGML tags.  So far
// examples of the new scheme have only been seen on chatrooms.  At some
// point this class should be modified to allow the switching between
// 'old' and 'new' encoding styles...
//
//      PURPOSE              OLD               NEW
//    +--------------------+-----------------+-----------------+
//    | Bold               | [esc]1m         | <b>             |
//    | Italic             | [esc]2m         | <i>             |
//    | Colour (enum)      | [esc]3?m        | <col_name>      |
//    | Colour (abs)       | [esc]3#rrggbbm  | <#rrggbb>       |
//    | Font               |                 | <font ... >     |
//    | Fade               |                 | <fade ... >     |
//    | Alt                |                 | <alt ... >      |
//    +--------------------+-----------------+-----------------+
//
// Note: Yahoo's colour escape codes do not work as containers - that is
// to say they do not have a close 'code' which undoes their effect.
// For as long as Yahoo uses escape codes rather than proper SGML-style
// containers (<abc>...</abc>) this code offers overloaded methods to
// 'fake' containers via a stack of colours, so that 'pseudo' end codes
// can be added by simply repeating the colour code above the 'closing'
// element in the stack.
// *********************************************************************
public class MutableMessageElement extends MessageElement implements java.util.List
{  private static IllegalStateException wrongType;  // Accessors may throw this
  private static String esc;
  private static String boldOn,boldOff;      // Bold esc sequences
  private static String italicOn,italicOff;    // Italic esc sequences
  private static String underlineOn,underlineOff;  // Underline esc sequences

  protected int idxColour;
  protected String namedColour;
  private boolean container=true;          // Element can hold children?

  // -----------------------------------------------------------------
  // CONSTRUCTOR - accessable only from static factory methods
  // -----------------------------------------------------------------
  private MutableMessageElement(int t) { super(null,t); }
  private MutableMessageElement(int t,boolean c) { this(t);  container=c; }

  /*private void _initOld()
  {  boldOn = esc+"1m";  boldOff=esc+"x1m";
    italicOn=esc+"2m";  italicOff=esc+"x2m";
    underlineOn=esc+"4m";  underlineOff=esc+"x4m";
  }
  private void _initNew()
  {  boldOn="<b>";  boldOff="</b>";
    italicOn="<i>";  italicOff="</i>";
    underlineOn="<u>";  underlineOff="</u>";
  }*/

  // -----------------------------------------------------------------
  // STATIC CONSTRUCTOR
  // -----------------------------------------------------------------
  static
  {  wrongType = new IllegalStateException("Incorrect element type for operation");

    esc = MessageDecoder.ESC_SEQ;
    boldOn = esc+"1m";  boldOff=esc+"x1m";
    italicOn=esc+"2m";  italicOff=esc+"x2m";
    underlineOn=esc+"4m";  underlineOff=esc+"x4m";
  }

  // -----------------------------------------------------------------
  // Static factory type methods to create new types.  Many types are
  // containers, but some are not (either because they are leaves by
  // their very nature, like TEXT, or the Yahoo protocol doesn't appear
  // to support a closing tag for them.)
  // -----------------------------------------------------------------
  public static MutableMessageElement createRoot()
  {  return new MutableMessageElement(ROOT);
  }

  public static MutableMessageElement createText(String text)
  {  MutableMessageElement mme = new MutableMessageElement(TEXT,false);
    mme.setText(text);  return mme;
  }

  public static MutableMessageElement createBold()
  {  return new MutableMessageElement(BOLD);
  }

  public static MutableMessageElement createItalic()
  {  return new MutableMessageElement(ITALIC);
  }

  public static MutableMessageElement createIndexedColour(int idx)
  {  MutableMessageElement mme = new MutableMessageElement(COLOUR_INDEX,false);
    mme.setIndexedColour(idx);  return mme;
  }

  public static MutableMessageElement createNamedColour(String n)
  {  MutableMessageElement mme = new MutableMessageElement(COLOUR_NAME,false);
    mme.setNamedColour(n);  return mme;
  }

  public static MutableMessageElement createAbsoluteColour(Color c)
  {  MutableMessageElement mme = new MutableMessageElement(COLOUR_ABS,false);
    mme.setAbsoluteColour(c);  return mme;
  }

  public static MutableMessageElement createUnderline()
  {  return new MutableMessageElement(UNDERLINE);
  }

  /*public static MutableMessageElement createFont(String face,int size)
  {  MutableMessageElement mme = new MutableMessageElement(FONT);
    mme.setFont(face,size);  return mme;
  }*/

  public static MutableMessageElement createFont(Font f)
  {  MutableMessageElement mme = new MutableMessageElement(FONT);
    mme.setFont(f);  return mme;
  }

  public static MutableMessageElement createFade(Color[] c)
  {  MutableMessageElement mme = new MutableMessageElement(FADE);
    mme.setTransition(c);  return mme;
  }

  public static MutableMessageElement createAlt(Color[] c)
  {  MutableMessageElement mme = new MutableMessageElement(ALT);
    mme.setTransition(c);  return mme;
  }


  // -----------------------------------------------------------------
  // Accessors
  // -----------------------------------------------------------------
  public int getType() { return type; }

  public String getText() throws IllegalStateException
  {  _checkType(TEXT);  return text;
  }
  public void setText(String t) throws IllegalStateException
  {  _checkType(TEXT);  text=t;
  }

  public int getIndexedColour() throws IllegalStateException
  {  _checkType(COLOUR_INDEX);  return idxColour;
  }
  public void setIndexedColour(int i) throws IllegalStateException
  {  _checkType(COLOUR_INDEX);  idxColour=i;  colour=COLOUR_OBJECTS[i];
  }

  public String getNamedColour() throws IllegalStateException
  {  _checkType(COLOUR_NAME);  return namedColour;
  }
  public void setNamedColour(String n) throws IllegalStateException
  {  _checkType(COLOUR_NAME);  namedColour=n;
    colour=COLOUR_OBJECTS[MessageElement.whichColourName(n)];
  }

  public Color getAbsoluteColour() throws IllegalStateException
  {  _checkType(COLOUR_ABS);  return colour;
  }
  public void setAbsoluteColour(Color c) throws IllegalStateException
  {  _checkType(COLOUR_ABS);  colour=c;
  }

  public Font getFont() throws IllegalStateException
  {  _checkType(FONT);  return new Font(fontFace,Font.PLAIN,fontSize);
  }
  public void setFont(Font f) throws IllegalStateException
  {  _checkType(FONT);  fontFace=f.getFamily();  fontSize=f.getSize();
  }
  /*public void setFont(String f,int sz) throws IllegalStateException
  {  _checkType(FONT);  fontFace=f;  fontSize=sz;
  }*/

  public Color[] getTransition() throws IllegalStateException
  {  if(type!=FADE && type!=ALT)  throw wrongType;
    return transition;
  }
  public void setTransition(Color[] c)  throws IllegalStateException
  {  if(type!=FADE && type!=ALT)  throw wrongType;
    transition=c;
  }

  private void _checkType(int t) throws IllegalStateException
  {  if(type!=t)  throw wrongType;
  }


  // -----------------------------------------------------------------
  // List interface methods all defer to the child array.  (I wish there
  // was an easier way to do this - making MessageElement subclass one of
  // the Collection classes would work, but then MessageElement would be
  // mutable, which I'd like to avoid.)
  // -----------------------------------------------------------------
  public void add(int index,Object element) { children.add(index,element); }
  public boolean add(Object o) { return children.add(o); }
  public boolean addAll(Collection c) { return children.addAll(c); }
  public boolean addAll(int index,Collection c) { return children.addAll(index,c); }
  public void clear() { children.clear(); }
  public boolean contains(Object o) { return children.contains(o); }
  public boolean containsAll(Collection c) { return children.containsAll(c); }
  public boolean equals(Object o) { return children.equals(o); }
  public Object get(int index) { return children.get(index); }
  public int hashCode() { return children.hashCode(); }
  public int indexOf(Object o) { return children.indexOf(o); }
  public boolean isEmpty() { return children.isEmpty(); }
  public Iterator iterator() { return children.iterator(); }
  public int lastIndexOf(Object o) { return children.lastIndexOf(o); }
  public ListIterator listIterator() { return children.listIterator(); }
  public ListIterator listIterator(int index) { return children.listIterator(index); }
  public Object remove(int index) { return children.remove(index); }
  public boolean remove(Object o) { return children.remove(o); }
  public boolean removeAll(Collection c) { return children.removeAll(c); }
  public boolean retainAll(Collection c) { return children.retainAll(c); }
  public Object set(int index,Object element) { return children.set(index,element); }
  public int size() { return children.size(); }
  public List subList(int fromIndex,int toIndex) { return children.subList(fromIndex,toIndex); }
  public Object[] toArray() { return children.toArray(); }
  public Object[] toArray(Object[] a) { return children.toArray(a); }


  // -----------------------------------------------------------------
  // Translate to Yahoo instant messenger format
  // -----------------------------------------------------------------
  public String toYahooIM()
  {  return toYahooIM(false);
  }
  public String toYahooIM(boolean fc)
  {  StringBuffer sb = new StringBuffer();
    Stack colStack = fc ? new Stack() : null;
    toYahooIM(sb,colStack);
    return sb.toString();
  }

  private void toYahooIM(StringBuffer sb,Stack colStack)
  {  switch(type)
    {  case NULL :      break;
      case TEXT :      sb.append(text);  break;
      case BOLD :      sb.append(boldOn);  break;
      case ITALIC :    sb.append(italicOn);  break;
      case COLOUR_INDEX :  sb.append(_colIdx1(idxColour,colStack));  break;
      case COLOUR_ABS :  break;  // Not supported by IM ?
      case COLOUR_NAME :  break;  // Not supported by IM ?
      case UNDERLINE :  sb.append(underlineOn);  break;
      case FONT :      sb.append("<font face=\""+fontFace+"\" size=\""+fontSize+"\">");  break;
      case FADE :      break;  // Not supported by IM ?
      case ALT :      break;  // Not supported by IM ?
    }
    for(int i=0;i<children.size();i++)
    {  MutableMessageElement el = (MutableMessageElement)children.elementAt(i);
      el.toYahooIM(sb,colStack);
    }
    switch(type)
    {  case NULL :      break;
      case BOLD :      sb.append(boldOff);  break;
      case ITALIC :    sb.append(italicOff);  break;
      case COLOUR_INDEX :  if(colStack!=null)  sb.append(_colPop(colStack));  break;
      case COLOUR_ABS :  break;  // Not supported by IM ?
      case COLOUR_NAME :  break;  // Not supported by IM ?
      case UNDERLINE :  sb.append(underlineOff);  break;
      case FONT :      sb.append("</font>");  break;
      case FADE :      break;  // Not supported by IM ?
      case ALT :      break;  // Not supported by IM ?
    }
  }

  // -----------------------------------------------------------------
  // Translate to Yahoo chat format
  // -----------------------------------------------------------------
  public String toYahooChat()
  {  return toYahooChat(false);
  }
  public String toYahooChat(boolean fc)
  {  StringBuffer sb = new StringBuffer();
    Stack colStack = fc ? new Stack() : null;
    toYahooChat(sb,colStack);
    return sb.toString();
  }

  private void toYahooChat(StringBuffer sb,Stack colStack)
  {  switch(type)
    {  case NULL :      break;
      case TEXT :      sb.append(text);  break;
      case BOLD :      sb.append(boldOn);  break;
      case ITALIC :    sb.append(italicOn);  break;
      case COLOUR_INDEX :  sb.append(_colIdx1(idxColour,colStack));  break;
      case COLOUR_ABS :  sb.append(_colAbs1(colour,colStack));  break;
      case COLOUR_NAME :  sb.append("<"+namedColour+">");  break;
      case UNDERLINE :  sb.append(underlineOn);  break;
      case FONT :      sb.append("<font face=\""+fontFace+"\" size=\""+fontSize+"\">");  break;
      case FADE :      sb.append("<fade "+_toTransition(transition)+">");  break;
      case ALT :      sb.append("<alt "+_toTransition(transition)+">");  break;
    }
    for(int i=0;i<children.size();i++)
    {  MutableMessageElement el = (MutableMessageElement)children.elementAt(i);
      el.toYahooChat(sb,colStack);
    }
    switch(type)
    {  case NULL :      break;
      case BOLD :      sb.append(boldOff);  break;
      case ITALIC :    sb.append(italicOff);  break;
      case COLOUR_INDEX :  if(colStack!=null)  sb.append(_colPop(colStack));  break;
      case COLOUR_ABS :  if(colStack!=null)  sb.append(_colPop(colStack));  break;
      case COLOUR_NAME :  sb.append("</"+namedColour+">");  break;
      case UNDERLINE :  sb.append(underlineOff);  break;
      case FONT :      sb.append("</font>");  break;
      case FADE :      sb.append("</fade>");  break;
      case ALT :      sb.append("</alt>");  break;
    }
  }

  private String _colIdx1(int idxColour,Stack colStack)
  {  String tmp = esc+"3"+(char)('0'+idxColour)+"m";
    if(colStack!=null)  colStack.push(tmp);
    return tmp;
  }
  private String _colAbs1(Color colour,Stack colStack)
  {  String tmp = esc+"3#"+_to6HexDigits(colour)+"m";
    if(colStack!=null)  colStack.push(tmp);
    return tmp;
  }
  private String _colPop(Stack colStack)
  {  colStack.pop();    // Pop ourselves from stack
    if(!colStack.empty())  return  (String)colStack.peek();
      else  return "";
  }

  // -----------------------------------------------------------------
  // Utility methods
  // -----------------------------------------------------------------
  private String _to6HexDigits(Color c)
  {  StringBuffer sb = new StringBuffer( Integer.toString((c.getRGB()&0xffffff),16) );
    while(sb.length()<6)  sb.insert(0,'0');
    return new String(sb);
  }

  private String _toTransition(Color[] c)
  {  StringBuffer sb = new StringBuffer();
    for(int i=0;i<c.length;i++)
    {  if(i!=0)  sb.append(',');
      sb.append('#').append( _to6HexDigits(c[i]) );
    }
    return new String(sb);
  }

  /*public static void main(String[] args)
  {  Color[] c = { Color.red, Color.green, Color.blue };

    System.out.println("-Test 1-");
    // -----Outer container
    MutableMessageElement root = MutableMessageElement.createRoot();
    // -----Fade on
    MutableMessageElement el = MutableMessageElement.createFade(c);
    el.add( MutableMessageElement.createText("[Start text]") );
    // -----Bold on
    MutableMessageElement el2 = MutableMessageElement.createBold();
    el2.add( MutableMessageElement.createText("[Bold]") );
    el.add(el2);
    // -----Bold off
    el.add( MutableMessageElement.createText("[End text]") );
    root.add(el);
    // -----Fade off
    root.add( MutableMessageElement.createText("[Not faded]") );
    // -----Colour on
    el=MutableMessageElement.createAbsoluteColour(Color.red);
    el.add( MutableMessageElement.createText("[Coloured]") );
    root.add(el);
    // -----Colour off
    System.out.println(root.toTree());
    System.out.println(root.toYahooIM());
    System.out.println(root.toYahooChat());

    System.out.println("-Test 2-");
    // -----Test 2, forced containers
    root = MutableMessageElement.createIndexedColour(1);
    root.add( MutableMessageElement.createText("[Colour 1]") );
    el = MutableMessageElement.createIndexedColour(2);
    el.add( MutableMessageElement.createText("[Colour 2]") );
    root.add(el);
    root.add( MutableMessageElement.createText("[Colour 1 or 2]") );
    System.out.println(root.toTree());
    System.out.println(root.toYahooIM(true));
    System.out.println(root.toYahooChat(true));
    System.out.println(root.toYahooIM(false));
    System.out.println(root.toYahooChat(false));

  }*/
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.