Map<String, String> sofamap = new TreeMap<String, String>();
SofaMapping[] sofaMappings = this.getSofaMappings();
if (sofaMappings != null) {
for (int s = 0; s < sofaMappings.length; s++) {
String componentKey = sofaMappings[s].getComponentKey();
ResourceSpecifier componentSpec = getComponentSpecifier(componentKey);
if (componentSpec == null) {
throw new ResourceInitializationException(
ResourceInitializationException.SOFA_MAPPING_HAS_UNDEFINED_COMPONENT_KEY,
new Object[] { componentKey, sofaMappings[s].getAggregateSofaName(), aggName,
getSourceUrlString() });
}
String componentSofaName = sofaMappings[s].getComponentSofaName();
if (componentSofaName == null) {
componentSofaName = CAS.NAME_DEFAULT_SOFA;
} else if (componentSpec instanceof AnalysisEngineDescription
&& !CAS.NAME_DEFAULT_SOFA.equals(componentSofaName)
&& !declaresSofa((AnalysisEngineDescription) componentSpec, componentSofaName)) {
throw new ResourceInitializationException(
ResourceInitializationException.SOFA_MAPPING_HAS_UNDEFINED_COMPONENT_SOFA,
new Object[] { componentKey, componentSofaName,
sofaMappings[s].getAggregateSofaName(), aggName, getSourceUrlString() });
}
String compoundKey = sofaMappings[s].getComponentKey() + "@/@"
+ sofaMappings[s].getComponentSofaName();
String aggSofaName = sofaMappings[s].getAggregateSofaName();
// check for double-mapping
String existingMapping = (String) sofamap.get(compoundKey);
if (existingMapping != null && !existingMapping.equals(aggSofaName)) {
throw new ResourceInitializationException(
ResourceInitializationException.SOFA_MAPPING_CONFLICT, new Object[] {
sofaMappings[s].getComponentSofaName(), sofaMappings[s].getComponentKey(),
aggName, existingMapping, aggSofaName, getSourceUrlString() });
} else {
sofamap.put(compoundKey, aggSofaName);
}
}
}
// Rules for SofAs:
// (1) Each component output sofa must be mapped to an aggregate output sofa
// (2) Each aggregate output sofa must be mapped to a component output sofa
// (3) Each component input sofa must be mapped to an aggregate input sofa OR a component output
// sofa
// (4) Each aggregate input sofa must be mapped to a component input sofa
// From (1) and (3) we derive that:
// Each component input sofa must be mapped to an aggregate input sofa OR an aggregate output
// sofa
// (which is easier to check)
// Exception: if aggregate contains a remote component, we cannot check that remote
// component's input or output sofas, so rules (2) and (4) cannot be checked.
boolean containsRemote = false;
Set<String> correctlyMappedAggregateOutputs = new HashSet<String>();
Set<String> correctlyMappedAggregateInputs = new HashSet<String>();
Iterator<Map.Entry<String, ResourceSpecifier>> iter;
try {
iter = getDelegateAnalysisEngineSpecifiers().entrySet().iterator();
} catch (InvalidXMLException e) {
throw new ResourceInitializationException(e);
}
while (iter.hasNext()) {
Map.Entry<String, ResourceSpecifier> entry = iter.next();
String componentKey = entry.getKey();
ResourceSpecifier delegateSpec = entry.getValue();
if (delegateSpec instanceof AnalysisEngineDescription) {
Capability[] caps = ((AnalysisEngineDescription) delegateSpec).getAnalysisEngineMetaData()
.getCapabilities();
for (int i = 0; i < caps.length; i++) {