*
* @param change the change describing the node to be processed.
*/
protected void processChange( NetChange change ) {
final ExecutionContext context = this.getExecutionContext();
final Logger logger = context.getLogger(getClass());
assert logger != null;
try {
final String repositorySourceName = change.getRepositorySourceName();
final String repositoryWorkspaceName = change.getRepositoryWorkspaceName();
// Figure out which sequencers accept this path,
// and track which output nodes should be passed to each sequencer...
final Path nodePath = change.getPath();
final String nodePathStr = context.getValueFactories().getStringFactory().create(nodePath);
Map<SequencerCall, Set<RepositoryNodePath>> sequencerCalls = new HashMap<SequencerCall, Set<RepositoryNodePath>>();
List<Sequencer> allSequencers = this.sequencerLibrary.getInstances();
List<Sequencer> sequencers = new ArrayList<Sequencer>(allSequencers.size());
for (Sequencer sequencer : allSequencers) {
final SequencerConfig config = sequencer.getConfiguration();
for (SequencerPathExpression pathExpression : config.getPathExpressions()) {
for (Property property : change.getModifiedProperties()) {
Name propertyName = property.getName();
String propertyNameStr = context.getValueFactories().getStringFactory().create(propertyName);
String path = nodePathStr + "/@" + propertyNameStr;
SequencerPathExpression.Matcher matcher = pathExpression.matcher(path);
if (matcher.matches()) {
// String selectedPath = matcher.getSelectedPath();
RepositoryNodePath outputPath = RepositoryNodePath.parse(matcher.getOutputPath(),
repositorySourceName,
repositoryWorkspaceName);
SequencerCall call = new SequencerCall(sequencer, propertyNameStr);
// Record the output path ...
Set<RepositoryNodePath> outputPaths = sequencerCalls.get(call);
if (outputPaths == null) {
outputPaths = new HashSet<RepositoryNodePath>();
sequencerCalls.put(call, outputPaths);
}
outputPaths.add(outputPath);
sequencers.add(sequencer);
break;
}
}
}
}
RepositorySource source = repositoryLibrary.getSource(repositorySourceName);
Graph graph = Graph.create(source, context);
Node node = null;
if (!sequencers.isEmpty()) {
// Find the changed node ...
node = graph.getNodeAt(nodePath);
// Figure out which sequencers should run ...
sequencers = this.sequencerSelector.selectSequencers(sequencers, node, change);
}
if (sequencers.isEmpty()) {
this.statistics.recordNodeSkipped();
if (logger.isDebugEnabled()) {
logger.trace("Skipping '{0}': no sequencers matched this condition", change);
}
} else {
// Run each of those sequencers ...
for (Map.Entry<SequencerCall, Set<RepositoryNodePath>> entry : sequencerCalls.entrySet()) {
final SequencerCall sequencerCall = entry.getKey();
final Set<RepositoryNodePath> outputPaths = entry.getValue();
final Sequencer sequencer = sequencerCall.getSequencer();
final String sequencerName = sequencer.getConfiguration().getName();
final String propertyName = sequencerCall.getSequencedPropertyName();
// Get the paths to the nodes where the sequencer should write it's output ...
assert outputPaths != null && outputPaths.size() != 0;
// Create a new execution context for each sequencer
final SimpleProblems problems = new SimpleProblems();
SequencerContext sequencerContext = new SequencerContext(context, graph);
try {
sequencer.execute(node, propertyName, change, outputPaths, sequencerContext, problems);
sequencerContext.getDestination().submit();
} catch (SequencerException e) {
logger.error(e, RepositoryI18n.errorWhileSequencingNode, sequencerName, change);
}
}
this.statistics.recordNodeSequenced();
}
} catch (Throwable e) {
logger.error(e, RepositoryI18n.errorFindingSequencersToRunAgainstNode, change);
}
}