View Javadoc
1   /*
2    * Copyright (C) 2016 Ronald Jack Jenkins Jr.
3    *
4    * This program is free software: you can redistribute it and/or modify
5    * it under the terms of the GNU General Public License as published by
6    * the Free Software Foundation, either version 3 of the License, or
7    * (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16   */
17  package info.ronjenkins.slf4bukkit;
18  
19  /**
20   * A {@link StringBuilder}-like class with a fluent API for adding content
21   * colored via {@link ColorMarker}s. You may call {@link #toString()} to get the
22   * current value and then continue adding content to this object. This class is
23   * thread-safe.
24   *
25   * <p>
26   * Plugins can use this class even if they will be executed in environments
27   * where JAnsi is not available (e.g. PaperSpigot) because all colors are
28   * stripped when the message is logged. This class does not depend on JAnsi,
29   * so it is safe to use in such environments.
30   * </p>
31   *
32   * @author Ronald Jack Jenkins Jr.
33   */
34  public final class ColorString {
35  
36    private ColorMarker         currentColor = ColorMarker.NONE;
37    private final StringBuilder value        = new StringBuilder();
38  
39    /** Constructor. */
40    public ColorString() {
41    }
42  
43    /**
44     * Sets the color to {@link ColorMarker#AQUA}, then calls
45     * {@link StringBuilder#append(String)}.
46     *
47     * @param append
48     *          the string to append.
49     * @return this.
50     */
51    public ColorString aqua(final String append) {
52      synchronized (this.value) {
53        this.setColor(ColorMarker.AQUA);
54        this.value.append(append);
55        return this;
56      }
57    }
58  
59    /**
60     * Sets the color to {@link ColorMarker#BLACK}, then calls
61     * {@link StringBuilder#append(String)}.
62     *
63     * @param append
64     *          the string to append.
65     * @return this.
66     */
67    public ColorString black(final String append) {
68      synchronized (this.value) {
69        this.setColor(ColorMarker.BLACK);
70        this.value.append(append);
71        return this;
72      }
73    }
74  
75    /**
76     * Sets the color to {@link ColorMarker#BLUE}, then calls
77     * {@link StringBuilder#append(String)}.
78     *
79     * @param append
80     *          the string to append.
81     * @return this.
82     */
83    public ColorString blue(final String append) {
84      synchronized (this.value) {
85        this.setColor(ColorMarker.BLUE);
86        this.value.append(append);
87        return this;
88      }
89    }
90  
91    /**
92     * Sets the color to {@link ColorMarker#DARK_AQUA}, then calls
93     * {@link StringBuilder#append(String)}.
94     *
95     * @param append
96     *          the string to append.
97     * @return this.
98     */
99    public ColorString darkAqua(final String append) {
100     synchronized (this.value) {
101       this.setColor(ColorMarker.DARK_AQUA);
102       this.value.append(append);
103       return this;
104     }
105   }
106 
107   /**
108    * Sets the color to {@link ColorMarker#DARK_BLUE}, then calls
109    * {@link StringBuilder#append(String)}.
110    *
111    * @param append
112    *          the string to append.
113    * @return this.
114    */
115   public ColorString darkBlue(final String append) {
116     synchronized (this.value) {
117       this.setColor(ColorMarker.DARK_BLUE);
118       this.value.append(append);
119       return this;
120     }
121   }
122 
123   /**
124    * Sets the color to {@link ColorMarker#DARK_GRAY}, then calls
125    * {@link StringBuilder#append(String)}.
126    *
127    * @param append
128    *          the string to append.
129    * @return this.
130    */
131   public ColorString darkGray(final String append) {
132     synchronized (this.value) {
133       this.setColor(ColorMarker.DARK_GRAY);
134       this.value.append(append);
135       return this;
136     }
137   }
138 
139   /**
140    * Sets the color to {@link ColorMarker#DARK_GREEN}, then calls
141    * {@link StringBuilder#append(String)}.
142    *
143    * @param append
144    *          the string to append.
145    * @return this.
146    */
147   public ColorString darkGreen(final String append) {
148     synchronized (this.value) {
149       this.setColor(ColorMarker.DARK_GREEN);
150       this.value.append(append);
151       return this;
152     }
153   }
154 
155   /**
156    * Sets the color to {@link ColorMarker#DARK_RED}, then calls
157    * {@link StringBuilder#append(String)}.
158    *
159    * @param append
160    *          the string to append.
161    * @return this.
162    */
163   public ColorString darkRed(final String append) {
164     synchronized (this.value) {
165       this.setColor(ColorMarker.DARK_RED);
166       this.value.append(append);
167       return this;
168     }
169   }
170 
171   /**
172    * Sets the color to {@link ColorMarker#GOLD}, then calls
173    * {@link StringBuilder#append(String)}.
174    *
175    * @param append
176    *          the string to append.
177    * @return this.
178    */
179   public ColorString gold(final String append) {
180     synchronized (this.value) {
181       this.setColor(ColorMarker.GOLD);
182       this.value.append(append);
183       return this;
184     }
185   }
186 
187   /**
188    * Sets the color to {@link ColorMarker#GRAY}, then calls
189    * {@link StringBuilder#append(String)}.
190    *
191    * @param append
192    *          the string to append.
193    * @return this.
194    */
195   public ColorString gray(final String append) {
196     synchronized (this.value) {
197       this.setColor(ColorMarker.GRAY);
198       this.value.append(append);
199       return this;
200     }
201   }
202 
203   /**
204    * Sets the color to {@link ColorMarker#GREEN}, then calls
205    * {@link StringBuilder#append(String)}.
206    *
207    * @param append
208    *          the string to append.
209    * @return this.
210    */
211   public ColorString green(final String append) {
212     synchronized (this.value) {
213       this.setColor(ColorMarker.GREEN);
214       this.value.append(append);
215       return this;
216     }
217   }
218 
219   /**
220    * Resets all formatting at the current position, then calls
221    * {@link StringBuilder#append(String)}.
222    *
223    * @param append
224    *          the string to append.
225    * @return this.
226    */
227   public ColorString none(final String append) {
228     synchronized (this.value) {
229       this.setColor(ColorMarker.NONE);
230       this.value.append(append);
231       return this;
232     }
233   }
234 
235   /**
236    * Sets the color to {@link ColorMarker#LIGHT_PURPLE}, then calls
237    * {@link StringBuilder#append(String)}.
238    *
239    * @param append
240    *          the string to append.
241    * @return this.
242    */
243   public ColorString pink(final String append) {
244     synchronized (this.value) {
245       this.setColor(ColorMarker.LIGHT_PURPLE);
246       this.value.append(append);
247       return this;
248     }
249   }
250 
251   /**
252    * Sets the color to {@link ColorMarker#DARK_PURPLE}, then calls
253    * {@link StringBuilder#append(String)}.
254    *
255    * @param append
256    *          the string to append.
257    * @return this.
258    */
259   public ColorString purple(final String append) {
260     synchronized (this.value) {
261       this.setColor(ColorMarker.DARK_PURPLE);
262       this.value.append(append);
263       return this;
264     }
265   }
266 
267   /**
268    * Sets the color to {@link ColorMarker#RED}, then calls
269    * {@link StringBuilder#append(String)}.
270    *
271    * @param append
272    *          the string to append.
273    * @return this.
274    */
275   public ColorString red(final String append) {
276     synchronized (this.value) {
277       this.setColor(ColorMarker.RED);
278       this.value.append(append);
279       return this;
280     }
281   }
282 
283   /**
284    * Resets all formatting at the current position, then returns the string's
285    * value.
286    *
287    * @return never null.
288    */
289   @Override
290   public String toString() {
291     synchronized (this.value) {
292       this.setColor(ColorMarker.NONE);
293       return this.value.toString();
294     }
295   }
296 
297   /**
298    * Appends the given color to the string sequence, then returns the string's
299    * value.
300    *
301    * @param color
302    *          the desired color suffix. Null is coerced to
303    *          {@link ColorMarker#NONE}, which resets all formatting at the
304    *          current position.
305    * @return never null. Returns {@link #toString()} if the color is null.
306    */
307   public String toString(final ColorMarker color) {
308     synchronized (this.value) {
309       if (color == null) { return this.toString(); }
310       this.setColor(color);
311       return this.value.toString();
312     }
313   }
314 
315   /**
316    * Sets the color to {@link ColorMarker#WHITE}, then calls
317    * {@link StringBuilder#append(String)}.
318    *
319    * @param append
320    *          the string to append.
321    * @return this.
322    */
323   public ColorString white(final String append) {
324     synchronized (this.value) {
325       this.setColor(ColorMarker.WHITE);
326       this.value.append(append);
327       return this;
328     }
329   }
330 
331   /**
332    * Sets the color to {@link ColorMarker#YELLOW}, then calls
333    * {@link StringBuilder#append(String)}.
334    *
335    * @param append
336    *          the string to append.
337    * @return this.
338    */
339   public ColorString yellow(final String append) {
340     synchronized (this.value) {
341       this.setColor(ColorMarker.YELLOW);
342       this.value.append(append);
343       return this;
344     }
345   }
346 
347   private void setColor(final ColorMarker color) {
348     synchronized (this.value) {
349       if (color != this.currentColor) {
350         this.value.append(color.getValue());
351         this.currentColor = color;
352       }
353     }
354   }
355 
356 }