From e742bf9b8d1bc5ee7a97586510643db6fd3174f2 Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 18 Nov 2019 14:53:44 +0100 Subject: Implement basic API (#15) --- .../pl/edu/mimuw/cloudatlas/model/Attribute.java | 4 +- .../edu/mimuw/cloudatlas/model/AttributesMap.java | 3 +- .../java/pl/edu/mimuw/cloudatlas/model/Type.java | 6 +- .../edu/mimuw/cloudatlas/model/TypePrimitive.java | 6 ++ .../java/pl/edu/mimuw/cloudatlas/model/Value.java | 4 +- .../edu/mimuw/cloudatlas/model/ValueDuration.java | 5 +- .../pl/edu/mimuw/cloudatlas/model/ValueList.java | 1 + .../pl/edu/mimuw/cloudatlas/model/ValueQuery.java | 70 ++++++++++++++++++++++ .../java/pl/edu/mimuw/cloudatlas/model/ZMI.java | 35 +++++++++++ 9 files changed, 127 insertions(+), 7 deletions(-) create mode 100644 src/main/java/pl/edu/mimuw/cloudatlas/model/ValueQuery.java (limited to 'src/main/java/pl/edu/mimuw/cloudatlas/model') diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/Attribute.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/Attribute.java index aa0cb64..eb916be 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/model/Attribute.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/Attribute.java @@ -24,6 +24,8 @@ package pl.edu.mimuw.cloudatlas.model; +import java.io.Serializable; + /** * Represents an attribute (without value, name only). *

@@ -32,7 +34,7 @@ package pl.edu.mimuw.cloudatlas.model; *

* This class is immutable. */ -public class Attribute { +public class Attribute implements Serializable { private final String name; /** diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/AttributesMap.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/AttributesMap.java index 4065ad6..c74c1df 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/model/AttributesMap.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/AttributesMap.java @@ -24,6 +24,7 @@ package pl.edu.mimuw.cloudatlas.model; +import java.io.Serializable; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -32,7 +33,7 @@ import java.util.Map.Entry; /** * Represents a map from Attribute to Value. It cannot contain duplicate keys. */ -public class AttributesMap implements Iterable>, Cloneable { +public class AttributesMap implements Iterable>, Cloneable, Serializable { private Map map = new HashMap(); private void checkNulls(Attribute attribute, Value value) { diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/Type.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/Type.java index 986db71..0994cba 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/model/Type.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/Type.java @@ -24,16 +24,18 @@ package pl.edu.mimuw.cloudatlas.model; +import java.io.Serializable; + /** * A type of a value that may be stored as an attribute. */ -public abstract class Type { +public abstract class Type implements Serializable { /** * A primary type. This is a characteristic that every type has. It can be extended: for instance a collection may * be parameterized with a type of stored values. */ public static enum PrimaryType { - BOOLEAN, CONTACT, DOUBLE, DURATION, INT, LIST, NULL, SET, STRING, TIME, + BOOLEAN, CONTACT, DOUBLE, DURATION, INT, LIST, NULL, SET, STRING, TIME, QUERY } private final PrimaryType primaryType; diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/TypePrimitive.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/TypePrimitive.java index ab28cb4..ad07c0a 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/model/TypePrimitive.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/TypePrimitive.java @@ -73,6 +73,11 @@ public class TypePrimitive extends Type { */ public static final TypePrimitive TIME = new TypePrimitive(PrimaryType.TIME); + /** + * Query type. + */ + public static final TypePrimitive QUERY = new TypePrimitive(PrimaryType.QUERY); + private TypePrimitive(PrimaryType primaryType) { super(primaryType); switch(primaryType) { @@ -84,6 +89,7 @@ public class TypePrimitive extends Type { case NULL: case STRING: case TIME: + case QUERY: break; default: throw new IllegalArgumentException( diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/Value.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/Value.java index c4054cf..55353c1 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/model/Value.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/Value.java @@ -26,10 +26,12 @@ package pl.edu.mimuw.cloudatlas.model; import pl.edu.mimuw.cloudatlas.model.Value; +import java.io.Serializable; + /** * A single value stored as an attribute. */ -public abstract class Value { +public abstract class Value implements Serializable { /** * An operation that may be performed on values. */ diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueDuration.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueDuration.java index 7022bbd..7a74776 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueDuration.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueDuration.java @@ -248,7 +248,8 @@ public class ValueDuration extends ValueSimple { return new ValueDuration(-getValue()); } - public String toString() { + + private String makeString() { long remainingUnits = getValue(); boolean positive = remainingUnits >= 0; remainingUnits = positive ? remainingUnits : -remainingUnits; @@ -272,7 +273,7 @@ public class ValueDuration extends ValueSimple { public Value convertTo(Type type) { switch(type.getPrimaryType()) { case STRING: - return getValue() == null? ValueString.NULL_STRING : new ValueString(toString()); + return getValue() == null? ValueString.NULL_STRING : new ValueString(makeString()); case DURATION: return this; default: diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueList.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueList.java index 8414cc4..c7f1036 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueList.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueList.java @@ -24,6 +24,7 @@ package pl.edu.mimuw.cloudatlas.model; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueQuery.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueQuery.java new file mode 100644 index 0000000..d9cbe4c --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueQuery.java @@ -0,0 +1,70 @@ +package pl.edu.mimuw.cloudatlas.model; + +import java.io.ByteArrayInputStream; + +import pl.edu.mimuw.cloudatlas.interpreter.query.Absyn.Program; +import pl.edu.mimuw.cloudatlas.interpreter.query.parser; +import pl.edu.mimuw.cloudatlas.interpreter.query.Yylex; +import pl.edu.mimuw.cloudatlas.model.Value; + +/** + * A class that holds a CloudAtlas query. + */ +public class ValueQuery extends Value { + // Original source code + private String code; + // Parsed query + private Program query; + /** + * Constructs a new ValueQuery object. + * + * @param name the name of the query + * @param query the code of the query + */ + public ValueQuery(String query) throws Exception { + this.code = query; + Yylex lex = new Yylex(new ByteArrayInputStream(query.getBytes())); + this.query = (new parser(lex)).pProgram(); + } + + private ValueQuery() { + this.code = null; + this.query = null; + } + + @Override + public Type getType() { + return TypePrimitive.QUERY; + } + + @Override + public boolean isNull() { + return query == null || code == null; + } + + public Value isEqual(Value value) { + sameTypesOrThrow(value, Operation.EQUAL); + if(isNull() && value.isNull()) + return new ValueBoolean(true); + else if(isNull() || value.isNull()) + return new ValueBoolean(false); + return new ValueBoolean(code.equals(((ValueQuery)value).code)); + } + + @Override + public Value getDefaultValue() { + return new ValueQuery(); + } + + @Override + public Value convertTo(Type type) { + switch(type.getPrimaryType()) { + case QUERY: + return this; + case STRING: + return isNull() ? ValueString.NULL_STRING : new ValueString(code); + default: + throw new UnsupportedConversionException(getType(), type); + } + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java index 5a560ae..a311c61 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java @@ -41,6 +41,11 @@ import com.esotericsoftware.kryo.io.Output; * references to its father and sons in the tree. */ public class ZMI implements Cloneable { + public class NoSuchZoneException extends Exception { + public NoSuchZoneException(PathName path) { + super("No such zone: " + path); + } + } private final AttributesMap attributes = new AttributesMap(); private final List sons = new ArrayList(); @@ -85,6 +90,26 @@ public class ZMI implements Cloneable { this.father = father; } + public ZMI findDescendant(PathName path) throws NoSuchZoneException { + ZMI descendant = this; + for (String component : path.getComponents()) { + boolean foundNextSon = false; + for (ZMI son : descendant.getSons()) { + if (son.getAttributes().get("name").equals(new ValueString(component))) { + descendant = son; + foundNextSon = true; + break; + } + } + + if (!foundNextSon) { + throw new NoSuchZoneException(path); + } + } + + return descendant; + } + /** * Gets the list of sons of this ZMI. Modifying a value in the returned list will cause an exception. * @@ -170,6 +195,16 @@ public class ZMI implements Cloneable { return attributes.toString(); } + /** + * Gets the PathName representing this zone. + * + * @return a PathName object representing this zone + */ + public PathName getPathName() { + String name = ((ValueString)getAttributes().get("name")).getValue(); + return getFather() == null? PathName.ROOT : getFather().getPathName().levelDown(name); + } + public static ZMI deserialize(InputStream in) { Kryo kryo = new Kryo(); Input kryoInput = new Input(in); -- cgit v1.2.3