JLineMessageBuilderFactory.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.jline;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.maven.api.Constants;
import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.di.Named;
import org.apache.maven.api.di.Priority;
import org.apache.maven.api.di.Singleton;
import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.jline.utils.AttributedStringBuilder;
import org.jline.utils.AttributedStyle;
import org.jline.utils.StyleResolver;
@Experimental
@Named
@Singleton
@Priority(10)
public class JLineMessageBuilderFactory implements MessageBuilderFactory {
private final StyleResolver resolver;
public JLineMessageBuilderFactory() {
this.resolver = new MavenStyleResolver();
}
@Override
public boolean isColorEnabled() {
return MessageUtils.isColorEnabled();
}
@Override
public int getTerminalWidth() {
return MessageUtils.getTerminalWidth();
}
@Override
public MessageBuilder builder() {
return builder(64);
}
@Override
public MessageBuilder builder(int size) {
return new JlineMessageBuilder(resolver, size);
}
private static class JlineMessageBuilder implements MessageBuilder {
private final StyleResolver styleResolver;
private final AttributedStringBuilder builder;
private JlineMessageBuilder(StyleResolver styleResolver, int size) {
this.styleResolver = styleResolver;
this.builder = new AttributedStringBuilder(size);
}
@Override
public MessageBuilder style(String style) {
if (MessageUtils.isColorEnabled()) {
builder.style(styleResolver.resolve(style));
}
return this;
}
@Override
public MessageBuilder resetStyle() {
builder.style(AttributedStyle.DEFAULT);
return this;
}
@Override
public MessageBuilder append(CharSequence cs) {
builder.append(cs);
return this;
}
@Override
public MessageBuilder append(CharSequence cs, int start, int end) {
builder.append(cs, start, end);
return this;
}
@Override
public MessageBuilder append(char c) {
builder.append(c);
return this;
}
@Override
public MessageBuilder setLength(int length) {
builder.setLength(length);
return this;
}
@Override
public String build() {
return builder.toAnsi(MessageUtils.terminal);
}
@Override
public String toString() {
return build();
}
}
private static class MavenStyleResolver extends StyleResolver {
private final Map<String, AttributedStyle> styles = new ConcurrentHashMap<>();
private MavenStyleResolver() {
super(key -> {
String v = System.getProperty(Constants.MAVEN_STYLE_PREFIX + key);
if (v == null) {
v = System.getProperty("style." + key);
}
return v;
});
}
@Override
public AttributedStyle resolve(String spec) {
return styles.computeIfAbsent(spec, this::doResolve);
}
@Override
public AttributedStyle resolve(String spec, String defaultSpec) {
return resolve(defaultSpec != null ? spec + ":-" + defaultSpec : spec);
}
private AttributedStyle doResolve(String spec) {
String def = null;
int i = spec.indexOf(":-");
if (i != -1) {
String[] parts = spec.split(":-");
spec = parts[0].trim();
def = parts[1].trim();
}
return super.resolve(spec, def);
}
}
}