ChronoRepository.java
package org.docascode.api.core.chrono;
import org.apache.commons.io.FilenameUtils;
import org.docascode.api.core.chrono.generated.Maven;
import org.docascode.api.core.errors.DocAsCodeException;
import org.docascode.api.core.Substitute;
import org.docascode.api.core.chrono.generated.BaseArtifact;
import org.docascode.api.core.chrono.generated.Delivery;
import org.docascode.api.core.errors.ArtifactNotFoundException;
import org.docascode.api.core.errors.ProcessingException;
import org.docascode.api.core.mvn.ArtifactContainer;
import org.docascode.api.core.office.PropertiesProcessor;
import org.docascode.api.event.Event;
import org.docascode.api.listener.APIEventListener;
import org.docascode.api.listener.EventListener;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.xml.sax.SAXException;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.io.File;
import java.io.InputStream;
import java.util.*;
import static org.docascode.api.event.Event.Level.DEBUG;
public class ChronoRepository extends APIEventListener {
private static final String ARTIFACT_NOT_FOUND = "Artifact '%s' not found.";
private File chronoXML;
private File baseDir;
private Delivery delivery = null;
public ChronoRepository(File chronoXML, File baseDir){
this.baseDir = baseDir;
this.chronoXML = chronoXML;
}
private Delivery load() throws ProcessingException {
try {
JAXBContext context = JAXBContext.newInstance(Delivery.class);
Unmarshaller un = context.createUnmarshaller();
//Setup schema validator
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("org/docascode/api/core/chrono.xsd");
StreamSource xsd = new StreamSource(resourceAsStream);
Schema schema = sf.newSchema(xsd);
un.setSchema(schema);
return (Delivery) un.unmarshal(chronoXML);
} catch (JAXBException | SAXException e) {
throw new ProcessingException("Unable to unmarshal file "+chronoXML.getAbsolutePath(),e);
}
}
public Delivery getDelivery() throws ProcessingException {
if (delivery == null){
delivery = load();
}
return delivery;
}
public void save(Delivery delivery) throws ProcessingException {
this.delivery = delivery;
try {
JAXBContext context = JAXBContext.newInstance(Delivery.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(delivery, chronoXML);
} catch (javax.xml.bind.JAXBException e) {
throw new ProcessingException("Unable to marshal delivery to file "+chronoXML.getAbsolutePath(),e);
}
}
public ArtifactContainer toArtifacts(List<String> ids) throws DocAsCodeException {
ArtifactContainer result = new ArtifactContainer();
for (String id : ids){
org.docascode.api.core.chrono.generated.Artifact a = getDelivery().getArtifacts().get(id);
if (a==null){
throw new ArtifactNotFoundException(
String.format(ARTIFACT_NOT_FOUND,
id));
} else {
Maven n = a.getMaven();
if (n != null) {
if (a.getFile() == null) {
Event e = new Event(this);
e.setMessage(String.format(
"Main Artifact '%s' is not deployable since it has no 'file' field.", id)
);
fireEvent(e);
} else {
Map<String, String> dict = new PropertiesProcessor().list(new File(baseDir, a.getFile()));
org.eclipse.aether.artifact.Artifact artifact =
new DefaultArtifact(Substitute.substitute(n.getGroupId(), dict),
Substitute.substitute(n.getArtifactId(), dict),
Substitute.substitute("", dict),
getExtension(a),
Substitute.substitute(n.getVersion(), dict));
artifact = artifact.setFile(new File(baseDir, a.getFile()));
result.add(artifact);
if (a.getAttach() != null) {
for (Map.Entry<String, BaseArtifact> baseArtifactEntry : a.getAttach().entrySet()) {
BaseArtifact baseArtifact = baseArtifactEntry.getValue();
if (baseArtifact.getFile() == null) {
Event e = new Event(this);
e.setMessage(String.format(
"Attached Artifact '%s:%s' is not deployable since it has no 'file' field.",
id,
baseArtifactEntry.getKey()));
fireEvent(e);
} else {
artifact =
new DefaultArtifact(Substitute.substitute(n.getGroupId(), dict),
Substitute.substitute(n.getArtifactId(), dict),
Substitute.substitute(baseArtifactEntry.getKey(), dict),
getExtension(baseArtifact),
Substitute.substitute(n.getVersion(), dict));
artifact = artifact.setFile(new File(baseDir, baseArtifact.getFile()));
result.add(artifact);
}
}
}
}
}
}
}
return result;
}
private String getExtension(BaseArtifact artifact){
if (artifact.getFile() != null){
return FilenameUtils.getExtension(artifact.getFile());
} else {
return null;
}
}
public Map<String,String> toMap(String name) throws ProcessingException {
Map<String,String> result = new HashMap<>();
for (org.docascode.api.core.chrono.generated.Artifact artifact : getDelivery().getArtifacts().values()){
if (artifact.getFile() == null || artifact.getOutputs()==null || !artifact.getOutputs().containsKey(name)) {
//Resolve artifact
} else {
result.put(artifact.getFile(),artifact.getOutputs().get(name));
}
if (artifact.getAttach() != null) {
for (BaseArtifact baseArtifact : artifact.getAttach().values()) {
if (baseArtifact.getFile() == null || baseArtifact.getOutputs()==null || !baseArtifact.getOutputs().containsKey(name)) {
//Resolve artifact
} else {
result.put(baseArtifact.getFile(),
baseArtifact.getOutputs().get(name));
}
}
}
}
return result;
}
@Override
public ChronoRepository addListener(EventListener listener){
this.listeners.add(listener);
return this;
}
private Set<EventListener> listeners = new HashSet<>();
public List<String> toFileNames(List<String> ids) throws ArtifactNotFoundException, ProcessingException {
List<String> result = new ArrayList<>();
for (String id : ids){
org.docascode.api.core.chrono.generated.Artifact a = getDelivery().getArtifacts().get(id);
if (a==null){
throw new ArtifactNotFoundException(
String.format(ARTIFACT_NOT_FOUND,
id));
} else {
if (a.getFile() != null) {
result.add(a.getFile());
}
if (a.getAttach() != null) {
for (Map.Entry<String, BaseArtifact> baseArtifactEntry : a.getAttach().entrySet()) {
BaseArtifact baseArtifact = baseArtifactEntry.getValue();
if (baseArtifact.getFile() != null) {
result.add(baseArtifact.getFile());
}
}
}
}
}
return result;
}
private Map<String, Artifact> artifactFileMap;
public Map<String, Artifact> toArtifactFileMap() throws DocAsCodeException {
if (artifactFileMap==null) {
artifactFileMap = new HashMap<>();
for (Map.Entry<String, org.docascode.api.core.chrono.generated.Artifact> entry :
getDelivery().getArtifacts().entrySet()) {
org.docascode.api.core.chrono.generated.Artifact a = entry.getValue();
Maven n = a.getMaven();
if (n != null) {
if (a.getFile() == null) {
log(String.format(
"Main Artifact '%s' is not deployable since it has no 'file' field.", entry.getKey()),
DEBUG);
} else {
if (!(new File(this.baseDir, a.getFile())).exists()) {
log(String.format("The file '%s' is missing for artifact '%s'. This artifact and all nested artifacts are not deployable.", a.getFile(), entry.getKey()), DEBUG);
} else {
Map<String, String> dict = new PropertiesProcessor().list(new File(this.baseDir,a.getFile()));
org.eclipse.aether.artifact.Artifact artifact =
new DefaultArtifact(Substitute.substitute(n.getGroupId(), dict),
Substitute.substitute(n.getArtifactId(), dict),
Substitute.substitute("", dict),
getExtension(a),
Substitute.substitute(n.getVersion(), dict));
artifact = artifact.setFile(new File(this.baseDir, a.getFile()));
artifactFileMap.put(a.getFile(), artifact);
if (a.getAttach() != null) {
for (Map.Entry<String, BaseArtifact> baseArtifactEntry : a.getAttach().entrySet()) {
BaseArtifact baseArtifact = baseArtifactEntry.getValue();
if (baseArtifact.getFile() == null) {
log(String.format(
"Attached Artifact '%s:%s' is not deployable since it has no 'file' field.",
entry.getKey(),
baseArtifactEntry.getKey()),DEBUG);
} else {
artifact =
new DefaultArtifact(Substitute.substitute(n.getGroupId(), dict),
Substitute.substitute(n.getArtifactId(), dict),
Substitute.substitute(baseArtifactEntry.getKey(), dict),
getExtension(baseArtifact),
Substitute.substitute(n.getVersion(), dict));
artifact = artifact.setFile(new File(this.baseDir, baseArtifact.getFile()));
artifactFileMap.put(baseArtifact.getFile(), artifact);
}
}
}
}
}
}
}
}
return artifactFileMap;
}
}