Skip to content

Commit

Permalink
Support entity references inside XML configuration.
Browse files Browse the repository at this point in the history
This commit declares protocols opt4j:// and env:// to access Opt4j and
environment provided variables in SYSTEM entity declarations.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration [
  <!ENTITY CONFIGDIR SYSTEM "opt4j://CONFIGDIR">
  <!ENTITY SYSTEMOC  SYSTEM "env://SYSTEMOC_INSTALLDIR">
]>
<configuration>
  ...
    <property name="measuringStartScript">&CONFIGDIR;/../resources/runMeasureSynth</property>
    <property name="systeMoCInstallDir">&SYSTEMOC;</property>
  ...
</configuration>
  • Loading branch information
JoachimFalk committed Jun 4, 2020
1 parent f2cb505 commit 16e75d4
Showing 1 changed file with 48 additions and 1 deletion.
49 changes: 48 additions & 1 deletion opt4j-core/src/main/java/org/opt4j/core/config/ModuleLoader.java
Expand Up @@ -25,6 +25,7 @@

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
Expand All @@ -36,6 +37,8 @@
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;

import com.google.inject.Module;

Expand Down Expand Up @@ -73,6 +76,48 @@ public Collection<? extends Module> load(String filename) {
return load(file);
}

/**
* Entity resolver for replacing XML entity references inside the XML
* configuration loaded by Opt4j to configure the active modules and their
* parameters.
*/
public class Opt4JEntityResolver implements EntityResolver {

File configDirectory;

/**
* Constructs a {@link Opt4JEntityResolver}.
*
* @param configDirectory
* the directory where the configuration that is currently
* parsed resides in
*/
Opt4JEntityResolver(File configDirectory) {
this.configDirectory = configDirectory;
}

@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
String result = null;
if (systemId.startsWith("opt4j://")) {
if (systemId.equals("opt4j://CONFIGDIR"))
result = configDirectory.getPath();
else
throw new SAXException(
"Entity definition " + systemId + " within protocol opt4j:// is not supported!");
} else if (systemId.startsWith("env://")) {
String var = systemId.substring(6);
result = System.getenv(var);
if (result == null)
throw new SAXException("Environment variable " + var + " used by entity definition " + systemId
+ " is not defined!");
} else
return null;
return new InputSource(new StringReader(result));
}

};

/**
* Loads all modules from a {@link File}.
*
Expand All @@ -86,10 +131,12 @@ public Collection<? extends Module> load(File file) {

try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setExpandEntityReferences(true);
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(new Opt4JEntityResolver(file.getParentFile().getAbsoluteFile()));
Document document = builder.parse(file);

modules.addAll(get(document.getFirstChild()));
modules.addAll(get(document.getDocumentElement()));

} catch (ParserConfigurationException e) {
e.printStackTrace();
Expand Down

0 comments on commit 16e75d4

Please sign in to comment.