001 package org.crsh.text; 002 003 import org.crsh.util.Safe; 004 import org.crsh.util.Utils; 005 006 import java.io.IOException; 007 import java.io.Serializable; 008 009 /** 010 * @author <a href="mailto:alain.defrance@exoplatform.com">Alain Defrance</a> 011 */ 012 public abstract class Style implements Serializable { 013 014 public static final Style reset = new Style(null, null, null) { 015 @Override 016 public void writeAnsiTo(Appendable appendable) throws IOException { 017 appendable.append("\033[0m"); 018 } 019 }; 020 021 static class Regular extends Style { 022 Regular(Decoration decoration, Color foreground, Color background) { 023 super(decoration, foreground, background); 024 } 025 026 @Override 027 public void writeAnsiTo(Appendable appendable) throws IOException { 028 if (decoration != null|| foreground != null || background != null) { 029 appendable.append("\033["); 030 boolean appended = false; 031 if (decoration != null) { 032 appendable.append(Integer.toString(decoration.code)); 033 appended = true; 034 } 035 if (foreground != null) { 036 if (appended) { 037 appendable.append(";"); 038 } 039 appendable.append(Integer.toString(foreground.code(30))); 040 appended = true; 041 } 042 if (background != null) { 043 if (appended) { 044 appendable.append(";"); 045 } 046 appendable.append(Integer.toString(background.code(40))); 047 } 048 appendable.append("m"); 049 } 050 else { 051 // 052 } 053 } 054 055 @Override 056 public boolean equals(Object obj) { 057 if (obj == this) { 058 return true; 059 } 060 if (obj instanceof Regular) { 061 Regular that = (Regular)obj; 062 return Safe.equals(decoration, that.decoration) && 063 Safe.equals(foreground, that.foreground) && 064 Safe.equals(background, that.background); 065 } 066 return false; 067 } 068 } 069 070 public static Style style(Color foreground) { 071 return new Regular(null, foreground, null); 072 } 073 074 public static Style style(Color foreground, Color background) { 075 return new Regular(null, foreground, background); 076 } 077 078 public static Style style(Decoration decoration, Color foreground, Color background) { 079 return new Regular(decoration, foreground, background); 080 } 081 082 public static Style style(Decoration decoration) { 083 return new Regular(decoration, null, null); 084 } 085 086 public static Style style(Decoration decoration, Color foreground) { 087 return new Regular(decoration, foreground, null); 088 } 089 090 /** . */ 091 protected final Decoration decoration; 092 093 /** . */ 094 protected final Color foreground; 095 096 /** . */ 097 protected final Color background; 098 099 private Style(Decoration decoration, Color foreground, Color background) { 100 this.decoration = decoration; 101 this.foreground = foreground; 102 this.background = background; 103 } 104 105 public Decoration getDecoration() { 106 return decoration; 107 } 108 109 public Color getForeground() { 110 return foreground; 111 } 112 113 public Color getBackground() { 114 return background; 115 } 116 117 public Style merge(Style s) throws NullPointerException { 118 if (s == null) { 119 throw new NullPointerException(); 120 } 121 if (s == reset) { 122 return reset; 123 } else { 124 Decoration dec = Utils.notNull(s.decoration, decoration); 125 Color fg = Utils.notNull(s.foreground, foreground); 126 Color bg = Utils.notNull(s.background, background); 127 return new Regular(dec, fg, bg); 128 } 129 } 130 131 public CharSequence toAnsiSequence() { 132 StringBuilder sb = new StringBuilder(); 133 try { 134 writeAnsiTo(sb); 135 } 136 catch (IOException e) { 137 // Should not happen 138 throw new AssertionError(e); 139 } 140 return sb.toString(); 141 } 142 143 public abstract void writeAnsiTo(Appendable appendable) throws IOException; 144 145 @Override 146 public String toString() { 147 return "Style[decoration=" + decoration + ",background=" + background + ",foreground=" + foreground + "]"; 148 } 149 }