Created
November 16, 2015 19:23
-
-
Save virtuald/fda8e589c741cf20c510 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.takari.incrementalbuild.spi; | |
import java.io.File; | |
import java.io.IOException; | |
import java.io.Serializable; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import java.util.Collections; | |
import java.util.HashSet; | |
import javax.inject.Inject; | |
import javax.inject.Named; | |
import org.apache.maven.execution.scope.MojoExecutionScoped; | |
import io.takari.incrementalbuild.Output; | |
import io.takari.incrementalbuild.ResourceStatus; | |
import io.takari.incrementalbuild.aggregator.InputAggregator; | |
import io.takari.incrementalbuild.aggregator.internal.DefaultAggregatorBuildContext; | |
@Named | |
@MojoExecutionScoped | |
public class EnhancedAggregateBuildContext extends DefaultAggregatorBuildContext{ | |
protected static final String AGGREGATE_PREFIX = "agg://"; | |
protected static final String AGGREGATE_DATA = "aggregate-data"; | |
static File addPostfix(File f) { | |
try { | |
return new File(f.getCanonicalPath() + "_agg"); | |
} catch (IOException e) { | |
return new File(f.getAbsolutePath() + "_agg"); | |
} | |
} | |
@Inject | |
public EnhancedAggregateBuildContext(BuildContextEnvironment env) { | |
// have to change the statefile, as the same statefile is used for each context | |
// and that leads to some really strange errors | |
super(env.getWorkspace(), addPostfix(env.getStateFile()), env.getParameters(), env.getFinalizer()); | |
//super(configuration); | |
} | |
/** | |
* Associates metadata for an input with with an output file | |
*/ | |
public void setOutputInputAttribute(File outputFile, File inputFile, Serializable s) { | |
markProcessedResource(inputFile); | |
setResourceAttribute(inputFile, getAttributeKey(outputFile), s); | |
} | |
public <T extends Serializable> T getOutputInputAttribute(File outputFile, File inputFile, Class<T> clazz) { | |
// always returns from new state | |
return getResourceAttribute(state, inputFile, getAttributeKey(outputFile), clazz); | |
} | |
/** | |
* Associates metadata with an output file | |
*/ | |
public void setOutputAggregateAttribute(File outputFile, Serializable s) { | |
setResourceAttribute(outputFile, AGGREGATE_DATA, s); | |
} | |
/** | |
* Retrieves metadata associated with an output file | |
*/ | |
public <T extends Serializable> T getOutputAggregateAttribute(Output<File> outputFile, Class<T> clazz) { | |
return getAttribute(outputFile.getResource(), AGGREGATE_DATA, clazz); | |
} | |
/** | |
* Retrieves metadata associated with input files as set by | |
* setOutputInputAttribute | |
*/ | |
public <T extends Serializable> Collection<T> getOutputMetadata(Output<File> output, Iterable<File> inputs, Class<T> clazz) { | |
String key = getAttributeKey(output.getResource()); | |
Collection<T> metadata = new ArrayList<>(); | |
for (File input: inputs) { | |
metadata.add(getAttribute(input, key, clazz)); | |
} | |
return metadata; | |
} | |
@Override | |
public boolean aggregateIfNecessary(Collection<File> inputs, File outputFile, InputAggregator creator) | |
throws IOException { | |
String attrKey = getAttributeKey(outputFile); | |
// old inputs that haven't changed should be registered and added to | |
// the input set, and their attribute copied over | |
if (!isEscalated()) { | |
for (Object input: getOutputInputs(oldState, outputFile)) { | |
if (getResourceStatus(input) == ResourceStatus.UNMODIFIED) { | |
File inputFile = (File)input; | |
registerInput(inputFile); | |
inputs.add(inputFile); | |
// don't overwrite new metadata | |
Serializable attr = state.getResourceAttribute(input, attrKey); | |
if (attr == null) { | |
// carry it over | |
attr = oldState.getResourceAttribute(input, attrKey); | |
if (attr != null) | |
state.putResourceAttribute(input, attrKey, attr); | |
} | |
} | |
} | |
} | |
return super.aggregateIfNecessary(inputs, outputFile, creator); | |
} | |
protected boolean processingWasRequired(File oldOutput) { | |
for (Object input : getOutputInputs(oldState, oldOutput)) { | |
ResourceStatus st = getResourceStatus(input); | |
if (st != ResourceStatus.UNMODIFIED) { | |
return true; | |
} | |
} | |
return false; | |
} | |
@Override | |
public void commit(MessageSinkAdaptor messager) throws IOException { | |
try { | |
assertOpen(); | |
} catch (IllegalStateException e) { | |
return; | |
} | |
// if the input files to an output haven't been updated, then | |
// assume that the output doesn't need to be changed | |
if (!isEscalated()) { | |
for (File oldOutput: oldState.getOutputs()) { | |
if (!isRegisteredResource(oldOutput) && !processingWasRequired(oldOutput)) { | |
aggregateIfNecessary(new HashSet<File>(), oldOutput, NullInputAggregator); | |
} | |
} | |
} | |
super.commit(messager); | |
} | |
protected String getAttributeKey(File outputFile) { | |
return AGGREGATE_PREFIX + normalize(outputFile).toString(); | |
} | |
protected Collection<Object> getOutputInputs(DefaultBuildContextState state, File outputFile) { | |
Collection<Object> inputs = state.getOutputInputs(outputFile); | |
return inputs != null && !inputs.isEmpty() ? inputs : Collections.emptyList(); | |
} | |
protected static InputAggregator NullInputAggregator = new InputAggregator(){ | |
@Override | |
public void aggregate(Output<File> output, Iterable<File> inputs) throws IOException { | |
throw new IllegalStateException("processing should not be required"); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment