All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.mmm.util.nls.impl.formatter.NlsMessageFormatterImpl Maven / Gradle / Ivy

/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
 * http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.nls.impl.formatter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;

import net.sf.mmm.util.lang.api.Visitor;
import net.sf.mmm.util.nls.api.NlsArgument;
import net.sf.mmm.util.nls.api.NlsArgumentParser;
import net.sf.mmm.util.nls.api.NlsTemplateResolver;
import net.sf.mmm.util.nls.base.AbstractNlsMessageFormatter;
import net.sf.mmm.util.nls.base.NlsDependencies;
import net.sf.mmm.util.scanner.base.CharSequenceScanner;

/**
 * This is the implementation of the {@link net.sf.mmm.util.nls.api.NlsMessageFormatter} interface. 
* NOTE:
* This is more or less a rewrite of {@link java.text.MessageFormat} and is syntax-compatible with the * {@link java.text.MessageFormat#applyPattern(String) MessageFormat-pattern} -format. Some special (and * somewhat sick) features as modifying internal {@link java.text.Format}s or {@link java.text.FieldPosition} * are NOT supported. Currently also parsing is NOT supported.
* Instead this implementation is immutable and thread-safe. Further it works on any {@link Appendable} rather * than only on {@link StringBuffer}. It also uses the same {@link Appendable} for recursive invocations. * * @author Joerg Hohwiller (hohwille at users.sourceforge.net) * @since 1.0.0 */ public class NlsMessageFormatterImpl extends AbstractNlsMessageFormatter { /** The parsed segments of the message pattern. */ private final PatternSegment[] segments; /** The suffix (last segment) of the pattern. */ private final String suffix; /** The {@link NlsDependencies} to use. */ private final NlsDependencies nlsDependnecies; /** * The constructor. * * @param pattern is the pattern of the message to format. It is syntax-compatible with * {@link java.text.MessageFormat}. * @param nlsDependencies are the {@link NlsDependencies}. */ public NlsMessageFormatterImpl(String pattern, NlsDependencies nlsDependencies) { super(); Objects.requireNonNull(nlsDependencies, "nlsDependencies"); this.nlsDependnecies = nlsDependencies; List segmentList = new ArrayList<>(); CharSequenceScanner scanner = new CharSequenceScanner(pattern); String prefix = scanner.readUntil(NlsArgumentParser.START_EXPRESSION, true, '\\'); while (scanner.hasNext()) { NlsArgument argument; int index = scanner.getCurrentIndex() - 1; try { argument = this.nlsDependnecies.getArgumentParser().parse(scanner); } catch (Exception e) { throw new IllegalArgumentException(scanner.substring(index, scanner.getCurrentIndex()), e); } PatternSegment segment = new PatternSegment(prefix, argument); segmentList.add(segment); prefix = scanner.readUntil(NlsArgumentParser.START_EXPRESSION, true, '\\'); } this.suffix = prefix; this.segments = segmentList.toArray(new PatternSegment[segmentList.size()]); } @Override public final void format(Void nothing, Locale locale, Map arguments, NlsTemplateResolver resolver, Appendable buffer) throws IOException { for (PatternSegment segment : this.segments) { buffer.append(segment.prefix); NlsArgument argument = segment.argument; this.nlsDependnecies.getArgumentFormatter().format(argument, locale, arguments, resolver, buffer); } buffer.append(this.suffix); } /** * @return the suffix to append after all {@link PatternSegment}s. */ public String getSuffix() { return this.suffix; } @Override public void visit(Visitor staticTextVisitor, Visitor dynamicArgumentVisitor) { for (PatternSegment segment : this.segments) { staticTextVisitor.visit(segment.prefix); dynamicArgumentVisitor.visit(segment.argument); } staticTextVisitor.visit(this.suffix); } /** * This inner class represents a segment out of the parsed message-pattern.
* E.g. if the message-pattern is "Hi {0} you have {1} items!" then it is parsed into two * {@link PatternSegment}s. The first has a {@link #getPrefix() prefix} of {@code "Hi "} and * {@link #getArgument() argument} of {0} and the second has {@code " you have "} as * {@link #getPrefix() prefix} and {@link #getArgument() argument} of {1}. The rest of the * pattern which is {@code " items!"} will be stored in {@link NlsMessageFormatterImpl#getSuffix() suffix}. */ protected static class PatternSegment { private final String prefix; private final NlsArgument argument; /** * The constructor. * * @param prefix is the {@link #getPrefix() prefix}. * @param argument is the {@link #getArgument() argument}. */ public PatternSegment(String prefix, NlsArgument argument) { super(); this.prefix = prefix; this.argument = argument; } /** * This method gets the prefix. This is the raw part of the message-pattern (until the next '{') that will * be taken as is. * * @return the prefix */ public String getPrefix() { return this.prefix; } /** * This method gets the {@link NlsArgument}. * * @return the argument. */ public NlsArgument getArgument() { return this.argument; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(this.prefix); sb.append(this.argument); return sb.toString(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy