diff options
Diffstat (limited to 'src/pl')
22 files changed, 2292 insertions, 2292 deletions
diff --git a/src/pl/edu/mimuw/cloudatlas/model/Attribute.java b/src/pl/edu/mimuw/cloudatlas/model/Attribute.java index 6e91672..46ffab3 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/Attribute.java +++ b/src/pl/edu/mimuw/cloudatlas/model/Attribute.java @@ -33,74 +33,74 @@ package pl.edu.mimuw.cloudatlas.model; * This class is immutable. */ public class Attribute { - private final String name; - - /** - * Creates a new <code>Attribute</code> object with the specified <code>name</code>. - * - * @param name the name of the attribute - * @throws IllegalArgumentException if the <code>name</code> does not meet the rules - */ - public Attribute(String name) { - if(!name.matches("^&?[a-zA-Z]{1}[a-zA-z0-9_]*$")) - throw new IllegalArgumentException("Invalid name: may contain only letters, digits, underscores, " - + "must start with a letter and may optionally have an ampersand at the beginning."); - this.name = name; - } - - /** - * Indicates whether an <code>attribute</code> represents a query. This is true if and only if the attribute's name starts with an ampersand. - * - * @param attribute the attribute to check - * @return whether the <code>attribute</code> represents a query - */ - public static boolean isQuery(Attribute attribute) { - return attribute.getName().startsWith("&"); - } - - /** - * Gets the name of this attribute. - * - * @return string representing name - */ - public String getName() { - return name; - } - - /** - * Returns a hash code value for this attribute. For proper behavior when using <code>Attribute</code> objects in - * <code>HashMap</code>, <code>HashSet</code> etc. this is the hash code of a string representing the attribute's name. - * - * @return hash code for this attribute - */ - @Override - public int hashCode() { - return name.hashCode(); - } - - /** - * Indicates whether another object is equal to this attribute. - * - * @param object the object to check - * @return true if and only if the <code>object</code> is an instance of <code>Attribute</code> class and has + private final String name; + + /** + * Creates a new <code>Attribute</code> object with the specified <code>name</code>. + * + * @param name the name of the attribute + * @throws IllegalArgumentException if the <code>name</code> does not meet the rules + */ + public Attribute(String name) { + if(!name.matches("^&?[a-zA-Z]{1}[a-zA-z0-9_]*$")) + throw new IllegalArgumentException("Invalid name: may contain only letters, digits, underscores, " + + "must start with a letter and may optionally have an ampersand at the beginning."); + this.name = name; + } + + /** + * Indicates whether an <code>attribute</code> represents a query. This is true if and only if the attribute's name starts with an ampersand. + * + * @param attribute the attribute to check + * @return whether the <code>attribute</code> represents a query + */ + public static boolean isQuery(Attribute attribute) { + return attribute.getName().startsWith("&"); + } + + /** + * Gets the name of this attribute. + * + * @return string representing name + */ + public String getName() { + return name; + } + + /** + * Returns a hash code value for this attribute. For proper behavior when using <code>Attribute</code> objects in + * <code>HashMap</code>, <code>HashSet</code> etc. this is the hash code of a string representing the attribute's name. + * + * @return hash code for this attribute + */ + @Override + public int hashCode() { + return name.hashCode(); + } + + /** + * Indicates whether another object is equal to this attribute. + * + * @param object the object to check + * @return true if and only if the <code>object</code> is an instance of <code>Attribute</code> class and has * an identical name - */ - @Override - public boolean equals(Object object) { - if(object == null) - return false; - if(getClass() != object.getClass()) - return false; - return name.equals(((Attribute)object).name); - } - - /** - * Returns a textual representation of this attribute. - * - * @return the name of this attribute - */ - @Override - public String toString() { - return name; - } + */ + @Override + public boolean equals(Object object) { + if(object == null) + return false; + if(getClass() != object.getClass()) + return false; + return name.equals(((Attribute)object).name); + } + + /** + * Returns a textual representation of this attribute. + * + * @return the name of this attribute + */ + @Override + public String toString() { + return name; + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/AttributesMap.java b/src/pl/edu/mimuw/cloudatlas/model/AttributesMap.java index 86f8969..da13819 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/AttributesMap.java +++ b/src/pl/edu/mimuw/cloudatlas/model/AttributesMap.java @@ -33,250 +33,250 @@ import java.util.Map.Entry; * Represents a map from <code>Attribute</code> to <code>Value</code>. It cannot contain duplicate keys. */ public class AttributesMap implements Iterable<Entry<Attribute, Value>>, Cloneable { - private Map<Attribute, Value> map = new HashMap<Attribute, Value>(); - - private void checkNulls(Attribute attribute, Value value) { - if(attribute == null) - throw new NullPointerException("The attribute cannot be null."); - if(value == null) - throw new NullPointerException( - "The value cannot be null. You may want create a Value object that contains null."); - } - - /** - * Adds to this map a new <code>attribute</code> mapping to the specified <code>value</code>. The - * <code>attribute</code> cannot already exist in the map. To overwrite an existing attribute, use method - * {@link #addOrChange(Attribute, Value)} instead. - * - * @param attribute the attribute to add - * @param value the value for the <code>attribute</code> - * @throws IllegalArgumentException if the <code>attribute</code> already exists in this map - * @throws NullPointerException if either the <code>attribute</code> or the <code>value</code> is <code>null</code>; - * for null value, create a <code>Value</code> object containing <code>null</code> - * @see #addOrChange(Attribute, Value) - * @see #add(String, Value) - * @see #add(Entry) - * @see #add(AttributesMap) - */ - public void add(Attribute attribute, Value value) { - if(getOrNull(attribute) != null) - throw new IllegalArgumentException("Attribute \"" + attribute.getName() - + "\" already exists. Use method addOrChange(Attribute, Value) instead."); - checkNulls(attribute, value); - map.put(attribute, value); - } - - /** - * Adds a new attribute mapping to the specified <code>value</code>. Convenient version of - * {@link #add(Attribute, Value)}. - * - * @param name the attribute name - * @param value the attribute value - * @see #add(Attribute, Value) - * @see #addOrChange(String, Value) - */ - public void add(String name, Value value) { - add(new Attribute(name), value); - } - - /** - * Adds a new mapping to this map. Convenient version of {@link #add(Attribute, Value)}. - * - * @param entry a pair containing both an attribute and a value - * @see #add(Attribute, Value) - * @see #addOrChange(Entry) - */ - public void add(Entry<Attribute, Value> entry) { - add(entry.getKey(), entry.getValue()); - } - - /** - * Adds all entries from another map to this map. This method uses {@link #add(Attribute, Value)}, so it throws an - * exception when trying to overwrite an existing attribute. - * - * @param attributes the map to add - * @see #add(Attribute, Value) - * @see #addOrChange(AttributesMap) - */ - public void add(AttributesMap attributes) { - for(Entry<Attribute, Value> entry : attributes.map.entrySet()) - add(entry); - } - - /** - * Adds to this map a new <code>attribute</code> mapping to the specified <code>value</code>. Unlike - * {@link #add(Attribute, Value)}, this method overwrites an existing attribute with the same name. - * - * @param attribute the attribute to add or overwrite - * @param value the value for the <code>attribute</code> - * @throws NullPointerException if either the <code>attribute</code> or the <code>value</code> is <code>null</code>; - * for null value create a <code>Value</code> object containing <code>null</code> - * @see #add(Attribute, Value) - * @see #addOrChange(String, Value) - * @see #addOrChange(Entry) - * @see #addOrChange(AttributesMap) - */ - public void addOrChange(Attribute attribute, Value value) { - map.put(attribute, value); - checkNulls(attribute, value); - } - - /** - * Adds a new attribute< mapping to the specified <code>value</code> or overwrites an existing one. Convenient - * version of {@link #addOrChange(Attribute, Value)}. - * - * @param name the attribute name - * @param value the attribute value - * @see #addOrChange(Attribute, Value) - * @see #add(String, Value) - */ - public void addOrChange(String name, Value value) { - addOrChange(new Attribute(name), value); - } - - /** - * Adds a new mapping to this map or overwrites an existing one with the same attribute name. Convenient version of - * {@link #addOrChange(Attribute, Value)}. - * - * @param entry a pair containing both an attribute and a value - * @see #addOrChange(Attribute, Value) - * @see #add(Entry) - */ - public void addOrChange(Entry<Attribute, Value> entry) { - addOrChange(entry.getKey(), entry.getValue()); - } - - /** - * Adds all entries from another map to this map. If any attribute with the same name exists in this map, it will be - * overwritten. - * - * @param attributes the map to add - * @see #addOrChange(Attribute, Value) - * @see #add(AttributesMap) - */ - public void addOrChange(AttributesMap attributes) { - for(Entry<Attribute, Value> entry : attributes.map.entrySet()) - addOrChange(entry); - } - - private void checkAttribute(Attribute attribute) { - if(attribute == null) - throw new NullPointerException("The attribute cannot be null."); - } - - /** - * Gets the value mapped to the specified <code>attribute</code>. If such mapping does not exist, this method throws - * an exception. If this is not an expected behavior, use method {@link #getOrNull(Attribute)} instead. - * - * @param attribute the attribute to obtain - * @return the value mapped to the <code>attribute</code> - * @throws IllegalArgumentException if no value is mapped to the <code>attribute</code> - * @throws NullPointerException if the <code>attribute</code> is <code>null</code> - * @see #getOrNull(Attribute) - * @see #get(String) - */ - public Value get(Attribute attribute) { - Value value = getOrNull(attribute); - if(value == null) - throw new IllegalArgumentException("Attribute " + attribute.getName() - + " does not exist. Use method getOrNull(Attribute) instead."); - return value; - } - - /** - * Gets the value mapped to the specified attribute. Convenient version of {@link #get(Attribute)}. - * - * @param name name of the attribute - * @return the value mapped to the specified attribute - * @see #get(Attribute) - * @see #getOrNull(String) - */ - public Value get(String name) { - return get(new Attribute(name)); - } - - /** - * Gets the value mapped to the specified <code>attribute</code>. Unlike {@link #get(Attribute)}, this method - * returns <code>null</code> if the requested mapping does not exist. - * - * @param attribute the attribute to obtain - * @return the value mapped to the <code>attribute</code> or <code>null</code> if it does not exist - * @throws NullPointerException if the <code>attribute</code> is <code>null</code> - * @see #get(Attribute) - * @see #getOrNull(String) - */ - public Value getOrNull(Attribute attribute) { - checkAttribute(attribute); - return map.get(attribute); - } - - /** - * Gets the value mapped to the specified attribute. Convenient version of {@link #getOrNull(Attribute)}. - * - * @param name name of the attribute - * @return the value mapped to specified attribute or <code>null</code> if it does not exist - * @see #getOrNull(Attribute) - * @see #getOr(String) - */ - public Value getOrNull(String name) { - return getOrNull(new Attribute(name)); - } - - /** - * Removes the specified <code>attribute</code> and its value from this map. If the <code>attribute</code> does not - * exist, this method performs nothing. - * - * @param attribute the attribute to remove - * @throws NullPointerException if the <code>attribute</code> is <code>null</code> - * @see #remove(String) - */ - public void remove(Attribute attribute) { - checkAttribute(attribute); - map.remove(attribute); - } - - /** - * Removes the specified attribute and its value from this map. Convenient version of {@link #remove(Attribute)}. - * - * @param name the name of the attribute to remove - * @see #remove(Attribute) - */ - public void remove(String name) { - map.remove(new Attribute(name)); - } - - /** - * Returns an iterator over all entries stored in this map. - * - * @return an iterator for this map - * @see java.util.Iterator - * @see java.lang.Iterable - */ - @Override - public Iterator<Entry<Attribute, Value>> iterator() { - return map.entrySet().iterator(); - } - - /** - * Creates a copy of this map. Since <code>Value</code> and <code>Attribute</code> are immutable classes, this - * method does not clone them. - * - * @return a copy of this map containing identical entries - */ - @Override - public AttributesMap clone() { - AttributesMap result = new AttributesMap(); - result.add(this); - return result; - } - - /** - * Returns a string representation of this map listing all key-value pairs stored in it. - * - * @return a string representation of this object - */ - @Override - public String toString() { - return map.toString(); - } + private Map<Attribute, Value> map = new HashMap<Attribute, Value>(); + + private void checkNulls(Attribute attribute, Value value) { + if(attribute == null) + throw new NullPointerException("The attribute cannot be null."); + if(value == null) + throw new NullPointerException( + "The value cannot be null. You may want create a Value object that contains null."); + } + + /** + * Adds to this map a new <code>attribute</code> mapping to the specified <code>value</code>. The + * <code>attribute</code> cannot already exist in the map. To overwrite an existing attribute, use method + * {@link #addOrChange(Attribute, Value)} instead. + * + * @param attribute the attribute to add + * @param value the value for the <code>attribute</code> + * @throws IllegalArgumentException if the <code>attribute</code> already exists in this map + * @throws NullPointerException if either the <code>attribute</code> or the <code>value</code> is <code>null</code>; + * for null value, create a <code>Value</code> object containing <code>null</code> + * @see #addOrChange(Attribute, Value) + * @see #add(String, Value) + * @see #add(Entry) + * @see #add(AttributesMap) + */ + public void add(Attribute attribute, Value value) { + if(getOrNull(attribute) != null) + throw new IllegalArgumentException("Attribute \"" + attribute.getName() + + "\" already exists. Use method addOrChange(Attribute, Value) instead."); + checkNulls(attribute, value); + map.put(attribute, value); + } + + /** + * Adds a new attribute mapping to the specified <code>value</code>. Convenient version of + * {@link #add(Attribute, Value)}. + * + * @param name the attribute name + * @param value the attribute value + * @see #add(Attribute, Value) + * @see #addOrChange(String, Value) + */ + public void add(String name, Value value) { + add(new Attribute(name), value); + } + + /** + * Adds a new mapping to this map. Convenient version of {@link #add(Attribute, Value)}. + * + * @param entry a pair containing both an attribute and a value + * @see #add(Attribute, Value) + * @see #addOrChange(Entry) + */ + public void add(Entry<Attribute, Value> entry) { + add(entry.getKey(), entry.getValue()); + } + + /** + * Adds all entries from another map to this map. This method uses {@link #add(Attribute, Value)}, so it throws an + * exception when trying to overwrite an existing attribute. + * + * @param attributes the map to add + * @see #add(Attribute, Value) + * @see #addOrChange(AttributesMap) + */ + public void add(AttributesMap attributes) { + for(Entry<Attribute, Value> entry : attributes.map.entrySet()) + add(entry); + } + + /** + * Adds to this map a new <code>attribute</code> mapping to the specified <code>value</code>. Unlike + * {@link #add(Attribute, Value)}, this method overwrites an existing attribute with the same name. + * + * @param attribute the attribute to add or overwrite + * @param value the value for the <code>attribute</code> + * @throws NullPointerException if either the <code>attribute</code> or the <code>value</code> is <code>null</code>; + * for null value create a <code>Value</code> object containing <code>null</code> + * @see #add(Attribute, Value) + * @see #addOrChange(String, Value) + * @see #addOrChange(Entry) + * @see #addOrChange(AttributesMap) + */ + public void addOrChange(Attribute attribute, Value value) { + map.put(attribute, value); + checkNulls(attribute, value); + } + + /** + * Adds a new attribute< mapping to the specified <code>value</code> or overwrites an existing one. Convenient + * version of {@link #addOrChange(Attribute, Value)}. + * + * @param name the attribute name + * @param value the attribute value + * @see #addOrChange(Attribute, Value) + * @see #add(String, Value) + */ + public void addOrChange(String name, Value value) { + addOrChange(new Attribute(name), value); + } + + /** + * Adds a new mapping to this map or overwrites an existing one with the same attribute name. Convenient version of + * {@link #addOrChange(Attribute, Value)}. + * + * @param entry a pair containing both an attribute and a value + * @see #addOrChange(Attribute, Value) + * @see #add(Entry) + */ + public void addOrChange(Entry<Attribute, Value> entry) { + addOrChange(entry.getKey(), entry.getValue()); + } + + /** + * Adds all entries from another map to this map. If any attribute with the same name exists in this map, it will be + * overwritten. + * + * @param attributes the map to add + * @see #addOrChange(Attribute, Value) + * @see #add(AttributesMap) + */ + public void addOrChange(AttributesMap attributes) { + for(Entry<Attribute, Value> entry : attributes.map.entrySet()) + addOrChange(entry); + } + + private void checkAttribute(Attribute attribute) { + if(attribute == null) + throw new NullPointerException("The attribute cannot be null."); + } + + /** + * Gets the value mapped to the specified <code>attribute</code>. If such mapping does not exist, this method throws + * an exception. If this is not an expected behavior, use method {@link #getOrNull(Attribute)} instead. + * + * @param attribute the attribute to obtain + * @return the value mapped to the <code>attribute</code> + * @throws IllegalArgumentException if no value is mapped to the <code>attribute</code> + * @throws NullPointerException if the <code>attribute</code> is <code>null</code> + * @see #getOrNull(Attribute) + * @see #get(String) + */ + public Value get(Attribute attribute) { + Value value = getOrNull(attribute); + if(value == null) + throw new IllegalArgumentException("Attribute " + attribute.getName() + + " does not exist. Use method getOrNull(Attribute) instead."); + return value; + } + + /** + * Gets the value mapped to the specified attribute. Convenient version of {@link #get(Attribute)}. + * + * @param name name of the attribute + * @return the value mapped to the specified attribute + * @see #get(Attribute) + * @see #getOrNull(String) + */ + public Value get(String name) { + return get(new Attribute(name)); + } + + /** + * Gets the value mapped to the specified <code>attribute</code>. Unlike {@link #get(Attribute)}, this method + * returns <code>null</code> if the requested mapping does not exist. + * + * @param attribute the attribute to obtain + * @return the value mapped to the <code>attribute</code> or <code>null</code> if it does not exist + * @throws NullPointerException if the <code>attribute</code> is <code>null</code> + * @see #get(Attribute) + * @see #getOrNull(String) + */ + public Value getOrNull(Attribute attribute) { + checkAttribute(attribute); + return map.get(attribute); + } + + /** + * Gets the value mapped to the specified attribute. Convenient version of {@link #getOrNull(Attribute)}. + * + * @param name name of the attribute + * @return the value mapped to specified attribute or <code>null</code> if it does not exist + * @see #getOrNull(Attribute) + * @see #getOr(String) + */ + public Value getOrNull(String name) { + return getOrNull(new Attribute(name)); + } + + /** + * Removes the specified <code>attribute</code> and its value from this map. If the <code>attribute</code> does not + * exist, this method performs nothing. + * + * @param attribute the attribute to remove + * @throws NullPointerException if the <code>attribute</code> is <code>null</code> + * @see #remove(String) + */ + public void remove(Attribute attribute) { + checkAttribute(attribute); + map.remove(attribute); + } + + /** + * Removes the specified attribute and its value from this map. Convenient version of {@link #remove(Attribute)}. + * + * @param name the name of the attribute to remove + * @see #remove(Attribute) + */ + public void remove(String name) { + map.remove(new Attribute(name)); + } + + /** + * Returns an iterator over all entries stored in this map. + * + * @return an iterator for this map + * @see java.util.Iterator + * @see java.lang.Iterable + */ + @Override + public Iterator<Entry<Attribute, Value>> iterator() { + return map.entrySet().iterator(); + } + + /** + * Creates a copy of this map. Since <code>Value</code> and <code>Attribute</code> are immutable classes, this + * method does not clone them. + * + * @return a copy of this map containing identical entries + */ + @Override + public AttributesMap clone() { + AttributesMap result = new AttributesMap(); + result.add(this); + return result; + } + + /** + * Returns a string representation of this map listing all key-value pairs stored in it. + * + * @return a string representation of this object + */ + @Override + public String toString() { + return map.toString(); + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/IncompatibleTypesException.java b/src/pl/edu/mimuw/cloudatlas/model/IncompatibleTypesException.java index e8a962d..c872e98 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/IncompatibleTypesException.java +++ b/src/pl/edu/mimuw/cloudatlas/model/IncompatibleTypesException.java @@ -28,54 +28,54 @@ import pl.edu.mimuw.cloudatlas.model.Value.Operation; /** * An exception thrown when an unsupported binary operation on values is requested. - * + * * @see UnsupportedValueOperationException * @see UnsupportedConversionException */ @SuppressWarnings("serial") public class IncompatibleTypesException extends UnsupportedOperationException { - private final Type left; - private final Type right; - private final Operation operation; - - /** - * Creates a new object representing this exception. - * - * @param left type of a left operand - * @param right type of a right operand - * @param operation an operation that caused this exception - */ - protected IncompatibleTypesException(Type left, Type right, Operation operation) { - super("Incompatible types: " + left + " and " + right + " in operation " + operation + "."); - this.left = left; - this.right = right; - this.operation = operation; - } - - /** - * Gets a type of a left operand in an operation that caused this exception. - * - * @return the type of the left operand - */ - public Type getLeft() { - return left; - } - - /** - * Gets a type of a right operand in an operation that caused this exception. - * - * @return the type of the right operand - */ - public Type getRight() { - return right; - } - - /** - * Gets an object representing an operation that caused this exception. - * - * @return an operation that caused this exception - */ - public Operation getOperation() { - return operation; - } + private final Type left; + private final Type right; + private final Operation operation; + + /** + * Creates a new object representing this exception. + * + * @param left type of a left operand + * @param right type of a right operand + * @param operation an operation that caused this exception + */ + protected IncompatibleTypesException(Type left, Type right, Operation operation) { + super("Incompatible types: " + left + " and " + right + " in operation " + operation + "."); + this.left = left; + this.right = right; + this.operation = operation; + } + + /** + * Gets a type of a left operand in an operation that caused this exception. + * + * @return the type of the left operand + */ + public Type getLeft() { + return left; + } + + /** + * Gets a type of a right operand in an operation that caused this exception. + * + * @return the type of the right operand + */ + public Type getRight() { + return right; + } + + /** + * Gets an object representing an operation that caused this exception. + * + * @return an operation that caused this exception + */ + public Operation getOperation() { + return operation; + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/PathName.java b/src/pl/edu/mimuw/cloudatlas/model/PathName.java index c5ef4e8..ba1a931 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/PathName.java +++ b/src/pl/edu/mimuw/cloudatlas/model/PathName.java @@ -34,147 +34,147 @@ import java.util.List; * Represent a fully qualified name of a zone, also known as a global name or a path name. This class is immutable. */ public class PathName { - /** - * The object representing a name of the root zone (/). - */ - public static final PathName ROOT = new PathName("/"); - - private final List<String> components; - private final String name; - - /** - * Creates a <code>PathName</code> object representing the specified path. For the root zone, there are three - * accepted forms: <code>null</code> reference, empty string or slash. Any other zone is represented by a string - * starting with slash and containing names of zones at each level of hierarchy, separated by slashes. Zone name - * must contain only letters and digits. - * - * @param name path name of a zone, for instance: <code>/warsaw/uw/violet07</code> - * @throws IllegalArgumentException if the <code>name</code> is incorrect - */ - public PathName(String name) { - // we accept null and "/" as names of a root zone, however, we convert all of them to "" - name = name == null || name.equals("/")? "" : name.trim(); - if(!name.matches("(/\\w+)*")) - throw new IllegalArgumentException("Incorrect fully qualified name: " + name + "."); - this.name = name; - components = name.equals("")? new ArrayList<String>() : Arrays.asList(name.substring(1).split("/")); - } - - /** - * Creates a <code>PathName</code> object from a collection of zones names. Every zone name must contain only - * letters and digits. - * - * @param components a collection of zones names at subsequent levels of hierarchy (starting from root); empty - * collection represents the root zone - * @throws IllegalArgumentException if any zone name is incorrect - */ - public PathName(Collection<String> components) { - this.components = new ArrayList<String>(components); - if(components.isEmpty()) - this.name = ""; - else { - String currentName = ""; - for(String c : components) { - currentName += "/" + c; - if(!c.matches("\\w+")) - throw new IllegalArgumentException("Incorrect component " + c + "."); - } - this.name = currentName; - } - } - - /** - * Gets zones names at subsequent levels of hierarchy, starting from root. For the root zone, this method returns an - * empty collection. Modifying returned list will throw an exception. - * - * @return a collection of zones names - */ - public List<String> getComponents() { - return Collections.unmodifiableList(components); - } - - /** - * Gets a full path name. For the root zone, this method returns an empty string. - * - * @return a path name represented by this object - * @see #toString() - */ - public String getName() { - return name; - } - - /** - * Gets a name one level up in a hierarchy. For the root zone, this method returns a new instance of the same zone. - * - * @return a new <code>PathName</code> object representing a zone one level up in the hierarchy - */ - public PathName levelUp() { - List<String> componentsUp = new ArrayList<String>(components); - if(!componentsUp.isEmpty()) - componentsUp.remove(componentsUp.size() - 1); - return new PathName(componentsUp); - } - - /** - * Gets a name one level down in a hierarchy. - * - * @param son zone name at a lower level - * @return a new <code>PathName</code> object representing a zone one level down in the hierarchy - */ - public PathName levelDown(String son) { - return new PathName(name + "/" + son); - } - - /** - * Gets a zone name at the lowest level (highest number) in a hierarchy. - * - * @return a leaf zone - * @throws UnsupportedOperationException if this object represents the root zone - */ - public String getSingletonName() { - try { - return components.get(components.size() - 1); - } catch(IndexOutOfBoundsException exception) { - throw new UnsupportedOperationException("getSingletonName() is not supported for the root zone."); - } - } - - /** - * Returns a hash code value for this object. This method returns a hash code of a string representing full path - * name. - * - * @return a hash code for this object - */ - @Override - public int hashCode() { - return name.hashCode(); - } - - /** - * Indicates whether this object is equal to another. A <code>PathName</code> object is equal to other objects of - * the same class representing identical path name. - * - * @object the object to check - * @return whether the <code>object</code> is equal to this name - */ - @Override - public boolean equals(Object object) { - if(object == null) - return false; - if(getClass() != object.getClass()) - return false; - return name.equals(((PathName)object).name); - } - - /** - * Returns a textual representation for this <code>PathName</code>. For the root zone, unlike {@link #getName()}, - * this method returns slash. - * - * @return a path name for this object - * @see #getName() - */ - @Override - public String toString() { - return name.equals("")? "/" : getName(); - } + /** + * The object representing a name of the root zone (/). + */ + public static final PathName ROOT = new PathName("/"); + + private final List<String> components; + private final String name; + + /** + * Creates a <code>PathName</code> object representing the specified path. For the root zone, there are three + * accepted forms: <code>null</code> reference, empty string or slash. Any other zone is represented by a string + * starting with slash and containing names of zones at each level of hierarchy, separated by slashes. Zone name + * must contain only letters and digits. + * + * @param name path name of a zone, for instance: <code>/warsaw/uw/violet07</code> + * @throws IllegalArgumentException if the <code>name</code> is incorrect + */ + public PathName(String name) { + // we accept null and "/" as names of a root zone, however, we convert all of them to "" + name = name == null || name.equals("/")? "" : name.trim(); + if(!name.matches("(/\\w+)*")) + throw new IllegalArgumentException("Incorrect fully qualified name: " + name + "."); + this.name = name; + components = name.equals("")? new ArrayList<String>() : Arrays.asList(name.substring(1).split("/")); + } + + /** + * Creates a <code>PathName</code> object from a collection of zones names. Every zone name must contain only + * letters and digits. + * + * @param components a collection of zones names at subsequent levels of hierarchy (starting from root); empty + * collection represents the root zone + * @throws IllegalArgumentException if any zone name is incorrect + */ + public PathName(Collection<String> components) { + this.components = new ArrayList<String>(components); + if(components.isEmpty()) + this.name = ""; + else { + String currentName = ""; + for(String c : components) { + currentName += "/" + c; + if(!c.matches("\\w+")) + throw new IllegalArgumentException("Incorrect component " + c + "."); + } + this.name = currentName; + } + } + + /** + * Gets zones names at subsequent levels of hierarchy, starting from root. For the root zone, this method returns an + * empty collection. Modifying returned list will throw an exception. + * + * @return a collection of zones names + */ + public List<String> getComponents() { + return Collections.unmodifiableList(components); + } + + /** + * Gets a full path name. For the root zone, this method returns an empty string. + * + * @return a path name represented by this object + * @see #toString() + */ + public String getName() { + return name; + } + + /** + * Gets a name one level up in a hierarchy. For the root zone, this method returns a new instance of the same zone. + * + * @return a new <code>PathName</code> object representing a zone one level up in the hierarchy + */ + public PathName levelUp() { + List<String> componentsUp = new ArrayList<String>(components); + if(!componentsUp.isEmpty()) + componentsUp.remove(componentsUp.size() - 1); + return new PathName(componentsUp); + } + + /** + * Gets a name one level down in a hierarchy. + * + * @param son zone name at a lower level + * @return a new <code>PathName</code> object representing a zone one level down in the hierarchy + */ + public PathName levelDown(String son) { + return new PathName(name + "/" + son); + } + + /** + * Gets a zone name at the lowest level (highest number) in a hierarchy. + * + * @return a leaf zone + * @throws UnsupportedOperationException if this object represents the root zone + */ + public String getSingletonName() { + try { + return components.get(components.size() - 1); + } catch(IndexOutOfBoundsException exception) { + throw new UnsupportedOperationException("getSingletonName() is not supported for the root zone."); + } + } + + /** + * Returns a hash code value for this object. This method returns a hash code of a string representing full path + * name. + * + * @return a hash code for this object + */ + @Override + public int hashCode() { + return name.hashCode(); + } + + /** + * Indicates whether this object is equal to another. A <code>PathName</code> object is equal to other objects of + * the same class representing identical path name. + * + * @object the object to check + * @return whether the <code>object</code> is equal to this name + */ + @Override + public boolean equals(Object object) { + if(object == null) + return false; + if(getClass() != object.getClass()) + return false; + return name.equals(((PathName)object).name); + } + + /** + * Returns a textual representation for this <code>PathName</code>. For the root zone, unlike {@link #getName()}, + * this method returns slash. + * + * @return a path name for this object + * @see #getName() + */ + @Override + public String toString() { + return name.equals("")? "/" : getName(); + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/Type.java b/src/pl/edu/mimuw/cloudatlas/model/Type.java index ba6cf62..eb1fb7b 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/Type.java +++ b/src/pl/edu/mimuw/cloudatlas/model/Type.java @@ -28,54 +28,54 @@ package pl.edu.mimuw.cloudatlas.model; * A type of a value that may be stored as an attribute. */ public abstract class Type { - /** - * 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, - } - - private final PrimaryType primaryType; - - /** - * Creates a <code>Type</code> object with a given primary type. - * - * @param primaryType a primary type for this type - */ - public Type(PrimaryType primaryType) { - this.primaryType = primaryType; - } - - /** - * Returns a primary type of this type. - * - * @return a primary type - */ - public PrimaryType getPrimaryType() { - return primaryType; - } - - /** - * Indicates whether this type can be implicitly "cast" to given one and vice verse. This is introduced to deal with - * null values. In practice, two types are compatible either if they are the same or if one them is a special - * "null type". - * - * @param type a type to check - * @return whether two types are compatible with each other - * @see TypePrimitive#NULL - * @see ValueNull - */ - public boolean isCompatible(Type type) { - return getPrimaryType() == PrimaryType.NULL || type.getPrimaryType() == PrimaryType.NULL; - } - - /** - * Indicates whether this type represents a collection. - * - * @return true for collections, false otherwise - */ - public boolean isCollection() { - return false; - } + /** + * 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, + } + + private final PrimaryType primaryType; + + /** + * Creates a <code>Type</code> object with a given primary type. + * + * @param primaryType a primary type for this type + */ + public Type(PrimaryType primaryType) { + this.primaryType = primaryType; + } + + /** + * Returns a primary type of this type. + * + * @return a primary type + */ + public PrimaryType getPrimaryType() { + return primaryType; + } + + /** + * Indicates whether this type can be implicitly "cast" to given one and vice verse. This is introduced to deal with + * null values. In practice, two types are compatible either if they are the same or if one them is a special + * "null type". + * + * @param type a type to check + * @return whether two types are compatible with each other + * @see TypePrimitive#NULL + * @see ValueNull + */ + public boolean isCompatible(Type type) { + return getPrimaryType() == PrimaryType.NULL || type.getPrimaryType() == PrimaryType.NULL; + } + + /** + * Indicates whether this type represents a collection. + * + * @return true for collections, false otherwise + */ + public boolean isCollection() { + return false; + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/TypeCollection.java b/src/pl/edu/mimuw/cloudatlas/model/TypeCollection.java index 9ace5c5..6e08e42 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/TypeCollection.java +++ b/src/pl/edu/mimuw/cloudatlas/model/TypeCollection.java @@ -33,84 +33,84 @@ import pl.edu.mimuw.cloudatlas.model.ValueNull; /** * Represents a collection type with specified element type. - * + * * @see TypePrimitve */ public class TypeCollection extends Type { - private final Type elementType; - - /** - * Creates a new collection type. - * - * @param primaryType a type of this collection (set, list etc.) - * @param elementType a type of an element of this collection; may be a complex type (for instance - * <code>TypeCollection</code>) - */ - public TypeCollection(PrimaryType primaryType, Type elementType) { - super(primaryType); - switch(primaryType) { - case LIST: - case SET: - break; - default: - throw new IllegalArgumentException("This class can represent a collection only (list, set etc.)."); - } - this.elementType = elementType; - } - - /** - * Gets a type of elements stored in this collection. - * - * @return type of element in this collection - */ - public Type getElementType() { - return elementType; - } - - /** - * Returns a friendly textual representation of this collection, for instance: "SET of (STRING)". - * - * @return a textual representation of this type - */ - @Override - public String toString() { - return getPrimaryType().toString() + " of (" + elementType.toString() + ")"; - } - - @Override - public boolean isCompatible(Type type) { - return super.isCompatible(type) - || (getPrimaryType() == type.getPrimaryType() && elementType - .isCompatible(((TypeCollection)type).elementType)); - } - - @Override - public boolean isCollection() { - return true; - } - - /** - * Returns a type of all elements in the specified collection. If the collection is empty, this method returns - * {@link TypePrimitive#NULL}. If the collection contains at least two elements of distinct types that are not nulls, - * an exception is thrown. - * - * @param collection a collection of values to check - * @return type of elements in this collection - * @throws IllegalArgumentException if the collection contains non-null elements of different types - */ - public static Type computeElementType(Collection<Value> collection) { - Type mainType = null; - - for(Value v : collection) { - if(v.isNull()) - v = ValueNull.getInstance(); - if(mainType == null) { - if(v.getType().getPrimaryType() != Type.PrimaryType.NULL) - mainType = v.getType(); - } else if(!mainType.isCompatible(v.getType())) - throw new IllegalArgumentException("Collection has non-null elements of different types."); - } - - return mainType == null? TypePrimitive.NULL : mainType; - } + private final Type elementType; + + /** + * Creates a new collection type. + * + * @param primaryType a type of this collection (set, list etc.) + * @param elementType a type of an element of this collection; may be a complex type (for instance + * <code>TypeCollection</code>) + */ + public TypeCollection(PrimaryType primaryType, Type elementType) { + super(primaryType); + switch(primaryType) { + case LIST: + case SET: + break; + default: + throw new IllegalArgumentException("This class can represent a collection only (list, set etc.)."); + } + this.elementType = elementType; + } + + /** + * Gets a type of elements stored in this collection. + * + * @return type of element in this collection + */ + public Type getElementType() { + return elementType; + } + + /** + * Returns a friendly textual representation of this collection, for instance: "SET of (STRING)". + * + * @return a textual representation of this type + */ + @Override + public String toString() { + return getPrimaryType().toString() + " of (" + elementType.toString() + ")"; + } + + @Override + public boolean isCompatible(Type type) { + return super.isCompatible(type) + || (getPrimaryType() == type.getPrimaryType() && elementType + .isCompatible(((TypeCollection)type).elementType)); + } + + @Override + public boolean isCollection() { + return true; + } + + /** + * Returns a type of all elements in the specified collection. If the collection is empty, this method returns + * {@link TypePrimitive#NULL}. If the collection contains at least two elements of distinct types that are not nulls, + * an exception is thrown. + * + * @param collection a collection of values to check + * @return type of elements in this collection + * @throws IllegalArgumentException if the collection contains non-null elements of different types + */ + public static Type computeElementType(Collection<Value> collection) { + Type mainType = null; + + for(Value v : collection) { + if(v.isNull()) + v = ValueNull.getInstance(); + if(mainType == null) { + if(v.getType().getPrimaryType() != Type.PrimaryType.NULL) + mainType = v.getType(); + } else if(!mainType.isCompatible(v.getType())) + throw new IllegalArgumentException("Collection has non-null elements of different types."); + } + + return mainType == null? TypePrimitive.NULL : mainType; + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/TypePrimitive.java b/src/pl/edu/mimuw/cloudatlas/model/TypePrimitive.java index 4940a16..6e2c79e 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/TypePrimitive.java +++ b/src/pl/edu/mimuw/cloudatlas/model/TypePrimitive.java @@ -26,83 +26,83 @@ package pl.edu.mimuw.cloudatlas.model; /** * Convenient class for types that just wrap ordinary Java types. - * + * * @see TypeCollection */ public class TypePrimitive extends Type { - /** - * Boolean type. - */ - public static final TypePrimitive BOOLEAN = new TypePrimitive(PrimaryType.BOOLEAN); - - /** - * Contact type. - */ - public static final TypePrimitive CONTACT = new TypePrimitive(PrimaryType.CONTACT); - - /** - * Double type. - */ - public static final TypePrimitive DOUBLE = new TypePrimitive(PrimaryType.DOUBLE); - - /** - * Duration type. - */ - public static final TypePrimitive DURATION = new TypePrimitive(PrimaryType.DURATION); - - /** - * Integer type. - */ - public static final TypePrimitive INTEGER = new TypePrimitive(PrimaryType.INT); - - /** - * A special "null type" that represents null value of an unknown type. It can be converted to any other type. - * - * @see Type#isCompatible(Type) - * @see ValueNull - */ - public static final TypePrimitive NULL = new TypePrimitive(PrimaryType.NULL); - - /** - * String type. - */ - public static final TypePrimitive STRING = new TypePrimitive(PrimaryType.STRING); - - /** - * Time type. - */ - public static final TypePrimitive TIME = new TypePrimitive(PrimaryType.TIME); - - private TypePrimitive(PrimaryType primaryType) { - super(primaryType); - switch(primaryType) { - case BOOLEAN: - case CONTACT: - case DOUBLE: - case DURATION: - case INT: - case NULL: - case STRING: - case TIME: - break; - default: - throw new IllegalArgumentException( - "This class can represent a primitive type only (boolean, int etc.)."); - } - } - - /** - * Gets a textual representation of this type. - * - * @return a string representing this type - */ - @Override - public String toString() { - return getPrimaryType().toString(); - } - - @Override - public boolean isCompatible(Type type) { - return super.isCompatible(type) || getPrimaryType() == type.getPrimaryType(); - } + /** + * Boolean type. + */ + public static final TypePrimitive BOOLEAN = new TypePrimitive(PrimaryType.BOOLEAN); + + /** + * Contact type. + */ + public static final TypePrimitive CONTACT = new TypePrimitive(PrimaryType.CONTACT); + + /** + * Double type. + */ + public static final TypePrimitive DOUBLE = new TypePrimitive(PrimaryType.DOUBLE); + + /** + * Duration type. + */ + public static final TypePrimitive DURATION = new TypePrimitive(PrimaryType.DURATION); + + /** + * Integer type. + */ + public static final TypePrimitive INTEGER = new TypePrimitive(PrimaryType.INT); + + /** + * A special "null type" that represents null value of an unknown type. It can be converted to any other type. + * + * @see Type#isCompatible(Type) + * @see ValueNull + */ + public static final TypePrimitive NULL = new TypePrimitive(PrimaryType.NULL); + + /** + * String type. + */ + public static final TypePrimitive STRING = new TypePrimitive(PrimaryType.STRING); + + /** + * Time type. + */ + public static final TypePrimitive TIME = new TypePrimitive(PrimaryType.TIME); + + private TypePrimitive(PrimaryType primaryType) { + super(primaryType); + switch(primaryType) { + case BOOLEAN: + case CONTACT: + case DOUBLE: + case DURATION: + case INT: + case NULL: + case STRING: + case TIME: + break; + default: + throw new IllegalArgumentException( + "This class can represent a primitive type only (boolean, int etc.)."); + } + } + + /** + * Gets a textual representation of this type. + * + * @return a string representing this type + */ + @Override + public String toString() { + return getPrimaryType().toString(); + } + + @Override + public boolean isCompatible(Type type) { + return super.isCompatible(type) || getPrimaryType() == type.getPrimaryType(); + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/UnsupportedConversionException.java b/src/pl/edu/mimuw/cloudatlas/model/UnsupportedConversionException.java index 024c89f..98cbd3a 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/UnsupportedConversionException.java +++ b/src/pl/edu/mimuw/cloudatlas/model/UnsupportedConversionException.java @@ -26,42 +26,42 @@ package pl.edu.mimuw.cloudatlas.model; /** * An exception describing unsupported conversion of a value to another type. - * + * * @see IncompatibleTypesException * @see UnsupportedValueOperationException */ @SuppressWarnings("serial") public class UnsupportedConversionException extends UnsupportedOperationException { - private final Type from; - private final Type to; - - /** - * Creates a new instance of this this exception. - * - * @param from source type of an unsupported conversion - * @param to destination type of an unsupported conversion - */ - protected UnsupportedConversionException(Type from, Type to) { - super("Type " + from + " cannot be converted to " + to + "."); - this.from = from; - this.to = to; - } - - /** - * Gets a source type of an unsupported conversion that caused this exception. - * - * @return source type - */ - public Type getFrom() { - return from; - } - - /** - * Gets a destination type of an unsupported conversion that caused this exception. - * - * @return destination type - */ - public Type getTo() { - return to; - } + private final Type from; + private final Type to; + + /** + * Creates a new instance of this this exception. + * + * @param from source type of an unsupported conversion + * @param to destination type of an unsupported conversion + */ + protected UnsupportedConversionException(Type from, Type to) { + super("Type " + from + " cannot be converted to " + to + "."); + this.from = from; + this.to = to; + } + + /** + * Gets a source type of an unsupported conversion that caused this exception. + * + * @return source type + */ + public Type getFrom() { + return from; + } + + /** + * Gets a destination type of an unsupported conversion that caused this exception. + * + * @return destination type + */ + public Type getTo() { + return to; + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/UnsupportedValueOperationException.java b/src/pl/edu/mimuw/cloudatlas/model/UnsupportedValueOperationException.java index e292265..0cab2fb 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/UnsupportedValueOperationException.java +++ b/src/pl/edu/mimuw/cloudatlas/model/UnsupportedValueOperationException.java @@ -28,42 +28,42 @@ import pl.edu.mimuw.cloudatlas.model.Value.Operation; /** * An exception caused by calling an unsupported unary operation on value. - * + * * @see IncompatibleTypesException * @see UnsupportedConversionException */ @SuppressWarnings("serial") public class UnsupportedValueOperationException extends UnsupportedOperationException { - private final Type left; - private final Operation operation; - - /** - * Creates a new object representing this exception. - * - * @param left type of a value that was an argument of an operation that caused this exception - * @param operation the operation that caused this exception - */ - protected UnsupportedValueOperationException(Type left, Operation operation) { - super("Type: " + left + " does not provide operation " + operation + "."); - this.left = left; - this.operation = operation; - } - - /** - * Gets a type of value that was an argument to an operation that caused this exception. - * - * @return first argument of the operation - */ - public Type getLeft() { - return left; - } - - /** - * Gets an operation that caused this exception. - * - * @return the operation - */ - public Operation getOperation() { - return operation; - } + private final Type left; + private final Operation operation; + + /** + * Creates a new object representing this exception. + * + * @param left type of a value that was an argument of an operation that caused this exception + * @param operation the operation that caused this exception + */ + protected UnsupportedValueOperationException(Type left, Operation operation) { + super("Type: " + left + " does not provide operation " + operation + "."); + this.left = left; + this.operation = operation; + } + + /** + * Gets a type of value that was an argument to an operation that caused this exception. + * + * @return first argument of the operation + */ + public Type getLeft() { + return left; + } + + /** + * Gets an operation that caused this exception. + * + * @return the operation + */ + public Operation getOperation() { + return operation; + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/Value.java b/src/pl/edu/mimuw/cloudatlas/model/Value.java index 236f307..02b4bd4 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/Value.java +++ b/src/pl/edu/mimuw/cloudatlas/model/Value.java @@ -30,212 +30,212 @@ import pl.edu.mimuw.cloudatlas.model.Value; * A single value stored as an attribute. */ public abstract class Value { - /** - * An operation that may be performed on values. - */ - public enum Operation { - EQUAL, COMPARE, ADD, SUBTRACT, MULTIPLY, DIVIDE, MODULO, AND, OR, REG_EXPR, NEGATE, VALUE_SIZE, - } - - /** - * Gets the type of this value. - * - * @return type of this value - */ - public abstract Type getType(); - - /** - * Indicates whether this value is null. Distinct from a <code>Value</code> reference that is <code>null</code> - * itself. - * - * @return true if and only if this value is null - */ - public abstract boolean isNull(); - - protected final void sameTypesOrThrow(Value value, Operation operation) { - if(!getType().isCompatible(value.getType())) - throw new IncompatibleTypesException(getType(), value.getType(), operation); - } - - /** - * Checks whether this value is equal to the specified one (operator ==). - * - * @param value the right side of the operator - * @return a <code>ValueBoolean</code> representing true if and only if both values are equal - * @throws UnsupportedValueOperationException if this operation is unsupported for these values - */ - public Value isEqual(Value value) { - throw new UnsupportedValueOperationException(getType(), Operation.EQUAL); - } - - /** - * Indicates whether this object is equal to another one. - * - * @param object the object to check - * @return whether two objects are equal - */ - @Override - public boolean equals(Object object) { - if(!(object instanceof Value)) - return false; - return ((ValueBoolean)isEqual((Value)object)).getValue(); - } - - /** - * Checks whether this value is lower than the specified one (operator <=). - * - * @param value the right side of the operator - * @return a <code>ValueBoolean</code> representing true if and only if this value is lower than the provided one - * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example - * incompatible or non-numeric types) - */ - public Value isLowerThan(Value value) { - throw new UnsupportedValueOperationException(getType(), Operation.COMPARE); - } - - /** - * Returns a new value created by adding argument to this value (operator +). - * - * @param value the right side of the operator - * @return a sum of two values - * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example - * incompatible or non-numeric types) - */ - public Value addValue(Value value) { - // name clash with add from List interface - throw new UnsupportedValueOperationException(getType(), Operation.ADD); - } - - /** - * Returns a new value created by subtracting argument from this value (operator -). - * - * @param value the right side of the operator - * @return a difference of two values - * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example - * incompatible or non-numeric types) - */ - public Value subtract(Value value) { - throw new UnsupportedValueOperationException(getType(), Operation.SUBTRACT); - } - - /** - * Returns a new value created by multiplying this value by an argument (operator *). - * - * @param value the right side of the operator - * @return a product of two values - * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example - * incompatible or non-numeric types) - */ - public Value multiply(Value value) { - throw new UnsupportedValueOperationException(getType(), Operation.MULTIPLY); - } - - /** - * Returns a new value created by dividing this value by an argument (operator /). - * - * @param value the right side of the operator - * @return a quotient of two values - * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example - * incompatible or non-numeric types) - */ - public Value divide(Value value) { - throw new UnsupportedValueOperationException(getType(), Operation.DIVIDE); - } - - /** - * Returns the remainder of division of this value by an argument (operator %). - * - * @param value the right side of the operator - * @return a remainder - * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example - * incompatible or non-numeric types) - */ - public Value modulo(Value value) { - throw new UnsupportedValueOperationException(getType(), Operation.MODULO); - } - - /** - * Returns the result of a logical AND (operator &&). - * - * @param value the right side of the operator - * @return a conjunction of the two values - * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example - * non-boolean types) - */ - public Value and(Value value) { - throw new UnsupportedValueOperationException(getType(), Operation.AND); - } - - /** - * Returns the result of a logical OR (operator ||). - * - * @param value the right side of the operator - * @return an alternative of two values - * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example - * non-boolean types) - */ - public Value or(Value value) { - throw new UnsupportedValueOperationException(getType(), Operation.OR); - } - - /** - * Returns a result of trying to match to this value with a regular expression specified as an argument. - * - * @param value the regular expression to match against - * @return a <code>ValueBoolean</code> representing true if and only if this value matches provided regular - * expression - * @throws UnsupportedValueOperationException if this operator is unsupported for these values - */ - public Value regExpr(Value value) { - throw new UnsupportedValueOperationException(getType(), Operation.REG_EXPR); - } - - /** - * Returns the negation (numeric or logical) of this value. This may refer to operator - or !, depending on type. - * - * @return a value that is the negation of this value - * @throws UnsupportedValueOperationException if this operator is unsupported for this value - */ - public Value negate() { // !, - - throw new UnsupportedValueOperationException(getType(), Operation.NEGATE); - } - - /** - * Returns the size of this value. Semantics depend on type. - * - * @return a size of this value - * @throws UnsupportedValueOperationException if this operation is unsupported for this value - */ - public Value valueSize() { - // name clash with size from List interface - throw new UnsupportedValueOperationException(getType(), Operation.VALUE_SIZE); - } - - /** - * Returns this value converted to another type. - * - * @param to a desired type - * @return this value converted to the <code>type</code> - * @throws UnsupportedConversionException if a requested conversion is unsupported - */ - public abstract Value convertTo(Type to); - - /** - * Returns a textual representation of this value. This method uses conversion to <code>ValueString</code>. - * - * @return a textual representation of this value - * @see #convertTo(Type) - */ - @Override - public String toString() { - return ((ValueString)convertTo(TypePrimitive.STRING)).getValue(); - } - - /** - * Returns a default value (such as uninitialized variable). This may be <code>0</code> for integer types, - * <code>false</code> for boolean, <code>null</code> for complex types etc. - * - * @return a default value of this type - */ - public abstract Value getDefaultValue(); + /** + * An operation that may be performed on values. + */ + public enum Operation { + EQUAL, COMPARE, ADD, SUBTRACT, MULTIPLY, DIVIDE, MODULO, AND, OR, REG_EXPR, NEGATE, VALUE_SIZE, + } + + /** + * Gets the type of this value. + * + * @return type of this value + */ + public abstract Type getType(); + + /** + * Indicates whether this value is null. Distinct from a <code>Value</code> reference that is <code>null</code> + * itself. + * + * @return true if and only if this value is null + */ + public abstract boolean isNull(); + + protected final void sameTypesOrThrow(Value value, Operation operation) { + if(!getType().isCompatible(value.getType())) + throw new IncompatibleTypesException(getType(), value.getType(), operation); + } + + /** + * Checks whether this value is equal to the specified one (operator ==). + * + * @param value the right side of the operator + * @return a <code>ValueBoolean</code> representing true if and only if both values are equal + * @throws UnsupportedValueOperationException if this operation is unsupported for these values + */ + public Value isEqual(Value value) { + throw new UnsupportedValueOperationException(getType(), Operation.EQUAL); + } + + /** + * Indicates whether this object is equal to another one. + * + * @param object the object to check + * @return whether two objects are equal + */ + @Override + public boolean equals(Object object) { + if(!(object instanceof Value)) + return false; + return ((ValueBoolean)isEqual((Value)object)).getValue(); + } + + /** + * Checks whether this value is lower than the specified one (operator <=). + * + * @param value the right side of the operator + * @return a <code>ValueBoolean</code> representing true if and only if this value is lower than the provided one + * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example + * incompatible or non-numeric types) + */ + public Value isLowerThan(Value value) { + throw new UnsupportedValueOperationException(getType(), Operation.COMPARE); + } + + /** + * Returns a new value created by adding argument to this value (operator +). + * + * @param value the right side of the operator + * @return a sum of two values + * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example + * incompatible or non-numeric types) + */ + public Value addValue(Value value) { + // name clash with add from List interface + throw new UnsupportedValueOperationException(getType(), Operation.ADD); + } + + /** + * Returns a new value created by subtracting argument from this value (operator -). + * + * @param value the right side of the operator + * @return a difference of two values + * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example + * incompatible or non-numeric types) + */ + public Value subtract(Value value) { + throw new UnsupportedValueOperationException(getType(), Operation.SUBTRACT); + } + + /** + * Returns a new value created by multiplying this value by an argument (operator *). + * + * @param value the right side of the operator + * @return a product of two values + * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example + * incompatible or non-numeric types) + */ + public Value multiply(Value value) { + throw new UnsupportedValueOperationException(getType(), Operation.MULTIPLY); + } + + /** + * Returns a new value created by dividing this value by an argument (operator /). + * + * @param value the right side of the operator + * @return a quotient of two values + * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example + * incompatible or non-numeric types) + */ + public Value divide(Value value) { + throw new UnsupportedValueOperationException(getType(), Operation.DIVIDE); + } + + /** + * Returns the remainder of division of this value by an argument (operator %). + * + * @param value the right side of the operator + * @return a remainder + * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example + * incompatible or non-numeric types) + */ + public Value modulo(Value value) { + throw new UnsupportedValueOperationException(getType(), Operation.MODULO); + } + + /** + * Returns the result of a logical AND (operator &&). + * + * @param value the right side of the operator + * @return a conjunction of the two values + * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example + * non-boolean types) + */ + public Value and(Value value) { + throw new UnsupportedValueOperationException(getType(), Operation.AND); + } + + /** + * Returns the result of a logical OR (operator ||). + * + * @param value the right side of the operator + * @return an alternative of two values + * @throws UnsupportedValueOperationException if this operator is unsupported for these values (for example + * non-boolean types) + */ + public Value or(Value value) { + throw new UnsupportedValueOperationException(getType(), Operation.OR); + } + + /** + * Returns a result of trying to match to this value with a regular expression specified as an argument. + * + * @param value the regular expression to match against + * @return a <code>ValueBoolean</code> representing true if and only if this value matches provided regular + * expression + * @throws UnsupportedValueOperationException if this operator is unsupported for these values + */ + public Value regExpr(Value value) { + throw new UnsupportedValueOperationException(getType(), Operation.REG_EXPR); + } + + /** + * Returns the negation (numeric or logical) of this value. This may refer to operator - or !, depending on type. + * + * @return a value that is the negation of this value + * @throws UnsupportedValueOperationException if this operator is unsupported for this value + */ + public Value negate() { // !, - + throw new UnsupportedValueOperationException(getType(), Operation.NEGATE); + } + + /** + * Returns the size of this value. Semantics depend on type. + * + * @return a size of this value + * @throws UnsupportedValueOperationException if this operation is unsupported for this value + */ + public Value valueSize() { + // name clash with size from List interface + throw new UnsupportedValueOperationException(getType(), Operation.VALUE_SIZE); + } + + /** + * Returns this value converted to another type. + * + * @param to a desired type + * @return this value converted to the <code>type</code> + * @throws UnsupportedConversionException if a requested conversion is unsupported + */ + public abstract Value convertTo(Type to); + + /** + * Returns a textual representation of this value. This method uses conversion to <code>ValueString</code>. + * + * @return a textual representation of this value + * @see #convertTo(Type) + */ + @Override + public String toString() { + return ((ValueString)convertTo(TypePrimitive.STRING)).getValue(); + } + + /** + * Returns a default value (such as uninitialized variable). This may be <code>0</code> for integer types, + * <code>false</code> for boolean, <code>null</code> for complex types etc. + * + * @return a default value of this type + */ + public abstract Value getDefaultValue(); } diff --git a/src/pl/edu/mimuw/cloudatlas/model/ValueBoolean.java b/src/pl/edu/mimuw/cloudatlas/model/ValueBoolean.java index 1ca20fc..ba2b4f6 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/ValueBoolean.java +++ b/src/pl/edu/mimuw/cloudatlas/model/ValueBoolean.java @@ -31,63 +31,63 @@ import pl.edu.mimuw.cloudatlas.model.ValueBoolean; * A class that wraps a Java <code>Boolean</code> object. */ public class ValueBoolean extends ValueSimple<Boolean> { - /** - * Constructs a new <code>ValueBoolean</code> object wrapping the specified <code>value</code>. - * - * @param value the value to wrap - */ - public ValueBoolean(Boolean value) { - super(value); - } - - @Override - public Type getType() { - return TypePrimitive.BOOLEAN; - } - - @Override - public Value getDefaultValue() { - return new ValueBoolean(false); - } - - @Override - public ValueBoolean isLowerThan(Value value) { - sameTypesOrThrow(value, Operation.COMPARE); - if(isNull() || value.isNull()) - return new ValueBoolean(null); - return new ValueBoolean(!getValue() && ((ValueBoolean)value).getValue()); - } - - @Override - public ValueBoolean and(Value value) { - sameTypesOrThrow(value, Operation.AND); - if(isNull() || value.isNull()) - return new ValueBoolean(null); - return new ValueBoolean(getValue() && ((ValueBoolean)value).getValue()); - } - - @Override - public ValueBoolean or(Value value) { // - - sameTypesOrThrow(value, Operation.OR); - if(isNull() || value.isNull()) - return new ValueBoolean(null); - return new ValueBoolean(getValue() || ((ValueBoolean)value).getValue()); - } - - @Override - public ValueBoolean negate() { // ! - return new ValueBoolean(isNull()? null : !getValue()); - } - - @Override - public Value convertTo(Type type) { - switch(type.getPrimaryType()) { - case BOOLEAN: - return this; - case STRING: - return getValue() == null? ValueString.NULL_STRING : new ValueString(getValue().toString()); - default: - throw new UnsupportedConversionException(getType(), type); - } - } + /** + * Constructs a new <code>ValueBoolean</code> object wrapping the specified <code>value</code>. + * + * @param value the value to wrap + */ + public ValueBoolean(Boolean value) { + super(value); + } + + @Override + public Type getType() { + return TypePrimitive.BOOLEAN; + } + + @Override + public Value getDefaultValue() { + return new ValueBoolean(false); + } + + @Override + public ValueBoolean isLowerThan(Value value) { + sameTypesOrThrow(value, Operation.COMPARE); + if(isNull() || value.isNull()) + return new ValueBoolean(null); + return new ValueBoolean(!getValue() && ((ValueBoolean)value).getValue()); + } + + @Override + public ValueBoolean and(Value value) { + sameTypesOrThrow(value, Operation.AND); + if(isNull() || value.isNull()) + return new ValueBoolean(null); + return new ValueBoolean(getValue() && ((ValueBoolean)value).getValue()); + } + + @Override + public ValueBoolean or(Value value) { // - + sameTypesOrThrow(value, Operation.OR); + if(isNull() || value.isNull()) + return new ValueBoolean(null); + return new ValueBoolean(getValue() || ((ValueBoolean)value).getValue()); + } + + @Override + public ValueBoolean negate() { // ! + return new ValueBoolean(isNull()? null : !getValue()); + } + + @Override + public Value convertTo(Type type) { + switch(type.getPrimaryType()) { + case BOOLEAN: + return this; + case STRING: + return getValue() == null? ValueString.NULL_STRING : new ValueString(getValue().toString()); + default: + throw new UnsupportedConversionException(getType(), type); + } + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/ValueContact.java b/src/pl/edu/mimuw/cloudatlas/model/ValueContact.java index 5101d17..670a025 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/ValueContact.java +++ b/src/pl/edu/mimuw/cloudatlas/model/ValueContact.java @@ -36,65 +36,65 @@ import pl.edu.mimuw.cloudatlas.model.ValueContact; * This class is immutable. */ public class ValueContact extends Value { - private final PathName name; - private final InetAddress address; - - /** - * Constructs a new <code>ValueContact</code> with the specified path name and IP address. - * - * @param name the full path name of a node - * @param address the IP address of the node - */ - public ValueContact(PathName name, InetAddress address) { - this.name = name; - this.address = address; - } - - @Override - public Value getDefaultValue() { - return new ValueContact(null, null); - } - - /** - * Returns a name stored in this object. - * - * @return the name of a node - */ - public PathName getName() { - return name; - } - - /** - * Returns an IP address stored in this object. - * - * @return the IP address of a node - */ - public InetAddress getAddress() { - return address; - } - - @Override - public Type getType() { - return TypePrimitive.CONTACT; - } - - @Override - public Value convertTo(Type type) { - switch(type.getPrimaryType()) { - case CONTACT: - return this; - case STRING: - if(isNull()) - return ValueString.NULL_STRING; - else - return new ValueString("(" + name.toString() + ", " + address.toString() + ")"); - default: - throw new UnsupportedConversionException(getType(), type); - } - } - - @Override - public boolean isNull() { - return name == null || address == null; - } + private final PathName name; + private final InetAddress address; + + /** + * Constructs a new <code>ValueContact</code> with the specified path name and IP address. + * + * @param name the full path name of a node + * @param address the IP address of the node + */ + public ValueContact(PathName name, InetAddress address) { + this.name = name; + this.address = address; + } + + @Override + public Value getDefaultValue() { + return new ValueContact(null, null); + } + + /** + * Returns a name stored in this object. + * + * @return the name of a node + */ + public PathName getName() { + return name; + } + + /** + * Returns an IP address stored in this object. + * + * @return the IP address of a node + */ + public InetAddress getAddress() { + return address; + } + + @Override + public Type getType() { + return TypePrimitive.CONTACT; + } + + @Override + public Value convertTo(Type type) { + switch(type.getPrimaryType()) { + case CONTACT: + return this; + case STRING: + if(isNull()) + return ValueString.NULL_STRING; + else + return new ValueString("(" + name.toString() + ", " + address.toString() + ")"); + default: + throw new UnsupportedConversionException(getType(), type); + } + } + + @Override + public boolean isNull() { + return name == null || address == null; + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/ValueDouble.java b/src/pl/edu/mimuw/cloudatlas/model/ValueDouble.java index b979f5f..920a8ef 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/ValueDouble.java +++ b/src/pl/edu/mimuw/cloudatlas/model/ValueDouble.java @@ -31,81 +31,81 @@ import pl.edu.mimuw.cloudatlas.model.ValueDouble; * A class that wraps a Java <code>Double</code> object. */ public class ValueDouble extends ValueSimple<Double> { - /** - * Constructs a new <code>ValueDouble</code> object wrapping the specified <code>value</code>. - * - * @param value the value to wrap - */ - public ValueDouble(Double value) { - super(value); - } - - @Override - public Type getType() { - return TypePrimitive.DOUBLE; - } - - @Override - public Value getDefaultValue() { - return new ValueDouble(0.0); - } - - @Override - public ValueBoolean isLowerThan(Value value) { - sameTypesOrThrow(value, Operation.COMPARE); - if(isNull() || value.isNull()) - return new ValueBoolean(null); - return new ValueBoolean(getValue() < ((ValueDouble)value).getValue()); - } - - @Override - public ValueDouble addValue(Value value) { - sameTypesOrThrow(value, Operation.ADD); - if(isNull() || value.isNull()) - return new ValueDouble(null); - return new ValueDouble(getValue() + ((ValueDouble)value).getValue()); - } - - @Override - public ValueDouble subtract(Value value) { - sameTypesOrThrow(value, Operation.SUBTRACT); - if(isNull() || value.isNull()) - return new ValueDouble(null); - return new ValueDouble(getValue() - ((ValueDouble)value).getValue()); - } - - @Override - public ValueDouble multiply(Value value) { - sameTypesOrThrow(value, Operation.MULTIPLY); - if(isNull() || value.isNull()) - return new ValueDouble(null); - return new ValueDouble(getValue() * ((ValueDouble)value).getValue()); - } - - @Override - public ValueDouble divide(Value value) { - sameTypesOrThrow(value, Operation.DIVIDE); - if(isNull() || value.isNull()) - return new ValueDouble(null); - return new ValueDouble(getValue() / ((ValueDouble)value).getValue()); - } - - @Override - public ValueDouble negate() { - return new ValueDouble(isNull()? null : -getValue()); - } - - @Override - public Value convertTo(Type type) { - switch(type.getPrimaryType()) { - case DOUBLE: - return this; - case INT: - return new ValueInt(getValue() == null? null : getValue().longValue()); - case STRING: - return getValue() == null? ValueString.NULL_STRING : new ValueString(getValue().toString()); - default: - throw new UnsupportedConversionException(getType(), type); - } - } + /** + * Constructs a new <code>ValueDouble</code> object wrapping the specified <code>value</code>. + * + * @param value the value to wrap + */ + public ValueDouble(Double value) { + super(value); + } + + @Override + public Type getType() { + return TypePrimitive.DOUBLE; + } + + @Override + public Value getDefaultValue() { + return new ValueDouble(0.0); + } + + @Override + public ValueBoolean isLowerThan(Value value) { + sameTypesOrThrow(value, Operation.COMPARE); + if(isNull() || value.isNull()) + return new ValueBoolean(null); + return new ValueBoolean(getValue() < ((ValueDouble)value).getValue()); + } + + @Override + public ValueDouble addValue(Value value) { + sameTypesOrThrow(value, Operation.ADD); + if(isNull() || value.isNull()) + return new ValueDouble(null); + return new ValueDouble(getValue() + ((ValueDouble)value).getValue()); + } + + @Override + public ValueDouble subtract(Value value) { + sameTypesOrThrow(value, Operation.SUBTRACT); + if(isNull() || value.isNull()) + return new ValueDouble(null); + return new ValueDouble(getValue() - ((ValueDouble)value).getValue()); + } + + @Override + public ValueDouble multiply(Value value) { + sameTypesOrThrow(value, Operation.MULTIPLY); + if(isNull() || value.isNull()) + return new ValueDouble(null); + return new ValueDouble(getValue() * ((ValueDouble)value).getValue()); + } + + @Override + public ValueDouble divide(Value value) { + sameTypesOrThrow(value, Operation.DIVIDE); + if(isNull() || value.isNull()) + return new ValueDouble(null); + return new ValueDouble(getValue() / ((ValueDouble)value).getValue()); + } + + @Override + public ValueDouble negate() { + return new ValueDouble(isNull()? null : -getValue()); + } + + @Override + public Value convertTo(Type type) { + switch(type.getPrimaryType()) { + case DOUBLE: + return this; + case INT: + return new ValueInt(getValue() == null? null : getValue().longValue()); + case STRING: + return getValue() == null? ValueString.NULL_STRING : new ValueString(getValue().toString()); + default: + throw new UnsupportedConversionException(getType(), type); + } + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/ValueDuration.java b/src/pl/edu/mimuw/cloudatlas/model/ValueDuration.java index 12c2c73..c111d09 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/ValueDuration.java +++ b/src/pl/edu/mimuw/cloudatlas/model/ValueDuration.java @@ -30,144 +30,144 @@ package pl.edu.mimuw.cloudatlas.model; * <code>Long</code> object. */ public class ValueDuration extends ValueSimple<Long> { - /** - * Constructs a new <code>ValueDuration</code> object wrapping the specified <code>value</code>. - * - * @param value the value to wrap - */ - public ValueDuration(Long value) { - super(value); - } - - @Override - public Type getType() { - // TODO - throw new UnsupportedOperationException("Not yet implemented"); - } - - @Override - public Value getDefaultValue() { - // TODO - throw new UnsupportedOperationException("Not yet implemented"); - } - - /** - * Constructs a new <code>ValueDuration</code> object from the specified amounts of different time units. - * - * @param seconds a number of full seconds - * @param milliseconds a number of milliseconds (an absolute value does not have to be lower than 1000) - */ - public ValueDuration(long seconds, long milliseconds) { - this(seconds * 1000l + milliseconds); - } - - /** - * Constructs a new <code>ValueDuration</code> object from the specified amounts of different time units. - * - * @param minutes a number of full minutes - * @param seconds a number of full seconds (an absolute value does not have to be lower than 60) - * @param milliseconds a number of milliseconds (an absolute value does not have to be lower than 1000) - */ - public ValueDuration(long minutes, long seconds, long milliseconds) { - this(minutes * 60l + seconds, milliseconds); - } - - /** - * Constructs a new <code>ValueDuration</code> object from the specified amounts of different time units. - * - * @param hours a number of full hours - * @param minutes a number of full minutes (an absolute value does not have to be lower than 60) - * @param seconds a number of full seconds (an absolute value does not have to be lower than 60) - * @param milliseconds a number of milliseconds (an absolute value does not have to be lower than 1000) - */ - public ValueDuration(long hours, long minutes, long seconds, long milliseconds) { - this(hours * 60l + minutes, seconds, milliseconds); - } - - /** - * Constructs a new <code>ValueDuration</code> object from the specified amounts of different time units. - * - * @param days a number of full days - * @param hours a number of full hours (an absolute value does not have to be lower than 24) - * @param minutes a number of full minutes (an absolute value does not have to be lower than 60) - * @param seconds a number of full seconds (an absolute value does not have to be lower than 60) - * @param milliseconds a number of milliseconds (an absolute value does not have to be lower than 1000) - */ - public ValueDuration(long days, long hours, long minutes, long seconds, long milliseconds) { - this(days * 24l + hours, minutes, seconds, milliseconds); - } - - /** - * Constructs a new <code>ValueDuration</code> object from its textual representation. The representation has - * format: <code>sd hh:mm:ss.lll</code> where: - * <ul> - * <li><code>s</code> is a sign (<code>+</code> or <code>-</code>),</li> - * <li><code>d</code> is a number of days,</li> - * <li><code>hh</code> is a number of hours (between <code>00</code> and <code>23</code>),</li> - * <li><code>mm</code> is a number of minutes (between <code>00</code> and <code>59</code>),</li> - * <li><code>ss</code> is a number of seconds (between <code>00</code> and <code>59</code>),</li> - * <li><code>lll</code> is a number of milliseconds (between <code>000</code> and <code>999</code>).</li> - * </ul> - * <p> - * All fields are obligatory. - * - * @param value a textual representation of a duration - * @throws IllegalArgumentException if <code>value</code> does not meet described rules - */ - public ValueDuration(String value) { - this(parseDuration(value)); - } - - private static long parseDuration(String value) { - // TODO - throw new UnsupportedOperationException("Not yet implemented"); - } - - @Override - public ValueBoolean isLowerThan(Value value) { - // TODO - throw new UnsupportedOperationException("Not yet implemented"); - } - - @Override - public ValueDuration addValue(Value value) { - // TODO - throw new UnsupportedOperationException("Not yet implemented"); - } - - @Override - public ValueDuration subtract(Value value) { - // TODO - throw new UnsupportedOperationException("Not yet implemented"); - } - - @Override - public ValueDuration multiply(Value value) { - // TODO - throw new UnsupportedOperationException("Not yet implemented"); - } - - @Override - public Value divide(Value value) { - // TODO - throw new UnsupportedOperationException("Not yet implemented"); - } - - @Override - public ValueDuration modulo(Value value) { - // TODO - throw new UnsupportedOperationException("Not yet implemented"); - } - - @Override - public ValueDuration negate() { - // TODO - throw new UnsupportedOperationException("Not yet implemented"); - } - - @Override - public Value convertTo(Type type) { - // TODO - throw new UnsupportedOperationException("Not yet implemented"); - } + /** + * Constructs a new <code>ValueDuration</code> object wrapping the specified <code>value</code>. + * + * @param value the value to wrap + */ + public ValueDuration(Long value) { + super(value); + } + + @Override + public Type getType() { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public Value getDefaultValue() { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } + + /** + * Constructs a new <code>ValueDuration</code> object from the specified amounts of different time units. + * + * @param seconds a number of full seconds + * @param milliseconds a number of milliseconds (an absolute value does not have to be lower than 1000) + */ + public ValueDuration(long seconds, long milliseconds) { + this(seconds * 1000l + milliseconds); + } + + /** + * Constructs a new <code>ValueDuration</code> object from the specified amounts of different time units. + * + * @param minutes a number of full minutes + * @param seconds a number of full seconds (an absolute value does not have to be lower than 60) + * @param milliseconds a number of milliseconds (an absolute value does not have to be lower than 1000) + */ + public ValueDuration(long minutes, long seconds, long milliseconds) { + this(minutes * 60l + seconds, milliseconds); + } + + /** + * Constructs a new <code>ValueDuration</code> object from the specified amounts of different time units. + * + * @param hours a number of full hours + * @param minutes a number of full minutes (an absolute value does not have to be lower than 60) + * @param seconds a number of full seconds (an absolute value does not have to be lower than 60) + * @param milliseconds a number of milliseconds (an absolute value does not have to be lower than 1000) + */ + public ValueDuration(long hours, long minutes, long seconds, long milliseconds) { + this(hours * 60l + minutes, seconds, milliseconds); + } + + /** + * Constructs a new <code>ValueDuration</code> object from the specified amounts of different time units. + * + * @param days a number of full days + * @param hours a number of full hours (an absolute value does not have to be lower than 24) + * @param minutes a number of full minutes (an absolute value does not have to be lower than 60) + * @param seconds a number of full seconds (an absolute value does not have to be lower than 60) + * @param milliseconds a number of milliseconds (an absolute value does not have to be lower than 1000) + */ + public ValueDuration(long days, long hours, long minutes, long seconds, long milliseconds) { + this(days * 24l + hours, minutes, seconds, milliseconds); + } + + /** + * Constructs a new <code>ValueDuration</code> object from its textual representation. The representation has + * format: <code>sd hh:mm:ss.lll</code> where: + * <ul> + * <li><code>s</code> is a sign (<code>+</code> or <code>-</code>),</li> + * <li><code>d</code> is a number of days,</li> + * <li><code>hh</code> is a number of hours (between <code>00</code> and <code>23</code>),</li> + * <li><code>mm</code> is a number of minutes (between <code>00</code> and <code>59</code>),</li> + * <li><code>ss</code> is a number of seconds (between <code>00</code> and <code>59</code>),</li> + * <li><code>lll</code> is a number of milliseconds (between <code>000</code> and <code>999</code>).</li> + * </ul> + * <p> + * All fields are obligatory. + * + * @param value a textual representation of a duration + * @throws IllegalArgumentException if <code>value</code> does not meet described rules + */ + public ValueDuration(String value) { + this(parseDuration(value)); + } + + private static long parseDuration(String value) { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public ValueBoolean isLowerThan(Value value) { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public ValueDuration addValue(Value value) { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public ValueDuration subtract(Value value) { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public ValueDuration multiply(Value value) { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public Value divide(Value value) { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public ValueDuration modulo(Value value) { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public ValueDuration negate() { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public Value convertTo(Type type) { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/ValueInt.java b/src/pl/edu/mimuw/cloudatlas/model/ValueInt.java index d48532d..8811d57 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/ValueInt.java +++ b/src/pl/edu/mimuw/cloudatlas/model/ValueInt.java @@ -32,102 +32,102 @@ import pl.edu.mimuw.cloudatlas.model.ValueInt; * A class that wraps a Java <code>Long</code> object. */ public class ValueInt extends ValueSimple<Long> { - /** - * Constructs a new <code>ValueInt</code> object wrapping the specified <code>value</code>. - * - * @param value the value to wrap - */ - public ValueInt(Long value) { - super(value); - } - - @Override - public Type getType() { - return TypePrimitive.INTEGER; - } - - @Override - public Value getDefaultValue() { - return new ValueInt(0l); - } - - @Override - public ValueBoolean isLowerThan(Value value) { - sameTypesOrThrow(value, Operation.COMPARE); - if(isNull() || value.isNull()) - return new ValueBoolean(null); - return new ValueBoolean(getValue() < ((ValueInt)value).getValue()); - } - - @Override - public ValueInt addValue(Value value) { - sameTypesOrThrow(value, Operation.ADD); - if(isNull() || value.isNull()) - return new ValueInt(null); - return new ValueInt(getValue() + ((ValueInt)value).getValue()); - } - - @Override - public ValueInt subtract(Value value) { - sameTypesOrThrow(value, Operation.SUBTRACT); - if(isNull() || value.isNull()) - return new ValueInt(null); - return new ValueInt(getValue() - ((ValueInt)value).getValue()); - } - - @Override - public Value multiply(Value value) { - if(value.getType().getPrimaryType() == PrimaryType.DURATION) - return value.multiply(this); - sameTypesOrThrow(value, Operation.MULTIPLY); - if(isNull() || value.isNull()) - return new ValueInt(null); - return new ValueInt(getValue() * ((ValueInt)value).getValue()); - } - - @Override - public ValueDouble divide(Value value) { - sameTypesOrThrow(value, Operation.DIVIDE); - if(value.isNull()) - return new ValueDouble(null); - if(((ValueInt)value).getValue() == 0l) - throw new ArithmeticException("Division by zero."); - if(isNull()) - return new ValueDouble(null); - return new ValueDouble((double)getValue() / ((ValueInt)value).getValue()); - } - - @Override - public ValueInt modulo(Value value) { - sameTypesOrThrow(value, Operation.MODULO); - if(value.isNull()) - return new ValueInt(null); - if(((ValueInt)value).getValue() == 0l) - throw new ArithmeticException("Division by zero."); - if(isNull()) - return new ValueInt(null); - return new ValueInt(getValue() % ((ValueInt)value).getValue()); - } - - @Override - public ValueInt negate() { - return new ValueInt(isNull()? null : -getValue()); - } - - @Override - public Value convertTo(Type type) { - switch(type.getPrimaryType()) { - case DOUBLE: - return new ValueDouble(getValue() == null? null : getValue().doubleValue()); - case DURATION: - return new ValueDuration(getValue()); - case INT: - return this; - case STRING: - return getValue() == null? ValueString.NULL_STRING : new ValueString(Long.toString(getValue() - .longValue())); - default: - throw new UnsupportedConversionException(getType(), type); - } - } + /** + * Constructs a new <code>ValueInt</code> object wrapping the specified <code>value</code>. + * + * @param value the value to wrap + */ + public ValueInt(Long value) { + super(value); + } + + @Override + public Type getType() { + return TypePrimitive.INTEGER; + } + + @Override + public Value getDefaultValue() { + return new ValueInt(0l); + } + + @Override + public ValueBoolean isLowerThan(Value value) { + sameTypesOrThrow(value, Operation.COMPARE); + if(isNull() || value.isNull()) + return new ValueBoolean(null); + return new ValueBoolean(getValue() < ((ValueInt)value).getValue()); + } + + @Override + public ValueInt addValue(Value value) { + sameTypesOrThrow(value, Operation.ADD); + if(isNull() || value.isNull()) + return new ValueInt(null); + return new ValueInt(getValue() + ((ValueInt)value).getValue()); + } + + @Override + public ValueInt subtract(Value value) { + sameTypesOrThrow(value, Operation.SUBTRACT); + if(isNull() || value.isNull()) + return new ValueInt(null); + return new ValueInt(getValue() - ((ValueInt)value).getValue()); + } + + @Override + public Value multiply(Value value) { + if(value.getType().getPrimaryType() == PrimaryType.DURATION) + return value.multiply(this); + sameTypesOrThrow(value, Operation.MULTIPLY); + if(isNull() || value.isNull()) + return new ValueInt(null); + return new ValueInt(getValue() * ((ValueInt)value).getValue()); + } + + @Override + public ValueDouble divide(Value value) { + sameTypesOrThrow(value, Operation.DIVIDE); + if(value.isNull()) + return new ValueDouble(null); + if(((ValueInt)value).getValue() == 0l) + throw new ArithmeticException("Division by zero."); + if(isNull()) + return new ValueDouble(null); + return new ValueDouble((double)getValue() / ((ValueInt)value).getValue()); + } + + @Override + public ValueInt modulo(Value value) { + sameTypesOrThrow(value, Operation.MODULO); + if(value.isNull()) + return new ValueInt(null); + if(((ValueInt)value).getValue() == 0l) + throw new ArithmeticException("Division by zero."); + if(isNull()) + return new ValueInt(null); + return new ValueInt(getValue() % ((ValueInt)value).getValue()); + } + + @Override + public ValueInt negate() { + return new ValueInt(isNull()? null : -getValue()); + } + + @Override + public Value convertTo(Type type) { + switch(type.getPrimaryType()) { + case DOUBLE: + return new ValueDouble(getValue() == null? null : getValue().doubleValue()); + case DURATION: + return new ValueDuration(getValue()); + case INT: + return this; + case STRING: + return getValue() == null? ValueString.NULL_STRING : new ValueString(Long.toString(getValue() + .longValue())); + default: + throw new UnsupportedConversionException(getType(), type); + } + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/ValueList.java b/src/pl/edu/mimuw/cloudatlas/model/ValueList.java index d914736..d60e896 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/ValueList.java +++ b/src/pl/edu/mimuw/cloudatlas/model/ValueList.java @@ -42,234 +42,234 @@ import pl.edu.mimuw.cloudatlas.model.ValueList; * <p> * All constructors expect type of elements stored in this list. This type is checked when adding elements to the list * and an <code>IllegalArgumentException</code> is thrown in case of error. - * + * * @see java.util.List */ public class ValueList extends ValueSimple<List<Value>> implements List<Value> { - private TypeCollection type; - - /** - * Creates a new <code>ValueList</code> containing all the elements in the specified list. - * - * @param value a list which content will be copied to this value - * @param elementType type of elements stored in this list - */ - public ValueList(List<Value> value, Type elementType) { - this(elementType); - if(value != null) - setValue(value); - } - - /** - * Creates an empty list. - * - * @param elementType type of elements stored in this list - */ - public ValueList(Type elementType) { - super(new ArrayList<Value>()); - type = new TypeCollection(Type.PrimaryType.LIST, elementType); - } - - @Override - public Type getType() { - return type; - } - - @Override - public Value getDefaultValue() { - return new ValueList(((TypeCollection)this.getType()).getElementType()); - } - - /** - * Gets a <code>List</code> containing all the objects stored in this value. Modifying a return value will cause an - * exception. - */ - @Override - public List<Value> getValue() { - return getList() == null? null : Collections.unmodifiableList(getList()); - } - - @Override - public ValueList addValue(Value value) { - sameTypesOrThrow(value, Operation.ADD); - if(isNull() || value.isNull()) - return new ValueList(null, ((TypeCollection)getType()).getElementType()); - List<Value> result = new ArrayList<Value>(getValue()); - result.addAll(((ValueList)value).getValue()); - return new ValueList(result, ((TypeCollection)getType()).getElementType()); - } - - @Override - public Value convertTo(Type type) { - switch(type.getPrimaryType()) { - case LIST: - if(getType().isCompatible(type)) - return this; - throw new UnsupportedConversionException(getType(), type); - case SET: - if(this.type.getElementType().isCompatible(((TypeCollection)type).getElementType())) { - if(this.isNull()) - return new ValueSet(null, this.type.getElementType()); - Set<Value> l = new HashSet<Value>(); - l.addAll(this); - return new ValueSet(l, this.type.getElementType()); - } - throw new UnsupportedConversionException(getType(), type); - case STRING: - return getValue() == null? ValueString.NULL_STRING : new ValueString(getValue().toString()); - default: - throw new UnsupportedConversionException(getType(), type); - } - } - - @Override - public ValueInt valueSize() { - return new ValueInt((getList() == null? null : (long)getList().size())); - } - - @Override - public void setValue(List<Value> list) { - if(list == null) - super.setValue(null); - else { - super.setValue(new ArrayList<Value>()); - for(Value e : list) - add(e); - } - } - - private List<Value> getList() { - return super.getValue(); - } - - private void checkElement(Value element) { - if(element == null) - throw new IllegalArgumentException("If you want to use null, create an object containing null instead."); - if(!type.getElementType().isCompatible(element.getType())) - throw new IllegalArgumentException("This list contains elements of type " - + type.getElementType().toString() + " only. Not compatibile with elements of type: " - + element.getType().toString()); - } - - @Override - public boolean add(Value e) { - checkElement(e); - return getList().add(e); - } - - @Override - public void add(int index, Value element) { - checkElement(element); - getList().add(index, element); - } - - @Override - public boolean addAll(Collection<? extends Value> c) { - for(Value e : c) - checkElement(e); - return getList().addAll(c); - } - - @Override - public boolean addAll(int index, Collection<? extends Value> c) { - for(Value e : c) - checkElement(e); - return getList().addAll(index, c); - } - - @Override - public void clear() { - getList().clear(); - } - - @Override - public boolean contains(Object o) { - return getList().contains(o); - } - - @Override - public boolean containsAll(Collection<?> c) { - return getList().containsAll(c); - } - - @Override - public Value get(int index) { - return getList().get(index); - } - - @Override - public int indexOf(Object o) { - return getList().indexOf(o); - } - - @Override - public boolean isEmpty() { - return getList().isEmpty(); - } - - @Override - public Iterator<Value> iterator() { - return getList().iterator(); - } - - @Override - public int lastIndexOf(Object o) { - return getList().lastIndexOf(o); - } - - @Override - public ListIterator<Value> listIterator() { - return getList().listIterator(); - } - - @Override - public ListIterator<Value> listIterator(int index) { - return getList().listIterator(index); - } - - @Override - public boolean remove(Object o) { - return getList().remove(o); - } - - @Override - public Value remove(int index) { - return getList().remove(index); - } - - @Override - public boolean removeAll(Collection<?> c) { - return getList().removeAll(c); - } - - @Override - public boolean retainAll(Collection<?> c) { - return getList().retainAll(c); - } - - @Override - public Value set(int index, Value element) { - checkElement(element); - return getList().set(index, element); - } - - @Override - public int size() { - return getList().size(); - } - - @Override - public List<Value> subList(int fromIndex, int toIndex) { - return new ValueList(getList().subList(fromIndex, toIndex), type.getElementType()); - } - - @Override - public Object[] toArray() { - return getList().toArray(); - } - - @Override - public <Y> Y[] toArray(Y[] a) { - return getList().toArray(a); - } + private TypeCollection type; + + /** + * Creates a new <code>ValueList</code> containing all the elements in the specified list. + * + * @param value a list which content will be copied to this value + * @param elementType type of elements stored in this list + */ + public ValueList(List<Value> value, Type elementType) { + this(elementType); + if(value != null) + setValue(value); + } + + /** + * Creates an empty list. + * + * @param elementType type of elements stored in this list + */ + public ValueList(Type elementType) { + super(new ArrayList<Value>()); + type = new TypeCollection(Type.PrimaryType.LIST, elementType); + } + + @Override + public Type getType() { + return type; + } + + @Override + public Value getDefaultValue() { + return new ValueList(((TypeCollection)this.getType()).getElementType()); + } + + /** + * Gets a <code>List</code> containing all the objects stored in this value. Modifying a return value will cause an + * exception. + */ + @Override + public List<Value> getValue() { + return getList() == null? null : Collections.unmodifiableList(getList()); + } + + @Override + public ValueList addValue(Value value) { + sameTypesOrThrow(value, Operation.ADD); + if(isNull() || value.isNull()) + return new ValueList(null, ((TypeCollection)getType()).getElementType()); + List<Value> result = new ArrayList<Value>(getValue()); + result.addAll(((ValueList)value).getValue()); + return new ValueList(result, ((TypeCollection)getType()).getElementType()); + } + + @Override + public Value convertTo(Type type) { + switch(type.getPrimaryType()) { + case LIST: + if(getType().isCompatible(type)) + return this; + throw new UnsupportedConversionException(getType(), type); + case SET: + if(this.type.getElementType().isCompatible(((TypeCollection)type).getElementType())) { + if(this.isNull()) + return new ValueSet(null, this.type.getElementType()); + Set<Value> l = new HashSet<Value>(); + l.addAll(this); + return new ValueSet(l, this.type.getElementType()); + } + throw new UnsupportedConversionException(getType(), type); + case STRING: + return getValue() == null? ValueString.NULL_STRING : new ValueString(getValue().toString()); + default: + throw new UnsupportedConversionException(getType(), type); + } + } + + @Override + public ValueInt valueSize() { + return new ValueInt((getList() == null? null : (long)getList().size())); + } + + @Override + public void setValue(List<Value> list) { + if(list == null) + super.setValue(null); + else { + super.setValue(new ArrayList<Value>()); + for(Value e : list) + add(e); + } + } + + private List<Value> getList() { + return super.getValue(); + } + + private void checkElement(Value element) { + if(element == null) + throw new IllegalArgumentException("If you want to use null, create an object containing null instead."); + if(!type.getElementType().isCompatible(element.getType())) + throw new IllegalArgumentException("This list contains elements of type " + + type.getElementType().toString() + " only. Not compatibile with elements of type: " + + element.getType().toString()); + } + + @Override + public boolean add(Value e) { + checkElement(e); + return getList().add(e); + } + + @Override + public void add(int index, Value element) { + checkElement(element); + getList().add(index, element); + } + + @Override + public boolean addAll(Collection<? extends Value> c) { + for(Value e : c) + checkElement(e); + return getList().addAll(c); + } + + @Override + public boolean addAll(int index, Collection<? extends Value> c) { + for(Value e : c) + checkElement(e); + return getList().addAll(index, c); + } + + @Override + public void clear() { + getList().clear(); + } + + @Override + public boolean contains(Object o) { + return getList().contains(o); + } + + @Override + public boolean containsAll(Collection<?> c) { + return getList().containsAll(c); + } + + @Override + public Value get(int index) { + return getList().get(index); + } + + @Override + public int indexOf(Object o) { + return getList().indexOf(o); + } + + @Override + public boolean isEmpty() { + return getList().isEmpty(); + } + + @Override + public Iterator<Value> iterator() { + return getList().iterator(); + } + + @Override + public int lastIndexOf(Object o) { + return getList().lastIndexOf(o); + } + + @Override + public ListIterator<Value> listIterator() { + return getList().listIterator(); + } + + @Override + public ListIterator<Value> listIterator(int index) { + return getList().listIterator(index); + } + + @Override + public boolean remove(Object o) { + return getList().remove(o); + } + + @Override + public Value remove(int index) { + return getList().remove(index); + } + + @Override + public boolean removeAll(Collection<?> c) { + return getList().removeAll(c); + } + + @Override + public boolean retainAll(Collection<?> c) { + return getList().retainAll(c); + } + + @Override + public Value set(int index, Value element) { + checkElement(element); + return getList().set(index, element); + } + + @Override + public int size() { + return getList().size(); + } + + @Override + public List<Value> subList(int fromIndex, int toIndex) { + return new ValueList(getList().subList(fromIndex, toIndex), type.getElementType()); + } + + @Override + public Object[] toArray() { + return getList().toArray(); + } + + @Override + public <Y> Y[] toArray(Y[] a) { + return getList().toArray(a); + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/ValueNull.java b/src/pl/edu/mimuw/cloudatlas/model/ValueNull.java index e0c3f2a..60a53af 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/ValueNull.java +++ b/src/pl/edu/mimuw/cloudatlas/model/ValueNull.java @@ -29,127 +29,127 @@ import pl.edu.mimuw.cloudatlas.model.ValueNull; /** * A special null value of an unknown type introduced to deal with nulls. This class is a singleton. - * + * * @see TypePrimitve#NULL * @see Type#isCompatible(Value) */ public class ValueNull extends Value { - private static ValueNull instance = null; - - private ValueNull() {} - - /** - * Gets a singleton instance of a <code>ValueNull</code> class. Every call to this method returns the same - * reference. - * - * @return an instance of <code>ValueNull</code> - */ - public static ValueNull getInstance() { - if(instance == null) - instance = new ValueNull(); - return instance; - } - - @Override - public Value getDefaultValue() { - return instance; - } - - @Override - public Value convertTo(Type type) { - switch(type.getPrimaryType()) { - case STRING: - return ValueString.NULL_STRING; - default: - return this; - } - } - - @Override - public Type getType() { - return TypePrimitive.NULL; - } - - @Override - public boolean isNull() { - return true; - } - - @Override - public Value isEqual(Value value) { - return new ValueBoolean(isNull() && value.isNull()); - } - - @Override - public Value isLowerThan(Value value) { - if(value == getInstance()) - return this; - return value.isLowerThan(this); - } - - @Override - public Value addValue(Value value) { - if(value == getInstance()) - return this; - return value.addValue(this); - } - - @Override - public Value subtract(Value value) { - if(value == getInstance()) - return this; - return value.subtract(this); - } - - @Override - public Value multiply(Value value) { - if(value == getInstance()) - return this; - return value.multiply(this); - } - - @Override - public Value divide(Value value) { - if(value == getInstance()) - return this; - return value.divide(this); - } - - @Override - public Value modulo(Value value) { - if(value == getInstance()) - return this; - return value.modulo(this); - } - - @Override - public Value and(Value value) { - if(value == getInstance()) - return this; - return value.and(this); - } - - @Override - public Value or(Value value) { - if(value == getInstance()) - return this; - return value.or(this); - } - - @Override - public Value regExpr(Value value) { - if(value == getInstance()) - return this; - return value.regExpr(this); - } - - @Override - public Value negate() { - return this; - } - - @Override - public Value valueSize() { - return this; - } + private static ValueNull instance = null; + + private ValueNull() {} + + /** + * Gets a singleton instance of a <code>ValueNull</code> class. Every call to this method returns the same + * reference. + * + * @return an instance of <code>ValueNull</code> + */ + public static ValueNull getInstance() { + if(instance == null) + instance = new ValueNull(); + return instance; + } + + @Override + public Value getDefaultValue() { + return instance; + } + + @Override + public Value convertTo(Type type) { + switch(type.getPrimaryType()) { + case STRING: + return ValueString.NULL_STRING; + default: + return this; + } + } + + @Override + public Type getType() { + return TypePrimitive.NULL; + } + + @Override + public boolean isNull() { + return true; + } + + @Override + public Value isEqual(Value value) { + return new ValueBoolean(isNull() && value.isNull()); + } + + @Override + public Value isLowerThan(Value value) { + if(value == getInstance()) + return this; + return value.isLowerThan(this); + } + + @Override + public Value addValue(Value value) { + if(value == getInstance()) + return this; + return value.addValue(this); + } + + @Override + public Value subtract(Value value) { + if(value == getInstance()) + return this; + return value.subtract(this); + } + + @Override + public Value multiply(Value value) { + if(value == getInstance()) + return this; + return value.multiply(this); + } + + @Override + public Value divide(Value value) { + if(value == getInstance()) + return this; + return value.divide(this); + } + + @Override + public Value modulo(Value value) { + if(value == getInstance()) + return this; + return value.modulo(this); + } + + @Override + public Value and(Value value) { + if(value == getInstance()) + return this; + return value.and(this); + } + + @Override + public Value or(Value value) { + if(value == getInstance()) + return this; + return value.or(this); + } + + @Override + public Value regExpr(Value value) { + if(value == getInstance()) + return this; + return value.regExpr(this); + } + + @Override + public Value negate() { + return this; + } + + @Override + public Value valueSize() { + return this; + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/ValueSet.java b/src/pl/edu/mimuw/cloudatlas/model/ValueSet.java index c91374d..7f4968b 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/ValueSet.java +++ b/src/pl/edu/mimuw/cloudatlas/model/ValueSet.java @@ -41,192 +41,192 @@ import pl.edu.mimuw.cloudatlas.model.ValueSet; * <p> * All constructors expect type of elements stored in this set. This type is checked when adding elements to the set and * an <code>IllegalArgumentException</code> is thrown in case of error. - * + * * @see java.util.Set */ public class ValueSet extends ValueSimple<Set<Value>> implements Set<Value> { - private TypeCollection type; - - /** - * Creates a new <code>ValueSet</code> containing all the elements in the specified set. - * - * @param value a set which content will be copied to this value - * @param elementType type of elements stored in this set - */ - public ValueSet(Set<Value> value, Type elementType) { - this(elementType); - if(value != null) - setValue(value); - } - - /** - * Creates an empty set. - * - * @param elementType type of elements stored in this set - */ - public ValueSet(Type elementType) { - super(new HashSet<Value>()); - type = new TypeCollection(Type.PrimaryType.SET, elementType); - } - - @Override - public Type getType() { - return type; - } - - @Override - public Value getDefaultValue() { - return new ValueSet(((TypeCollection)this.getType()).getElementType()); - } - - /** - * Gets a <code>Set</code> containing all the objects stored in this value. Modifying a return value will cause an - * exception. - */ - @Override - public Set<Value> getValue() { - return getSet() == null? null : Collections.unmodifiableSet(getSet()); - } - - @Override - public ValueSet addValue(Value value) { - sameTypesOrThrow(value, Operation.ADD); - if(isNull() || value.isNull()) - return new ValueSet(null, ((TypeCollection)getType()).getElementType()); - Set<Value> result = new HashSet<Value>(getValue()); - result.addAll(((ValueSet)value).getValue()); - return new ValueSet(result, ((TypeCollection)getType()).getElementType()); - } - - @Override - public ValueInt valueSize() { - return new ValueInt((getSet() == null? null : (long)getSet().size())); - } - - @Override - public void setValue(Set<Value> set) { - if(set == null) - super.setValue(null); - else { - super.setValue(new HashSet<Value>()); - for(Value e : set) - add(e); - } - } - - private Set<Value> getSet() { - return super.getValue(); - } - - private void checkElement(Value element) { - if(element == null) - throw new IllegalArgumentException("If you want to use null, create an object containing null instead."); - if(!type.getElementType().isCompatible(element.getType())) - throw new IllegalArgumentException("This set contains elements of type " + type.getElementType().toString() - + " only. Not compatibile with elements of type: " + element.getType().toString()); - } - - @Override - public boolean add(Value e) { - checkElement(e); - return getSet().add(e); - } - - @Override - public boolean addAll(Collection<? extends Value> c) { - for(Value e : c) - checkElement(e); - return getSet().addAll(c); - } - - @Override - public void clear() { - getSet().clear(); - } - - @Override - public boolean contains(Object o) { - return getSet().contains(o); - } - - @Override - public boolean containsAll(Collection<?> c) { - return getSet().containsAll(c); - } - - @Override - public boolean isEmpty() { - return getSet().isEmpty(); - } - - @Override - public Iterator<Value> iterator() { - return getSet().iterator(); - } - - @Override - public boolean remove(Object o) { - return getSet().remove(o); - } - - @Override - public boolean removeAll(Collection<?> c) { - return getSet().removeAll(c); - } - - @Override - public boolean retainAll(Collection<?> c) { - return getSet().retainAll(c); - } - - @Override - public int size() { - return getSet().size(); - } - - @Override - public Object[] toArray() { - return getSet().toArray(); - } - - @Override - public <U> U[] toArray(U[] a) { - return getSet().toArray(a); - } - - @Override - public Value convertTo(Type type) { - switch(type.getPrimaryType()) { - case SET: - if(getType().isCompatible(type)) - return this; - throw new UnsupportedConversionException(getType(), type); - case LIST: - if(this.type.getElementType().isCompatible(((TypeCollection)type).getElementType())) { - if(this.isNull()) - return new ValueList(null, this.type.getElementType()); - List<Value> l = new ArrayList<Value>(); - l.addAll(this); - return new ValueList(l, this.type.getElementType()); - } - throw new UnsupportedConversionException(getType(), type); - case STRING: - if(getValue() == null) - return ValueString.NULL_STRING; - StringBuilder sb = new StringBuilder(); - sb.append("{"); - boolean notFirst = false; - for(Value v : getValue()) { - if(notFirst) { - sb.append(", "); - } else - notFirst = true; - sb.append(v.toString()); - } - sb.append("}"); - return new ValueString(sb.toString()); - default: - throw new UnsupportedConversionException(getType(), type); - } - } + private TypeCollection type; + + /** + * Creates a new <code>ValueSet</code> containing all the elements in the specified set. + * + * @param value a set which content will be copied to this value + * @param elementType type of elements stored in this set + */ + public ValueSet(Set<Value> value, Type elementType) { + this(elementType); + if(value != null) + setValue(value); + } + + /** + * Creates an empty set. + * + * @param elementType type of elements stored in this set + */ + public ValueSet(Type elementType) { + super(new HashSet<Value>()); + type = new TypeCollection(Type.PrimaryType.SET, elementType); + } + + @Override + public Type getType() { + return type; + } + + @Override + public Value getDefaultValue() { + return new ValueSet(((TypeCollection)this.getType()).getElementType()); + } + + /** + * Gets a <code>Set</code> containing all the objects stored in this value. Modifying a return value will cause an + * exception. + */ + @Override + public Set<Value> getValue() { + return getSet() == null? null : Collections.unmodifiableSet(getSet()); + } + + @Override + public ValueSet addValue(Value value) { + sameTypesOrThrow(value, Operation.ADD); + if(isNull() || value.isNull()) + return new ValueSet(null, ((TypeCollection)getType()).getElementType()); + Set<Value> result = new HashSet<Value>(getValue()); + result.addAll(((ValueSet)value).getValue()); + return new ValueSet(result, ((TypeCollection)getType()).getElementType()); + } + + @Override + public ValueInt valueSize() { + return new ValueInt((getSet() == null? null : (long)getSet().size())); + } + + @Override + public void setValue(Set<Value> set) { + if(set == null) + super.setValue(null); + else { + super.setValue(new HashSet<Value>()); + for(Value e : set) + add(e); + } + } + + private Set<Value> getSet() { + return super.getValue(); + } + + private void checkElement(Value element) { + if(element == null) + throw new IllegalArgumentException("If you want to use null, create an object containing null instead."); + if(!type.getElementType().isCompatible(element.getType())) + throw new IllegalArgumentException("This set contains elements of type " + type.getElementType().toString() + + " only. Not compatibile with elements of type: " + element.getType().toString()); + } + + @Override + public boolean add(Value e) { + checkElement(e); + return getSet().add(e); + } + + @Override + public boolean addAll(Collection<? extends Value> c) { + for(Value e : c) + checkElement(e); + return getSet().addAll(c); + } + + @Override + public void clear() { + getSet().clear(); + } + + @Override + public boolean contains(Object o) { + return getSet().contains(o); + } + + @Override + public boolean containsAll(Collection<?> c) { + return getSet().containsAll(c); + } + + @Override + public boolean isEmpty() { + return getSet().isEmpty(); + } + + @Override + public Iterator<Value> iterator() { + return getSet().iterator(); + } + + @Override + public boolean remove(Object o) { + return getSet().remove(o); + } + + @Override + public boolean removeAll(Collection<?> c) { + return getSet().removeAll(c); + } + + @Override + public boolean retainAll(Collection<?> c) { + return getSet().retainAll(c); + } + + @Override + public int size() { + return getSet().size(); + } + + @Override + public Object[] toArray() { + return getSet().toArray(); + } + + @Override + public <U> U[] toArray(U[] a) { + return getSet().toArray(a); + } + + @Override + public Value convertTo(Type type) { + switch(type.getPrimaryType()) { + case SET: + if(getType().isCompatible(type)) + return this; + throw new UnsupportedConversionException(getType(), type); + case LIST: + if(this.type.getElementType().isCompatible(((TypeCollection)type).getElementType())) { + if(this.isNull()) + return new ValueList(null, this.type.getElementType()); + List<Value> l = new ArrayList<Value>(); + l.addAll(this); + return new ValueList(l, this.type.getElementType()); + } + throw new UnsupportedConversionException(getType(), type); + case STRING: + if(getValue() == null) + return ValueString.NULL_STRING; + StringBuilder sb = new StringBuilder(); + sb.append("{"); + boolean notFirst = false; + for(Value v : getValue()) { + if(notFirst) { + sb.append(", "); + } else + notFirst = true; + sb.append(v.toString()); + } + sb.append("}"); + return new ValueString(sb.toString()); + default: + throw new UnsupportedConversionException(getType(), type); + } + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/ValueSimple.java b/src/pl/edu/mimuw/cloudatlas/model/ValueSimple.java index 76d9062..94d9abd 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/ValueSimple.java +++ b/src/pl/edu/mimuw/cloudatlas/model/ValueSimple.java @@ -28,62 +28,62 @@ package pl.edu.mimuw.cloudatlas.model; * Convenient class for wrapping Java types into <code>Value</code> objects. * <p> * This class is immutable. - * + * * @param <T> a wrapped type */ abstract class ValueSimple<T> extends Value { - private T value; - - /** - * Constructs a new <code>Value</code> wrapping the specified <code>value</code>. - * - * @param value the value to wrap - */ - public ValueSimple(T value) { - setValue(value); - } - - /** - * Returns a hash code value for this object. This is a hash code of underlying wrapped object. - * - * @return the hash code for this value - */ - @Override - public int hashCode() { - return getValue().hashCode(); - } - - /** - * Gets a wrapped object. - * - * @return the wrapped value - */ - public T getValue() { - return value; - } - - /** - * Sets a wrapped value. This method is not public to ensure that the underlying value cannot be changed. - * - * @param value the value to set - */ - void setValue(T value) { - this.value = value; - } - - @Override - public boolean isNull() { - return value == null; - } - - @SuppressWarnings("unchecked") - @Override - public Value isEqual(Value v) { - sameTypesOrThrow(v, Operation.EQUAL); - if(isNull() && v.isNull()) - return new ValueBoolean(true); - else if(isNull() || v.isNull()) - return new ValueBoolean(false); - return new ValueBoolean(value.equals(((ValueSimple<T>)v).getValue())); - } + private T value; + + /** + * Constructs a new <code>Value</code> wrapping the specified <code>value</code>. + * + * @param value the value to wrap + */ + public ValueSimple(T value) { + setValue(value); + } + + /** + * Returns a hash code value for this object. This is a hash code of underlying wrapped object. + * + * @return the hash code for this value + */ + @Override + public int hashCode() { + return getValue().hashCode(); + } + + /** + * Gets a wrapped object. + * + * @return the wrapped value + */ + public T getValue() { + return value; + } + + /** + * Sets a wrapped value. This method is not public to ensure that the underlying value cannot be changed. + * + * @param value the value to set + */ + void setValue(T value) { + this.value = value; + } + + @Override + public boolean isNull() { + return value == null; + } + + @SuppressWarnings("unchecked") + @Override + public Value isEqual(Value v) { + sameTypesOrThrow(v, Operation.EQUAL); + if(isNull() && v.isNull()) + return new ValueBoolean(true); + else if(isNull() || v.isNull()) + return new ValueBoolean(false); + return new ValueBoolean(value.equals(((ValueSimple<T>)v).getValue())); + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/ValueString.java b/src/pl/edu/mimuw/cloudatlas/model/ValueString.java index 34af8d1..e6fe9dd 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/ValueString.java +++ b/src/pl/edu/mimuw/cloudatlas/model/ValueString.java @@ -33,88 +33,88 @@ import pl.edu.mimuw.cloudatlas.model.ValueString; * A class that wraps a Java <code>String</code> object. */ public class ValueString extends ValueSimple<String> { - /** - * A result of conversion values representing null to <code>ValueString</code>. - */ - protected static final ValueString NULL_STRING = new ValueString("NULL"); - - /** - * Constructs a new <code>ValueString</code> object wrapping the specified <code>value</code>. - * - * @param value the value to wrap - */ - public ValueString(String value) { - super(value); - } - - @Override - public Type getType() { - return TypePrimitive.STRING; - } - - @Override - public Value getDefaultValue() { - return new ValueString(""); - } - - @Override - public ValueBoolean isLowerThan(Value value) { - sameTypesOrThrow(value, Operation.COMPARE); - if(isNull() || value.isNull()) - return new ValueBoolean(null); - return new ValueBoolean(getValue().compareTo(((ValueString)value).getValue()) < 0); - } - - @Override - public ValueString addValue(Value value) { - sameTypesOrThrow(value, Operation.ADD); - if(isNull() || value.isNull()) - return new ValueString(null); - return new ValueString(getValue().concat(((ValueString)value).getValue())); - } - - @Override - public ValueBoolean regExpr(Value value) { - sameTypesOrThrow(value, Operation.REG_EXPR); - if(isNull() || value.isNull()) - return new ValueBoolean(null); - return new ValueBoolean(getValue().matches(((ValueString)value).getValue())); - } - - @Override - public Value convertTo(Type type) { - switch(type.getPrimaryType()) { - case BOOLEAN: - return new ValueBoolean(Boolean.parseBoolean(getValue())); - case DOUBLE: - try { - return new ValueDouble(Double.parseDouble(getValue())); - } catch(NumberFormatException exception) { - return new ValueDouble(null); - } - case DURATION: - return new ValueDuration(getValue()); - case INT: - try { - return new ValueInt(Long.parseLong(getValue())); - } catch(NumberFormatException exception) { - return new ValueInt(null); - } - case STRING: - return getValue() == null? ValueString.NULL_STRING : this; - case TIME: - try { - return new ValueTime(getValue()); - } catch(ParseException exception) { - return new ValueTime((Long)null); - } - default: - throw new UnsupportedConversionException(getType(), type); - } - } - - @Override - public ValueInt valueSize() { - return new ValueInt(getValue() == null? null : (long)getValue().length()); - } + /** + * A result of conversion values representing null to <code>ValueString</code>. + */ + protected static final ValueString NULL_STRING = new ValueString("NULL"); + + /** + * Constructs a new <code>ValueString</code> object wrapping the specified <code>value</code>. + * + * @param value the value to wrap + */ + public ValueString(String value) { + super(value); + } + + @Override + public Type getType() { + return TypePrimitive.STRING; + } + + @Override + public Value getDefaultValue() { + return new ValueString(""); + } + + @Override + public ValueBoolean isLowerThan(Value value) { + sameTypesOrThrow(value, Operation.COMPARE); + if(isNull() || value.isNull()) + return new ValueBoolean(null); + return new ValueBoolean(getValue().compareTo(((ValueString)value).getValue()) < 0); + } + + @Override + public ValueString addValue(Value value) { + sameTypesOrThrow(value, Operation.ADD); + if(isNull() || value.isNull()) + return new ValueString(null); + return new ValueString(getValue().concat(((ValueString)value).getValue())); + } + + @Override + public ValueBoolean regExpr(Value value) { + sameTypesOrThrow(value, Operation.REG_EXPR); + if(isNull() || value.isNull()) + return new ValueBoolean(null); + return new ValueBoolean(getValue().matches(((ValueString)value).getValue())); + } + + @Override + public Value convertTo(Type type) { + switch(type.getPrimaryType()) { + case BOOLEAN: + return new ValueBoolean(Boolean.parseBoolean(getValue())); + case DOUBLE: + try { + return new ValueDouble(Double.parseDouble(getValue())); + } catch(NumberFormatException exception) { + return new ValueDouble(null); + } + case DURATION: + return new ValueDuration(getValue()); + case INT: + try { + return new ValueInt(Long.parseLong(getValue())); + } catch(NumberFormatException exception) { + return new ValueInt(null); + } + case STRING: + return getValue() == null? ValueString.NULL_STRING : this; + case TIME: + try { + return new ValueTime(getValue()); + } catch(ParseException exception) { + return new ValueTime((Long)null); + } + default: + throw new UnsupportedConversionException(getType(), type); + } + } + + @Override + public ValueInt valueSize() { + return new ValueInt(getValue() == null? null : (long)getValue().length()); + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/ValueTime.java b/src/pl/edu/mimuw/cloudatlas/model/ValueTime.java index f494757..0d4747d 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/ValueTime.java +++ b/src/pl/edu/mimuw/cloudatlas/model/ValueTime.java @@ -35,83 +35,83 @@ import pl.edu.mimuw.cloudatlas.model.ValueTime; * A class representing the POSIX time in milliseconds. This is a simple wrapper of a Java <code>Long</code> object. */ public class ValueTime extends ValueSimple<Long> { - /** - * A format of string representing <code>ValueTime</code> when constructing from or converting to a - * <code>String</code> object. - */ - public static final DateFormat TIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS"); - - /** - * Constructs a new <code>ValueTime</code> object wrapping the specified value. - * - * @param value the POSIX time - */ - public ValueTime(Long value) { - super(value); - } - - @Override - public Type getType() { - return TypePrimitive.TIME; - } - - @Override - public Value getDefaultValue() { - return new ValueTime(0l); - } - - /** - * Constructs a new <code>ValueTime</code> object from its textual representation. - * - * @param time a time formatted according to {@link #TIME_FORMAT} - * @throws ParseException if the <code>time</code> is incorrect - * @see #TIME_FORMAT - */ - public ValueTime(String time) throws ParseException { - this(TIME_FORMAT.parse(time).getTime()); - } - - @Override - public ValueBoolean isLowerThan(Value value) { - sameTypesOrThrow(value, Operation.COMPARE); - if(isNull() || value.isNull()) - return new ValueBoolean(null); - return new ValueBoolean(getValue() < ((ValueTime)value).getValue()); - } - - @Override - public ValueTime addValue(Value value) { - if(!value.getType().isCompatible(TypePrimitive.DURATION)) - throw new IncompatibleTypesException(getType(), value.getType(), Operation.ADD); - if(isNull() || value.isNull()) - return new ValueTime((Long)null); - return new ValueTime(getValue() + ((ValueDuration)value).getValue()); - } - - @Override - public Value subtract(Value value) { - if(value.getType().isCompatible(TypePrimitive.DURATION)) { - if(isNull() || value.isNull()) - return new ValueTime((Long)null); - return new ValueTime(getValue() - ((ValueDuration)value).getValue()); - } else if(value.getType().isCompatible(TypePrimitive.TIME)) { - if(isNull() || value.isNull()) - return new ValueTime((Long)null); - return new ValueDuration(getValue() - ((ValueTime)value).getValue()); - } - throw new IncompatibleTypesException(getType(), value.getType(), Operation.SUBTRACT); - - } - - @Override - public Value convertTo(Type type) { - switch(type.getPrimaryType()) { - case STRING: - return getValue() == null? ValueString.NULL_STRING : new ValueString(TIME_FORMAT.format(getValue())); - case TIME: - return this; - default: - throw new UnsupportedConversionException(getType(), type); - } - } + /** + * A format of string representing <code>ValueTime</code> when constructing from or converting to a + * <code>String</code> object. + */ + public static final DateFormat TIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS"); + + /** + * Constructs a new <code>ValueTime</code> object wrapping the specified value. + * + * @param value the POSIX time + */ + public ValueTime(Long value) { + super(value); + } + + @Override + public Type getType() { + return TypePrimitive.TIME; + } + + @Override + public Value getDefaultValue() { + return new ValueTime(0l); + } + + /** + * Constructs a new <code>ValueTime</code> object from its textual representation. + * + * @param time a time formatted according to {@link #TIME_FORMAT} + * @throws ParseException if the <code>time</code> is incorrect + * @see #TIME_FORMAT + */ + public ValueTime(String time) throws ParseException { + this(TIME_FORMAT.parse(time).getTime()); + } + + @Override + public ValueBoolean isLowerThan(Value value) { + sameTypesOrThrow(value, Operation.COMPARE); + if(isNull() || value.isNull()) + return new ValueBoolean(null); + return new ValueBoolean(getValue() < ((ValueTime)value).getValue()); + } + + @Override + public ValueTime addValue(Value value) { + if(!value.getType().isCompatible(TypePrimitive.DURATION)) + throw new IncompatibleTypesException(getType(), value.getType(), Operation.ADD); + if(isNull() || value.isNull()) + return new ValueTime((Long)null); + return new ValueTime(getValue() + ((ValueDuration)value).getValue()); + } + + @Override + public Value subtract(Value value) { + if(value.getType().isCompatible(TypePrimitive.DURATION)) { + if(isNull() || value.isNull()) + return new ValueTime((Long)null); + return new ValueTime(getValue() - ((ValueDuration)value).getValue()); + } else if(value.getType().isCompatible(TypePrimitive.TIME)) { + if(isNull() || value.isNull()) + return new ValueTime((Long)null); + return new ValueDuration(getValue() - ((ValueTime)value).getValue()); + } + throw new IncompatibleTypesException(getType(), value.getType(), Operation.SUBTRACT); + + } + + @Override + public Value convertTo(Type type) { + switch(type.getPrimaryType()) { + case STRING: + return getValue() == null? ValueString.NULL_STRING : new ValueString(TIME_FORMAT.format(getValue())); + case TIME: + return this; + default: + throw new UnsupportedConversionException(getType(), type); + } + } } diff --git a/src/pl/edu/mimuw/cloudatlas/model/ZMI.java b/src/pl/edu/mimuw/cloudatlas/model/ZMI.java index 0e1c852..3e3f3a2 100644 --- a/src/pl/edu/mimuw/cloudatlas/model/ZMI.java +++ b/src/pl/edu/mimuw/cloudatlas/model/ZMI.java @@ -35,132 +35,132 @@ import java.util.Map.Entry; * references to its father and sons in the tree. */ public class ZMI implements Cloneable { - private final AttributesMap attributes = new AttributesMap(); - - private final List<ZMI> sons = new ArrayList<ZMI>(); - private ZMI father; - - /** - * Creates a new ZMI with no father (the root zone) and empty sons list. - */ - public ZMI() { - this(null); - } - - /** - * Creates a new ZMI with the specified node as a father and empty sons list. This method does not perform any - * operation on the <code>father</code>. Especially, setting this object as a <code>father</code>'s son must be done - * separately. - * - * @param father a father of this ZMI - * @see #addSon(ZMI) - */ - public ZMI(ZMI father) { - this.father = father; - } - - /** - * Gets a father of this ZMI in a tree. - * - * @return a father of this ZMI or <code>null</code> if this is the root zone - */ - public ZMI getFather() { - return father; - } - - /** - * Sets or changes a father of this ZMI in a tree. This method does not perform any operation on the - * <code>father</code>. Especially, setting this object as a <code>father</code>'s son must be done separately. - * - * @param father a new father for this ZMI - * @see #addSon(ZMI) - */ - public void setFather(ZMI father) { - this.father = father; - } - - /** - * Gets a list of sons of this ZMI in a tree. Modifying a return value will cause an exception. - * - * @return - */ - public List<ZMI> getSons() { - return Collections.unmodifiableList(sons); - } - - /** - * Adds the specified ZMI to the list of sons of this ZMI. This method does not perform any operation on a - * <code>son</code>. Especially, setting this object as a <code>son</code>'s father must be done separately. - * - * @param son - * @see #ZMI(ZMI) - * @see #setFather(ZMI) - */ - public void addSon(ZMI son) { - sons.add(son); - } - - /** - * Removes the specified ZMI from the list of sons of this ZMI. This method does not perform any operation on a - * <code>son</code>. Especially, its father remains unchanged. - * - * @param son - * @see #setFather(ZMI) - */ - public void removeSon(ZMI son) { - sons.remove(son); - } - - /** - * Gets a map of all the attributes stored in this ZMI. - * - * @return map of attributes - */ - public AttributesMap getAttributes() { - return attributes; - } - - /** - * Prints recursively in a prefix order (starting from this ZMI) a whole tree with all the attributes. - * - * @param stream a destination stream - * @see #toString() - */ - public void printAttributes(PrintStream stream) { - for(Entry<Attribute, Value> entry : attributes) - stream.println(entry.getKey() + " : " + entry.getValue().getType() + " = " + entry.getValue()); - System.out.println(); - for(ZMI son : sons) - son.printAttributes(stream); - } - - /** - * Creates an independent copy of a whole hierarchy. A returned ZMI has the same reference as a father (but the - * father does not have a reference to it as a son). For the root zone, the copy is completely independent, since - * its father is <code>null</code>. - * - * @return a deep copy of this ZMI - */ - @Override - public ZMI clone() { - ZMI result = new ZMI(father); - result.attributes.add(attributes.clone()); - for(ZMI son : sons) { - ZMI sonClone = son.clone(); - result.sons.add(sonClone); - sonClone.father = result; - } - return result; - } - - /** - * Prints a textual representation of this ZMI. It contains only attributes of this node. - * - * @return a textual representation of this object - * @see #printAttributes(PrintStream) - */ - @Override - public String toString() { - return attributes.toString(); - } + private final AttributesMap attributes = new AttributesMap(); + + private final List<ZMI> sons = new ArrayList<ZMI>(); + private ZMI father; + + /** + * Creates a new ZMI with no father (the root zone) and empty sons list. + */ + public ZMI() { + this(null); + } + + /** + * Creates a new ZMI with the specified node as a father and empty sons list. This method does not perform any + * operation on the <code>father</code>. Especially, setting this object as a <code>father</code>'s son must be done + * separately. + * + * @param father a father of this ZMI + * @see #addSon(ZMI) + */ + public ZMI(ZMI father) { + this.father = father; + } + + /** + * Gets a father of this ZMI in a tree. + * + * @return a father of this ZMI or <code>null</code> if this is the root zone + */ + public ZMI getFather() { + return father; + } + + /** + * Sets or changes a father of this ZMI in a tree. This method does not perform any operation on the + * <code>father</code>. Especially, setting this object as a <code>father</code>'s son must be done separately. + * + * @param father a new father for this ZMI + * @see #addSon(ZMI) + */ + public void setFather(ZMI father) { + this.father = father; + } + + /** + * Gets a list of sons of this ZMI in a tree. Modifying a return value will cause an exception. + * + * @return + */ + public List<ZMI> getSons() { + return Collections.unmodifiableList(sons); + } + + /** + * Adds the specified ZMI to the list of sons of this ZMI. This method does not perform any operation on a + * <code>son</code>. Especially, setting this object as a <code>son</code>'s father must be done separately. + * + * @param son + * @see #ZMI(ZMI) + * @see #setFather(ZMI) + */ + public void addSon(ZMI son) { + sons.add(son); + } + + /** + * Removes the specified ZMI from the list of sons of this ZMI. This method does not perform any operation on a + * <code>son</code>. Especially, its father remains unchanged. + * + * @param son + * @see #setFather(ZMI) + */ + public void removeSon(ZMI son) { + sons.remove(son); + } + + /** + * Gets a map of all the attributes stored in this ZMI. + * + * @return map of attributes + */ + public AttributesMap getAttributes() { + return attributes; + } + + /** + * Prints recursively in a prefix order (starting from this ZMI) a whole tree with all the attributes. + * + * @param stream a destination stream + * @see #toString() + */ + public void printAttributes(PrintStream stream) { + for(Entry<Attribute, Value> entry : attributes) + stream.println(entry.getKey() + " : " + entry.getValue().getType() + " = " + entry.getValue()); + System.out.println(); + for(ZMI son : sons) + son.printAttributes(stream); + } + + /** + * Creates an independent copy of a whole hierarchy. A returned ZMI has the same reference as a father (but the + * father does not have a reference to it as a son). For the root zone, the copy is completely independent, since + * its father is <code>null</code>. + * + * @return a deep copy of this ZMI + */ + @Override + public ZMI clone() { + ZMI result = new ZMI(father); + result.attributes.add(attributes.clone()); + for(ZMI son : sons) { + ZMI sonClone = son.clone(); + result.sons.add(sonClone); + sonClone.father = result; + } + return result; + } + + /** + * Prints a textual representation of this ZMI. It contains only attributes of this node. + * + * @return a textual representation of this object + * @see #printAttributes(PrintStream) + */ + @Override + public String toString() { + return attributes.toString(); + } } |