filebot/source/net/filebot/History.java

231 lines
4.9 KiB
Java

package net.filebot;
import static java.util.Collections.*;
import static net.filebot.Logging.*;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
import java.util.stream.Stream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "history")
public class History {
@XmlElement(name = "sequence")
private List<Sequence> sequences;
public History() {
this.sequences = new ArrayList<Sequence>();
}
public History(Collection<Sequence> sequences) {
this.sequences = new ArrayList<Sequence>(sequences);
}
public static class Sequence {
@XmlAttribute(name = "date", required = true)
private Date date;
@XmlElement(name = "rename", required = true)
private List<Element> elements;
private Sequence() {
// hide constructor
}
public Date date() {
return date;
}
public List<Element> elements() {
if (elements == null)
return emptyList();
return unmodifiableList(elements);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Sequence) {
Sequence other = (Sequence) obj;
return date.equals(other.date) && elements.equals(other.elements);
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(elements, date);
}
}
public static class Element {
@XmlAttribute(name = "dir", required = true)
private File dir;
@XmlAttribute(name = "from", required = true)
private String from;
@XmlAttribute(name = "to", required = true)
private String to;
public Element() {
// used by JAXB
}
public Element(String from, String to, File dir) {
this.from = from;
this.to = to;
this.dir = dir;
}
public File dir() {
return dir;
}
public String from() {
return from;
}
public String to() {
return to;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Element) {
Element element = (Element) obj;
return to.equals(element.to) && from.equals(element.from) && dir.getPath().equals(element.dir.getPath());
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(to, from, dir);
}
}
public List<Sequence> sequences() {
return unmodifiableList(sequences);
}
public void add(Collection<Element> elements) {
Sequence sequence = new Sequence();
sequence.date = new Date();
sequence.elements = new ArrayList<Element>(elements);
add(sequence);
}
public void add(Sequence sequence) {
this.sequences.add(sequence);
}
public void addAll(Collection<Sequence> sequences) {
this.sequences.addAll(sequences);
}
public void merge(History history) {
for (Sequence sequence : history.sequences()) {
if (!sequences.contains(sequence)) {
add(sequence);
}
}
}
public int totalSize() {
int i = 0;
for (Sequence it : sequences()) {
i += it.elements.size();
}
return i;
}
public void clear() {
sequences.clear();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof History) {
History other = (History) obj;
return sequences.equals(other.sequences);
}
return false;
}
@Override
public int hashCode() {
return sequences.hashCode();
}
public Map<File, File> getRenameMap() {
Map<File, File> map = new LinkedHashMap<File, File>();
for (History.Sequence seq : sequences) {
for (History.Element elem : seq.elements()) {
File to = new File(elem.to());
if (!to.isAbsolute()) {
to = new File(elem.dir(), elem.to());
}
File from = new File(elem.dir(), elem.from());
map.put(from, to);
}
}
return map;
}
public Stream<File> getOriginalPath(File destination) {
return sequences.stream().flatMap(s -> s.elements().stream()).filter(e -> {
File to = new File(e.to());
if (!to.isAbsolute()) {
to = new File(e.dir(), e.to());
}
return destination.equals(to);
}).map(e -> new File(e.dir(), e.from()));
}
public static void exportHistory(History history, OutputStream output) {
try {
Marshaller marshaller = JAXBContext.newInstance(History.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(history, output);
} catch (Exception e) {
debug.log(Level.SEVERE, "Failed to write history", e);
}
}
public static History importHistory(InputStream stream) {
try {
Unmarshaller unmarshaller = JAXBContext.newInstance(History.class).createUnmarshaller();
return ((History) unmarshaller.unmarshal(stream));
} catch (Exception e) {
debug.log(Level.SEVERE, "Failed to read history", e);
}
// default to empty history
return new History();
}
}