View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.jline;
20  
21  import javax.inject.Named;
22  import javax.inject.Singleton;
23  
24  import java.util.Map;
25  import java.util.concurrent.ConcurrentHashMap;
26  
27  import org.apache.maven.message.MessageBuilder;
28  import org.apache.maven.message.MessageBuilderFactory;
29  import org.eclipse.sisu.Priority;
30  import org.jline.utils.AttributedStringBuilder;
31  import org.jline.utils.AttributedStyle;
32  import org.jline.utils.StyleResolver;
33  
34  @Named
35  @Singleton
36  @Priority(10)
37  public class JLineMessageBuilderFactory implements MessageBuilderFactory {
38      private final StyleResolver resolver;
39  
40      public JLineMessageBuilderFactory() {
41          this.resolver = new MavenStyleResolver();
42      }
43  
44      @Override
45      public boolean isColorEnabled() {
46          return MessageUtils.isColorEnabled();
47      }
48  
49      @Override
50      public int getTerminalWidth() {
51          return MessageUtils.getTerminalWidth();
52      }
53  
54      @Override
55      public MessageBuilder builder() {
56          return builder(64);
57      }
58  
59      @Override
60      public MessageBuilder builder(int size) {
61          return new JlineMessageBuilder(resolver, size);
62      }
63  
64      private static class JlineMessageBuilder implements MessageBuilder {
65          private final StyleResolver styleResolver;
66          private final AttributedStringBuilder builder;
67  
68          private JlineMessageBuilder(StyleResolver styleResolver, int size) {
69              this.styleResolver = styleResolver;
70              this.builder = new AttributedStringBuilder(size);
71          }
72  
73          @Override
74          public MessageBuilder style(String style) {
75              if (MessageUtils.isColorEnabled()) {
76                  builder.style(styleResolver.resolve(style));
77              }
78              return this;
79          }
80  
81          @Override
82          public MessageBuilder resetStyle() {
83              builder.style(AttributedStyle.DEFAULT);
84              return this;
85          }
86  
87          @Override
88          public MessageBuilder append(CharSequence cs) {
89              builder.append(cs);
90              return this;
91          }
92  
93          @Override
94          public MessageBuilder append(CharSequence cs, int start, int end) {
95              builder.append(cs, start, end);
96              return this;
97          }
98  
99          @Override
100         public MessageBuilder append(char c) {
101             builder.append(c);
102             return this;
103         }
104 
105         @Override
106         public MessageBuilder setLength(int length) {
107             builder.setLength(length);
108             return this;
109         }
110 
111         @Override
112         public String build() {
113             return builder.toAnsi(MessageUtils.terminal);
114         }
115 
116         @Override
117         public String toString() {
118             return build();
119         }
120     }
121 
122     private static class MavenStyleResolver extends StyleResolver {
123         private final Map<String, AttributedStyle> styles = new ConcurrentHashMap<>();
124 
125         private MavenStyleResolver() {
126             super(key -> {
127                 String v = System.getProperty("maven.style." + key);
128                 if (v == null) {
129                     v = System.getProperty("style." + key);
130                 }
131                 return v;
132             });
133         }
134 
135         @Override
136         public AttributedStyle resolve(String spec) {
137             return styles.computeIfAbsent(spec, this::doResolve);
138         }
139 
140         @Override
141         public AttributedStyle resolve(String spec, String defaultSpec) {
142             return resolve(defaultSpec != null ? spec + ":-" + defaultSpec : spec);
143         }
144 
145         private AttributedStyle doResolve(String spec) {
146             String def = null;
147             int i = spec.indexOf(":-");
148             if (i != -1) {
149                 String[] parts = spec.split(":-");
150                 spec = parts[0].trim();
151                 def = parts[1].trim();
152             }
153             return super.resolve(spec, def);
154         }
155     }
156 }