📄 paodingmaker.java
字号:
/**
* Copyright 2007 The Apache Software Foundation
*
* 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 net.paoding.analysis.knife;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import net.paoding.analysis.Constants;
import net.paoding.analysis.analyzer.impl.MostWordsModeDictionariesCompiler;
import net.paoding.analysis.analyzer.impl.SortingDictionariesCompiler;
import net.paoding.analysis.dictionary.support.detection.Difference;
import net.paoding.analysis.dictionary.support.detection.DifferenceListener;
import net.paoding.analysis.exception.PaodingAnalysisException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*
* @author Zhiliang Wang [qieqie.wang@gmail.com]
*
* @since 2.0.0
*/
public class PaodingMaker {
public static final String DEFAULT_PROPERTIES_PATH = "classpath:paoding-analysis.properties";
private PaodingMaker() {
}
private static Log log = LogFactory.getLog(PaodingMaker.class);
private static ObjectHolder/* <Properties> */propertiesHolder = new ObjectHolder/* <Properties> */();
private static ObjectHolder/* <Paoding> */paodingHolder = new ObjectHolder/* <Paoding> */();
// ----------------获取Paoding对象的方法-----------------------
/**
*
* 读取类路径下的paoding-analysis.properties文件,据之获取一个Paoding对象.
* <p>
* 第一次调用本方法时,从该属性文件中读取配置,并创建一个新的Paoding对象,之后,如果
* 属性文件没有变更过,则每次调用本方法都将返回先前创建的Paoding对象。而不重新构建 Paoding对象。
* <p>
*
* 如果配置文件没有变更,但词典文件有变更。仍然是返回同样的Paoding对象。而且是,只要
* 词典文件发生了变更,Paoding对象在一定时间内会收到更新的。所以返回的Paoding对象 一定是最新配置的。
*
*
*
* @return
*/
public static Paoding make() {
return make(DEFAULT_PROPERTIES_PATH);
}
/**
* 读取类指定路径的配置文件(如果配置文件放置在类路径下,则应该加"classpath:"为前缀),据之获取一个新的Paoding对象.
* <p>
*
* 第一次调用本方法时,从该属性文件中读取配置,并创建一个新的Paoding对象,之后,如果
* 属性文件没有变更过,则每次调用本方法都将返回先前创建的Paoding对象。而不重新构建 Paoding对象。
* <p>
*
* 如果配置文件没有变更,但词典文件有变更。仍然是返回同样的Paoding对象。而且是,只要
* 词典文件发生了变更,Paoding对象在一定时间内会收到更新的。所以返回的Paoding对象 一定是最新配置的。
*
* @param propertiesPath
* @return
*/
public static Paoding make(String propertiesPath) {
return make(getProperties(propertiesPath));
}
/**
* 根据给定的属性对象获取一个Paoding对象.
* <p>
*
* @param properties
* @return
*/
public static Paoding make(Properties p) {
postPropertiesLoaded(p);
return implMake(p);
}
// --------------------------------------------------
public static Properties getProperties() {
return getProperties(DEFAULT_PROPERTIES_PATH);
}
public static Properties getProperties(String path) {
if (path == null) {
throw new NullPointerException("path should not be null!");
}
try {
//
Properties p = (Properties) propertiesHolder.get(path);
if (p == null || modified(p)) {
p = loadProperties(new Properties(), path);
propertiesHolder.set(path, p);
paodingHolder.remove(path);
postPropertiesLoaded(p);
String absolutePaths = p.getProperty("paoding.analysis.properties.files.absolutepaths");
log.info("config paoding analysis from: " + absolutePaths);
}
return p;
} catch (IOException e) {
throw new PaodingAnalysisException(e);
}
}
// -------------------私有 或 辅助方法----------------------------------
private static boolean modified(Properties p)
throws IOException {
String lastModifieds = p
.getProperty("paoding.analysis.properties.lastModifieds");
String[] lastModifedsArray = lastModifieds.split(";");
String files = p.getProperty("paoding.analysis.properties.files");
String[] filesArray = files.split(";");
for (int i = 0; i < filesArray.length; i++) {
File file = getFile(filesArray[i]);
if (file.exists() && !String.valueOf(getFileLastModified(file)).equals(lastModifedsArray[i])) {
return true;
}
}
return false;
}
private static Properties loadProperties(Properties p, String path)
throws IOException {
URL url;
File file;
String absolutePath;
InputStream in;
// 若ifexists为真表示如果该文件存在则读取他的内容,不存在则忽略它
boolean skipWhenNotExists = false;
if (path.startsWith("ifexists:")) {
skipWhenNotExists = true;
path = path.substring("ifexists:".length());
}
if (path.startsWith("classpath:")) {
path = path.substring("classpath:".length());
url = getClassLoader().getResource(path);
if (url == null) {
if (skipWhenNotExists) {
return p;
}
throw new FileNotFoundException("Not found " + path
+ " in classpath.");
}
file = new File(url.getFile());
in = url.openStream();
} else {
if (path.startsWith("dic-home:")) {
File dicHome = new File(getDicHome(p));
path = path.substring("dic-home:".length());
file = new File(dicHome, path);
}
else {
file = new File(path);
}
if (skipWhenNotExists && !file.exists()) {
return p;
}
in = new FileInputStream(file);
}
absolutePath = file.getAbsolutePath();
p.load(in);
in.close();
String lastModifieds = p.getProperty("paoding.analysis.properties.lastModifieds");
String files = p.getProperty("paoding.analysis.properties.files");
String absolutePaths = p.getProperty("paoding.analysis.properties.files.absolutepaths");
if (lastModifieds == null) {
p.setProperty("paoding.dic.properties.path", path);
lastModifieds = String.valueOf(getFileLastModified(file));
files = path;
absolutePaths = absolutePath;
} else {
lastModifieds = lastModifieds + ";" + getFileLastModified(file);
files = files + ";" + path;
absolutePaths = absolutePaths + ";" + absolutePath;
}
p.setProperty("paoding.analysis.properties.lastModifieds", lastModifieds);
p.setProperty("paoding.analysis.properties.files", files);
p.setProperty("paoding.analysis.properties.files.absolutepaths", absolutePaths);
String importsValue = p.getProperty("paoding.imports");
if (importsValue != null) {
p.remove("paoding.imports");
String[] imports = importsValue.split(";");
for (int i = 0; i < imports.length; i++) {
loadProperties(p, imports[i]);
}
}
return p;
}
private static long getFileLastModified(File file) throws IOException {
String path = file.getPath();
int jarIndex = path.indexOf(".jar!");
if (jarIndex == -1) {
return file.lastModified();
}
else {
path = path.replaceAll("%20", " ").replaceAll("\\\\", "/");
int protocalIndex = path.indexOf(":");
String jarPath = path.substring(protocalIndex + ":".length(), jarIndex + ".jar".length());
File jarPathFile = new File(jarPath);
JarFile jarFile;
try {
jarFile = new JarFile(jarPathFile);
String entryPath = path.substring(jarIndex + ".jar!/".length());
JarEntry entry = jarFile.getJarEntry(entryPath);
return entry.getTime();
} catch (IOException e) {
System.err.println("error in handler path=" + path);
System.err.println("error in handler jarPath=" + jarPath);
throw e;
}
}
}
private static String getDicHome(Properties p) {
setDicHomeProperties(p);
return p.getProperty("paoding.dic.home.absolute.path");
}
private static void postPropertiesLoaded(Properties p) {
if ("done".equals(p.getProperty("paoding.analysis.postPropertiesLoaded"))) {
return;
}
setDicHomeProperties(p);
p.setProperty("paoding.analysis.postPropertiesLoaded", "done");
}
private static void setDicHomeProperties(Properties p) {
String dicHomeAbsultePath = p.getProperty("paoding.dic.home.absolute.path");
if (dicHomeAbsultePath != null) {
return;
}
// 获取词典安装目录配置:
// 如配置了PAODING_DIC_HOME环境变量,则将其作为字典的安装主目录
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -