Skip to content

Commit e7ca79b

Browse files
committed
centralise replace placeholder functionality
1 parent 90b02a7 commit e7ca79b

File tree

11 files changed

+162
-65
lines changed

11 files changed

+162
-65
lines changed

core/src/main/java/lucee/runtime/config/CFConfigImport.java

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package lucee.runtime.config;
22

33
import java.nio.charset.Charset;
4+
import java.util.HashMap;
45
import java.util.Iterator;
6+
import java.util.Map;
57
import java.util.Map.Entry;
68

79
import lucee.commons.io.SystemUtil;
@@ -15,7 +17,6 @@
1517
import lucee.runtime.op.Caster;
1618
import lucee.runtime.type.Collection;
1719
import lucee.runtime.type.Collection.Key;
18-
import lucee.runtime.type.KeyImpl;
1920
import lucee.runtime.type.Struct;
2021
import lucee.runtime.util.Cast;
2122

@@ -121,7 +122,7 @@ public Struct execute(boolean throwException) throws PageException {
121122
json = ConfigFile.read(file, charset);
122123
}
123124

124-
replacePlaceHolder(json, placeHolderData);
125+
replacePlaceHolder(json, toMap(placeHolderData));
125126

126127
// dynAttr = (DynamicAttributes) tag;
127128
boolean isServer = "server".equalsIgnoreCase(type);
@@ -153,51 +154,33 @@ public Struct execute(boolean throwException) throws PageException {
153154

154155
}
155156

156-
private static void replacePlaceHolder(Collection coll, Struct placeHolderData) {
157+
private Map<Key, String> toMap(Struct placeHolderData) {
158+
if (placeHolderData == null) return null;
159+
Map<Key, String> map = new HashMap<>();
160+
Iterator<Entry<Key, Object>> it = placeHolderData.entryIterator();
161+
while (it.hasNext()) {
162+
Entry<Key, Object> e = it.next();
163+
map.put(e.getKey(), Caster.toString(e.getValue(), ""));
164+
}
165+
return map;
166+
}
167+
168+
private void replacePlaceHolder(Collection coll, Map<Key, String> placeHolderData) {
157169
// ${MAILSERVER_HOST:smtp.sendgrid.net}
158170
Iterator<Entry<Key, Object>> it = coll.entryIterator();
159171
Entry<Key, Object> e;
160172
Object obj;
161173
while (it.hasNext()) {
162174
e = it.next();
163175
obj = e.getValue();
164-
if (obj instanceof String) replacePlaceHolder(e, placeHolderData);
165-
if (obj instanceof Collection) replacePlaceHolder((Collection) obj, placeHolderData);
166-
}
167-
}
176+
if (obj instanceof String) {
168177

169-
private static void replacePlaceHolder(Entry<Key, Object> e, Struct placeHolderData) {
170-
String str = (String) e.getValue();
171-
String res;
172-
boolean modified = false;
173-
int startIndex = -1;
174-
while (true) {
175-
startIndex = str.indexOf("${", startIndex + 1);
176-
if (startIndex == -1) break;
177-
int endIndex = str.indexOf("}", startIndex + 1);
178-
if (endIndex == -1) break;
179-
modified = true;
180-
String content = str.substring(startIndex + 2, endIndex);
181-
String envVarName, defaultValue = "";
182-
int index = content.indexOf(':');
183-
if (index == -1) {
184-
envVarName = content;
178+
String str = (String) e.getValue();
179+
String resolved = config.replacePlaceHolder(str, placeHolderData);
180+
if (!str.equals(resolved)) e.setValue(resolved);
185181
}
186-
else {
187-
envVarName = content.substring(0, index);
188-
defaultValue = content.substring(index + 1);
189-
}
190-
191-
Object val = null;
192-
if (placeHolderData != null) val = placeHolderData.get(KeyImpl.init(envVarName), null);
193-
if (val == null) val = SystemUtil.getSystemPropOrEnvVar(envVarName, null);
194-
195-
if (val != null) res = Caster.toString(val, "");
196-
else res = defaultValue;
197-
198-
str = str.substring(0, startIndex) + res + str.substring(endIndex + 1);
182+
if (obj instanceof Collection) replacePlaceHolder((Collection) obj, placeHolderData);
199183
}
200-
if (modified) e.setValue(str);
201184
}
202185

203186
private boolean setPasswordIfNecessary(ConfigPro config) throws PageException {

core/src/main/java/lucee/runtime/config/ConfigFactoryImpl.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ public static Map<String, AIEngine> _loadAI(Config config, Struct ai) {
492492
if (data == null) continue;
493493
strId = entry.getKey().getString();
494494
if (!StringUtil.isEmpty(strId)) {
495-
data = (Struct) ConfigUtil.replaceConfigPlaceHolders(config, data);
495+
data = (Struct) ConfigUtil.replacePlaceHolders(config, data);
496496
strId = strId.trim().toLowerCase();
497497
engines.put(strId, AIEngineFactory.getInstance(config, strId, data));
498498
}
@@ -1358,22 +1358,22 @@ public static String getAttr(Config config, Struct data, String name) {
13581358
return null;
13591359
}
13601360
if (StringUtil.isEmpty(v)) return "";
1361-
return ConfigUtil.replaceConfigPlaceHolder(config, v);
1361+
return ((ConfigPro) config).replacePlaceHolder(v);
13621362
}
13631363

13641364
public static String getAttr(Config config, Struct data, String name, String alias) {
13651365
String v = ConfigUtil.getAsString(name, data, null);
13661366
if (v == null) v = ConfigUtil.getAsString(alias, data, null);
13671367
if (v == null) return null;
13681368
if (StringUtil.isEmpty(v)) return "";
1369-
return ConfigUtil.replaceConfigPlaceHolder(config, v);
1369+
return ((ConfigPro) config).replacePlaceHolder(v);
13701370
}
13711371

13721372
public static String getAttr(Config config, Struct data, String[] names) {
13731373
String v;
13741374
for (String name: names) {
13751375
v = ConfigUtil.getAsString(name, data, null);
1376-
if (!StringUtil.isEmpty(v)) return ConfigUtil.replaceConfigPlaceHolder(config, v);
1376+
if (!StringUtil.isEmpty(v)) return ((ConfigPro) config).replacePlaceHolder(v);
13771377
}
13781378
return null;
13791379
}
@@ -1382,7 +1382,7 @@ public static String getAttr(Config config, Struct data, lucee.runtime.type.Coll
13821382
String v;
13831383
for (lucee.runtime.type.Collection.Key name: names) {
13841384
v = ConfigUtil.getAsString(name, data, null);
1385-
if (!StringUtil.isEmpty(v)) return ConfigUtil.replaceConfigPlaceHolder(config, v);
1385+
if (!StringUtil.isEmpty(v)) return ((ConfigPro) config).replacePlaceHolder(v);
13861386
}
13871387
return null;
13881388
}

core/src/main/java/lucee/runtime/config/ConfigPro.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,4 +429,8 @@ public Resource[] getResources(PageContext pc, Mapping[] mappings, String realPa
429429
public String getDapSecret();
430430

431431
public boolean getDapBreakpoint();
432+
433+
public String replacePlaceHolder(String str);
434+
435+
public String replacePlaceHolder(String str, Map<Key, String> customPlaceHolderData);
432436
}

core/src/main/java/lucee/runtime/config/ConfigServerImpl.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.ArrayList;
3434
import java.util.Arrays;
3535
import java.util.Collection;
36+
import java.util.Collections;
3637
import java.util.HashMap;
3738
import java.util.HashSet;
3839
import java.util.Iterator;
@@ -321,7 +322,8 @@ public final class ConfigServerImpl implements ConfigServer, ConfigPro {
321322
private TagLib coreTLDs;
322323
private FunctionLib coreFLDs;
323324
private LinkedHashMapMaxSize<Long, String> previousNonces = new LinkedHashMapMaxSize<Long, String>(100);
324-
325+
private Map<Key, String> placeHolderdata;
326+
private boolean insidePlaceHolder;
325327
//////////////////////////
326328
//////////////////////////
327329

@@ -1320,6 +1322,55 @@ protected ConfigServerImpl(CFMLEngineImpl engine, Map<String, CFMLFactory> initC
13201322
instance = this;
13211323
}
13221324

1325+
Map<Key, String> getPlaceHolderData() {
1326+
if (this.placeHolderdata == null) {
1327+
synchronized (SystemUtil.createToken("configweb", "placeHolderdata")) {
1328+
if (this.placeHolderdata == null) {
1329+
if (insidePlaceHolder) return new HashMap<>();
1330+
insidePlaceHolder = true;
1331+
try {
1332+
Map<Key, String> data = new HashMap<>();
1333+
data.put(KeyImpl.init("lucee-config"), getConfigDir().getAbsolutePath());
1334+
data.put(KeyImpl.init("lucee-config-dir"), getConfigDir().getAbsolutePath());
1335+
data.put(KeyImpl.init("lucee-config-directory"), getConfigDir().getAbsolutePath());
1336+
data.put(KeyImpl.init("lucee-web"), getConfigDir().getAbsolutePath());
1337+
data.put(KeyImpl.init("lucee-web-dir"), getConfigDir().getAbsolutePath());
1338+
data.put(KeyImpl.init("lucee-web-directory"), getConfigDir().getAbsolutePath());
1339+
1340+
data.put(KeyConstants._temp, getTempDirectory().getAbsolutePath());
1341+
data.put(KeyImpl.init("temp-dir"), getTempDirectory().getAbsolutePath());
1342+
data.put(KeyImpl.init("temp-directory"), getTempDirectory().getAbsolutePath());
1343+
1344+
// add constants
1345+
Struct constants = getConstants();
1346+
if (constants != null) {
1347+
Iterator<Entry<Key, Object>> it = constants.entryIterator();
1348+
while (it.hasNext()) {
1349+
Entry<Key, Object> e = it.next();
1350+
data.put(e.getKey(), Caster.toString(e.getValue(), ""));
1351+
}
1352+
}
1353+
this.placeHolderdata = Collections.unmodifiableMap(data);
1354+
}
1355+
finally {
1356+
insidePlaceHolder = false;
1357+
}
1358+
}
1359+
}
1360+
}
1361+
return this.placeHolderdata;
1362+
}
1363+
1364+
@Override
1365+
public String replacePlaceHolder(String str) {
1366+
return ConfigUtil.replacePlaceHolder(this, str, getPlaceHolderData());
1367+
}
1368+
1369+
@Override
1370+
public String replacePlaceHolder(String str, Map<Key, String> customPlaceHolderData) {
1371+
return ConfigUtil.replacePlaceHolder(this, str, customPlaceHolderData != null ? ConfigUtil.merge(getPlaceHolderData(), customPlaceHolderData) : getPlaceHolderData());
1372+
}
1373+
13231374
public List<Monitor> getMonitors() {
13241375
if (monitors == null) {
13251376
synchronized (SystemUtil.createToken("config", "monitors")) {
@@ -5334,6 +5385,8 @@ public ConfigServerImpl resetConstants() {
53345385
synchronized (SystemUtil.createToken("config", "getConstants")) {
53355386
if (constants != null) {
53365387
constants = null;
5388+
placeHolderdata = null;
5389+
53375390
}
53385391
}
53395392
}

core/src/main/java/lucee/runtime/config/ConfigUtil.java

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.ArrayList;
2424
import java.util.Arrays;
2525
import java.util.Comparator;
26+
import java.util.HashMap;
2627
import java.util.Iterator;
2728
import java.util.List;
2829
import java.util.Map;
@@ -772,24 +773,24 @@ protected static FunctionLib[] duplicate(FunctionLib[] flds, boolean deepCopy) {
772773
return rst;
773774
}
774775

775-
public static Object replaceConfigPlaceHolders(Config config, Object obj) {
776+
private static Object _replacePlaceHolders(Config config, Object obj) {
776777
if (obj == null) return obj;
777778

778779
// handle simple value
779780
if (Decision.isSimpleValue(obj)) {
780-
if (obj instanceof CharSequence) return replaceConfigPlaceHolder(config, obj.toString());
781+
if (obj instanceof CharSequence) return ((ConfigPro) config).replacePlaceHolder(obj.toString());
781782
return obj;
782783
}
783784

784785
// handle collection
785786
if (obj instanceof lucee.runtime.type.Collection) {
786-
return replaceConfigPlaceHolders(config, (lucee.runtime.type.Collection) obj);
787+
return replacePlaceHolders(config, (lucee.runtime.type.Collection) obj);
787788
}
788789

789790
return obj;
790791
}
791792

792-
public static lucee.runtime.type.Collection replaceConfigPlaceHolders(Config config, lucee.runtime.type.Collection data) {
793+
public static lucee.runtime.type.Collection replacePlaceHolders(Config config, lucee.runtime.type.Collection data) {
793794
if (data == null) return data;
794795

795796
lucee.runtime.type.Collection repl;
@@ -800,16 +801,20 @@ public static lucee.runtime.type.Collection replaceConfigPlaceHolders(Config con
800801
Entry<Key, Object> e;
801802
while (it.hasNext()) {
802803
e = it.next();
803-
repl.setEL(e.getKey(), replaceConfigPlaceHolders(config, e.getValue()));
804+
repl.setEL(e.getKey(), _replacePlaceHolders(config, e.getValue()));
804805
}
805806
return repl;
806807
}
807808

808-
public static String replaceConfigPlaceHolderX(String v) {
809-
return replaceConfigPlaceHolder(null, v);
809+
public static Map<Key, String> merge(Map<Key, String> left, Map<Key, String> right) {
810+
if (left == null) return right;
811+
if (right == null) return left;
812+
Map<Key, String> merged = new HashMap<>(left);
813+
merged.putAll(right);
814+
return merged;
810815
}
811816

812-
public final static String replaceConfigPlaceHolder(Config config, String v) {
817+
public final static String replacePlaceHolder(Config config, String v, Map<Key, String> placeHolderData) {
813818
if (StringUtil.isEmpty(v) || v.indexOf('{') == -1) return v;
814819

815820
int s = -1, e = -1, d = -1, sec = -1;
@@ -848,9 +853,8 @@ else if (sec > -1) {
848853
end = v.indexOf('}', start);
849854
if (end > prefixLen) {
850855
_name = v.substring(start + prefixLen, end);
851-
// print.edate(_name);
852-
if (isSecret) {
853856

857+
if (isSecret) {
854858
String[] _parts = _name.split(":");
855859
try {
856860
if (config == null) throw new ApplicationException("cannot use secret in this context");
@@ -867,7 +871,17 @@ else if (sec > -1) {
867871
}
868872
else if (isDollar) {
869873
String[] _parts = _name.split(":");
870-
_prop = SystemUtil.getSystemPropOrEnvVar(_parts[0], (_parts.length > 1) ? _parts[1] : null);
874+
String envVarName = _parts[0];
875+
String defaultValue = (_parts.length > 1) ? _parts[1] : null;
876+
877+
// try placeHolderData first
878+
_prop = null;
879+
if (placeHolderData != null) {
880+
Object val = placeHolderData.get(KeyImpl.init(envVarName));
881+
if (val != null) _prop = Caster.toString(val, "");
882+
}
883+
// fall back to system prop or env var
884+
if (_prop == null) _prop = SystemUtil.getSystemPropOrEnvVar(envVarName, defaultValue);
871885
}
872886
else {
873887
_prop = isSystem ? System.getProperty(_name) : System.getenv(_name);
@@ -879,10 +893,10 @@ else if (isDollar) {
879893
}
880894
else start = end;
881895
}
882-
else start = end; // set start to end for the next round
896+
else start = end;
883897
s = -1;
884-
e = -1; // reset index
885-
d = -1; // I don't think we need this?
898+
e = -1;
899+
d = -1;
886900
}
887901
return v;
888902
}
@@ -908,7 +922,7 @@ public static Array getAsArray(Config config, Struct input, boolean replacePlace
908922
input.put(names[0], arr);
909923
return arr;
910924
}
911-
return replacePlaceholders ? (Array) replaceConfigPlaceHolders(config, arr) : arr;
925+
return replacePlaceholders ? (Array) replacePlaceHolders(config, arr) : arr;
912926
}
913927

914928
public static Struct getAsStruct(Config config, Struct input, boolean allowCSSString, String... names) {
@@ -939,7 +953,7 @@ public static Struct getAsStruct(Config config, Struct input, boolean allowCSSSt
939953
input.put(names[0], sct);
940954
return sct;
941955
}
942-
return (Struct) replaceConfigPlaceHolders(config, sct);
956+
return (Struct) replacePlaceHolders(config, sct);
943957
}
944958

945959
public static Struct toStruct(Config config, String str) {
@@ -950,7 +964,7 @@ public static Struct toStruct(Config config, String str) {
950964
String[] item;
951965
for (int i = 0; i < arr.length; i++) {
952966
item = ListUtil.toStringArray(ListUtil.listToArrayRemoveEmpty(arr[i], '='));
953-
if (item.length == 2) sct.setEL(KeyImpl.init(URLDecoder.decode(item[0], true).trim()), replaceConfigPlaceHolder(config, URLDecoder.decode(item[1], true)));
967+
if (item.length == 2) sct.setEL(KeyImpl.init(URLDecoder.decode(item[0], true).trim()), ((ConfigPro) config).replacePlaceHolder(URLDecoder.decode(item[1], true)));
954968
else if (item.length == 1) sct.setEL(KeyImpl.init(URLDecoder.decode(item[0], true).trim()), "");
955969
}
956970
}
@@ -1066,7 +1080,7 @@ else if (arr == null) {
10661080
return arr;
10671081
}
10681082

1069-
if (replacePlaceHolder) return (Array) replaceConfigPlaceHolders(config, arr);
1083+
if (replacePlaceHolder) return (Array) replacePlaceHolders(config, arr);
10701084

10711085
return arr;
10721086
}

0 commit comments

Comments
 (0)