Skip to content

Commit f3c8e77

Browse files
committed
refactoring
1 parent 59870fd commit f3c8e77

File tree

5 files changed

+87
-75
lines changed

5 files changed

+87
-75
lines changed

jcp/src/main/java/com/igormaznitsa/jcp/InfoHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public static List<String> makeTextForHelpInfo() {
118118
result.add(DELIMITER);
119119
result.add("Functions");
120120
result.add(SHORT_DELIMITER);
121-
for (final AbstractFunction handler : AbstractFunction.getAllFunctions()) {
121+
for (final AbstractFunction handler : AbstractFunction.findAllFunctions()) {
122122
result.add(makeFunctionReference(handler));
123123
}
124124
result.add(DELIMITER);

jcp/src/main/java/com/igormaznitsa/jcp/expression/functions/AbstractFunction.java

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@
3535
import com.igormaznitsa.jcp.expression.functions.xml.FunctionXML_TEXT;
3636
import com.igormaznitsa.jcp.expression.functions.xml.FunctionXML_XELEMENT;
3737
import com.igormaznitsa.jcp.expression.functions.xml.FunctionXML_XLIST;
38+
import java.util.Comparator;
39+
import java.util.List;
3840
import java.util.Map;
3941
import java.util.concurrent.atomic.AtomicLong;
42+
import java.util.concurrent.atomic.AtomicReference;
4043
import java.util.stream.Collectors;
41-
import java.util.stream.Stream;
4244

4345
/**
4446
* The abstract class is the base for each function handler in the preprocessor
@@ -51,59 +53,69 @@ public abstract class AbstractFunction implements ExpressionItem {
5153
* The string contains the prefix for all executing methods of functions
5254
*/
5355
public static final String EXECUTION_PREFIX = "execute";
56+
5457
/**
55-
* Inside counter to generate UID for some cases
58+
* Internal counter to generate UID for some cases
5659
*/
5760
protected static final AtomicLong UID_COUNTER = new AtomicLong(1);
61+
5862
/**
59-
* Inside array contains all functions supported by the preprocessor
63+
* Current internal map contains all preprocessor functions, mapped by their names
6064
*/
61-
private static volatile AbstractFunction[] allFunctions;
62-
private static volatile Map<String, AbstractFunction> functionNameMap;
63-
64-
65-
public static AbstractFunction[] getAllFunctions() {
66-
if (allFunctions == null) {
67-
allFunctions = new AbstractFunction[] {
68-
new FunctionABS(),
69-
new FunctionROUND(),
70-
new FunctionESC(),
71-
new FunctionSTR2INT(),
72-
new FunctionSTR2WEB(),
73-
new FunctionSTR2CSV(),
74-
new FunctionSTR2JS(),
75-
new FunctionSTR2JSON(),
76-
new FunctionSTR2XML(),
77-
new FunctionSTR2JAVA(),
78-
new FunctionSTR2GO(),
79-
new FunctionTRIMLINES(),
80-
new FunctionSTRLEN(),
81-
new FunctionISSUBSTR(),
82-
new FunctionIS(),
83-
new FunctionEVALFILE(),
84-
new FunctionBINFILE(),
85-
new FunctionXML_GET(),
86-
new FunctionXML_SIZE(),
87-
new FunctionXML_ATTR(),
88-
new FunctionXML_ROOT(),
89-
new FunctionXML_NAME(),
90-
new FunctionXML_LIST(),
91-
new FunctionXML_TEXT(),
92-
new FunctionXML_OPEN(),
93-
new FunctionXML_XLIST(),
94-
new FunctionXML_XELEMENT()
95-
};
65+
private static final AtomicReference<Map<String, AbstractFunction>> allFunctions =
66+
new AtomicReference<>();
67+
68+
@SuppressWarnings("StaticInitializerReferencesSubClass")
69+
private static final List<AbstractFunction> DEFAULT_INTERNAL_FUNCTIONS = List.of(
70+
new FunctionABS(),
71+
new FunctionROUND(),
72+
new FunctionESC(),
73+
new FunctionSTR2INT(),
74+
new FunctionSTR2WEB(),
75+
new FunctionSTR2CSV(),
76+
new FunctionSTR2JS(),
77+
new FunctionSTR2JSON(),
78+
new FunctionSTR2XML(),
79+
new FunctionSTR2JAVA(),
80+
new FunctionSTR2GO(),
81+
new FunctionTRIMLINES(),
82+
new FunctionSTRLEN(),
83+
new FunctionISSUBSTR(),
84+
new FunctionIS(),
85+
new FunctionEVALFILE(),
86+
new FunctionBINFILE(),
87+
new FunctionXML_GET(),
88+
new FunctionXML_SIZE(),
89+
new FunctionXML_ATTR(),
90+
new FunctionXML_ROOT(),
91+
new FunctionXML_NAME(),
92+
new FunctionXML_LIST(),
93+
new FunctionXML_TEXT(),
94+
new FunctionXML_OPEN(),
95+
new FunctionXML_XLIST(),
96+
new FunctionXML_XELEMENT()
97+
);
98+
private static final Map<String, AbstractFunction> DEFAULT_INTERNAL_FUNCTIONS_MAP =
99+
DEFAULT_INTERNAL_FUNCTIONS.stream()
100+
.collect(Collectors.toMap(AbstractFunction::getName, x -> x));
101+
102+
public static List<AbstractFunction> findAllFunctions() {
103+
Map<String, AbstractFunction> currentAllFunctions = allFunctions.get();
104+
if (currentAllFunctions == null) {
105+
return DEFAULT_INTERNAL_FUNCTIONS;
106+
} else {
107+
return currentAllFunctions.values().stream()
108+
.sorted(Comparator.comparing(AbstractFunction::getName))
109+
.collect(Collectors.toList());
96110
}
97-
return allFunctions;
98111
}
99112

100-
101113
public static Map<String, AbstractFunction> getFunctionNameMap() {
102-
if (functionNameMap == null) {
103-
functionNameMap =
104-
Stream.of(getAllFunctions()).collect(Collectors.toMap(AbstractFunction::getName, x -> x));
114+
final Map<String, AbstractFunction> result = allFunctions.get();
115+
if (result == null) {
116+
return DEFAULT_INTERNAL_FUNCTIONS_MAP;
105117
}
106-
return functionNameMap;
118+
return result;
107119
}
108120

109121
/**
@@ -117,7 +129,7 @@ public static Map<String, AbstractFunction> getFunctionNameMap() {
117129
*/
118130
public static <E extends AbstractFunction> E findForClass(final Class<E> functionClass) {
119131
E result = null;
120-
for (final AbstractFunction function : getAllFunctions()) {
132+
for (final AbstractFunction function : findAllFunctions()) {
121133
if (function.getClass() == functionClass) {
122134
result = functionClass.cast(function);
123135
break;

jcp/src/main/java/com/igormaznitsa/jcp/expression/functions/xml/FunctionXML_XELEMENT.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ public final class FunctionXML_XELEMENT extends AbstractXMLFunction {
4141
new ValueType[][] {{ValueType.STRING, ValueType.STRING}};
4242

4343
@Override
44-
4544
public String getName() {
4645
return "xml_xelement";
4746
}

jcp/src/main/java/com/igormaznitsa/jcp/expression/functions/xml/FunctionXML_XLIST.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ public final class FunctionXML_XLIST extends AbstractXMLFunction {
4141
new ValueType[][] {{ValueType.STRING, ValueType.STRING}};
4242

4343
@Override
44-
4544
public String getName() {
4645
return "xml_xlist";
4746
}
@@ -75,20 +74,16 @@ public int getArity() {
7574
}
7675

7776
@Override
78-
79-
8077
public ValueType[][] getAllowedArgumentTypes() {
8178
return ARG_TYPES;
8279
}
8380

8481
@Override
85-
8682
public String getReference() {
8783
return "find element list with XPath";
8884
}
8985

9086
@Override
91-
9287
public ValueType getResultType() {
9388
return ValueType.STRING;
9489
}

jcp/src/main/java/com/igormaznitsa/jcp/expression/operators/AbstractOperator.java

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
import com.igormaznitsa.jcp.expression.ExpressionItem;
2525
import com.igormaznitsa.jcp.expression.ExpressionItemType;
26+
import java.util.List;
27+
import java.util.concurrent.atomic.AtomicReference;
2628

2729
/**
2830
* The class is the base for all operator handlers
@@ -37,31 +39,35 @@ public abstract class AbstractOperator implements ExpressionItem {
3739
public static final String EXECUTION_PREFIX = "execute";
3840

3941
/**
40-
* The array contains all operators allowed by the preprocessor
42+
* The list contains operators allowed by the preprocessor
4143
*/
42-
private static AbstractOperator[] allOperators;
43-
44-
45-
public static AbstractOperator[] getAllOperators() {
46-
if (allOperators == null) {
47-
allOperators = new AbstractOperator[] {
48-
new OperatorEQU(),
49-
new OperatorGREAT(),
50-
new OperatorGREATEQU(),
51-
new OperatorLESS(),
52-
new OperatorLESSEQU(),
53-
new OperatorNOTEQU(),
54-
new OperatorADD(),
55-
new OperatorSUB(),
56-
new OperatorMUL(),
57-
new OperatorDIV(),
58-
new OperatorMOD(),
59-
new OperatorNOT(),
60-
new OperatorAND(),
61-
new OperatorOR(),
62-
new OperatorXOR()};
44+
private static final AtomicReference<List<AbstractOperator>> allOperators = new AtomicReference<>();
45+
46+
@SuppressWarnings("StaticInitializerReferencesSubClass")
47+
private static final List<AbstractOperator> DEFAULT_OPERATORS = List.of(
48+
new OperatorEQU(),
49+
new OperatorGREAT(),
50+
new OperatorGREATEQU(),
51+
new OperatorLESS(),
52+
new OperatorLESSEQU(),
53+
new OperatorNOTEQU(),
54+
new OperatorADD(),
55+
new OperatorSUB(),
56+
new OperatorMUL(),
57+
new OperatorDIV(),
58+
new OperatorMOD(),
59+
new OperatorNOT(),
60+
new OperatorAND(),
61+
new OperatorOR(),
62+
new OperatorXOR()
63+
);
64+
65+
public static List<AbstractOperator> getAllOperators() {
66+
final List<AbstractOperator> current = allOperators.get();
67+
if (current == null) {
68+
return DEFAULT_OPERATORS;
6369
}
64-
return allOperators;
70+
return current;
6571
}
6672

6773
/**

0 commit comments

Comments
 (0)