summaryrefslogtreecommitdiffstats
path: root/baseservice-i18n
diff options
context:
space:
mode:
authoryoubowu <wu.youbo@zte.com.cn>2017-02-08 10:58:20 +0800
committer6092002067 <wu.youbo@zte.com.cn>2017-02-13 11:24:21 +0800
commit5ffdd63a0bd74d1e7da97b58febaf0970493616e (patch)
tree4ef6d0d80d183888ae65a39850815fef941713cd /baseservice-i18n
parent6000f113793dce93bd1518a400f76835c018cb75 (diff)
Add international basic service module
Issue-ID:HOLMES-33 Change-Id: I2442ebfa65c6586a21655b226699b0dfbcbb3910 Signed-off-by: youbowu<wu.youbo@zte.com.cn>
Diffstat (limited to 'baseservice-i18n')
-rw-r--r--baseservice-i18n/pom.xml66
-rw-r--r--baseservice-i18n/src/main/java/org/openo/baseservice/i18n/DefaultErrorCodeI18n.java278
-rw-r--r--baseservice-i18n/src/main/java/org/openo/baseservice/i18n/DefaultI18nService.java59
-rw-r--r--baseservice-i18n/src/main/java/org/openo/baseservice/i18n/ErrorCodeException.java53
-rw-r--r--baseservice-i18n/src/main/java/org/openo/baseservice/i18n/ErrorCodeI18n.java151
-rw-r--r--baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18n.java132
-rw-r--r--baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nContainer.java148
-rw-r--r--baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nImpl.java137
-rw-r--r--baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nItem.java53
-rw-r--r--baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nJsonUtil.java170
-rw-r--r--baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nService.java38
-rw-r--r--baseservice-i18n/src/main/java/org/openo/baseservice/i18n/JsonResourceScanner.java81
12 files changed, 1366 insertions, 0 deletions
diff --git a/baseservice-i18n/pom.xml b/baseservice-i18n/pom.xml
new file mode 100644
index 0000000..d110db3
--- /dev/null
+++ b/baseservice-i18n/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2017 ZTE Corporation. Licensed 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openo.common-services.common-utilities</groupId>
+ <artifactId>common-setting</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>baseservice-i18n</artifactId>
+ <name>common-services-common-utilities/baseservice-i18n</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.reflections</groupId>
+ <artifactId>reflections</artifactId>
+ <version>0.9.10</version>
+ </dependency>
+ <dependency>
+ <groupId>io.dropwizard</groupId>
+ <artifactId>dropwizard-core</artifactId>
+ <version>0.8.0</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ <version>4.8.2</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.3</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/DefaultErrorCodeI18n.java b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/DefaultErrorCodeI18n.java
new file mode 100644
index 0000000..d225e1b
--- /dev/null
+++ b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/DefaultErrorCodeI18n.java
@@ -0,0 +1,278 @@
+/**
+ * Copyright 2017 ZTE Corporation.
+ *
+ * Licensed 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.openo.baseservice.i18n;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public final class DefaultErrorCodeI18n implements ErrorCodeI18n {
+
+ static final Logger logger = LoggerFactory.getLogger(DefaultErrorCodeI18n.class);
+ private static DefaultErrorCodeI18n singleton;
+ private static final Lock lock = new ReentrantLock();
+ private Map<Integer, ErrorItemImpl> errorItems;
+
+ private DefaultErrorCodeI18n() {
+ try {
+ init();
+ } catch (Exception e) {
+ logger.error("init ErrorCodeI18n failed.", e);
+ }
+ }
+
+ private void init() throws Exception {
+ final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+ final Map<Integer, ErrorItemImpl> errorItems = new HashMap<Integer, DefaultErrorCodeI18n.ErrorItemImpl>();
+ JsonResourceScanner.findErrorCodePaths().forEach(path -> {
+ HashMap<String, Object> fileValues = null;
+ try (InputStream ins = systemClassLoader.getResourceAsStream(path)) {
+ fileValues = I18nJsonUtil.getInstance().readFromJson(ins, HashMap.class);
+ logger.info("load errorcode file success: " + path);
+ } catch (IOException ex) {
+ logger.info("load errorcode file failed: " + path);
+ logger.info(
+ "load errorcode file failed: " + systemClassLoader.getResource(path).toString(),
+ ex);
+ return;
+ }
+ List<?> errcodes = (List<?>) fileValues.get("errcodes");
+ if (errcodes == null) {
+ logger.info("none errcodes field in: " + path);
+ return;
+ }
+
+ String fileName = null;
+ int i = path.lastIndexOf("/");
+ if (i > -1) {
+ fileName = path.substring(i + 1);
+ } else {
+ fileName = path;
+ }
+ i = fileName.indexOf("-errorcode-");
+ String localeSrc = fileName.substring(i + 11, fileName.lastIndexOf("."));
+ if (localeSrc.isEmpty()) {
+ logger.info("parse errorcode file failed: locale is null");
+ return;
+ }
+
+ String[] ss = localeSrc.replace("-", "_").split("_");
+ String tempLocale = null;
+ if (ss.length == 1) {
+ tempLocale = new Locale(ss[0]).toString();
+ } else if (ss.length == 2) {
+ tempLocale = new Locale(ss[0], ss[1]).toString();
+ } else {
+ logger.info("parse i18n file failed: locale is error \"" + localeSrc + "\"");
+ return;
+ }
+ String locale = tempLocale;
+ errcodes.forEach(errorcode -> {
+ Map<String, String> errorConfig = (Map<String, String>) errorcode;
+ Integer code = Integer.valueOf(errorConfig.get("code"));
+ String level = errorConfig.get("level");
+ String label = errorConfig.get("label");
+
+ ErrorItemImpl errorItem = errorItems.get(Integer.valueOf(code));
+ if (errorItem == null) {
+ errorItem = new ErrorItemImpl();
+ errorItem.errorCode = code.intValue();
+ errorItem.level = ErrorCodeLevelUtil.transfer2Int(level);
+ errorItems.put(code, errorItem);
+ }
+ errorItem.addLabel(locale, label);
+ });
+ });
+
+ errorItems.forEach((code, errorItem) -> {
+ errorItem.unmodifiable();
+ });
+ this.errorItems = Collections.unmodifiableMap(errorItems);
+ }
+
+
+ static DefaultErrorCodeI18n getInstance() {
+ if (singleton == null) {
+ lock.lock();
+ try {
+ if (singleton == null) {
+ singleton = new DefaultErrorCodeI18n();
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+ return singleton;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.zte.ums.zenap.i18n.ErrorCodeI18n#getErrorItem(int)
+ */
+ @Override
+ public Optional<ErrorItem> getErrorItem(int errorCode) {
+ return Optional.ofNullable(errorItems.get(Integer.valueOf(errorCode)));
+ }
+
+
+ public static class ErrorItemImpl implements ErrorItem {
+
+ private int errorCode;
+
+ private int level;
+
+ private Map<String, String> labels = new HashMap<String, String>();
+
+ private String jsonString = null;
+
+ @Override
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ @Override
+ public int getLevel() {
+ return level;
+ }
+
+ public Map<String, String> getLabels() {
+ return labels;
+ }
+
+ private void unmodifiable() {
+ if (labels != null) {
+ labels = Collections.unmodifiableMap(labels);
+ }
+ }
+
+ private synchronized void addLabel(String locale, String label) {
+ labels.put(locale, label);
+ }
+
+ @Override
+ public String getLabel(Locale theLocale) {
+ if (theLocale == null) {
+ return null;
+ }
+ return labels.get(I18nLocaleTransfer.transfer(theLocale, labels.keySet()));
+ }
+
+ @Override
+ public String getCanonicalLabels(int errorCode) {
+ String jsonString = this.jsonString;
+ if (jsonString == null) {
+ ErrorItem2 errorItem2 = new ErrorItem2();
+ errorItem2.setErrorCode(this.errorCode);
+ errorItem2.setLevel(ErrorCodeLevelUtil.transfer2String(this.errorCode));
+ errorItem2.setErrlabels(labels);
+ try {
+ jsonString = I18nJsonUtil.getInstance().writeToJson(errorItem2);
+ } catch (Exception e) {
+ logger.info("getCanonicalLabels failed from with param errorCode " + errorCode
+ + " and this errorCode " + this.errorCode, e);
+ return null;
+ }
+ this.jsonString = jsonString;
+ }
+ return jsonString;
+ }
+
+ }
+
+ protected static class ErrorItem2 {
+
+ private int errorCode;
+
+ private String level;
+
+ private Map<String, String> errlabels;
+
+ public ErrorItem2() {
+
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ public void setErrorCode(int errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ public String getLevel() {
+ return level;
+ }
+
+ public void setLevel(String level) {
+ this.level = level;
+ }
+
+ public Map<String, String> getErrlabels() {
+ return errlabels;
+ }
+
+ public void setErrlabels(Map<String, String> errlabels) {
+ this.errlabels = errlabels;
+ }
+ }
+
+ protected static class ErrorCodeLevelUtil {
+
+ public static final int ERROR_LEVEL = javax.swing.JOptionPane.ERROR_MESSAGE;
+
+ public static final int WARN_LEVEL = javax.swing.JOptionPane.WARNING_MESSAGE;
+
+ public static final int INFO_LEVEL = javax.swing.JOptionPane.INFORMATION_MESSAGE;
+
+ protected static String transfer2String(int errorCode) {
+ switch (errorCode) {
+ case ERROR_LEVEL:
+ return "ERROR";
+ case INFO_LEVEL:
+ return "INFO";
+ case WARN_LEVEL:
+ return "WARN";
+ }
+ return null;
+ }
+
+ protected static int transfer2Int(String level) {
+ switch (level) {
+ case "ERROR":
+ return ERROR_LEVEL;
+ case "INFO":
+ return INFO_LEVEL;
+ case "WARN":
+ return WARN_LEVEL;
+ }
+ return -1;
+ }
+
+ }
+
+}
diff --git a/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/DefaultI18nService.java b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/DefaultI18nService.java
new file mode 100644
index 0000000..820478c
--- /dev/null
+++ b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/DefaultI18nService.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright 2017 ZTE Corporation.
+ *
+ * Licensed 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.openo.baseservice.i18n;
+
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.Optional;
+import javax.inject.Inject;
+import org.jvnet.hk2.annotations.Service;
+import org.openo.baseservice.i18n.ErrorCodeI18n.ErrorItem;
+
+@Service
+public final class DefaultI18nService implements I18nService {
+
+ /**
+ * Get the corresponding examples of international documents (all languages), <br>
+ *
+ * for the above example topology (for example, the Chinese definition: topo-i18n-zh-CN.json, English definition
+ * Topo -i18n-en-US.json), into the reference into the "TOPO" can be <br>
+ *
+ * (i.e. except "-i18n-*.json" after the exact match).
+ *
+ * @param i18nFilePrefix International file prefix (-i18n-*.json front part)
+ * @return Optional<I18n>
+ */
+ public Optional<I18n> getI18n(String i18nFilePrefix) {
+ return I18nContainer.getInstance().getI18n(i18nFilePrefix);
+ }
+
+ /**
+ * Gets the corresponding error item based on the error code (including the error description information for all
+ * languages)
+ *
+ * @param errorCode
+ * @return Optional<ErrorItem>
+ */
+ public Optional<ErrorItem> getErrorItem(int errorCode) {
+ return ErrorCodeI18n.getInstance().getErrorItem(errorCode);
+ }
+
+ @Inject
+ public void setObjectMapper(ObjectMapper objectMapper) {
+ I18nJsonUtil.getInstance(objectMapper);
+ }
+
+}
diff --git a/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/ErrorCodeException.java b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/ErrorCodeException.java
new file mode 100644
index 0000000..fb470ab
--- /dev/null
+++ b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/ErrorCodeException.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright 2017 ZTE Corporation.
+ *
+ * Licensed 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.openo.baseservice.i18n;
+
+public class ErrorCodeException extends Exception {
+
+ private static final long serialVersionUID = 5522808473663280894L;
+
+ private int errorCode;
+
+ /**
+ * Error definition placeholder replacement
+ */
+ private String[] arguments;
+
+ /**
+ * According to the original exception, error code, debug print information and construct a new anomaly placeholder
+ *
+ * @param source
+ * @param errorCode
+ * @param debugMessage
+ * @param arguments
+ */
+ public ErrorCodeException(Throwable source, int errorCode, String debugMessage, String[] arguments) {
+ super(debugMessage, source);
+
+ this.errorCode = errorCode;
+
+ this.arguments = arguments;
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ public String[] getArguments() {
+ return arguments;
+ }
+
+}
diff --git a/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/ErrorCodeI18n.java b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/ErrorCodeI18n.java
new file mode 100644
index 0000000..39738b5
--- /dev/null
+++ b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/ErrorCodeI18n.java
@@ -0,0 +1,151 @@
+/**
+ * Copyright 2017 ZTE Corporation.
+ *
+ * Licensed 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.openo.baseservice.i18n;
+
+import org.openo.baseservice.i18n.DefaultErrorCodeI18n.ErrorCodeLevelUtil;
+import org.openo.baseservice.i18n.DefaultErrorCodeI18n.ErrorItem2;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+
+public interface ErrorCodeI18n {
+
+ static final Logger logger = LoggerFactory.getLogger(ErrorCodeI18n.class);
+
+ /**
+ * Access to the internationalization of the error code examples, scanning the process of all
+ * classes load path, loading all the *-errorcode-*.json files, and load all the international
+ * language information
+ *
+ * @return
+ */
+ static ErrorCodeI18n getInstance() {
+ return DefaultErrorCodeI18n.getInstance();
+ }
+
+ /**
+ * Gets the corresponding error item based on the error code (including the error description
+ * information for all languages)
+ *
+ * @param errorCode
+ * @return Optional<ErrorItem>
+ */
+ public Optional<ErrorItem> getErrorItem(int errorCode);
+
+ public static interface ErrorItem {
+
+ public int getErrorCode();
+
+ public int getLevel();
+
+ public Map<String, String> getLabels();
+
+ public String getLabel(Locale theLocale);
+
+ /**
+ * All language error information description of assembly. <br>
+ *
+ * some modules to store all the error information description or transfer, and finally the time
+ * to choose the appropriate value according to the locale presentation. <br>
+ *
+ * it is not necessary to pass the error code (code), but in order to take into account the
+ * subsequent scalability, so also passed, the general module does not need this information.
+ * Similar form:<br>
+ * { "code":53501, "level":"INFO", "errlabels":{"zh_CN":"拓扑定制文件无效。","en_US":"The topology
+ * customized file is invalid.","ru_RU":"Топология настроенный файл недействительно."} }
+ *
+ * @param errorCode
+ * @return
+ */
+ public String getCanonicalLabels(int errorCode);
+
+ /**
+ * With the use of the above interface, it is possible to obtain an international string
+ * corresponding to a specific language from the combination of all error messages
+ *
+ * @param labels Error message description string (Return value of the getCanonicalLabels
+ * method)
+ * @param theLocale
+ * @return
+ */
+ public static String getLabelFromCanonicalLabels(String labels, Locale theLocale) {
+ if (labels == null || theLocale == null) {
+ return null;
+ }
+ try {
+ ErrorItem2 errorItem2 = I18nJsonUtil.getInstance().readFromJson(labels, ErrorItem2.class);
+ Map<String, String> errlabels = errorItem2.getErrlabels();
+ return errlabels.get(I18nLocaleTransfer.transfer(theLocale, errlabels.keySet()));
+ } catch (Exception e) {
+ logger.info(
+ "getLabelFromCanonicalLabels failed from " + labels + " with local " + theLocale, e);
+ return null;
+ }
+ }
+
+ /**
+ * With the use of the above interface, we can get the error code corresponding to the specific
+ * language from all the error information
+ *
+ * @param labels Error message description string (Return value of the getCanonicalLabels
+ * method)
+ * @param theLocale
+ * @return errorCode
+ */
+ public static int getErrorcodeFromCanonicalLabels(String labels, Locale theLocale) {
+ if (labels == null) {
+ return -1;
+ }
+ try {
+ ErrorItem2 errorItem2 = I18nJsonUtil.getInstance().readFromJson(labels, ErrorItem2.class);
+ return errorItem2.getErrorCode();
+ } catch (Exception e) {
+ logger.info(
+ "getErrorcodeFromCanonicalLabels failed from " + labels + " with local " + theLocale,
+ e);
+ return -1;
+ }
+ }
+
+ /**
+ * With the above interface, the error level of the corresponding string is obtained from all
+ * the error messages
+ *
+ * @param labels Error message description string (Return value of the getCanonicalLabels
+ * method)
+ * @param theLocale
+ * @return error level
+ */
+ public static int getLevelFromCanonicalLabels(String labels, Locale theLocale) {
+ if (labels == null) {
+ return -1;
+ }
+ try {
+ ErrorItem2 errorItem2 = I18nJsonUtil.getInstance().readFromJson(labels, ErrorItem2.class);
+ return ErrorCodeLevelUtil.transfer2Int(errorItem2.getLevel());
+ } catch (Exception e) {
+ logger.info(
+ "getErrorcodeFromCanonicalLabels failed from " + labels + " with local " + theLocale,
+ e);
+ return -1;
+ }
+ }
+ }
+
+}
diff --git a/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18n.java b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18n.java
new file mode 100644
index 0000000..ec9197b
--- /dev/null
+++ b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18n.java
@@ -0,0 +1,132 @@
+/**
+ * Copyright 2017 ZTE Corporation.
+ *
+ * Licensed 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.openo.baseservice.i18n;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+
+public interface I18n {
+ static final Logger logger = LoggerFactory.getLogger(I18n.class);
+
+ /**
+ * Get the corresponding examples of international documents (all languages), <br>
+ *
+ * for the above example topology (for example, the Chinese definition: topo-i18n-zh-CN.json,
+ * English definition Topo -i18n-en-US.json), into the reference into the "TOPO" can be <br>
+ *
+ * (i.e. except "-i18n-*.json" after the exact match).
+ *
+ * @param i18nFilePrefix
+ * @return Optional<I18n>
+ */
+ public static Optional<I18n> getInstance(String i18nFilePrefix) {
+ return I18nContainer.getInstance().getI18n(i18nFilePrefix);
+ }
+
+ /**
+ * According to key, the internationalization of all languages is described (Map<locale,value>)
+ *
+ * @param labelKey key
+ * @return Map<locale,value>
+ */
+ public Map<String, String> getLabelValues(String labelKey);
+
+ /**
+ * According to key, the internationalization of all languages is described
+ *
+ * @param labelKey
+ * @param theLocale
+ * @return
+ */
+ public String getLabelValue(String labelKey, Locale theLocale);
+
+ /**
+ * According to key, the internationalization of all languages is described
+ *
+ * @param labelKey
+ * @param theLocale
+ * @param arguments
+ * @return
+ */
+ public String getLabelValue(String labelKey, Locale theLocale, String[] arguments);
+
+ /**
+ * Replace the placeholder that is defined in the internationalization description, as shown in
+ * the following example, <br>
+ *
+ * {0} represents first bits, which will be replaced by a specific number of days. : <br>
+ *
+ * {"col_dir_file_time_table": "save days {0} days"}
+ *
+ * @param labelKey
+ * @param arguments
+ * @return Map<locale,value>
+ */
+ public Map<String, String> getLabelValues(String labelKey, String[] arguments);
+
+ /**
+ * According to the key to get all the international description of the language, and the results
+ * will be combined into a Json string, used in the log module scene, <br>
+ *
+ * it is necessary to store all of the international information or transfer, and finally show the
+ * time according to locale to choose the appropriate value. <br>
+ *
+ * (here in order to form similar to read, plus a newline) <br>
+ * {"zh_CN":"统一公共应用","en_US":" Unified common application ","ru_RU":"Единый общий приложений"}
+ *
+ * @param labelKey key
+ * @return
+ */
+ public String getCanonicalLabelValues(String labelKey);
+
+ /**
+ * With the use of getCanonicalLabelValues interface, from all the international description of
+ * the combination of string and specific language corresponding to the international string. The
+ * return value of the getCanonicalLabelValues method
+ *
+ * @param values
+ * @param theLocale
+ * @return value
+ */
+ public static String getValuefromCanonicalValues(String values, Locale theLocale) {
+ try {
+ @SuppressWarnings("unchecked")
+ HashMap<String, String> map = I18nJsonUtil.getInstance().readFromJson(values, HashMap.class);
+
+ return map.get(I18nLocaleTransfer.transfer(theLocale, map.keySet()));
+ } catch (Exception e) {
+ logger.error("get i18n value failed by locale:" + theLocale + " from " + values, e);
+ return null;
+ }
+ }
+
+ /**
+ * According to the value to find the corresponding key, such as a module in accordance with
+ * international content filtering, search, database storage is key, then the front pass query is
+ * a kind of language corresponding to the value, to get the corresponding international key to
+ * the database query.
+ *
+ * @param value
+ * @return
+ */
+ public String getKeyFromValue(String value);
+
+}
diff --git a/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nContainer.java b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nContainer.java
new file mode 100644
index 0000000..95ae105
--- /dev/null
+++ b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nContainer.java
@@ -0,0 +1,148 @@
+/**
+ * Copyright 2017 ZTE Corporation.
+ *
+ * Licensed 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.openo.baseservice.i18n;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+
+final class I18nContainer {
+
+ private static Logger logger = LoggerFactory.getLogger(I18nContainer.class);
+
+ private Map<String, I18n> i18ns;
+
+ private I18nContainer() {
+ init();
+ }
+
+
+ private void init() {
+ Map<String, Map<String, I18nItem>> i18nTemps = generateI18ns();
+
+ i18ns = new HashMap<String, I18n>();
+ for (Entry<String, Map<String, I18nItem>> entry : i18nTemps.entrySet()) {
+ String name = entry.getKey();
+ Map<String, I18nItem> items = entry.getValue();
+ for (Entry<String, I18nItem> i18nItemEntry : items.entrySet()) {
+ i18nItemEntry.getValue().unmodifiable();
+ }
+
+ I18n i18n = new I18nImpl(name, items);
+ i18ns.put(name, i18n);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private Map<String, Map<String, I18nItem>> generateI18ns() {
+ Map<String, Map<String, I18nItem>> i18nTemps = new HashMap<String, Map<String, I18nItem>>();
+
+ ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+ JsonResourceScanner.findI18nPaths().forEach((path) -> {
+ HashMap<String, String> fileValues = null;
+ try (InputStream ins = systemClassLoader.getResourceAsStream(path)) {
+ fileValues = I18nJsonUtil.getInstance().readFromJson(ins, HashMap.class);
+ logger.info("load i18n file success: " + path);
+ } catch (IOException ex) {
+ logger.info("load i18n file failed: " + path);
+ logger.info("load i18n file failed: " + systemClassLoader.getResource(path).toString(), ex);
+ return;
+ }
+
+ if (!validateI18nFileValues(fileValues, path)) {
+ return;
+ }
+
+ String fileName = null;
+ int i = path.lastIndexOf("/");
+ if (i > -1) {
+ fileName = path.substring(i + 1);
+ } else {
+ fileName = path;
+ }
+ i = fileName.indexOf("-i18n-");
+ String name = fileName.substring(0, i);
+ String localeSrc = fileName.substring(i + 6, fileName.lastIndexOf("."));
+ if (name.isEmpty()) {
+ logger.info("parse i18n file failed: name is null");
+ return;
+ } else if (localeSrc.isEmpty()) {
+ logger.info("parse i18n file failed: locale is null");
+ return;
+ }
+
+ String[] ss = localeSrc.replace("-", "_").split("_");
+ String locale = null;
+ if (ss.length == 1) {
+ locale = new Locale(ss[0]).toString();
+ } else if (ss.length == 2) {
+ locale = new Locale(ss[0], ss[1]).toString();
+ } else {
+ logger.info("parse i18n file failed: locale is error \"" + localeSrc + "\"");
+ return;
+ }
+
+ Map<String, I18nItem> i18nItems = i18nTemps.get(name);
+ if (i18nItems == null) {
+ i18nItems = new HashMap<String, I18nItem>();
+ i18nTemps.put(name, i18nItems);
+ }
+
+ for (Entry<String, String> entry : fileValues.entrySet()) {
+ String label = entry.getKey();
+
+ I18nItem i18nItem = i18nItems.get(label);
+ if (i18nItem == null) {
+ i18nItem = new I18nItem(label);
+ i18nItems.put(label, i18nItem);
+ }
+
+ i18nItem.addValue(locale, entry.getValue());
+ }
+ });
+ return i18nTemps;
+ }
+
+ private boolean validateI18nFileValues(HashMap<String, String> fileValues, String path) {
+ for (Entry<String, String> entry : fileValues.entrySet()) {
+ if (entry.getValue() != null && !String.class.isInstance(entry.getValue())) {
+ logger.info("parse i18n file failed: " + path + " field's[" + entry.getKey()
+ + "] value is not string type");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected static I18nContainer getInstance() {
+ return I18nContainerSingleton.singleton;
+ }
+
+ Optional<I18n> getI18n(String name) {
+ return Optional.ofNullable(this.i18ns.get(name));
+ }
+
+ static class I18nContainerSingleton {
+ private static final I18nContainer singleton = new I18nContainer();
+ }
+}
diff --git a/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nImpl.java b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nImpl.java
new file mode 100644
index 0000000..bda6f2d
--- /dev/null
+++ b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nImpl.java
@@ -0,0 +1,137 @@
+/**
+ * Copyright 2017 ZTE Corporation.
+ *
+ * Licensed 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.openo.baseservice.i18n;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class I18nImpl implements I18n {
+ private static Logger logger = LoggerFactory.getLogger(I18nImpl.class);
+
+ private String name;
+
+ private Map<String, I18nItem> items;
+
+ private Map<String, String> keyToValueMap;
+
+ private Map<String, String> valueToKeyMap;
+
+
+ public I18nImpl(String name, Map<String, I18nItem> items) {
+ this.name = name;
+ this.items = Collections.unmodifiableMap(items);
+
+ keyToValueMap = new HashMap<>(items.size());
+ valueToKeyMap = new HashMap<>(items.size() * 3);
+
+ try {
+ for (Entry<String, I18nItem> entry : items.entrySet()) {
+ String key = entry.getKey();
+ I18nItem item = entry.getValue();
+ String value = I18nJsonUtil.getInstance().writeToJson(item.getValues());
+
+ keyToValueMap.put(key, value);
+ for (Entry<String, String> valueEntry : item.getValues().entrySet()) {
+ valueToKeyMap.put(valueEntry.getValue(), key);
+ }
+ }
+ } catch (Exception e) {
+ logger.error("new I18nImpl failed:" + name, e);
+ }
+
+ keyToValueMap = Collections.unmodifiableMap(keyToValueMap);
+ valueToKeyMap = Collections.unmodifiableMap(valueToKeyMap);
+ }
+
+ @Override
+ public Map<String, String> getLabelValues(String labelKey) {
+ I18nItem item = items.get(labelKey);
+ if (item != null) {
+ return item.getValues();
+ }
+ return null;
+ }
+
+ @Override
+ public String getLabelValue(String labelKey, Locale theLocale) {
+ I18nItem item = items.get(labelKey);
+ if (item != null) {
+ Map<String, String> values = item.getValues();
+ return values.get(I18nLocaleTransfer.transfer(theLocale, values.keySet()));
+ }
+ return null;
+ }
+
+ @Override
+ public String getLabelValue(String labelKey, Locale theLocale, String[] arguments) {
+ I18nItem item = items.get(labelKey);
+ if (item != null) {
+ Map<String, String> values = item.getValues();
+ String value = values.get(I18nLocaleTransfer.transfer(theLocale, values.keySet()));
+ return replaceArguments(value, arguments);
+ }
+ return null;
+ }
+
+ @Override
+ public Map<String, String> getLabelValues(String labelKey, String[] arguments) {
+ I18nItem item = items.get(labelKey);
+ if (item != null) {
+ Map<String, String> map = new HashMap<String, String>();
+ for (Entry<String, String> entry : item.getValues().entrySet()) {
+ String value = entry.getValue();
+ map.put(entry.getKey(), replaceArguments(value, arguments));
+ }
+ return map;
+ }
+ return null;
+ }
+
+ @Override
+ public String getCanonicalLabelValues(String labelKey) {
+ return keyToValueMap.get(labelKey);
+ }
+
+ @Override
+ public String getKeyFromValue(String aValue) {
+ return valueToKeyMap.get(aValue);
+ }
+
+ private String replaceArguments(String value, String[] arguments) {
+ if (value == null) {
+ return null;
+ }
+ if (arguments != null) {
+ int i = 0;
+ for (String argument : arguments) {
+ if (argument == null) {
+ value = value.replaceAll("\\{\\s*" + i + "\\s*\\}", "");
+ } else {
+ value = value.replaceAll("\\{\\s*" + i + "\\s*\\}", argument);
+ }
+ i++;
+ }
+ }
+ return value.replaceAll("\\{\\s*\\d+\\s*\\}", "");
+ }
+
+}
diff --git a/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nItem.java b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nItem.java
new file mode 100644
index 0000000..1aaaf6f
--- /dev/null
+++ b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nItem.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright 2017 ZTE Corporation.
+ *
+ * Licensed 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.openo.baseservice.i18n;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class I18nItem {
+
+ private String lable;
+
+ private Map<String, String> values;
+
+ public I18nItem(String lable) {
+ this.lable = lable;
+ values = new HashMap<String, String>();
+ }
+
+ public I18nItem(String lable, Map<String, String> values) {
+ this.lable = lable;
+ this.values = values;
+ }
+
+ public String getLable() {
+ return lable;
+ }
+
+ public Map<String, String> getValues() {
+ return values;
+ }
+
+ public void addValue(String locale, String value) {
+ values.put(locale, value);
+ }
+
+ public void unmodifiable() {
+ values = Collections.unmodifiableMap(values);
+ }
+}
diff --git a/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nJsonUtil.java b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nJsonUtil.java
new file mode 100644
index 0000000..e3746dc
--- /dev/null
+++ b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nJsonUtil.java
@@ -0,0 +1,170 @@
+/**
+ * Copyright 2017 ZTE Corporation.
+ *
+ * Licensed 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.openo.baseservice.i18n;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class I18nJsonUtil {
+
+ private static I18nJsonUtil util;
+ private static Lock lock = new ReentrantLock();
+ private ObjectMapper objectMapper;
+
+ public I18nJsonUtil(ObjectMapper objectMapper) {
+ this.objectMapper = objectMapper;
+ }
+
+ <T extends Object> T readFromJson(InputStream ins, Class<T> clazz)
+ throws JsonParseException, JsonMappingException, IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] bs = new byte[1024 * 10];
+ int length = -1;
+ while ((length = ins.read(bs)) > 0) {
+ baos.write(bs, 0, length);
+ }
+ bs = baos.toByteArray();
+
+ byte[] ubs = null;
+ if (bs.length > 3) {
+ // 删除bom头 -17, -69, -65
+ if (bs[0] == -17 && bs[1] == -69 && bs[2] == -65) {
+ ubs = new byte[bs.length - 3];
+ System.arraycopy(bs, 3, ubs, 0, ubs.length);
+ }
+ }
+ if (ubs == null) {
+ ubs = bs;
+ }
+ return objectMapper.readValue(ubs, clazz);
+ }
+
+ <T extends Object> T readFromJson(String str, Class<T> clazz)
+ throws JsonParseException, JsonMappingException, IOException {
+ return objectMapper.readValue(str, clazz);
+ }
+
+ String writeToJson(Object obj) throws JsonProcessingException {
+ return objectMapper.writeValueAsString(obj);
+ }
+
+ static I18nJsonUtil getInstance(ObjectMapper objectMapper) {
+ if (util == null) {
+ lock.lock();
+ try {
+ if (util == null) {
+ if (objectMapper == null) {
+ objectMapper = new ObjectMapper();
+ }
+ util = new I18nJsonUtil(objectMapper);
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+ return util;
+ }
+
+ static I18nJsonUtil getInstance() {
+ return getInstance(null);
+ }
+}
+
+
+/**
+ * 国际化转换工具
+ *
+ * @author 10163976
+ */
+class I18nLocaleTransfer {
+
+ private static Logger LOG = LoggerFactory.getLogger(I18nLocaleTransfer.class);
+
+ /**
+ * 方言转换<br> 如果存在直接返回<br> 如果不存在,则获取语言进行模糊匹配,未匹配上则返回默认方言<br>
+ *
+ * @param theLocale 待转换方言
+ * @param locales 存在的方言
+ * @return 转换后的方言
+ */
+ public static String transfer(Locale theLocale, Set<String> locales) {
+ if (locales == null || locales.isEmpty()) {
+ LOG.debug("locales is NULL or empty");
+ return null;
+ }
+ if (theLocale == null) {
+ String result = fetchDefault(locales);
+ LOG.debug("transfer NULL --> " + result + " in " + locales);
+ return result;
+ }
+ String locale = theLocale.toString();
+ if (locale.isEmpty()) {
+ String result = fetchDefault(locales);
+ LOG.debug("transfer EMPTY --> " + result + " in " + locales);
+ return result;
+ }
+ // 精确匹配
+ if (locales.contains(locale)) {
+ return locale;
+ }
+
+ // 根据语言模糊匹配
+ String language = theLocale.getLanguage();
+ if (locales.contains(language)) {
+ LOG.debug("transfer " + locale + " --> " + language + " in " + locales);
+ return language;
+ }
+
+ language = language + "_";
+ for (String temp : locales) {
+ if (temp.startsWith(language)) {
+ LOG.debug("transfer " + locale + " --> " + temp + " in " + locales);
+ return temp;
+ }
+ }
+ String result = fetchDefault(locales);
+ LOG.debug("transfer " + locale + " --> " + result + " in " + locales);
+ return result;
+ }
+
+ /**
+ * 返回默认方言,优先级为en,en_US,zh,zh_CN,如果都不存在,则随机返回一个
+ */
+ private static String fetchDefault(Set<String> locales) {
+ if (locales.contains("en")) {
+ return "en";
+ } else if (locales.contains("en_US")) {
+ return "en_US";
+ }
+ if (locales.contains("zh")) {
+ return "zh";
+ } else if (locales.contains("zh_CN")) {
+ return "zh_CN";
+ }
+ return locales.iterator().next();
+ }
+}
diff --git a/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nService.java b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nService.java
new file mode 100644
index 0000000..a643356
--- /dev/null
+++ b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/I18nService.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright 2017 ZTE Corporation.
+ *
+ * Licensed 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.openo.baseservice.i18n;
+
+
+import java.util.Optional;
+import org.jvnet.hk2.annotations.Contract;
+import org.openo.baseservice.i18n.ErrorCodeI18n.ErrorItem;
+
+@Contract
+public interface I18nService {
+
+ /**
+ * Get the corresponding examples of international documents (all languages), <br> for the above
+ * example topology (for example, the Chinese definition: topo-i18n-zh-CN.json, English
+ * definition Topo -i18n-en-US.json), into the reference into the "TOPO" can be <br> (i.e.
+ * except "-i18n-*.json" after the exact match).
+ *
+ * @return Optional<I18n>
+ */
+ public Optional<I18n> getI18n(String i18nFilePrefix);
+
+ public Optional<ErrorItem> getErrorItem(int errorCode);
+
+}
diff --git a/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/JsonResourceScanner.java b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/JsonResourceScanner.java
new file mode 100644
index 0000000..9f5ef3a
--- /dev/null
+++ b/baseservice-i18n/src/main/java/org/openo/baseservice/i18n/JsonResourceScanner.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright 2017 ZTE Corporation.
+ *
+ * Licensed 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.openo.baseservice.i18n;
+
+import org.reflections.Reflections;
+import org.reflections.scanners.ResourcesScanner;
+import org.reflections.util.ClasspathHelper;
+import org.reflections.util.ConfigurationBuilder;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+final class JsonResourceScanner {
+ private static final org.slf4j.Logger LOG =
+ org.slf4j.LoggerFactory.getLogger(JsonResourceScanner.class);
+ private static final Pattern PATTERN_OF_I18N_FILE_NAME =
+ Pattern.compile(".*?\\-i18n\\-.*?\\.json");
+ private static final Pattern PATTERN_OF_ERROR_CODE_FILE_NAME =
+ Pattern.compile(".*?\\-errorcode\\-.*?\\.json");
+
+ private static Collection<String> findFromClassPath(Pattern pattern) {
+ ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
+ Collection<URL> urls = ClasspathHelper.forJavaClassPath();
+
+ for (Iterator<URL> iter = urls.iterator(); iter.hasNext();) {
+ URL url = iter.next();
+ boolean exist = false;
+ try {
+ exist = new File(url.getFile()).exists();
+ if (!exist) {
+ LOG.info("class path url ignored for not exists: " + url.toString());
+ }
+ } catch (Exception e) {
+ LOG.info("class path url ignored for exception: " + url.toString(), e);
+ exist = false;
+ }
+ if (!exist) {
+ iter.remove();
+ }
+ }
+ for (URL url : urls) {
+ LOG.info("class path url:" + url.toString());
+ }
+ configurationBuilder.addUrls(urls);
+ configurationBuilder.setScanners(new ResourcesScanner());
+ configurationBuilder.useParallelExecutor();
+ Reflections reflections = new Reflections(configurationBuilder);
+ Set<String> results = reflections.getResources(pattern);
+ if (results == null) {
+ return Collections.emptySet();
+ } else {
+ return results;
+ }
+ }
+
+ static Collection<String> findI18nPaths() {
+ return findFromClassPath(PATTERN_OF_I18N_FILE_NAME);
+ }
+
+ static Collection<String> findErrorCodePaths() {
+ return findFromClassPath(PATTERN_OF_ERROR_CODE_FILE_NAME);
+ }
+}