Browse Source

REPORT-12850 10.0mac公式不显示=>FunctionConstants 重构

bugfix/10.0
plough 6 years ago
parent
commit
b8455e82a4
  1. 253
      designer-base/src/main/java/com/fr/design/formula/FunctionConstants.java
  2. 40
      designer-base/src/test/java/com/fr/design/formula/FunctionConstantsTest.java

253
designer-base/src/main/java/com/fr/design/formula/FunctionConstants.java

@ -35,13 +35,75 @@ import java.util.zip.ZipFile;
import javax.swing.DefaultListModel; import javax.swing.DefaultListModel;
public abstract class FunctionConstants { public final class FunctionConstants {
public static FunctionGroup PLUGIN = getPluginFunctionGroup();
public static FunctionGroup CUSTOM = getCustomFunctionGroup();
static NameAndFunctionList COMMON = getCommonFunctionList();
static NameAndTypeAndFunctionList[] EMBFUNCTIONS = getEmbededFunctionListArray();
public static FunctionGroup ALL = getAllFunctionGroup();
static {
loadEmbededFunctions();
}
/**
* Don't let anyone instantiate this class.
*/
private FunctionConstants() {}
private static void loadEmbededFunctions() {
String pkgName = "com.fr.function";
Class<Function> iface = Function.class;
ClassLoader classloader = iface.getClassLoader();
Enumeration<URL> urlEnumeration = null;
try {
urlEnumeration = classloader.getResources(pkgName.replace('.', '/'));
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage());
return;
}
while (urlEnumeration.hasMoreElements()) {
URL url = urlEnumeration.nextElement();
String classFilePath = url.getFile();
/*
* alex:url.getFile获取的地址中,如果有空格或中文会被URLEncoder.encode处理
* 会变成%20这种%打头的东西,但是new File的时候%20是无法解析成空格,所以在此需要做URLDecoder.decode处理
*/
try {
classFilePath = URLDecoder.decode(classFilePath, EncodeConstants.ENCODING_UTF_8);
} catch (UnsupportedEncodingException e1) {
FRContext.getLogger().error(e1.getMessage(), e1);
}
FRContext.getLogger().info("ClassFilePath:" + classFilePath);
/*
* alex:如果是jar包中的class文件
* file:/D:/opt/FineReport6.5/WebReport/WEB-INF/lib/fr-server-6.5.jar!/com/fr/rpt/script/function
*/
for (String fileName : findClassNamesUnderFilePath(classFilePath)) {
try {
Class<?> cls = Class.forName(pkgName + "." + fileName.substring(0, fileName.length() - 6));
if (StableUtils.classInstanceOf(cls, iface)) {
Function inst;
inst = (Function)cls.newInstance();
for (NameAndTypeAndFunctionList EMBFUNCTION : EMBFUNCTIONS) {
if (EMBFUNCTION.test(inst)) {
break;
}
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException ignore) {
}
}
}
}
/** /**
* 将函数分组插件中的函数添加到对应的列表中 * 将函数分组插件中的函数添加到对应的列表中
* @param listModel * @param listModel
*/ */
public static void addFunctionGroupFromPlugins(DefaultListModel listModel){ static void addFunctionGroupFromPlugins(DefaultListModel listModel){
//hugh:自定义函数分组 //hugh:自定义函数分组
Set<Mutable> containers = ExtraClassManager.getInstance().getArray(FunctionDefContainer.MARK_STRING); Set<Mutable> containers = ExtraClassManager.getInstance().getArray(FunctionDefContainer.MARK_STRING);
if(!containers.isEmpty()){ if(!containers.isEmpty()){
@ -76,7 +138,63 @@ public abstract class FunctionConstants {
}; };
} }
public static FunctionGroup PLUGIN = new FunctionGroup() {
private static String[] findClassNamesUnderFilePath(String filePath) {
java.util.List<String> classNameList = new ArrayList<String>();
/*
* alex:如果是jar包中的class文件
* file:/D:/opt/FineReport6.5/WebReport/WEB-INF/lib/fr-server-6.5.jar!/com/fr/rpt/script/function
*/
if (filePath.contains("!/")) {
String[] arr = filePath.split("!/");
String jarPath = arr[0].substring(6); // alex:substring(6)去掉前面的file:/这六个字符
String classPath = arr[1];
if(classPath.endsWith("/")){
classPath = classPath.substring(0, classPath.length() - 1);
}
if (!OperatingSystem.isWindows()){
//windows里substring后是d:\123\456, mac下substring后是Application/123/456
jarPath = StringUtils.perfectStart(jarPath, "/");
}
ZipFile zip;
try {
zip = new ZipFile(jarPath);
Enumeration entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
if (entry.isDirectory()) {
continue;
}
String entryName = entry.getName();
if (!entryName.contains(classPath) || !entryName.endsWith(".class")) {
continue;
}
classNameList.add(entryName.substring(classPath.length() + 1));
}
} catch (IOException e) {
FRContext.getLogger().error(e.getMessage(), e);
}
} else {
File dir = new File(filePath);
File[] files = dir.listFiles();
if (files != null) {
for (File f : files) {
String fileName = f.getName();
if (fileName.endsWith(".class")) {
classNameList.add(fileName);
}
}
}
}
return classNameList.toArray(new String[0]);
}
private static FunctionGroup getPluginFunctionGroup() {
return new FunctionGroup() {
@Override @Override
public String getGroupName() { public String getGroupName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Base_Formula_Plugin"); return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Base_Formula_Plugin");
@ -93,8 +211,10 @@ public abstract class FunctionConstants {
return nads; return nads;
} }
}; };
}
public static FunctionGroup CUSTOM = new FunctionGroup() { private static FunctionGroup getCustomFunctionGroup() {
return new FunctionGroup() {
@Override @Override
public String getGroupName() { public String getGroupName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Custom_Function"); return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Custom_Function");
@ -117,12 +237,16 @@ public abstract class FunctionConstants {
return new NameAndDescription[0]; return new NameAndDescription[0];
} }
}; };
}
public static NameAndFunctionList COMMON = new NameAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Most_Recently_Used"), new Function[] { private static NameAndFunctionList getCommonFunctionList() {
return new NameAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Most_Recently_Used"), new Function[] {
new SUM(), new COUNT(), new AVERAGE(), new CHAR(), new DATE(), new MAX(), new MIN(), new TIME(), new RANGE() new SUM(), new COUNT(), new AVERAGE(), new CHAR(), new DATE(), new MAX(), new MIN(), new TIME(), new RANGE()
}); });
}
public static NameAndTypeAndFunctionList[] EMBFUNCTIONS = new NameAndTypeAndFunctionList[] { private static NameAndTypeAndFunctionList[] getEmbededFunctionListArray() {
return new NameAndTypeAndFunctionList[] {
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Math_&_Trig"), Function.MATH), new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Math_&_Trig"), Function.MATH),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Text"), Function.TEXT), new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Text"), Function.TEXT),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Date_&_Time"), Function.DATETIME), new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Date_&_Time"), Function.DATETIME),
@ -132,8 +256,10 @@ public abstract class FunctionConstants {
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Other"), Function.OTHER), new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Other"), Function.OTHER),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Function_Type_Hierarchy"), Function.HA) new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Function_Type_Hierarchy"), Function.HA)
}; };
}
public static FunctionGroup ALL = new FunctionGroup() { private static FunctionGroup getAllFunctionGroup() {
return new FunctionGroup() {
@Override @Override
public String getGroupName() { public String getGroupName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_All"); return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_All");
@ -154,121 +280,16 @@ public abstract class FunctionConstants {
Collections.addAll(all,createFunctionGroup(((FunctionDefContainer)container)).getDescriptions()); Collections.addAll(all,createFunctionGroup(((FunctionDefContainer)container)).getDescriptions());
} }
} }
java.util.Collections.sort(all, NameAndDescriptionComparator);
return all.toArray(new NameAndDescription[all.size()]);
}
};
Collections.sort(all, new Comparator<NameAndDescription>() {
private static Comparator<NameAndDescription> NameAndDescriptionComparator = new Comparator<NameAndDescription>() {
@Override @Override
public int compare(NameAndDescription o1, NameAndDescription o2) { public int compare(NameAndDescription o1, NameAndDescription o2) {
return ComparatorUtils.compare(o1.getName(), o2.getName()); return ComparatorUtils.compare(o1.getName(), o2.getName());
} }
}; });
private static String[] findClassNamesUnderFilePath(String filePath) {
java.util.List<String> classNameList = new ArrayList<String>();
/*
* alex:如果是jar包中的class文件
* file:/D:/opt/FineReport6.5/WebReport/WEB-INF/lib/fr-server-6.5.jar!/com/fr/rpt/script/function
*/
if (filePath.indexOf("!/") >= 0) {
String[] arr = filePath.split("!/");
String jarPath = arr[0].substring(6); // alex:substring(6)去掉前面的file:/这六个字符
String classPath = arr[1];
if(classPath.endsWith("/")){
classPath = classPath.substring(0, classPath.length() - 1);
}
if (!OperatingSystem.isWindows()){
//windows里substring后是d:\123\456, mac下substring后是Application/123/456
jarPath = StringUtils.perfectStart(jarPath, "/");
}
ZipFile zip;
try {
zip = new ZipFile(jarPath);
Enumeration entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
if (entry.isDirectory()) {
continue;
}
String entryName = entry.getName();
if (entryName.indexOf(classPath) < 0 || !entryName.endsWith(".class")) {
continue;
}
classNameList.add(entryName.substring(classPath.length() + 1));
}
} catch (IOException e) {
FRContext.getLogger().error(e.getMessage(), e);
}
} else {
File dir = new File(filePath);
for (File f : dir.listFiles()) {
String fileName = f.getName();
if (fileName.endsWith(".class")) {
classNameList.add(fileName);
}
}
}
return classNameList.toArray(new String[classNameList.size()]);
}
// alex:读取com.fr.script.function包下面所有的Function类
static {
String pkgName = "com.fr.function";
Class<Function> iface = Function.class;
ClassLoader classloader = iface.getClassLoader();
Enumeration<URL> urlEnumeration = null;
try {
urlEnumeration = classloader.getResources(pkgName.replace('.', '/'));
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
while (urlEnumeration.hasMoreElements()) {
URL url = urlEnumeration.nextElement();
String classFilePath = url.getFile();
/*
* alex:url.getFile获取的地址中,如果有空格或中文会被URLEncoder.encode处理
* 会变成%20这种%打头的东西,但是new File的时候%20是无法解析成空格,所以在此需要做URLDecoder.decode处理
*/
try {
classFilePath = URLDecoder.decode(classFilePath, EncodeConstants.ENCODING_UTF_8);
} catch (UnsupportedEncodingException e1) {
FRContext.getLogger().error(e1.getMessage(), e1);
}
FRContext.getLogger().info("ClassFilePath:" + classFilePath);
/*
* alex:如果是jar包中的class文件
* file:/D:/opt/FineReport6.5/WebReport/WEB-INF/lib/fr-server-6.5.jar!/com/fr/rpt/script/function
*/
for (String fileName : findClassNamesUnderFilePath(classFilePath)) {
try {
Class<?> cls = Class.forName(pkgName + "." + fileName.substring(0, fileName.length() - 6));
System.out.println(pkgName + "." + fileName.substring(0, fileName.length() - 6));
if (StableUtils.classInstanceOf(cls, iface)) {
Function inst;
inst = (Function)cls.newInstance();
for (int fi = 0; fi < EMBFUNCTIONS.length; fi++) {
if (EMBFUNCTIONS[fi].test(inst)) {
break;
}
}
return all.toArray(new NameAndDescription[0]);
} }
} catch (ClassNotFoundException e) { };
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
}
}
}
} }
} }

40
designer-base/src/test/java/com/fr/design/formula/FunctionConstantsTest.java

@ -0,0 +1,40 @@
package com.fr.design.formula;
import org.junit.Test;
import static junit.framework.Assert.fail;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
/**
* Created by plough on 2018/12/7.
*/
public class FunctionConstantsTest {
@Test
public void testNewInstanceFail() throws Exception {
try {
FunctionConstants.class.newInstance();
fail("Not allowed to instantiate FunctionConstants!");
} catch (IllegalAccessException e) {
assertTrue(true);
}
}
@Test
public void testEmbedFuntionsAfterStaticInit() {
NameAndTypeAndFunctionList[] embFunctionLists = FunctionConstants.EMBFUNCTIONS;
// 一共有 8 个分类
assertEquals(8, embFunctionLists.length);
for (NameAndTypeAndFunctionList embFunctionsList : embFunctionLists) {
// 每个分类下都有函数
NameAndDescription[] nameAndDescriptions = embFunctionsList.getDescriptions();
assertTrue(nameAndDescriptions.length > 0);
}
}
@Test
public void testCommonFuntionsAfterStaticInit() {
NameAndFunctionList commonFunctionList = FunctionConstants.COMMON;
assertEquals(9, commonFunctionList.getDescriptions().length);
}
}
Loading…
Cancel
Save