1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.jline;
20
21 import java.util.Map;
22 import java.util.concurrent.ConcurrentHashMap;
23
24 import org.apache.maven.api.Constants;
25 import org.apache.maven.api.annotations.Experimental;
26 import org.apache.maven.api.di.Named;
27 import org.apache.maven.api.di.Priority;
28 import org.apache.maven.api.di.Singleton;
29 import org.apache.maven.api.services.MessageBuilder;
30 import org.apache.maven.api.services.MessageBuilderFactory;
31 import org.jline.utils.AttributedStringBuilder;
32 import org.jline.utils.AttributedStyle;
33 import org.jline.utils.StyleResolver;
34
35 @Experimental
36 @Named
37 @Singleton
38 @Priority(10)
39 public class JLineMessageBuilderFactory implements MessageBuilderFactory {
40 private final StyleResolver resolver;
41
42 public JLineMessageBuilderFactory() {
43 this.resolver = new MavenStyleResolver();
44 }
45
46 @Override
47 public boolean isColorEnabled() {
48 return MessageUtils.isColorEnabled();
49 }
50
51 @Override
52 public int getTerminalWidth() {
53 return MessageUtils.getTerminalWidth();
54 }
55
56 @Override
57 public MessageBuilder builder() {
58 return builder(64);
59 }
60
61 @Override
62 public MessageBuilder builder(int size) {
63 return new JlineMessageBuilder(resolver, size);
64 }
65
66 private static class JlineMessageBuilder implements MessageBuilder {
67 private final StyleResolver styleResolver;
68 private final AttributedStringBuilder builder;
69
70 private JlineMessageBuilder(StyleResolver styleResolver, int size) {
71 this.styleResolver = styleResolver;
72 this.builder = new AttributedStringBuilder(size);
73 }
74
75 @Override
76 public MessageBuilder style(String style) {
77 if (MessageUtils.isColorEnabled()) {
78 builder.style(styleResolver.resolve(style));
79 }
80 return this;
81 }
82
83 @Override
84 public MessageBuilder resetStyle() {
85 builder.style(AttributedStyle.DEFAULT);
86 return this;
87 }
88
89 @Override
90 public MessageBuilder append(CharSequence cs) {
91 builder.append(cs);
92 return this;
93 }
94
95 @Override
96 public MessageBuilder append(CharSequence cs, int start, int end) {
97 builder.append(cs, start, end);
98 return this;
99 }
100
101 @Override
102 public MessageBuilder append(char c) {
103 builder.append(c);
104 return this;
105 }
106
107 @Override
108 public MessageBuilder setLength(int length) {
109 builder.setLength(length);
110 return this;
111 }
112
113 @Override
114 public String build() {
115 return builder.toAnsi(MessageUtils.terminal);
116 }
117
118 @Override
119 public String toString() {
120 return build();
121 }
122 }
123
124 private static class MavenStyleResolver extends StyleResolver {
125 private final Map<String, AttributedStyle> styles = new ConcurrentHashMap<>();
126
127 private MavenStyleResolver() {
128 super(key -> {
129 String v = System.getProperty(Constants.MAVEN_STYLE_PREFIX + key);
130 if (v == null) {
131 v = System.getProperty("style." + key);
132 }
133 return v;
134 });
135 }
136
137 @Override
138 public AttributedStyle resolve(String spec) {
139 return styles.computeIfAbsent(spec, this::doResolve);
140 }
141
142 @Override
143 public AttributedStyle resolve(String spec, String defaultSpec) {
144 return resolve(defaultSpec != null ? spec + ":-" + defaultSpec : spec);
145 }
146
147 private AttributedStyle doResolve(String spec) {
148 String def = null;
149 int i = spec.indexOf(":-");
150 if (i != -1) {
151 String[] parts = spec.split(":-");
152 spec = parts[0].trim();
153 def = parts[1].trim();
154 }
155 return super.resolve(spec, def);
156 }
157 }
158 }