Implemented Universe Project save routine.

Edward M. Kagan 5 years ago
parent c1afb189a1
commit 48a0c2be81

@ -0,0 +1,15 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package link.pagan.traqtor;
import java.io.File;
/** @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >} */
public interface Directoried {
public File dir ();
}

@ -1,21 +1,47 @@
package link.pagan.traqtor;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import link.pagan.traqtor.deck.SystemConfig;
import link.pagan.traqtor.deck.op.OperationResult;
import link.pagan.traqtor.project.Project;
import link.pagan.traqtor.project.database.DatabaseProject;
import link.pagan.traqtor.project.universe.UniverseProject;
import link.pagan.traqtor.util.Name;
/** @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >} */
public class Workspace {
public class Workspace implements Filed, Directoried {
private File root;
// private File lockFile;
private Name name;
private boolean dirty;
private final List<Project> projects;
public UniverseProject universe () {
UniverseProject project = new UniverseProject(this);
this.projects.add(project);
this.dirty = true;
return project;
}
public DatabaseProject database () {
DatabaseProject project = new DatabaseProject(this);
this.projects.add(project);
this.dirty = true;
return project;
}
public Workspace () {
this.root = null;
this.dirty = true;
this.projects = new ArrayList<Project>();
}
public Name name () {
@ -31,11 +57,18 @@ public class Workspace {
return this;
}
public Workspace projects (Project... project) {
public List<Project> projects () {
return projects;
}
public Workspace projects (Project... projects) {
this.projects.addAll(Arrays.asList(projects));
this.dirty = true;
return this;
}
public File root () {
@Override
public File dir () {
return root;
}
@ -52,4 +85,124 @@ public class Workspace {
return dirty;
}
public OperationResult saveAs (File parentDir) {
return saveAs(this, parentDir, OperationResult.start());
}
private static OperationResult saveAs (Workspace workspace, File parent, OperationResult result) {
if (parent == null) {
return result
.info("Target directory must be set, are you OK?")
.fail("Failed to save workspace, no new root directory was passed");
}
if (!parent.exists()) {
return result
.info("Directory " + parent.getAbsolutePath() + " does not exist, deleted/moved/unmounted?")
.fail("Failed to save workspace, due non existent parent direcory for new workspace");
}
if (workspace.name() == null) {
return result
.info("Workspace does not contain name - how did you even achieve that?")
.fail("Failed to save workspace, due unknown name of it, huh...");
}
File root = new File(parent, workspace.name().asTiled());
if (!root.exists()) {
result.info("Creating new root direcory at " + root.getAbsolutePath());
if (!root.mkdirs()) {
return result
.info("Unable to create directory " + root.getAbsolutePath() + " - permission problem?")
.fail("Failed to save workspace, can not create new root directory");
}
}
if (root.listFiles().length > 0) {
return result
.info("Directory " + root.getAbsolutePath() + " is not empty, not safe to save?")
.fail("Failed to save workspace, due to polluted new root direcory");
}
File oldRoot = workspace.dir();
boolean oldDirty = workspace.dirty();
workspace.root(root);
workspace.dirty(true);
result.info("Setting workspace root to " + root.getAbsolutePath());
save(workspace, result.startSubresult());
if (!result.ok()) {
result.info("Reverting workspace root to " + oldRoot.getAbsolutePath());
workspace.root(oldRoot);
workspace.dirty(oldDirty);
}
return result;
}
public OperationResult save () {
return save(this, OperationResult.start());
}
private static OperationResult save (Workspace workspace, OperationResult result) {
if (!workspace.dirty()) { return result.warn("Workspace is not dirty - no need to save"); }
result.info("Saving workspace " + workspace.name().asTiled() + " ...");
if (workspace.dir() == null) {
return result
.info("Workspace root is not set - is this a new workspace?")
.fail("Failed to save workspace, due to unknown root directory");
}
if (!workspace.dir().exists()) {
return result
.info("Directory " + workspace.dir().getAbsolutePath() +
" does not exist, deleted/moved/unmounted?")
.fail("Failed to save workspace, due non existent root direcory");
}
if (!workspace.dir().canRead()) {
return result
.info("Unable to read " + workspace.dir().getAbsolutePath() + " - permission problem?")
.fail("Failed to save workspace, due unreadable root direcory");
}
if (!workspace.dir().canWrite()) {
return result
.info("Unable to write " + workspace.dir().getAbsolutePath() + " - permission problem?")
.fail("Failed to save workspace, due write restriction on root direcory");
}
for (Project project : workspace.projects()) { project.save(result.startSubresult()); }
writeJson(workspace, result.startSubresult());
if (result.ok()) { workspace.dirty(false); }
return result;
}
private static OperationResult writeJson (Workspace workspace, OperationResult result) {
File file = workspace.file();
result.info("Writing workspace descriptor file to " + file.getAbsolutePath() + " ...");
try {
SystemConfig.JSON.writeValue(file, workspace);
} catch (IOException ex) {
result.fail("Failed to write file " + file.getAbsolutePath() + " - IO exception");
result.fail(ex);
}
return result;
}
@Override
public File file () {
return new File(dir(), ".tw");
}
}

@ -0,0 +1,35 @@
package link.pagan.traqtor.deck;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import link.pagan.traqtor.Workspace;
import link.pagan.traqtor.WorkspaceSerializer;
import link.pagan.traqtor.project.universe.UniverseProject;
import link.pagan.traqtor.project.universe.UniverseProjectSerializer;
import link.pagan.traqtor.project.universe.element.Element;
import link.pagan.traqtor.project.universe.element.ElementSerializer;
import link.pagan.traqtor.project.universe.element.Particle;
import link.pagan.traqtor.project.universe.element.PaticleInfoSerializer;
import link.pagan.traqtor.project.universe.link.Link;
import link.pagan.traqtor.project.universe.link.LinkSerializer;
import link.pagan.traqtor.project.universe.schema.Constraint;
import link.pagan.traqtor.project.universe.schema.ConstraintInfoSerializer;
import link.pagan.traqtor.util.Name;
import link.pagan.traqtor.util.NameSerializer;
/** @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >} */
public abstract class SystemConfig {
public static final ObjectMapper JSON = new ObjectMapper()
.enable(SerializationFeature.INDENT_OUTPUT)
.registerModule(new SimpleModule()
.addSerializer(Name.class, new NameSerializer())
.addSerializer(UniverseProject.class, new UniverseProjectSerializer())
.addSerializer(Element.class, new ElementSerializer())
.addSerializer(Particle.class, new PaticleInfoSerializer())
.addSerializer(Constraint.class, new ConstraintInfoSerializer())
.addSerializer(Link.class, new LinkSerializer())
.addSerializer(Workspace.class, new WorkspaceSerializer()));
}

@ -5,35 +5,50 @@ import java.util.LinkedList;
/** @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >} */
public class OperationResult {
private final OperationResult parent;
private final long timestamp;
private final LinkedList<OperationMessage> messages;
private final LinkedList<OperationResult> subresults;
private OperationResult () {
private OperationResult (OperationResult parent) {
this.timestamp = System.currentTimeMillis();
this.messages = new LinkedList<OperationMessage>();
this.subresults = new LinkedList<OperationResult>();
this.parent = parent;
}
private OperationResult () {
this(null);
}
public OperationResult info (String message) {
this.messages.add(OperationMessage.info(message));
OperationMessage info = OperationMessage.info(message);
this.messages.add(info);
if (this.parent != null) { this.parent.info(message); }
return this;
}
public OperationResult warn (String message) {
this.messages.add(OperationMessage.warn(message));
OperationMessage warn = OperationMessage.warn(message);
this.messages.add(warn);
if (this.parent != null) { this.parent.warn(message); }
return this;
}
public OperationResult fail (Exception ex) {
this.messages.add(OperationMessage.fail(ex.getMessage()));
return this;
return fail(ex.getMessage());
}
public OperationResult fail (String message) {
this.messages.add(OperationMessage.fail(message));
OperationMessage fail = OperationMessage.fail(message);
this.messages.add(fail);
if (this.parent != null) { this.parent.fail(message); }
return this;
}
@ -41,16 +56,14 @@ public class OperationResult {
boolean proxiedOK = proxiedOK();
if (!proxiedOK) { this.messages.forEach(message -> {
System.out.println(message.toString());
});
}
System.out.println(message.toString());
}); }
return proxiedOK;
}
private boolean proxiedOK () {
if (this.messages.stream().anyMatch(message -> (message.type().equals(MessageType.FAIL)))) {
return false;
}
if (this.messages.stream().anyMatch(message -> (message.type().equals(MessageType.FAIL)))) { return false; }
return this.subresults.stream().noneMatch(subresult -> (!subresult.ok()));
}
@ -59,7 +72,7 @@ public class OperationResult {
}
public OperationMessage[] messages () {
return this.messages.toArray(new OperationMessage[this.messages.size()]);
return messages.toArray(new OperationMessage[messages.size()]);
}
public OperationResult[] subresults () {
@ -71,14 +84,19 @@ public class OperationResult {
}
public OperationResult startSubresult () {
OperationResult subresult = new OperationResult();
OperationResult subresult = new OperationResult(this);
this.subresults.add(subresult);
return subresult;
}
public OperationResult addSubresult (OperationResult subresult) {
this.subresults.add(subresult);
return this;
// public OperationResult addSubresult (OperationResult subresult) {
// this.subresults.add(subresult);
// return this;
// }
public void print () {
for (OperationMessage message : this.messages()) { System.out.println(message); }
}
}

@ -1,15 +1,26 @@
package link.pagan.traqtor.project;
import link.pagan.traqtor.Directoried;
import link.pagan.traqtor.Filed;
import link.pagan.traqtor.Workspace;
import link.pagan.traqtor.deck.op.OperationResult;
import link.pagan.traqtor.util.Name;
public abstract class Project {
public abstract class Project implements Filed, Directoried {
protected final Workspace workspace;
protected Name name;
protected boolean dirty;
public Project (Workspace workspace) {
this.workspace = workspace;
}
public Name name () {
if (name == null) return Name.NO_NAME;
if (name == null) { return Name.NO_NAME; }
return this.name;
}
@ -23,4 +34,6 @@ public abstract class Project {
return this;
}
public abstract OperationResult save (OperationResult result);
}

@ -0,0 +1,36 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package link.pagan.traqtor.project.backend.mapping;
import java.io.File;
import link.pagan.traqtor.Workspace;
import link.pagan.traqtor.deck.op.OperationResult;
import link.pagan.traqtor.project.Project;
/** @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >} */
public class BackendProject extends Project {
public BackendProject (Workspace workspace) {
super(workspace);
}
@Override
public OperationResult save (OperationResult result) {
throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose
// Tools | Templates.
}
@Override
public File file () {
return new File(this.dir(), "backend.json");
}
@Override
public File dir () {
return new File(workspace.dir(), this.name.asTiled() + "-backend");
}
}

@ -1,5 +1,8 @@
package link.pagan.traqtor.project.database;
import java.io.File;
import link.pagan.traqtor.Workspace;
import link.pagan.traqtor.deck.op.OperationResult;
import link.pagan.traqtor.project.universe.UniverseProject;
import link.pagan.traqtor.project.Project;
import link.pagan.traqtor.util.Name;
@ -7,7 +10,9 @@ import link.pagan.traqtor.util.Name;
/** @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >} */
public class DatabaseProject extends Project {
DatabaseProject () {}
public DatabaseProject (Workspace workspace) {
super(workspace);
}
@Override
public DatabaseProject name (String... parts) {
@ -29,4 +34,20 @@ public class DatabaseProject extends Project {
return this;
}
@Override
public OperationResult save (OperationResult result) {
throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose
// Tools | Templates.
}
@Override
public File file () {
return new File(this.dir(), "database.json");
}
@Override
public File dir () {
return new File(workspace.dir(), this.name.asTiled() + "-database");
}
}

@ -0,0 +1,36 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package link.pagan.traqtor.project.frontend;
import java.io.File;
import link.pagan.traqtor.Workspace;
import link.pagan.traqtor.deck.op.OperationResult;
import link.pagan.traqtor.project.Project;
/** @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >} */
public class FrontendProject extends Project {
public FrontendProject (Workspace workspace) {
super(workspace);
}
@Override
public OperationResult save (OperationResult result) {
throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose
// Tools | Templates.
}
@Override
public File file () {
return new File(this.dir(), "frontend.json");
}
@Override
public File dir () {
return new File(workspace.dir(), this.name.asTiled() + "-frontend");
}
}

@ -1,8 +1,5 @@
package link.pagan.traqtor.project.universe;
import link.pagan.traqtor.project.universe.element.Atom;
import link.pagan.traqtor.project.universe.element.Element;
import link.pagan.traqtor.project.universe.element.Isotope;
import link.pagan.traqtor.project.universe.link.Link;
import link.pagan.traqtor.project.universe.link.ManyToManyLink;
import link.pagan.traqtor.project.universe.link.OneToManyLink;
@ -11,18 +8,6 @@ import link.pagan.traqtor.project.universe.link.OneToOneLink;
/** @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >} */
public class Universe {
public static UniverseProject project () {
return new UniverseProject();
}
public static Atom atom () {
return Element.atom();
}
public static Isotope isotope () {
return Element.isotope();
}
public static OneToOneLink linkOneToOne () {
return Link.oneToOne();
}

@ -1,12 +1,19 @@
package link.pagan.traqtor.project.universe;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Set;
import java.util.TreeSet;
import link.pagan.traqtor.Workspace;
import link.pagan.traqtor.deck.SystemConfig;
import link.pagan.traqtor.deck.op.OperationResult;
import link.pagan.traqtor.project.Project;
import link.pagan.traqtor.project.universe.element.Atom;
import link.pagan.traqtor.project.universe.schema.DatatypeSchema;
import link.pagan.traqtor.project.universe.link.Link;
import link.pagan.traqtor.project.universe.element.Element;
import link.pagan.traqtor.project.universe.element.Isotope;
import link.pagan.traqtor.util.Name;
public class UniverseProject extends Project {
@ -17,16 +24,19 @@ public class UniverseProject extends Project {
private final Set<Link> links;
UniverseProject () {
public UniverseProject (Workspace workspace) {
super(workspace);
this.schemas = new TreeSet<DatatypeSchema>( (DatatypeSchema a, DatatypeSchema b) -> a.name()
.compareTo(b.name()));
this.elements = new TreeSet<Element>( (Element a, Element b) -> a.name().compareTo(b.name()));
this.links = new TreeSet<Link>( (Link a,
Link b) -> (a.from().name().asDotted() + "_" +
a.fromName().asDotted())
.compareTo((b.from().name().asDotted() +
"_" +
b.fromName().asDotted())));
Link b) -> (a.from().name().asDotted() + "_" + a.fromName().asDotted())
.compareTo((b.from()
.name()
.asDotted() +
"_" +
b.fromName()
.asDotted())));
}
@Override
@ -67,4 +77,62 @@ public class UniverseProject extends Project {
return this;
}
@Override
public OperationResult save (OperationResult result) {
return save(this, result);
}
private static OperationResult save (UniverseProject project, OperationResult result) {
if (!project.dir().exists()) {
result.warn("Project directory " + project.dir().getAbsolutePath() + " does not exist");
result.info("Creating project directory at " + project.dir().getAbsolutePath() + " ...");
if (!project.dir().mkdirs()) {
return result.fail("Failed to created project directory at " + project.dir().getAbsolutePath());
}
}
for (Element element : project.elements()) { element.save(result.startSubresult()); }
writeJson(project, result.startSubresult());
return result;
}
private static OperationResult writeJson (UniverseProject project, OperationResult result) {
File file = project.file();
result.info("Writing project descriptor file to " + file.getAbsolutePath() + " ...");
try {
SystemConfig.JSON.writeValue(file, project);
} catch (IOException ex) {
result.fail("Failed to write file " + file.getAbsolutePath() + " - IO exception");
result.fail(ex);
}
return result;
}
@Override
public File file () {
return new File(this.dir(), ".tup");
}
@Override
public File dir () {
return new File(workspace.dir(), this.name.asTiled() + "-universe");
}
public Atom atom () {
Atom res = new Atom(this);
this.elements.add(res);
return res;
}
public Isotope isotope (Element base) {
Isotope res = new Isotope(this, base);
this.elements.add(res);
return res;
}
}

@ -4,7 +4,6 @@ import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
import link.pagan.traqtor.project.universe.element.Element;
import link.pagan.traqtor.project.universe.link.Link;
import link.pagan.traqtor.project.universe.schema.DatatypeSchema;
@ -29,12 +28,6 @@ public class UniverseProjectSerializer extends StdSerializer<UniverseProject> {
for (DatatypeSchema schema : value.schemas()) { gen.writeObject(schema.name()); }
gen.writeEndArray();
gen.writeArrayFieldStart("elements");
for (Element element : value.elements()) { gen.writeObject(element); }
gen.writeEndArray();
gen.writeArrayFieldStart("links");
for (Link link : value.links()) { gen.writeObject(link); }

@ -1,12 +1,16 @@
package link.pagan.traqtor.project.universe.element;
import java.io.File;
import java.util.List;
import link.pagan.traqtor.project.universe.UniverseProject;
import link.pagan.traqtor.project.universe.schema.DataType;
import link.pagan.traqtor.util.Name;
public class Atom extends Element {
Atom () {}
public Atom (UniverseProject project) {
super(project);
}
@Override
public Atom name (Name name) {
@ -20,4 +24,9 @@ public class Atom extends Element {
return this;
}
@Override
public File file () {
return new File(this.project.dir(), this.name().asTiled() + ".tae");
}
}

@ -1,14 +1,22 @@
package link.pagan.traqtor.project.universe.element;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import link.pagan.traqtor.Filed;
import link.pagan.traqtor.deck.SystemConfig;
import link.pagan.traqtor.deck.op.OperationResult;
import link.pagan.traqtor.project.universe.UniverseProject;
import link.pagan.traqtor.project.universe.schema.DataType;
import link.pagan.traqtor.util.Name;
public abstract class Element {
public abstract class Element implements Filed {
protected final UniverseProject project;
private static final Comparator<Particle<? extends DataType>> PARTICLE_SORT_COMPARATOR = new Comparator<Particle<? extends DataType>>() {
@ -23,8 +31,9 @@ public abstract class Element {
private final Set<Particle<? extends DataType>> particles;
public Element () {
particles = new TreeSet<Particle<? extends DataType>>(PARTICLE_SORT_COMPARATOR);
public Element (UniverseProject project) {
this.project = project;
this.particles = new TreeSet<Particle<? extends DataType>>(PARTICLE_SORT_COMPARATOR);
}
public Name name () {
@ -56,12 +65,31 @@ public abstract class Element {
return this;
}
public static Atom atom () {
return new Atom();
public OperationResult save (OperationResult result) {
return save(this, result);
}
public static Isotope isotope () {
return new Isotope();
private static OperationResult save (Element element, OperationResult result) {
if (element.getClass().equals(Atom.class) || element.getClass().equals(Isotope.class)) {
writeJson(element, result.startSubresult());
} else {
return result.fail("Unknown element type - not supported class " + element.getClass().getName());
}
return result;
}
private static OperationResult writeJson (Element element, OperationResult result) {
File file = element.file();
result.info("Writing element to " + file.getAbsolutePath() + " ...");
try {
SystemConfig.JSON.writeValue(file, element);
} catch (IOException ex) {
result.fail("Failed to write file " + file.getAbsolutePath() + " - IO exception");
result.fail(ex);
}
return result;
}
}

@ -1,15 +1,20 @@
package link.pagan.traqtor.project.universe.element;
import java.io.File;
import java.util.List;
import link.pagan.traqtor.project.universe.UniverseProject;
import link.pagan.traqtor.project.universe.schema.DataType;
import link.pagan.traqtor.util.Name;
public class Isotope extends Element {
Isotope () {}
private Element base;
public Isotope (UniverseProject project, Element base) {
super(project);
this.base = base;
}
public Element base () {
return base;
}
@ -26,9 +31,9 @@ public class Isotope extends Element {
return this;
}
public Isotope base (Element base) {
this.base = base;
return this;
@Override
public File file () {
return new File(this.project.dir(), this.name().asTiled() + ".tie");
}
}

@ -11,33 +11,10 @@ import link.pagan.traqtor.util.Name;
public class Particle <T extends DataType> extends PaticleInfo {
private final DataType type;
private Name name;
private String description;
@Override
public Name name () {
if (name == null) { return Name.NO_NAME; }
return name;
}
@Override
public String description () {
return description;
}
@Override
public DataType type () {
return type;
}
private final Set<ConstraintInfo> constraints;
public Particle (DataType type) {
this.type = type;
super(type);
this.constraints = new TreeSet<ConstraintInfo>( (ConstraintInfo a,
ConstraintInfo b) -> a.name()
.asDotted()
@ -69,7 +46,8 @@ public class Particle <T extends DataType> extends PaticleInfo {
return this;
}
public Particle<T> optional () {
public Particle<T> optional (boolean optional) {
this.optional = optional;
return this;
}

@ -1,8 +1,3 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package link.pagan.traqtor.project.universe.element;
import java.util.Set;
@ -13,12 +8,36 @@ import link.pagan.traqtor.util.Name;
/** @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >} */
public abstract class PaticleInfo {
public abstract Name name ();
protected final DataType type;
public abstract String description ();
protected Name name;
protected String description;
protected boolean optional;
public PaticleInfo (DataType type) {
this.type = type;
}
public Name name () {
if (name == null) { return Name.NO_NAME; }
return name;
}
public String description () {
return description;
}
public DataType type () {
return type;
}
public abstract Set<ConstraintInfo> constraints ();
public abstract DataType type ();
public boolean optional () {
return this.optional;
}
}

@ -26,11 +26,17 @@ public class PaticleInfoSerializer extends StdSerializer<PaticleInfo> {
gen.writeObjectField("type", value.type().name());
if (value.description() != null) { gen.writeStringField("description", value.description()); }
gen.writeArrayFieldStart("constraints");
for (ConstraintInfo constraint : value.constraints()) { gen.writeObject(constraint); }
if (value.optional()) { gen.writeStringField("optional", value.description()); }
if (value.constraints().size() > 0) {
gen.writeArrayFieldStart("constraints");
for (ConstraintInfo constraint : value.constraints()) { gen.writeObject(constraint); }
gen.writeEndArray();
}
gen.writeEndArray();
gen.writeEndObject();
}

@ -5,24 +5,31 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.logging.Level;
import java.util.logging.Logger;
/** @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >} */
public class TestUtils {
private static final File TEST_DIR = new File(new File("").getAbsoluteFile().getParentFile(), "traqtor-test-root");
public static final void rebuildTestRoot () throws IOException {
public static final void rebuildTestRoot () {
deleteTestRoot();
TEST_DIR.mkdirs();
}
public static final void deleteTestRoot () throws IOException {
public static final void deleteTestRoot () {
if (TEST_DIR.exists()) {
Files.walk(TEST_DIR.toPath())
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
try {
Files.walk(TEST_DIR.toPath())
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
} catch (IOException ex) {
Logger.getLogger(TestUtils.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

@ -0,0 +1,34 @@
package link.pagan.traqtor.test;
import link.pagan.traqtor.Workspace;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
/** @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >} */
public class WorkspaceTest {
@BeforeEach
public void cleanTestDir () {
TestUtils.rebuildTestRoot();
}
@AfterEach
public void killCore () {
TestUtils.deleteTestRoot();
}
@Test
@DisplayName("Workspace save")
void workspaceSave () {
Workspace workspace = new Workspace().name("traqtor", "demo", "workspace");
Assertions.assertTrue(!workspace.save().ok());
TestUtils.deleteTestRoot();
Assertions.assertTrue(!workspace.root(TestUtils.testRoot()).save().ok());
TestUtils.rebuildTestRoot();
Assertions.assertTrue(workspace.saveAs(TestUtils.testRoot()).ok());
}
}

@ -0,0 +1,175 @@
package link.pagan.traqtor.test.project.universe;
import com.fasterxml.jackson.core.JsonProcessingException;
import link.pagan.traqtor.Workspace;
import link.pagan.traqtor.project.universe.Universe;
import link.pagan.traqtor.project.universe.UniverseProject;
import link.pagan.traqtor.project.universe.element.Element;
import link.pagan.traqtor.project.universe.element.Particle;
import link.pagan.traqtor.project.universe.schema.DatatypeSchema;
import link.pagan.traqtor.project.universe.schema.impl.LiteralDataTypeSchema;
import link.pagan.traqtor.project.universe.schema.impl.LogicDatatypeSchema;
import link.pagan.traqtor.project.universe.schema.impl.NumericDatatypeSchema;
import link.pagan.traqtor.project.universe.schema.impl.TemporalDatatypeSchema;
import link.pagan.traqtor.project.universe.schema.impl.data.literal.StringDataType;
import link.pagan.traqtor.project.universe.schema.impl.data.numeric.integer.IntDataType;
import link.pagan.traqtor.project.universe.schema.impl.data.numeric.real.DoubleDataType;
import link.pagan.traqtor.project.universe.schema.impl.data.numeric.real.FloatDataType;
import link.pagan.traqtor.test.TestUtils;
import link.pagan.traqtor.util.RegExpHelper;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
/** @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >} */
public class UniverseProjectTest {
@BeforeEach
public void cleanTestDir () {
TestUtils.rebuildTestRoot();
}
@AfterEach
public void killCore () {
TestUtils.deleteTestRoot();
}
@Test
@DisplayName("Universe Project save")
void projectSaveAs () throws JsonProcessingException {
DatatypeSchema LITERAL = LiteralDataTypeSchema.instance();
DatatypeSchema LOGIC = LogicDatatypeSchema.instance();
DatatypeSchema NUMERIC = NumericDatatypeSchema.instance();
DatatypeSchema TEMPORAL = TemporalDatatypeSchema.instance();
StringDataType STRING = LiteralDataTypeSchema.instance().STRING;
// LogicDataType BOOLEAN = LOGIC.BOOLEAN;
// IntegerDataType BYTE = NUMERIC.BYTE;
// IntegerDataType SHORT = NUMERIC.SHORT;
IntDataType INTEGER = NumericDatatypeSchema.instance().INTEGER;
// IntegerDataType LONG = NUMERIC.LONG;
FloatDataType FLOAT = NumericDatatypeSchema.instance().FLOAT;
DoubleDataType DOUBLE = NumericDatatypeSchema.instance().DOUBLE;
// TemporalDataType DATE = TEMPORAL.DATE;
// TemporalDataType TIME = TEMPORAL.TIME;
// TemporalDataType TIMESTAMP = TEMPORAL.TIMESTAMP;
Workspace workspace = new Workspace().name("traqtor", "demo", "workspace");
UniverseProject base = workspace.universe().name("base").schemas(LITERAL, LOGIC, NUMERIC, TEMPORAL);
Particle<StringDataType> email = STRING.particle()
.name("email")
.description("email as main identifier for an account")
.constraints(STRING.min(4), STRING.max(512), STRING.regExp(RegExpHelper.EMAIL));
Particle<StringDataType> phone = STRING.particle()
.name("phone")
.description("alternative identifier for an account")
.optional(true)
.constraints(STRING.min(10), STRING.max(32), STRING.regExp(RegExpHelper.PHONE));
Particle<StringDataType> password = STRING.particle()
.name("phone")
.description("account password")
.constraints(STRING.min(8), STRING.max(32));
Element account = base.atom()
.name("account")
.particles(email, phone, password);
Particle<StringDataType> lastName = STRING.particle()
.name("last", "name")
.description("last name of user")
.constraints(STRING.max(64), STRING.min(1));
Particle<StringDataType> firstName = STRING.particle()
.name("first", "name")
.description("first name of user")
.optional(true)
.constraints(STRING.max(64), STRING.min(1));
Particle<IntDataType> age = INTEGER.particle()
.name("age")
.description("age of user owning an account")
.constraints(INTEGER.min(18), INTEGER.max(65));
Element accountDetails = base.atom()
.name("account", "details")
.particles(lastName, firstName, age);
Particle<DoubleDataType> length = DOUBLE.particle()
.name("length")
.description("penis length")
.constraints(DOUBLE.min(0), DOUBLE.max(40));
Element male = base.isotope(account)
.name("male")
.particles(length);
Particle<FloatDataType> depth = FLOAT.particle()
.name("depth")
.description("vagina depth")
.constraints(DOUBLE.min(0), DOUBLE.max(40));
base.isotope(account)
.name("female")
.particles(depth);
Particle<StringDataType> positionName = STRING.particle()
.name("title")
.description("position name")
.constraints(STRING.max(255), STRING.min(3));
Element position = base.atom()
.name("position")
.particles(positionName);
Particle<StringDataType> idNumber = STRING.particle()
.name("number")
.description("military id number")
.constraints(STRING.max(11), STRING.min(11));
Element militaryId = base.atom()
.name("military", "id")
.particles(idNumber);
Element profile = base.atom()
.name(("profile"));
base.links(Universe.linkOneToOne()
.from(account)
.fromName("details")
.to(accountDetails)
.toName("account")
.mandatory(), Universe.linkOneToMany()
.from(account)
.fromName("profiles")
.to(profile)
.toName("account")
.more(0), Universe.linkManyToMany()
.from(profile)
.fromName("positions")
.to(position)
.toName("profiles"), Universe.linkOneToOne()
.from(male)
.fromName("military", "id")
.to(militaryId)
.toName("account"));
UniverseProject data = workspace.universe()
.name("data")
.schemas(LITERAL);
Particle<StringDataType> organizationName = STRING.particle()
.name("name")
.description("full name of an organization")
.constraints(STRING.max(255), STRING.min(3));
Element organization = data.atom();
organization.name("organization");
organization.particles(organizationName);
Assertions.assertTrue(workspace.saveAs(TestUtils.testRoot()).ok());
}
}
Loading…
Cancel
Save