
edu.uvm.ccts.arden.model.AObject Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of arden-model Show documentation
Show all versions of arden-model Show documentation
The Java model used to represent Arden objects
/*
* Copyright 2015 The University of Vermont and State
* Agricultural College, Vermont Oxford Network, and The University
* of Vermont Medical Center. All rights reserved.
*
* Written by Matthew B. Storer
*
* This file is part of Arden Model.
*
* Arden Model is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Arden Model is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Arden Model. If not, see .
*/
package edu.uvm.ccts.arden.model;
import edu.uvm.ccts.common.exceptions.InvalidAttributeException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.util.*;
/**
* An Arden-object object
*
* An object results from use of the New statement (see Section 10.2.8), the read as statement (Section 11.2.2), the
* destination as statement (Section 11.2.9), or the message as statement (Section 11.2.7). It may contain multiple
* named attributes, each of which may contain any valid Arden type (including lists or objects). The latter capability
* allows for complex data structures to be manipulated by an MLM (lists within lists, for example) which would
* otherwise not be possible. Objects are also useful for interfacing MLMs with other object-oriented domain models
* (outside the scope of this document).
* @see 8.10
*/
public class AObject extends PrimaryTimeDataType {
private AObjectType type;
private Map map = new LinkedHashMap();
public AObject(AObjectType type) {
this.type = type;
for (String attribute : type.getAttributes()) {
map.put(attribute, new ANull());
}
}
public AObject(AObject ao) {
this.type = ao.type;
for (Map.Entry entry : ao.map.entrySet()) {
map.put(entry.getKey(), entry.getValue().copy());
}
}
@Override
public String toString() {
List list = new ArrayList();
for (Map.Entry entry : map.entrySet()) {
list.add(entry.getKey() + "=" + entry.getValue());
}
return type.getName() + "{" + StringUtils.join(list, ", ") + "}";
}
/**
* Compares this object to another as an identity comparison, in which the primary time of the objects are
* considered.
* @param o
* @return {@code true} if {@code this} and {@code o} have the same value and the same primary
* time.
*/
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (o == this) return true;
if (o.getClass() != getClass()) return false;
AObject ao = (AObject) o;
return new EqualsBuilder()
.append(type, ao.type)
.append(map, ao.map)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(109, 43)
.append(type)
.append(map)
.toHashCode();
}
/**
* Compares this object to another, considering only the value of the object, and not the primary time.
* @param o
* @return {@code true} if {@code this} and {@code o} have the same value.
*/
@Override
public boolean hasValue(ADataType o) {
if (o == null) return false;
if (o == this) return true;
if (o.getClass() != getClass()) return false;
AObject ao = (AObject) o;
if ( ! type.hasValue(ao.type) ) return false;
if (map.size() != ao.map.size()) return false;
if ( ! map.keySet().equals(ao.map.keySet()) ) return false;
for (String key : map.keySet()) {
if ( ! map.get(key).hasValue(ao.map.get(key)) ) return false;
}
return true;
}
@Override
public AObject copy() {
return new AObject(this);
}
@Override
public boolean hasPrimaryTime() {
return getPrimaryTime() != null;
}
/**
* If all the objects attributes refer to data items with primary times, and all those times are equivalent, then
* this time is returned as the time of the object. If an attribute contains a list, then the primary time of the
* object is not defined (returns {@code null}) since lists do not have a specific primary time.
* @see 9.17.2
* @return
*/
@Override
public Time getPrimaryTime() {
Time primaryTime = null;
for (ADataType obj : map.values()) {
Time t = obj.getPrimaryTime();
if (t == null) return null;
if (primaryTime == null) primaryTime = t;
else if ( ! t.hasValue(primaryTime) ) return null;
}
return primaryTime;
}
@Override
public Object toJavaObject() {
Map map = new LinkedHashMap();
for (Map.Entry entry : this.map.entrySet()) {
map.put(entry.getKey(), entry.getValue().toJavaObject());
}
return map;
}
public Set getAttributeNames() {
return map.keySet();
}
/**
* Sets the attributes of this object using a properly-ordered list to source the data. Attributes are set
* in the order in which they were defined: the first attribute defined gets the first value from the list, etc.
* @param attrValues
*/
public void populate(List attrValues) {
int i = 0;
for (Map.Entry entry : map.entrySet()) {
if (attrValues.size() > i) {
entry.setValue(attrValues.get(i));
i ++;
} else {
break;
}
}
}
/**
* Determines whether or not this object has an attribute with the specified name
* @param attrName
* @return {@code true} if this object has an attribute with the specified name; {@code false} otherwise.
*/
public boolean hasAttribute(String attrName) {
return map.containsKey(attrName);
}
/**
* Attempts to retrieve the named attribute of this object
* @param attrName
* @return
* @throws InvalidAttributeException if no such attribute exists on this object
*/
public ADataType getAttribute(String attrName) throws InvalidAttributeException {
if (map.containsKey(attrName)) {
return map.get(attrName);
} else {
throw new InvalidAttributeException("invalid attribute for " + type.getName() + " : " + attrName);
}
}
/**
* Attempts to set the named attribute to the specified object
* @param attrName
* @param obj
* @throws InvalidAttributeException if no such attribute exists on this object
*/
public void setAttribute(String attrName, ADataType obj) throws InvalidAttributeException {
if (map.containsKey(attrName)) {
map.put(attrName, obj);
} else {
throw new InvalidAttributeException("invalid attribute for " + type.getName() + " : " + attrName);
}
}
public ABoolean isType(AObjectType type) {
return new ABoolean(this.type.getClass().isInstance(type));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy