package at.gv.egovernment.moa.spss.server.config;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.SAXException;
import iaik.ixsil.exceptions.URIException;
import iaik.ixsil.util.URI;
import iaik.pki.pathvalidation.ChainingModes;
import iaik.utils.RFC2253NameParser;
import iaik.utils.RFC2253NameParserException;
import at.gv.egovernment.moa.logging.LogMsg;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.Constants;
import at.gv.egovernment.moa.util.DOMUtils;
import at.gv.egovernment.moa.util.XPathUtils;
import at.gv.egovernment.moa.spss.util.MessageProvider;
/**
* A class that builds configuration data from a DOM based representation.
*
* @author Patrick Peck
* @version $Id$
*/
public class ConfigurationPartsBuilder {
//
// XPath namespace prefix shortcuts
//
private static final String CONF = Constants.MOA_CONFIG_PREFIX + ":";
private static final String DSIG = Constants.DSIG_PREFIX + ":";
//
// chaining mode constants appearing in the configuration file
//
private static final String CM_CHAINING = "chaining";
private static final String CM_PKIX = "pkix";
//
// XPath expressions to select certain parts of the configuration
//
private static final String ROOT = "/" + CONF + "MOAConfiguration/";
private static final String DIGEST_METHOD_XPATH =
ROOT + CONF + "DigestMethodAlgorithm/@name";
private static final String C14N_ALGORITHM_XPATH =
ROOT + CONF + "CanonicalizationAlgorithm/@name";
private static final String HARDWARE_CRYPTO_MODULE_XPATH =
ROOT + CONF + "HardwareCryptoModule";
private static final String HARDWARE_KEY_XPATH =
ROOT + CONF + "HardwareKeyModule";
private static final String SOFTWARE_KEY_XPATH =
ROOT + CONF + "SoftwareKeyModule";
private static final String KEYGROUP_XPATH = ROOT + CONF + "KeyGroup";
private static final String KEY_XPATH = CONF + "Key";
private static final String KEY_MODULE_ID_XPATH = CONF + "KeyModuleID";
private static final String KEY_CERT_XPATH = CONF + "KeyCertIssuerSerial";
private static final String KEYGROUP_MAPPING_XPATH =
ROOT + CONF + "KeyGroupMapping";
private static final String KEYGROUP_MAPPING_KEYGROUP_XPATH =
CONF + "KeyGroup";
private static final String ISSUER_SERIAL_XPATH = CONF + "X509IssuerSerial";
private static final String ISSUER_XPATH = DSIG + "X509IssuerName";
private static final String SERIAL_XPATH = DSIG + "X509SerialNumber";
private static final String CHAINING_MODES_XPATH =
ROOT + CONF + "ChainingModes";
private static final String CHAINING_MODES_DEFAULT_XPATH =
CHAINING_MODES_XPATH + "/@systemDefaultMode";
private static final String TRUST_ANCHOR_XPATH =
ROOT + CONF + "ChainingModes/" + CONF + "TrustAnchor";
private static final String CRL_DISTRIBUTION_POINT_XPATH =
ROOT + CONF + "CRLDistributionPoint";
private static final String CA_ISSUER_DN_XPATH = CONF + "CAIssuerDN";
private static final String DISTRIBUTION_POINT_XPATH =
CONF + "DistributionPoint";
private static final String CRL_ARCHIVE_XPATH = ROOT + CONF + "CRLArchive";
private static final String GENERIC_CONFIGURATION_XPATH =
ROOT + CONF + "GenericConfiguration";
private static final String CREATE_TRANSFORMS_INFO_PROFILE_XPATH =
ROOT + CONF + "CreateTransformsInfoProfile";
private static final String CREATE_SIGNATURE_ENVIRONMENT_PROFILE_XPATH =
ROOT + CONF + "CreateSignatureEnvironmentProfile";
private static final String VERIFY_TRANSFORMS_INFO_PROFILE_XPATH =
ROOT + CONF + "VerifyTransformsInfoProfile";
private static final String SUPPLEMENT_PROFILE_XPATH =
ROOT + CONF + "SupplementProfile";
private static final String TRUST_PROFILE_XPATH =
ROOT + CONF + "TrustProfile";
//
// default values for configuration parameters
//
/** The accepted canonicalization algorithm URIs, as an array */
private static final String[] ACCEPTED_C14N_ALGORITHMS_ARRAY =
{
Constants.C14N_URI,
Constants.C14N_WITH_COMMENTS_URI,
Constants.EXC_C14N_URI,
Constants.EXC_C14N_WITH_COMMENTS_URI };
/** The accepted canonicalization algorithm URIs, as a Set */
private static final Set ACCEPTED_C14N_ALGORITHMS =
new HashSet(Arrays.asList(ACCEPTED_C14N_ALGORITHMS_ARRAY));
/** Default canonicalization algorithm, if none/illegal has been configured */
private static final String C14N_ALGORITHM_DEFAULT = Constants.C14N_URI;
/** The accepted digest method algorithm URIs, as an array */
private static final String[] ACCEPTED_DIGEST_ALGORITHMS_ARRAY =
{ Constants.SHA1_URI };
/** The accepted digest method algorithm URIs, as a Set */
private static final Set ACCEPTED_DIGEST_ALGORITHMS =
new HashSet(Arrays.asList(ACCEPTED_DIGEST_ALGORITHMS_ARRAY));
/** Default digest algorithm URI, if none/illegal has been configured */
private static final String DIGEST_ALGORITHM_DEFAULT = Constants.SHA1_URI;
/** The root element of the MOA configuration */
private Element configElem;
/** Whether any warnings were encountered building the configuration. */
private List warnings = new ArrayList();
/**
* Create a new ConfigurationPartsBuilder
.
*
* @param configElem The root element of the MOA configuration.
*/
public ConfigurationPartsBuilder(Element configElem) {
this.configElem = configElem;
}
/**
* Returns the root element of the MOA configuration.
*
* @return The root element of the MOA configuration.
*/
public Element getConfigElem() {
return configElem;
}
/**
* Returns the warnings encountered during building the configuration.
*
* @return A List
of String
s, containing the
* warning messages.
*/
public List getWarnings() {
return warnings;
}
/**
* Returns the digest method algorithm name.
*
* @return The digest method algorithm name from the configuration.
*/
public String getDigestMethodAlgorithmName() {
String digestMethod =
getAttributeValue(getConfigElem(), DIGEST_METHOD_XPATH, null);
if (digestMethod == null
|| !ACCEPTED_DIGEST_ALGORITHMS.contains(digestMethod)) {
warn(
"config.23",
new Object[] { "DigestMethodAlgorithm", DIGEST_ALGORITHM_DEFAULT });
digestMethod = DIGEST_ALGORITHM_DEFAULT;
}
return digestMethod;
}
/**
* Returns the canonicalization algorithm name.
*
* @return The canonicalization algorithm name from the configuration.
*/
public String getCanonicalizationAlgorithmName() {
String c14nAlgorithm =
getAttributeValue(getConfigElem(), C14N_ALGORITHM_XPATH, null);
if (c14nAlgorithm == null
|| !ACCEPTED_C14N_ALGORITHMS.contains(c14nAlgorithm)) {
warn(
"config.23",
new Object[] { "CanonicalizationAlgorithm", C14N_ALGORITHM_DEFAULT });
c14nAlgorithm = C14N_ALGORITHM_DEFAULT;
}
return c14nAlgorithm;
}
/**
* Build the mapping of generic configuration properties.
*
* @return The mapping of generic configuration properties (a name to value
* mapping) from the configuration.
*/
public Map buildGenericConfiguration() {
Map genericConfiguration = new HashMap();
NodeIterator gcIter =
XPathUtils.selectNodeIterator(
getConfigElem(),
GENERIC_CONFIGURATION_XPATH);
Element gcElem;
while ((gcElem = (Element) gcIter.nextNode()) != null) {
String gcName = gcElem.getAttribute("name");
String gcValue = gcElem.getAttribute("value");
if (genericConfiguration.containsKey(gcName)) {
warn("config.24", new Object[] { gcName });
} else {
genericConfiguration.put(gcName, gcValue);
}
}
return genericConfiguration;
}
/**
* Build the configured hardware crypto modules.
*
* @return The hardware crypto modules from the configuration.
*/
public List buildHardwareCryptoModules() {
List modules = new ArrayList();
NodeIterator modIter =
XPathUtils.selectNodeIterator(
getConfigElem(),
HARDWARE_CRYPTO_MODULE_XPATH);
Element modElem;
while ((modElem = (Element) modIter.nextNode()) != null) {
String name = modElem.getAttribute("name");
String slotID = modElem.getAttribute("slotID");
String userPIN = modElem.getAttribute("userPIN");
HardwareCryptoModule module =
new HardwareCryptoModule(name, slotID, userPIN);
modules.add(module);
}
return modules;
}
/**
* Build the configured hardware keys.
*
* @param The keyModules that the configuration already knows about. To
* prevent multiple key modules with the same ID.
* @return The hardware keys contained in the configuration.
*/
public List buildHardwareKeyModules(List keyModules) {
Set existingIds = toIdSet(keyModules);
List hardwareKeys = new ArrayList();
NodeIterator hkIter =
XPathUtils.selectNodeIterator(getConfigElem(), HARDWARE_KEY_XPATH);
Element keyElem;
while ((keyElem = (Element) hkIter.nextNode()) != null) {
String id = keyElem.getAttribute("id");
String name = keyElem.getAttribute("name");
String slotID = keyElem.getAttribute("slotID");
String userPIN = keyElem.getAttribute("userPIN");
if (existingIds.contains(id)) {
warn(
"config.04",
new Object[] { "Hardware- oder SoftwareKeyModule", id });
} else {
KeyModule key = new HardwareKeyModule(id, name, slotID, userPIN);
hardwareKeys.add(key);
existingIds.add(id);
}
}
return hardwareKeys;
}
/**
* Build the configured software keys.
*
* @param The keyModules that the configuration already knows about. To
* prevent multiple key modules with the same ID.
* @param configRoot The directory containing the main configuration file.
* Used to resolve keystore files configured using a relative URI.
* @return The software keys contained in the configuration.
*/
public List buildSoftwareKeyModules(List keyModules, File configRoot) {
Set existingIds = toIdSet(keyModules);
List softwareKeys = new ArrayList();
NodeIterator skIter =
XPathUtils.selectNodeIterator(getConfigElem(), SOFTWARE_KEY_XPATH);
Element keyElem;
while ((keyElem = (Element) skIter.nextNode()) != null) {
String id = keyElem.getAttribute("id");
String fileName = keyElem.getAttribute("filename");
String passWord = keyElem.getAttribute("password");
if (existingIds.contains(id)) {
warn(
"config.04",
new Object[] { "Hardware- oder SoftwareKeyModule", id });
} else {
File keyFile;
KeyModule key;
// make keyFile absolute
keyFile = new File(fileName);
if (!keyFile.isAbsolute()) {
keyFile = new File(configRoot, fileName);
}
// check for existence
if (!keyFile.exists() || keyFile.isDirectory()) {
warn("config.25", new Object[] { id, keyFile.getAbsolutePath()});
} else {
// create a new key module
key = new SoftwareKeyModule(id, keyFile.getAbsolutePath(), passWord);
softwareKeys.add(key);
existingIds.add(id);
}
}
}
return softwareKeys;
}
/**
* Build the key group configuration.
*
* @param keyModules The KeyModule
s that the configuration
* knows about. Used to check for errors in the configuration.
* @return The mapping between key group IDs and key groups.
*/
public Map buildKeyGroups(List keyModules) {
Set keyModuleIds = toIdSet(keyModules);
Map keyGroups = new HashMap();
NodeIterator kgIter;
Element keyGroupElem;
// select all KeyGroup elements and build the KeyGroup objects from them
kgIter = XPathUtils.selectNodeIterator(getConfigElem(), KEYGROUP_XPATH);
while ((keyGroupElem = (Element) kgIter.nextNode()) != null) {
String keyGroupId = keyGroupElem.getAttribute("id");
Set keyGroupEntries =
buildKeyGroupEntries(keyGroupId, keyModuleIds, keyGroupElem);
KeyGroup keyGroup = new KeyGroup(keyGroupId, keyGroupEntries);
if (keyGroups.containsKey(keyGroupId)) {
warn("config.04", new Object[] { "KeyGroup", keyGroupId });
} else {
keyGroups.put(keyGroup.getId(), keyGroup);
}
}
return keyGroups;
}
/**
* Return the set of IDs contained in the given KeyModule
s.
*
* @param keyModules The KeyModule
s from which to extract the
* IDs.
* @return The IDs from the given KeyModule
s.
*/
private Set toIdSet(List keyModules) {
Set ids = new HashSet();
Iterator iter;
for (iter = keyModules.iterator(); iter.hasNext();) {
KeyModule keyModule = (KeyModule) iter.next();
ids.add(keyModule.getId());
}
return ids;
}
/**
* Build the key entries belonging to a key group.
*
* @param keyGroupId The ID of the key group we are building here. Passed
* for logging purposes.
* @param keyModuleIds The IDs of the HardwareKeyModule
s and
* SoftwareKeyModule
s that exist in the configuration.
* @param keyGroupElem The KeyGroup
DOM element to parse.
* @return A Set
of KeyGroupEntry
objects.
*/
private Set buildKeyGroupEntries(
String keyGroupId,
Set keyModuleIds,
Element keyGroupElem) {
Set entries = new HashSet();
NodeIterator keyEntryIter;
Element keyEntryElem;
// select all Key elements and put them into the Map
keyEntryIter = XPathUtils.selectNodeIterator(keyGroupElem, KEY_XPATH);
while ((keyEntryElem = (Element) keyEntryIter.nextNode()) != null) {
String keyModuleId =
getElementValue(keyEntryElem, KEY_MODULE_ID_XPATH, "");
Element keyCertElem =
(Element) XPathUtils.selectSingleNode(keyEntryElem, KEY_CERT_XPATH);
IssuerAndSerial issuerSerial = buildIssuerAndSerial(keyCertElem);
if (!keyModuleIds.contains(keyModuleId)) {
warn("config.26", new Object[] { keyGroupId, keyModuleId });
} else if (issuerSerial != null) {
KeyGroupEntry entry = new KeyGroupEntry(keyModuleId, issuerSerial);
entries.add(entry);
}
}
return entries;
}
/**
* Build the key group mapping.
*
* @param keyGroups The available key groups.
* @param anonymous The IssuerAndSerial
to be used for key group
* mappings not protected by a certificate.
* @return The key group mapping.
*/
public Map buildKeyGroupMappings(Map keyGroups, IssuerAndSerial anonymous) {
Map mappings = new HashMap();
NodeIterator mappingIter;
Element mappingElem;
// select all KeyGroupMapping elements
mappingIter =
XPathUtils.selectNodeIterator(getConfigElem(), KEYGROUP_MAPPING_XPATH);
// build the mapping for each KeyGroupMapping element
while ((mappingElem = (Element) mappingIter.nextNode()) != null) {
Element issuerSerialElem =
(Element) XPathUtils.selectSingleNode(mappingElem, ISSUER_SERIAL_XPATH);
IssuerAndSerial issuerAndSerial;
// build the IssuerAndSerial who has access to the key groups
if (issuerSerialElem != null) {
issuerAndSerial = buildIssuerAndSerial(issuerSerialElem);
} else {
// IssuerSerial element: the keygroup is generally available
issuerAndSerial = anonymous;
}
// add the key groups to the mappings
if (issuerAndSerial != null) {
Map groups = (Map) mappings.get(issuerAndSerial);
NodeIterator keyGroupIter;
Element keyGroupElem;
if (groups == null) {
// no mapping exist -> build one
groups = new HashMap();
mappings.put(issuerAndSerial, groups);
}
// select the available key groups and add them to the mapping
keyGroupIter =
XPathUtils.selectNodeIterator(
mappingElem,
KEYGROUP_MAPPING_KEYGROUP_XPATH);
while ((keyGroupElem = (Element) keyGroupIter.nextNode()) != null) {
String keyGroupId = keyGroupElem.getAttribute("id");
KeyGroup keyGroup = (KeyGroup) keyGroups.get(keyGroupId);
if (keyGroup != null) {
groups.put(keyGroupId, keyGroup);
} else {
warn("config.00", new Object[] { keyGroupId });
}
}
}
}
return mappings;
}
/**
* Returns the default chaining mode from the configuration.
*
* @return The default chaining mode.
*/
public String getDefaultChainingMode() {
String defaultChaining =
getAttributeValue(
getConfigElem(),
CHAINING_MODES_DEFAULT_XPATH,
CM_CHAINING);
return translateChainingMode(defaultChaining);
}
/**
* Build the chaining modes for all configured trust anchors.
*
* @return The mapping from trust anchors to chaining modes.
*/
public Map buildChainingModes() {
Map chainingModes = new HashMap();
NodeIterator trustIter =
XPathUtils.selectNodeIterator(getConfigElem(), TRUST_ANCHOR_XPATH);
Element trustAnchorElem;
while ((trustAnchorElem = (Element) trustIter.nextNode()) != null) {
IssuerAndSerial issuerAndSerial = buildIssuerAndSerial(trustAnchorElem);
String mode = trustAnchorElem.getAttribute("mode");
if (issuerAndSerial != null) {
chainingModes.put(issuerAndSerial, translateChainingMode(mode));
}
}
return chainingModes;
}
/**
* Build an IssuerAndSerial
from the DOM representation.
*
* @param root The root element (being of type dsig:
* X509IssuerSerialType
.
* @return The issuer and serial number contained in the root
* element or null
if could not be built for any reason.
*/
private IssuerAndSerial buildIssuerAndSerial(Element root) {
String issuer = getElementValue(root, ISSUER_XPATH, null);
String serial = getElementValue(root, SERIAL_XPATH, null);
if (issuer != null && serial != null) {
try {
RFC2253NameParser nameParser = new RFC2253NameParser(issuer);
Principal issuerDN = nameParser.parse();
return new IssuerAndSerial(issuerDN, new BigInteger(serial));
} catch (RFC2253NameParserException e) {
warn("config.16", new Object[] { issuer, serial }, e);
return null;
} catch (NumberFormatException e) {
warn("config.16", new Object[] { issuer, serial }, e);
return null;
}
}
return null;
}
/**
* Translate the chaining mode from the configuration file to one used in the
* IAIK MOA API.
*
* @param chainingMode The chaining mode from the configuration.
* @return The chaining mode as provided by the ChainingModes
* interface.
* @see iaik.pki.pathvalidation.ChainingModes
*/
private String translateChainingMode(String chainingMode) {
if (chainingMode.equals(CM_CHAINING)) {
return ChainingModes.CHAIN_MODE;
} else if (chainingMode.equals(CM_PKIX)) {
return ChainingModes.PKIX_MODE;
} else {
return ChainingModes.CHAIN_MODE;
}
}
/**
* Build the CRL distribution points mapping.
*
* @return The mapping from certificate authorities to distribution points.
*/
public Map buildCRLDistributionPoints() {
Map crlDps = new HashMap();
NodeIterator crlDpIter;
Element crlDpElem;
// select all CRLDistributionPoint elements and build the
// CRLDistributionPoints
crlDpIter =
XPathUtils.selectNodeIterator(
getConfigElem(),
CRL_DISTRIBUTION_POINT_XPATH);
// build the mapping of CA name to distribution points
while ((crlDpElem = (Element) crlDpIter.nextNode()) != null) {
String caIssuerDNText =
getElementValue(crlDpElem, CA_ISSUER_DN_XPATH, "");
RFC2253NameParser nameParser = new RFC2253NameParser(caIssuerDNText);
NodeIterator dpIter =
XPathUtils.selectNodeIterator(crlDpElem, DISTRIBUTION_POINT_XPATH);
String caIssuerDN;
Set dps;
Element dpElem;
try {
caIssuerDN = nameParser.parse().getName();
// check, if a mapping exists or make a new mapping
dps = (Set) crlDps.get(caIssuerDN);
if (dps == null) {
dps = new HashSet();
crlDps.put(caIssuerDN, dps);
}
// add the distribution points of this CA to the set
while ((dpElem = (Element) dpIter.nextNode()) != null) {
DistributionPoint dp = buildDistributionPoint(dpElem);
dps.add(dp);
}
} catch (RFC2253NameParserException e) {
warn("config.13", new Object[] { caIssuerDNText }, e);
}
}
return crlDps;
}
/**
* Build a distribution point from the DOM representation.
*
* @param dpElem The root element of the distribution point.
* @return The distribution point.
*/
private DistributionPoint buildDistributionPoint(Element dpElem) {
String uri = dpElem.getAttribute("uri");
String reasonCodes = dpElem.getAttribute("reasonCodes");
return new DistributionPoint(uri, reasonCodes != null ? reasonCodes : "");
}
/**
* Return the CRL archive duration.
*
* @return The value of the CRL archive duration setting from the
* configuration.
*/
public int getCRLArchiveDuration() {
Element crlArchiveElem =
(Element) XPathUtils.selectSingleNode(getConfigElem(), CRL_ARCHIVE_XPATH);
String crlArchiveDuration;
if (crlArchiveElem == null) {
return 0;
}
try {
crlArchiveDuration = crlArchiveElem.getAttribute("duration");
return Integer.parseInt(crlArchiveDuration);
} catch (NumberFormatException e) {
warn("config.01", null);
return 0;
}
}
/**
* Build the CreateTransformsInfoProfile
s.
*
* @param configRoot The directory of the main configuration file. Used for
* lookup of profiles with relative file names.
* @return The mapping from profile ID to profile.
*/
public Map buildCreateTransformsInfoProfiles(File configRoot) {
return loadProfiles(
configRoot,
CREATE_TRANSFORMS_INFO_PROFILE_XPATH,
"CreateTransformsInfoProfile");
}
/**
* Build the CreateSignatureEnvironmentProfile
s.
*
* @param configRoot The directory of the main configuration file. Used for
* lookup of profiles with relative file names.
* @return The mapping from profile ID to profile.
*/
public Map buildCreateSignatureEnvironmentProfiles(File configRoot) {
return loadProfiles(
configRoot,
CREATE_SIGNATURE_ENVIRONMENT_PROFILE_XPATH,
"CreateSignatureEnvironmentProfile");
}
/**
* Build the VerifyTransformsInfoProfile
s.
*
* @param configRoot The directory of the main configuration file. Used for
* lookup of profiles with relative file names.
* @return The mapping from profile ID to profile.
*/
public Map buildVerifyTransformsInfoProfiles(File configRoot) {
return loadProfiles(
configRoot,
VERIFY_TRANSFORMS_INFO_PROFILE_XPATH,
"VerifyTransformsInfoProfile");
}
/**
* Build the SupplementProfile
s.
*
* @param configRoot The directory of the main configuration file. Used for
* lookup of profiles with relative file names.
* @return The mapping from profile ID to profile.
*/
public Map buildSupplementProfiles(File configRoot) {
return loadProfiles(
configRoot,
SUPPLEMENT_PROFILE_XPATH,
"SupplementProfile");
}
/**
* Load a profile mapping.
*
* @param root The absolute directory path of the main configuration file.
* @param xpath The XPath to select the profiles from the configuration.
* @param profileRoot The name of the profile root element.
* @return Map The profile ID to profile mapping.
*/
private Map loadProfiles(File root, String xpath, String profileRoot) {
Map profiles = new HashMap();
NodeIterator profileIter =
XPathUtils.selectNodeIterator(getConfigElem(), xpath);
Element profileElem;
while ((profileElem = (Element) profileIter.nextNode()) != null) {
String id = profileElem.getAttribute("id");
String fileName = profileElem.getAttribute("filename");
if (profiles.containsKey(id)) {
warn("config.04", new Object[] { profileRoot, id });
} else {
Element profile;
try {
File profileFile = new File(fileName);
// make profileFile absolute
if (!profileFile.isAbsolute()) {
profileFile = new File(root, fileName);
}
// load the profile
info(
"config.22",
new Object[] { profileRoot, id, profileFile.getAbsoluteFile()});
profile = loadProfile(profileFile);
if (profile.getTagName().equals(profileRoot)) {
profiles.put(id, profile);
} else {
warn("config.02", new Object[] { profileRoot, id, fileName });
}
} catch (ConfigurationException e) {
warn("config.03", new Object[] { profileRoot, id });
}
}
}
return profiles;
}
/**
* Load a profile from a file.
*
* @param root The absolute directory path of the main configuration file.
* @param profileFile The file containing the profile.
* @return The profile in its DOM representation.
* @throws ConfigurationException An error occurred loading the profile.
*/
private Element loadProfile(File profileFile) throws ConfigurationException {
Element profile;
try {
profile = parseXml(new FileInputStream(profileFile));
} catch (Exception e) {
throw new ConfigurationException("config.12", null, e);
}
return profile;
}
/**
* Bulid the trust profile mapping.
*
* @param configRoot The absolute path to the main configuration file.
* @return The profile ID to profile mapping.
*/
public Map buildTrustProfiles(File configRoot) {
Map trustProfiles = new HashMap();
NodeIterator profileIter =
XPathUtils.selectNodeIterator(getConfigElem(), TRUST_PROFILE_XPATH);
Element profileElem;
while ((profileElem = (Element) profileIter.nextNode()) != null) {
String id = profileElem.getAttribute("id");
String uriStr = profileElem.getAttribute("uri");
try {
URI uri = new URI(uriStr);
TrustProfile profile;
File profileDir;
if (!uri.isAbsolute()) { // make it absolute to the config file
uri = new URI(configRoot.toURL() + uriStr);
}
profileDir = new File(uri.getPath());
if (!profileDir.exists() || !profileDir.isDirectory()) {
warn("config.27", new Object[] { id });
}
if (trustProfiles.containsKey(id)) {
warn("config.04", new Object[] { "TrustProfile", id });
} else {
profile = new TrustProfile(id, uri.toString());
trustProfiles.put(id, profile);
}
} catch (URIException e) {
warn("config.14", new Object[] { id, uriStr }, e);
} catch (MalformedURLException e) {
warn("config.15", null, e);
}
}
return trustProfiles;
}
//
// various utility methods
//
/**
* Parse a configuration XML file.
*
* @param inputStream The stream from which to read the XML data.
* @return The DOM representation of the XML data.
* @throws ParserConfigurationException XML parser not configured properly.
* @throws SAXException An error parsing the XML file.
* @throws IOException An error reading the stream.
*/
private static Element parseXml(InputStream inputStream)
throws ParserConfigurationException, SAXException, IOException {
return DOMUtils
.parseDocument(inputStream, true, Constants.ALL_SCHEMA_LOCATIONS, null)
.getDocumentElement();
}
/**
* Return the value of an element located by an XPath.
*
* @param root The root element from which to evaluate the xpath
.
* @param xpath The XPath pointing to the element.
* @param def The default value, if no element can be found with the given
* xpath
.
* @return The element value or def
, if the element cannot be
* found.
*/
private String getElementValue(Element root, String xpath, String def) {
Element elem = (Element) XPathUtils.selectSingleNode(root, xpath);
return elem != null ? DOMUtils.getText(elem) : def;
}
/**
* Return the value of an attribute located by an XPath.
*
* @param root The root element from which to evaluate the xpath
.
* @param xpath The XPath pointing to the attribute.
* @param def The default value, if no attribute can be found with the given
* xpath
.
* @return The element value or def
, if the attribute cannot be
* found.
*/
private String getAttributeValue(Element root, String xpath, String def) {
Attr attr = (Attr) XPathUtils.selectSingleNode(root, xpath);
return attr != null ? attr.getValue() : def;
}
/**
* Log an info message.
*
* @param messageId The message ID.
* @param parameters Additional parameters for the message.
* @see at.gv.egovernment.moa.spss.server.util.MessageProvider
*/
private static void info(String messageId, Object[] parameters) {
MessageProvider msg = MessageProvider.getInstance();
Logger.info(new LogMsg(msg.getMessage(messageId, parameters)));
}
/**
* Log a warning.
*
* @param messageId The message ID.
* @param args Additional parameters for the message.
* @see at.gv.egovernment.moa.spss.server.util.MessageProvider
*/
private void warn(String messageId, Object[] args) {
MessageProvider msg = MessageProvider.getInstance();
String txt = msg.getMessage(messageId, args);
Logger.warn(new LogMsg(txt));
warnings.add(txt);
}
/**
* Log a warning.
*
* @param messageId The message ID.
* @param args Additional parameters for the message.
* @param t An exception being the cause of the warning.
* @see at.gv.egovernment.moa.spss.server.util.MessageProvider
*/
private void warn(String messageId, Object[] args, Throwable t) {
MessageProvider msg = MessageProvider.getInstance();
String txt = msg.getMessage(messageId, args);
Logger.warn(new LogMsg(txt), t);
warnings.add(txt);
}
}