Skip to content

Commit faa128d

Browse files
committed
Switch from ExtendedProperties to PropertiesConfiguration
Although not officially deprecateed the docs contain strong encouragement to switch to the newer implementation as soon as it was available
1 parent 94488b0 commit faa128d

5 files changed

Lines changed: 95 additions & 97 deletions

File tree

main/pom.xml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@
99
<artifactId>butterfly-container</artifactId>
1010
<version>1.2.7-SNAPSHOT</version>
1111
</parent>
12-
13-
<groupId>org.openrefine.dependencies</groupId>
12+
1413
<artifactId>butterfly</artifactId>
15-
<version>1.2.7-SNAPSHOT</version>
1614

1715
<name>SIMILE Butterfly Engine</name>
1816
<url>https://github.com/OpenRefine/simile-butterfly/</url>
@@ -81,19 +79,24 @@
8179

8280
<dependencies>
8381
<dependency>
84-
<groupId>commons-collections</groupId>
85-
<artifactId>commons-collections</artifactId>
86-
<version>3.2.2</version>
82+
<groupId>org.apache.commons</groupId>
83+
<artifactId>commons-collections4</artifactId>
84+
<version>4.4</version>
85+
</dependency>
86+
<dependency>
87+
<groupId>org.apache.commons</groupId>
88+
<artifactId>commons-configuration2</artifactId>
89+
<version>2.10.1</version>
8790
</dependency>
8891
<dependency>
8992
<groupId>commons-io</groupId>
9093
<artifactId>commons-io</artifactId>
9194
<version>2.18.0</version>
9295
</dependency>
9396
<dependency>
94-
<groupId>commons-lang</groupId>
95-
<artifactId>commons-lang</artifactId>
96-
<version>2.6</version>
97+
<groupId>org.apache.commons</groupId>
98+
<artifactId>commons-lang3</artifactId>
99+
<version>3.18.0</version>
97100
</dependency>
98101
<dependency>
99102
<groupId>org.apache.velocity</groupId>

main/src/edu/mit/simile/butterfly/Butterfly.java

Lines changed: 70 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@
3636
import javax.servlet.http.HttpServletRequest;
3737
import javax.servlet.http.HttpServletResponse;
3838

39-
import org.apache.commons.collections.ExtendedProperties;
39+
import org.apache.commons.configuration2.AbstractConfiguration;
40+
import org.apache.commons.configuration2.CombinedConfiguration;
41+
import org.apache.commons.configuration2.PropertiesConfiguration;
42+
import org.apache.commons.configuration2.ex.ConfigurationException;
43+
import org.apache.commons.configuration2.tree.OverrideCombiner;
4044
import org.apache.velocity.app.VelocityEngine;
4145
import org.apache.velocity.runtime.RuntimeConstants;
4246
import org.mozilla.javascript.Context;
@@ -156,7 +160,7 @@ public static boolean isGAE(ServletConfig config) {
156160
transient protected ServletContext _context;
157161
transient protected ButterflyMounter _mounter;
158162

159-
protected ExtendedProperties _properties;
163+
protected PropertiesConfiguration _properties;
160164
protected File _contextDir;
161165
protected File _homeDir;
162166
protected File _webInfDir;
@@ -188,55 +192,38 @@ public void init(ServletConfig config) throws ServletException {
188192

189193
_contextDir = new File(_context.getRealPath("/"));
190194
_webInfDir = new File(_contextDir, "WEB-INF");
191-
_properties = new ExtendedProperties();
195+
_properties = new PropertiesConfiguration();
192196
_mounter = new ButterflyMounter();
193197

194198
// Load the butterfly properties
195199
String props = System.getProperty("butterfly.properties");
196200
File butterflyProperties = (props == null) ? new File(_webInfDir, "butterfly.properties") : new File(props);
197201

198-
BufferedInputStream is = null;
199-
try {
200-
is = new BufferedInputStream(new FileInputStream(butterflyProperties));
201-
_properties.load(is);
202-
} catch (FileNotFoundException e) {
202+
try (BufferedInputStream is = new BufferedInputStream(Files.newInputStream(butterflyProperties.toPath()))){
203+
_properties.read(new InputStreamReader(is, StandardCharsets.UTF_8));
204+
} catch (IOException|ConfigurationException e) {
203205
throw new ServletException("Could not find butterfly properties file",e);
204-
} catch (IOException e) {
205-
throw new ServletException("Could not read butterfly properties file",e);
206-
} finally {
207-
try {
208-
is.close();
209-
} catch (Exception e) {
210-
// ignore
211-
}
212206
}
213207

214208
// Process eventual properties includes
215209
String includes = _properties.getString("butterfly.includes");
216210
if (includes != null) {
217211
for (String prop : includes.split(",")) {
218212
File prop_file = (prop.startsWith("/")) ? new File(prop) : new File(_webInfDir, prop);
219-
try {
220-
is = new BufferedInputStream(new FileInputStream(prop_file));
221-
ExtendedProperties p = new ExtendedProperties();
222-
p.load(is);
223-
_properties.combine(p);
224-
} catch (Exception e) {
225-
// ignore
226-
} finally {
227-
try {
228-
is.close();
229-
} catch (Exception e) {
230-
// ignore
231-
}
213+
try (BufferedInputStream is = new BufferedInputStream(Files.newInputStream(prop_file.toPath()))){
214+
PropertiesConfiguration p = new PropertiesConfiguration();
215+
p.read(new InputStreamReader(is, StandardCharsets.UTF_8));
216+
_properties.append(p);
217+
} catch (ConfigurationException | IOException e) {
218+
_logger.warn("Error loading included properties file: " + prop_file, e);
232219
}
233220
}
234221
}
235222
// Overload with properties set from the command line
236223
// using the -Dkey=value parameters to the JVM
237224
Properties systemProperties = System.getProperties();
238-
for (Iterator<Object> i = systemProperties.keySet().iterator(); i.hasNext(); ) {
239-
String key = (String) i.next();
225+
for (Object o : systemProperties.keySet()) {
226+
String key = (String) o;
240227
String value = systemProperties.getProperty(key);
241228
_properties.setProperty(key, value);
242229
}
@@ -326,8 +313,7 @@ public void configure() {
326313
}
327314
_logger.info("Butterfly home: {}", _homeDir);
328315

329-
Iterator<String> i = _properties.getKeys(ZONE);
330-
while (i.hasNext()) {
316+
for(Iterator<String> i = _properties.getKeys(ZONE); i.hasNext(); ) {
331317
String zone = i.next();
332318
String path = _properties.getString(zone);
333319
zone = zone.substring(ZONE.length() + 1);
@@ -373,7 +359,7 @@ public void configure() {
373359

374360
_logger.info("> load modules");
375361
// load modules from the properties found in the butterfly.properties
376-
List<String> paths = _properties.getList(MODULES_PATH);
362+
List<String> paths = _properties.getList(String.class, MODULES_PATH);
377363
for (String path : paths) {
378364
findModulesIn(absolutize(_homeDir, path.trim()));
379365
}
@@ -394,16 +380,15 @@ public void configure() {
394380
_logger.info("< create modules");
395381

396382
_logger.info("> load module wirings");
397-
ExtendedProperties wirings = new ExtendedProperties();
398-
try {
399-
// Load the wiring properties
400-
File moduleWirings = absolutize(_homeDir, _properties.getString("butterfly.modules.wirings","WEB-INF/modules.properties"));
401-
_logger.info("Loaded module wirings from: {}", moduleWirings);
402-
_classLoader.watch(moduleWirings); // reload if the module wirings change
403-
FileInputStream fis = new FileInputStream(moduleWirings);
404-
wirings.load(fis);
405-
fis.close();
406-
} catch (Exception e) {
383+
PropertiesConfiguration wirings = new PropertiesConfiguration();
384+
385+
// Load the wiring properties
386+
File moduleWirings = absolutize(_homeDir, _properties.getString("butterfly.modules.wirings","WEB-INF/modules.properties"));
387+
_logger.info("Loaded module wirings from: {}", moduleWirings);
388+
_classLoader.watch(moduleWirings); // reload if the module wirings change
389+
try (FileInputStream fis = new FileInputStream(moduleWirings)) {
390+
wirings.read(new InputStreamReader(fis, StandardCharsets.UTF_8));
391+
} catch (IOException | ConfigurationException e) {
407392
_configurationException = new Exception("Failed to load module wirings", e);
408393
}
409394
_logger.info("< load module wirings");
@@ -526,7 +511,7 @@ public void service(HttpServletRequest request, HttpServletResponse response) th
526511

527512
protected Map<String,ButterflyModule> _modulesByName = new HashMap<String,ButterflyModule>();
528513
protected Map<String,Map<String,ButterflyModule>> _modulesByInterface = new HashMap<String,Map<String,ButterflyModule>>();
529-
protected Map<String,ExtendedProperties> _moduleProperties = new HashMap<String,ExtendedProperties>();
514+
protected Map<String,AbstractConfiguration> _moduleProperties = new HashMap<String,AbstractConfiguration>();
530515
protected Map<String,Boolean> _created = new HashMap<String,Boolean>();
531516

532517
final static private String routingCookie = "host";
@@ -573,13 +558,13 @@ protected void findModulesIn(File f) {
573558
try {
574559
String name = f.getName();
575560

576-
ExtendedProperties p = new ExtendedProperties();
561+
PropertiesConfiguration p = new PropertiesConfiguration();
577562
File propFile = new File(modFile,"module.properties");
578563
if (propFile.exists()) {
579-
_classLoader.watch(propFile); // reload if the the module properties change
580-
BufferedInputStream stream = new BufferedInputStream(new FileInputStream(propFile));
581-
p.load(stream);
582-
stream.close();
564+
_classLoader.watch(propFile); // reload if the module properties change
565+
try (BufferedInputStream stream = new BufferedInputStream(Files.newInputStream(propFile.toPath()))) {
566+
p.read(new InputStreamReader(stream, StandardCharsets.UTF_8));
567+
}
583568
}
584569

585570
p.addProperty(PATH_PROP, f.getAbsolutePath());
@@ -624,7 +609,7 @@ protected ButterflyModule createModule(String name) {
624609
return _modulesByName.get(name);
625610
}
626611

627-
ExtendedProperties p = _moduleProperties.get(name);
612+
AbstractConfiguration p = _moduleProperties.get(name);
628613
File path = new File(p.getString(PATH_PROP));
629614
_logger.debug("Module path: {}", path);
630615

@@ -685,8 +670,7 @@ protected ButterflyModule createModule(String name) {
685670
return m;
686671
}
687672

688-
@SuppressWarnings("unchecked")
689-
protected void wireModules(ExtendedProperties wirings) {
673+
protected void wireModules(PropertiesConfiguration wirings) {
690674
_logger.trace("> wireModules()");
691675

692676
_logger.info("mounting modules");
@@ -714,21 +698,32 @@ protected void wireModules(ExtendedProperties wirings) {
714698
for (String name : _moduleProperties.keySet()) {
715699
_logger.trace("> Expanding properties for module: {}", name);
716700
ButterflyModule m = _modulesByName.get(name);
717-
ExtendedProperties p = _moduleProperties.get(name);
718701
ButterflyModule extended = m.getExtendedModule();
719702

703+
// Highest priority properties need to be added first, so we need to collect them all first
704+
List<AbstractConfiguration> propertiesList = new ArrayList<>();
705+
propertiesList.add(_moduleProperties.get(name));
720706
while (extended != null) {
721707
_logger.trace("> Merging properties from extended module: {}", name);
722-
ExtendedProperties temp = p;
723-
p = _moduleProperties.get(extended.getName());
724-
p.combine(temp);
708+
AbstractConfiguration p = _moduleProperties.get(extended.getName());
709+
propertiesList.add(p);
725710
_logger.trace("< Merging properties from extended module: {} -> {}", name, p);
726711
extended = extended.getExtendedModule();
727712
}
713+
AbstractConfiguration p;
714+
if (propertiesList.size() == 1) {
715+
p = propertiesList.get(0);
716+
} else {
717+
p = new CombinedConfiguration(new OverrideCombiner());
718+
// Add files in reverse order to maintain priority
719+
for (int i = propertiesList.size() - 1; i >= 0; i--) {
720+
((CombinedConfiguration) p).addConfiguration(propertiesList.get(i));
721+
}
722+
}
728723

729-
_moduleProperties.put(name,p);
724+
_moduleProperties.put(name, p);
730725

731-
List<String> implementations = p.getList(implementsProperty);
726+
List<String> implementations = p.getList(String.class, implementsProperty);
732727
if (implementations != null) {
733728
for (String i : implementations) {
734729
Map<String, ButterflyModule> map = _modulesByInterface.get(i);
@@ -745,11 +740,11 @@ protected void wireModules(ExtendedProperties wirings) {
745740

746741
for (String name : _moduleProperties.keySet()) {
747742
_logger.trace("> Inject dependencies in module: {}", name);
748-
ExtendedProperties p = _moduleProperties.get(name);
743+
AbstractConfiguration p = _moduleProperties.get(name);
749744
ButterflyModule m = _modulesByName.get(name);
750745

751-
for (Object o : p.keySet()) {
752-
String s = (String) o;
746+
for (Iterator<String> keys = p.getKeys(); keys.hasNext(); ) {
747+
String s = keys.next();
753748
if (s.equals(dependencyPrefix)) {
754749
for (Object oo : p.getList(s)) {
755750
String dep = (String) oo;
@@ -800,12 +795,12 @@ protected void wireModules(ExtendedProperties wirings) {
800795
_logger.trace("< wireModules()");
801796
}
802797

803-
@SuppressWarnings("unchecked")
798+
804799
protected void configureModules() {
805800
_logger.trace("> configureModules()");
806801
for (String name : _moduleProperties.keySet()) {
807802
_logger.trace("> Configuring module: {}", name);
808-
ExtendedProperties p = _moduleProperties.get(name);
803+
AbstractConfiguration p = _moduleProperties.get(name);
809804
ButterflyModule m = _modulesByName.get(name);
810805

811806
// make the system properties accessible to the modules
@@ -818,16 +813,16 @@ protected void configureModules() {
818813
Properties properties = new Properties();
819814
File velocityProperties = new File(_webInfDir, "velocity.properties");
820815
_classLoader.watch(velocityProperties); // reload if the velocity properties change
821-
FileInputStream fis = new FileInputStream(velocityProperties);
822-
properties.load(fis);
823-
fis.close();
816+
try (FileInputStream fis = new FileInputStream(velocityProperties)) {
817+
properties.load(fis);
818+
}
824819

825820
// set properties for resource loading
826-
properties.setProperty("resource.loader", "butterfly");
827-
properties.setProperty("butterfly.resource.loader.class", ButterflyResourceLoader.class.getName());
828-
properties.setProperty("butterfly.resource.loader.cache", "true");
829-
properties.setProperty("butterfly.resource.loader.modificationCheckInterval", "1");
830-
properties.setProperty("butterfly.resource.loader.description", "Butterfly Resource Loader");
821+
properties.setProperty("resource.loaders", "butterfly");
822+
properties.setProperty("resource.loader.butterfly.class", ButterflyResourceLoader.class.getName());
823+
properties.setProperty("resource.loader.butterfly.cache", "true");
824+
properties.setProperty("resource.loader.butterfly.modification_check_interval", "1");
825+
properties.setProperty("resource.loader.butterfly.description", "Butterfly Resource Loader");
831826

832827
// set properties for macros
833828
properties.setProperty("velocimacro.library.path", p.getString("templating.macros", ""));
@@ -854,8 +849,8 @@ protected void configureModules() {
854849
_logger.trace("< enabling templating");
855850
}
856851

857-
List<String> scriptables = p.getList("scriptables");
858-
if (scriptables.size() > 0) {
852+
List<String> scriptables = p.getList(String.class, "scriptables");
853+
if (scriptables != null && !scriptables.isEmpty()) {
859854
Context context = Context.enter();
860855

861856
BufferedReader initializerReader = null;
@@ -887,7 +882,7 @@ protected void configureModules() {
887882
Context.exit();
888883
}
889884

890-
List<String> controllers = p.getList("controller", CONTROLLER);
885+
List<String> controllers = p.getList(String.class, "controller", CONTROLLER);
891886
Set<URL> controllerURLs = new HashSet<URL>(controllers.size());
892887
for (String controller : controllers) {
893888
URL controllerURL = m.getResource("MOD-INF/" + controller);

main/src/edu/mit/simile/butterfly/ButterflyModule.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import javax.servlet.http.HttpServletRequest;
1515
import javax.servlet.http.HttpServletResponse;
1616

17-
import org.apache.commons.collections.ExtendedProperties;
17+
import org.apache.commons.configuration2.FileBasedConfiguration;
1818
import org.apache.velocity.VelocityContext;
1919
import org.apache.velocity.app.VelocityEngine;
2020
import org.mozilla.javascript.Context;
@@ -65,7 +65,7 @@ public interface ButterflyModule {
6565

6666
public void setTemplateEngine(VelocityEngine velocity);
6767

68-
public void setProperties(ExtendedProperties properties);
68+
public void setProperties(FileBasedConfiguration properties);
6969

7070
public void setTimer(Timer timer);
7171

@@ -77,7 +77,7 @@ public interface ButterflyModule {
7777

7878
public String getName();
7979

80-
public ExtendedProperties getProperties();
80+
public FileBasedConfiguration getProperties();
8181

8282
public File getPath();
8383

0 commit comments

Comments
 (0)