提交 fa4793ca 编写于 作者: 程剑

Merge branch 'feature/多语言国际化' into 'develop'

多语言国际化框架部分

See merge request o2oa/o2oa!3474
......@@ -10,7 +10,8 @@
/o2server/store/*.war
/o2server/config/
/o2server/store/
/o2server/commons/
/o2server/commons/ext/
/o2server/commons/fonts/
/o2server/jvm/
/o2server/local/
/o2server/configSample/appStyle.json
......
com.x.base.core.project.exception.ExceptionAccessDenied=\u7528\u6237:{} \u6743\u9650\u4E0D\u8DB3.
com.x.base.core.project.exception.ExceptionAccessDenied_1=\u7528\u6237:{} \u8BBF\u95EE\u5BF9\u8C61 class:{}, id:{}, \u6743\u9650\u4E0D\u8DB3.
com.x.base.core.project.exception.ExceptionAccessDeniedOrEntityNotExist=\u7528\u6237:{} \u6743\u9650\u4E0D\u8DB3\u6216\u8005\u5BF9\u8C61\u4E0D\u5B58\u5728.
com.x.base.core.project.exception.ExceptionAccessDeniedOrEntityNotExist_1=\u7528\u6237:{} \u6743\u9650\u4E0D\u8DB3\u6216\u8005\u5BF9\u8C61\u4E0D\u5B58\u5728, {}.
com.x.base.core.project.exception.ExceptionEntityNotExist=\u6807\u8BC6\u4E3A:{} \u7684 {} \u5BF9\u8C61\u4E0D\u5B58\u5728.
com.x.base.core.project.exception.ExceptionEntityNotExist_1=\u6807\u8BC6\u4E3A:{} \u7684\u5BF9\u8C61\u4E0D\u5B58\u5728.
com.x.base.core.project.exception.ExceptionEntityNotExist_2=\u7C7B\u578B\u4E3A: {} \u7684\u5BF9\u8C61\u4E0D\u5B58\u5728.
com.x.base.core.project.exception.ExceptionAccessDenied=User :{} Insufficient permissions.
com.x.base.core.project.exception.ExceptionAccessDenied_1=User :{} access object class:{}, id:{}, insufficient permission.
com.x.base.core.project.exception.ExceptionAccessDeniedOrEntityNotExist=User :{} Insufficient permissions or the object does not exist.
com.x.base.core.project.exception.ExceptionAccessDeniedOrEntityNotExist_1=User :{} Insufficient permission or object does not exist, {}.
com.x.base.core.project.exception.ExceptionEntityNotExist=The {1} object identified as :{0} does not exist.
com.x.base.core.project.exception.ExceptionEntityNotExist_1=The object identified as :{} does not exist.
com.x.base.core.project.exception.ExceptionEntityNotExist_2=Object of type: {} does not exist.
com.x.base.core.project.exception.ExceptionAccessDenied=\u7528\u6237:{} \u6743\u9650\u4E0D\u8DB3.
com.x.base.core.project.exception.ExceptionAccessDenied_1=\u7528\u6237:{} \u8BBF\u95EE\u5BF9\u8C61 class:{}, id:{}, \u6743\u9650\u4E0D\u8DB3.
com.x.base.core.project.exception.ExceptionAccessDeniedOrEntityNotExist=\u7528\u6237:{} \u6743\u9650\u4E0D\u8DB3\u6216\u8005\u5BF9\u8C61\u4E0D\u5B58\u5728.
com.x.base.core.project.exception.ExceptionAccessDeniedOrEntityNotExist_1=\u7528\u6237:{} \u6743\u9650\u4E0D\u8DB3\u6216\u8005\u5BF9\u8C61\u4E0D\u5B58\u5728, {}.
com.x.base.core.project.exception.ExceptionEntityNotExist=\u6807\u8BC6\u4E3A:{} \u7684 {} \u5BF9\u8C61\u4E0D\u5B58\u5728.
com.x.base.core.project.exception.ExceptionEntityNotExist_1=\u6807\u8BC6\u4E3A:{} \u7684\u5BF9\u8C61\u4E0D\u5B58\u5728.
com.x.base.core.project.exception.ExceptionEntityNotExist_2=\u7C7B\u578B\u4E3A: {} \u7684\u5BF9\u8C61\u4E0D\u5B58\u5728.
......@@ -101,6 +101,7 @@ public class Config {
public static final String DIR_COMMONS = "commons";
public static final String DIR_COMMONS_TESS4J_TESSDATA = "commons/tess4j/tessdata";
public static final String DIR_COMMONS_EXT = "commons/ext";
public static final String DIR_COMMONS_LANGUAGE = "commons/language";
public static final String DIR_CONFIG = "config";
public static final String DIR_CONFIG_COVERTOWEBSERVER = "config/coverToWebServer";
public static final String DIR_CONFIGSAMPLE = "configSample";
......
......@@ -45,6 +45,7 @@ public class Person extends ConfigObject {
public static final String DEFAULT_PASSWORDREGEX = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,}$";
public static final String DEFAULT_PASSWORDREGEXHINT = "6位以上,包含数字和字母.";
public static final String DEFAULT_LANGUAGE = "zh_CN";
public Person() {
this.captchaLogin = DEFAULT_CAPTCHALOGIN;
......@@ -59,6 +60,7 @@ public class Person extends ConfigObject {
this.passwordRegexHint = DEFAULT_PASSWORDREGEXHINT;
this.personUnitOrderByAsc = DEFAULT_PERSONUNITORDERBYASC;
this.tokenCookieHttpOnly = DEFAULT_TOKENCOOKIEHTTPONLY;
this.language = DEFAULT_LANGUAGE;
}
public static Person defaultInstance() {
......@@ -118,6 +120,9 @@ public class Person extends ConfigObject {
@FieldDescribe("人员组织排序是否为升序,true为升序(默认),false为降序")
private Boolean personUnitOrderByAsc;
@FieldDescribe("平台语言:zh_CN(中文,默认)、en(英语)")
private String language;
public Boolean getTokenCookieHttpOnly() {
return BooleanUtils.isTrue(this.tokenCookieHttpOnly);
}
......@@ -319,4 +324,12 @@ public class Person extends ConfigObject {
public void setPersonUnitOrderByAsc(Boolean personUnitOrderByAsc) {
this.personUnitOrderByAsc = personUnitOrderByAsc;
}
}
\ No newline at end of file
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
}
......@@ -142,6 +142,8 @@ public class WebServers extends ConcurrentSkipListMap<String, WebServer> {
/* 密码规则 */
map.put("passwordRegex", Config.person().getPasswordRegex());
map.put("passwordRegexHint", Config.person().getPasswordRegexHint());
/* 平台语言 */
map.put("language", Config.person().getLanguage());
/* RSA */
File publicKeyFile = new File(Config.base(), "config/public.key");
......
......@@ -4,26 +4,31 @@ import java.util.Objects;
import com.x.base.core.entity.JpaObject;
import com.x.base.core.project.http.EffectivePerson;
import com.x.base.core.project.tools.LanguageTools;
public class ExceptionAccessDenied extends PromptException {
public class ExceptionAccessDenied extends LanguagePromptException {
private static final long serialVersionUID = -7354813827434276962L;
public static String defaultMessage = "用户:{} 权限不足.";
public ExceptionAccessDenied(String person) {
super("用户:{} 权限不足.", person);
super(defaultMessage, person);
}
public ExceptionAccessDenied(EffectivePerson effectivePerson) {
super("用户:{} 权限不足.", effectivePerson.getDistinguishedName());
super(defaultMessage, effectivePerson.getDistinguishedName());
this.setLanguageKey(this.getClass().getName());
}
public ExceptionAccessDenied(EffectivePerson effectivePerson, JpaObject jpa) {
super("用户:{} 访问对象 class:{}, id:{}, 权限不足.", effectivePerson.getDistinguishedName(),
(null == jpa) ? null : jpa.getClass().getName(), (null == jpa) ? null : jpa.getId());
this.setLanguageKey(this.getClass().getName()+"_1");
}
public ExceptionAccessDenied(EffectivePerson effectivePerson, String message) {
super("用户:{} 权限不足, {}.", effectivePerson.getDistinguishedName(), Objects.toString(message, ""));
super(defaultMessage, effectivePerson.getDistinguishedName(), Objects.toString(message, ""));
}
}
......@@ -3,21 +3,25 @@ package com.x.base.core.project.exception;
import java.util.Objects;
import com.x.base.core.project.http.EffectivePerson;
import com.x.base.core.project.tools.LanguageTools;
public class ExceptionAccessDeniedOrEntityNotExist extends PromptException {
public class ExceptionAccessDeniedOrEntityNotExist extends LanguagePromptException {
private static final long serialVersionUID = -7354813827434276962L;
public static String defaultMessage = "用户:{} 权限不足或者对象不存在.";
public ExceptionAccessDeniedOrEntityNotExist(String person) {
super("用户:{} 权限不足或者对象不存在.", person);
super(defaultMessage, person);
}
public ExceptionAccessDeniedOrEntityNotExist(EffectivePerson effectivePerson) {
super("用户:{} 权限不足或者对象不存在.", effectivePerson.getDistinguishedName());
super(defaultMessage, effectivePerson.getDistinguishedName());
}
public ExceptionAccessDeniedOrEntityNotExist(EffectivePerson effectivePerson, String message) {
super("用户:{} 权限不足或者对象不存在, {}.", effectivePerson.getDistinguishedName(), Objects.toString(message, ""));
this.setLanguageKey(this.getClass().getName()+"_1");
}
}
......@@ -2,37 +2,42 @@ package com.x.base.core.project.exception;
import java.util.List;
import com.x.base.core.project.tools.LanguageTools;
import org.apache.commons.lang3.StringUtils;
import com.x.base.core.entity.JpaObject;
public class ExceptionEntityNotExist extends PromptException {
public class ExceptionEntityNotExist extends LanguagePromptException {
private static final long serialVersionUID = -7354813827434276962L;
public static String defaultMessage = "标识为:{} 的 {} 对象不存在.";
public ExceptionEntityNotExist(String flag, JpaObject jpa) {
super("标识为:{} 的 {} 对象不存在.", flag, (null == jpa) ? null : jpa.nameOfEntity());
super(defaultMessage, flag, (null == jpa) ? null : jpa.nameOfEntity());
}
public <T extends JpaObject> ExceptionEntityNotExist(String flag, Class<T> cls) {
super("标识为:{} 的 {} 对象不存在.", flag, (null == cls) ? null : cls.getSimpleName());
super(defaultMessage, flag, (null == cls) ? null : cls.getSimpleName());
}
public <T extends JpaObject> ExceptionEntityNotExist(List<String> ids, Class<T> cls) {
super("标识为:{} 的 {} 对象不存在.", (null == ids) ? null : StringUtils.join(ids, ","),
super(defaultMessage, (null == ids) ? null : StringUtils.join(ids, ","),
(null == cls) ? null : cls.getSimpleName());
}
public <T extends JpaObject> ExceptionEntityNotExist(String flag, String name) {
super("标识为:{} 的 {} 对象不存在.", flag, name);
super(defaultMessage, flag, name);
}
public <T extends JpaObject> ExceptionEntityNotExist(String flag) {
super("标识为:{} 的对象不存在.", flag);
this.setLanguageKey(this.getClass().getName()+"_1");
}
public <T extends JpaObject> ExceptionEntityNotExist(Class<T> cls) {
super("类型为: {} 的对象不存在.", cls.getSimpleName());
this.setLanguageKey(this.getClass().getName()+"_2");
}
}
package com.x.base.core.project.exception;
import com.x.base.core.project.logger.MessageFormatter;
import com.x.base.core.project.tools.LanguageTools;
import org.apache.commons.lang3.StringUtils;
public abstract class LanguagePromptException extends PromptException {
private static final long serialVersionUID = -1212029031489695352L;
private Object[] argArray = null;
private String languageKey = null;
public LanguagePromptException() {
super();
}
public LanguagePromptException(String message) {
super(message);
}
public LanguagePromptException(String message, Object... os) {
super(format(message, os));
this.argArray = os;
}
public LanguagePromptException(Throwable cause) {
super(cause);
}
public LanguagePromptException(Throwable cause, String message) {
super(message, cause);
}
public LanguagePromptException(Throwable cause, String message, Object... os) {
super(format(message, os), cause);
this.argArray = os;
}
public String getFormatMessage(String key, String language){
if(StringUtils.isNotBlank(language)){
language = StringUtils.split(language, ",")[0].trim();
}
if(StringUtils.isNotBlank(this.languageKey)){
key = this.languageKey;
}
String languageString = LanguageTools.getValue(key, language);
if(this.argArray!=null && StringUtils.isNotBlank(languageString)){
languageString = MessageFormatter.arrayFormat(languageString, this.argArray).getMessage();
}
return languageString;
}
public String getLanguageKey() {
return languageKey;
}
public void setLanguageKey(String languageKey) {
this.languageKey = languageKey;
}
}
......@@ -9,6 +9,7 @@ import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.Response;
import com.x.base.core.project.exception.LanguagePromptException;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jetty.http.HttpHeader;
......@@ -26,6 +27,8 @@ public class ResponseFactory {
public static final String Accept_Ranges = "Accept-Ranges";
public static final String Content_Type = "Content-Type";
public static final String Content_Length = "Content-Length";
public static final String Accept_Language = "Accept-Language";
public static <T> Response getDefaultActionResultResponse(ActionResult<T> result) {
if (result.getType().equals(ActionResult.Type.error)) {
......@@ -73,6 +76,13 @@ public class ResponseFactory {
public static <T> Response getEntityTagActionResultResponse(HttpServletRequest request, ActionResult<T> result) {
if (result.getType().equals(ActionResult.Type.error)) {
if ((result.throwable instanceof LanguagePromptException)) {
LanguagePromptException e = (LanguagePromptException)result.throwable;
String message = e.getFormatMessage(result.getPrompt(), request.getHeader(Accept_Language));
if(StringUtils.isNotBlank(message)) {
result.setMessage(message);
}
}
if ((result.throwable instanceof CallbackPromptException)) {
return Response.ok(callbackError(result)).build();
} else {
......
......@@ -25,6 +25,8 @@ package com.x.base.core.project.logger;
*
*/
import org.apache.commons.lang3.StringUtils;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
......@@ -100,6 +102,7 @@ final public class MessageFormatter {
static final char DELIM_START = '{';
static final char DELIM_STOP = '}';
static final String DELIM_STR = "{}";
static final String DELIM_STR2 = "{%d}";
private static final char ESCAPE_CHAR = '\\';
/**
......@@ -200,7 +203,16 @@ final public class MessageFormatter {
StringBuilder sbuf = new StringBuilder(messagePattern.length() + 50);
int L;
String message = messagePattern;
for (L = 0; L < argArray.length; L++) {
j = messagePattern.indexOf(String.format(DELIM_STR2, L));
if(j > -1){
message = StringUtils.replace(message, String.format(DELIM_STR2, L), (String)argArray[L]);
if(L == argArray.length-1){
return new FormattingTuple(message, argArray, throwable);
}
continue;
}
j = messagePattern.indexOf(DELIM_STR, i);
......
package com.x.base.core.project.tools;
import com.x.base.core.project.config.Config;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;
import org.apache.commons.lang3.StringUtils;
import java.util.Locale;
import java.util.ResourceBundle;
public class LanguageTools {
private static Logger logger = LoggerFactory.getLogger(LanguageTools.class);
private final static String LANGUAGE_PLATFORM = "language.platform";
public static String getValue(String key) {
return getValue(key, null);
}
public static String getValue(String key, String locale) {
String message = null;
if(StringUtils.isBlank(key)){
return null;
}
try {
ResourceBundle resourceBundle = null;
if(StringUtils.isBlank(locale)){
try {
locale = Config.person().getLanguage();
} catch (Exception e) {
}
}
if(StringUtils.isBlank(locale)){
resourceBundle = ResourceBundle.getBundle(LANGUAGE_PLATFORM, Locale.getDefault());
}else if("zh".equalsIgnoreCase(locale) || "zh_CN".equalsIgnoreCase(locale)) {
resourceBundle = ResourceBundle.getBundle(LANGUAGE_PLATFORM, Locale.SIMPLIFIED_CHINESE);
}else if(locale.toLowerCase().startsWith("en")) {
resourceBundle = ResourceBundle.getBundle(LANGUAGE_PLATFORM, Locale.ENGLISH);
}else if("zh_HK".equalsIgnoreCase(locale) || "zh_TW".equalsIgnoreCase(locale)) {
resourceBundle = ResourceBundle.getBundle(LANGUAGE_PLATFORM, Locale.TRADITIONAL_CHINESE);
}else{
resourceBundle = ResourceBundle.getBundle(LANGUAGE_PLATFORM, Locale.getDefault());
}
message = resourceBundle.getString(key);
} catch (Exception e) {
logger.print("LanguageTools resourceBundle error:"+e.getMessage());
}
return message;
}
public static String getValue(String baseName ,String key, String locale) {
String message = null;
if(StringUtils.isBlank(key)){
return null;
}
try {
ResourceBundle resourceBundle = null;
if(StringUtils.isBlank(locale)){
try {
locale = Config.person().getLanguage();
} catch (Exception e) {
}
}
if(StringUtils.isBlank(locale)){
resourceBundle = ResourceBundle.getBundle(baseName, Locale.getDefault());
}else if("zh".equalsIgnoreCase(locale) || "zh_CN".equalsIgnoreCase(locale)) {
resourceBundle = ResourceBundle.getBundle(baseName, Locale.SIMPLIFIED_CHINESE);
}else if(locale.toLowerCase().startsWith("en")) {
resourceBundle = ResourceBundle.getBundle(baseName, Locale.ENGLISH);
}else if("zh_HK".equalsIgnoreCase(locale) || "zh_TW".equalsIgnoreCase(locale)) {
resourceBundle = ResourceBundle.getBundle(baseName, Locale.TRADITIONAL_CHINESE);
}else{
resourceBundle = ResourceBundle.getBundle(baseName, Locale.getDefault());
}
message = resourceBundle.getString(key);
} catch (Exception e) {
logger.print("LanguageTools resourceBundle error:"+e.getMessage());
}
return message;
}
}
......@@ -10,6 +10,7 @@ public class PathTools {
public static final String WEB_INF = "WEB-INF";
public static final String WEB_INF_WEB_XML = "WEB-INF/web.xml";
public static final String WEB_INF_CLASSES = "WEB-INF/classes";
public static final String WEB_INF_CLASSES_LANGUAGE = "WEB-INF/classes/language";
public static final String WEB_INF_LASTMODIFIED = "WEB-INF/lastModified";
public static final String META_INF = "META";
public static final String DOT_WAR = ".war";
......
......@@ -21,6 +21,8 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import ch.qos.logback.core.rolling.TimeBasedFileNamingAndTriggeringPolicyBase;
import com.x.base.core.project.tools.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.file.PathUtils;
......@@ -71,12 +73,6 @@ import com.x.base.core.project.config.Config;
import com.x.base.core.project.jaxrs.DenialOfServiceFilter;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;
import com.x.base.core.project.tools.ClassLoaderTools;
import com.x.base.core.project.tools.DefaultCharset;
import com.x.base.core.project.tools.JarTools;
import com.x.base.core.project.tools.ListTools;
import com.x.base.core.project.tools.PathTools;
import com.x.base.core.project.tools.StringTools;
import com.x.server.console.server.JettySeverTools;
import io.github.classgraph.ClassGraph;
......@@ -316,7 +312,7 @@ public class ApplicationServerTools extends JettySeverTools {
}
}
private static void modified(Path war, Path dir) throws IOException {
private static void modified(Path war, Path dir) throws Exception {
Path lastModified = Paths.get(dir.toString(), PathTools.WEB_INF_LASTMODIFIED);
if ((!Files.exists(lastModified)) || Files.isDirectory(lastModified)
|| (Files.getLastModifiedTime(war).toMillis() != NumberUtils
......@@ -332,6 +328,18 @@ public class ApplicationServerTools extends JettySeverTools {
}
FileUtils.writeStringToFile(lastModified.toFile(), Files.getLastModifiedTime(war).toMillis() + "",
DefaultCharset.charset_utf_8, false);
File commonLang = new File(Config.DIR_COMMONS_LANGUAGE);
if(commonLang.exists() && commonLang.isDirectory()){
File languageDir = new File(dir.toString(), PathTools.WEB_INF_CLASSES_LANGUAGE);
FileTools.forceMkdir(languageDir);
File[] files = commonLang.listFiles();
for(File file : files){
if(!file.isDirectory()){
File languageFile = new File(languageDir, file.getName());
FileUtils.copyFile(file, languageFile);
}
}
}
}
}
}
\ No newline at end of file
}
package com.x.organization.assemble.personal.jaxrs.person;
import java.io.File;
import java.util.List;
import javax.persistence.EntityManager;
......@@ -8,6 +9,9 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;
import com.x.base.core.project.tools.LanguageTools;
import org.apache.commons.collections4.set.ListOrderedSet;
import org.apache.commons.lang3.StringUtils;
......@@ -40,6 +44,8 @@ import java.util.Optional;
class ActionGet extends BaseAction {
private static Logger logger = LoggerFactory.getLogger(ActionGet.class);
ActionResult<Wo> execute(EffectivePerson effectivePerson) throws Exception {
try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
Business business = new Business(emc);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册