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

com.networknt.oas.validator.msg.MessagesHelper Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 *  Copyright (c) 2017 ModelSolv, Inc. and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *     ModelSolv, Inc. - initial API and implementation and/or initial documentation
 *******************************************************************************/
package com.networknt.oas.validator.msg;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class MessagesHelper {
	private static final Pattern placeholderPattern = Pattern.compile("%(\\d+)|%\\{(\\d+)\\}");

	/**
	 * Interpolate arguments into the message format string for the given message.
	 * 

* If a non-null locale is provided, an attempt is made to load a properties * file for the Message class of which this message is an instance, and the * property named by this message's name is used as the format string. If that * fails, or if the locale is null, the message object's default format string * is used. *

* The format string contains embedded place holders indicating where arguments * are to be substituted. Each place holder takes the form %n or * %{n}, where n is an integer from 1 to the number of * arguments. The second form allows interpolation at a site immediately * followed by other digits. *

* To prevent a percent sign from triggering interpolation, double it: * %%. For example, "%%1 %%{2}" will always produce * "%1 %{2}". *

* The result is obtained by replacing each placeholder with the corresponding * argument's {@link #toString()} value (except that null arguments are rendered * as empty strings). * * @param message Messages * @param args Args * @param locale Locale * @return message with interpolated arguments */ public static String format(Locale locale, Messages message, Object... args) { String formatString = message.getFormatString(locale); Object[] sortArgs = sortArgs(formatString, args); String printfString = Stream.of(formatString.split("%%")) .map(part -> placeholderPattern.matcher(part).replaceAll("%s")) // .collect(Collectors.joining("%%")); return String.format(printfString, sortArgs); } private static Object[] sortArgs(String format, Object[] args) { List sites = findInterpolationSites(format); sites.stream().forEach(site -> { if (site < 1 || site > args.length) { String msg = String.format("Interpolation position must be from 1 to %d: %%%d", args.length, site); throw new IndexOutOfBoundsException(msg); } }); return sites.stream().map(i -> args[i - 1] != null ? args[i - 1] : "").toArray(); } private static List findInterpolationSites(String format) { List sites = new ArrayList<>(); String[] parts = format.split("%%"); for (String part : parts) { Matcher m = placeholderPattern.matcher(part); while (m.find()) { boolean braces = m.group(1) == null; String digits = m.group(braces ? 2 : 1); int index = digits.isEmpty() ? 0 : Integer.valueOf(digits); sites.add(index); } } return sites; } private static Map, Map> localizationsByClass = new HashMap<>(); public static Properties loadLocalizations(Class msgClass, Locale locale) { if (!localizationsByClass.containsKey(msgClass)) { localizationsByClass.put(msgClass, new HashMap<>()); } Map localizations = localizationsByClass.get(msgClass); // try locale-specified variant tag first, then fall back to just the language // code for (String tag : Arrays.asList(locale.toLanguageTag(), locale.getLanguage())) { if (!localizations.containsKey(tag)) { URL resource = msgClass.getResource(String.format("localizations/%s/messages.properties", tag)); Properties props = null; if (resource != null) { props = new Properties(); try (InputStream in = resource.openStream()) { props.load(in); } catch (IOException e) { props = null; } } // if no props loaded, set null value in localizations so we don't keep trying localizations.put(tag, props); } Properties result = localizations.get(tag); if (result != null) { return result; } } return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy