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 }