Reputation: 25
I am changing SnakeYAML version to 2.0 from 1.3.2 in build.gradle file. The java code written using SnakeYAML 1.3.2 gives the following compilation problems.
package uscrn.archive.environment;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.time.Instant;
import java.time.YearMonth;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.AbstractConstruct;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.ScalarNode;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Represent;
import org.yaml.snakeyaml.representer.Representer;
import uscrn.archive.io.FileReadFailed;
import uscrn.archive.io.FileWriteFailed;
/**
* An implementation of WorkLog that persists information to the local file
* system in the Yaml text format. This allows the application to record
* the work it does, and later query the record for decision making.
*/
public class YamlFileWorkLog implements WorkLog {
private final File file;
private final TreeMap<YearMonth, Instant> entries;
public YamlFileWorkLog(File file) {
this.file = file;
this.entries = load(file);
}
public YamlFileWorkLog(Path path){
this(path.toFile());
}
@SuppressWarnings("unchecked")
private TreeMap<YearMonth, Instant> load(File file) {
TreeMap<YearMonth, Instant> result = new TreeMap<>();
try(InputStream input = new FileInputStream(file)){
Map<YearMonth, Instant> loaded = (Map<YearMonth, Instant>) yaml().load(input);
if(loaded != null){
result.putAll(loaded);
}
return result;
} catch (IOException e) {
throw new FileReadFailed(file.toPath(), e);
}
}
@Override
public Instant lookup(YearMonth month) {
return entries.get(month);
}
@Override
public void record(YearMonth month, Instant timestamp) {
entries.put(month, timestamp);
}
@Override
public void clear() {
entries.clear();
}
@Override
public boolean hasRecorded(YearMonth month) {
return entries.containsKey(month);
}
@Override
public void save() {
try(FileWriter output = new FileWriter(file)){
yaml().dump(entries, output);
} catch (IOException e) {
throw new FileWriteFailed(file.toPath(), e);
}
}
@Override
public int size() {
return entries.size();
}
@Override
public Instant latestTimestamp(){
Instant timestamp = null;
for(Entry<YearMonth, Instant> entry : entries.entrySet()){
if(timestamp == null || timestamp.isBefore(entry.getValue())){
timestamp = entry.getValue();
}
}
return timestamp;
}
@Override
public String toString(){
return yaml().dump(entries);
}
/**
* Returns an Yaml object that is configured to read and write WorkLog
* information.
* @return A configured Yaml object.
*/
private Yaml yaml(){
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
return new Yaml(new LogConstructor(), new LogRepresenter(), options);
}
/**
* A class that is used by the Yaml library to convert WorkLog entries
* into Yaml constructs, which can then be written out as text.
*/
private class LogRepresenter extends Representer {
public LogRepresenter() {
this.representers.put(YearMonth.class,
new Represent(){
@Override
public Node representData(Object data) {
YearMonth month = (YearMonth) data;
return representScalar(new Tag("!month"), month.toString());
}
}
);
this.representers.put(Instant.class,
new Represent(){
@Override
public Node representData(Object data) {
Instant timestamp = (Instant) data;
return representScalar(Tag.TIMESTAMP, timestamp.toString());
}
}
);
}
}
/**
* A class that is used by the Yaml library to convert text into WorkLog
* entries.
*/
private class LogConstructor extends SafeConstructor {
public LogConstructor() {
this.yamlConstructors.put(new Tag("!month"),
new AbstractConstruct(){
@Override
public Object construct(Node node) {
String val = (String) constructScalar((ScalarNode) node);
Integer year = Integer.parseInt(val.substring(0, 4));
Integer month = Integer.parseInt(val.substring(5, 7));
return YearMonth.of(year, month);
}
}
);
this.yamlConstructors.put(Tag.TIMESTAMP,
new AbstractConstruct(){
@Override
public Object construct(Node node) {
String val = (String) constructScalar((ScalarNode) node);
return Instant.parse(val);
}
}
);
}
}
}
Compilation error 1 : Constructor Representer in class Representer cannot be applied to given types;required: DumperOptionsfound: noargumentsreason: Actual and formal argument lists differ in length.
Compilation error 2 : Constructor SafeConstructor in class SafeConstructor cannot be applied to given types;required : LoaderOptionsfound: noargumentsreason: Actual and formal argument lists differ in length.
Upvotes: 0
Views: 468
Reputation: 4961
In SnakeYAML 2.x, the Representer and SafeConstructor classes no longer contain a default, no-args constructor. Representer's constructor needs a DumperOptions
object while SafeConstructor's constructor needs a LoaderOptions
one. Once you pass those, the compilation errors will be resolved. The code might look something like the below:
private Yaml yaml(){
DumperOptions dumperOptions = new DumperOptions();
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
LoaderOptions loaderOptions = new LoaderOptions();
return new Yaml(new LogConstructor(loaderOptions), new LogRepresenter(dumperOptions), dumperOptions);
}
private class LogRepresenter extends Representer {
public LogRepresenter(DumperOptions options) {
super(options);
// Existing code
}
}
private class LogConstructor extends SafeConstructor {
public LogConstructor(LoaderOptions loaderOptions) {
super(loaderOptions);
// Existing code
}
}
Upvotes: 0