package rocks.inspectit.shared.all.communication;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import javax.validation.constraints.NotNull;
import rocks.inspectit.shared.all.cmr.cache.IObjectSizes;
import rocks.inspectit.shared.all.indexing.IIndexQuery;
/**
* The {@link DefaultData} class is the base class for all data and value objects. Data objects are
* persisted on the CMR and can be requested from the interfaces. Value Objects on the other hand
* are only used as a transmission container from the Agent(s) to the CMR.
* <p>
* Every value object implementation needs to override the {@link #finalizeData()} method to return
* a data object which can be persisted.
* <p>
* Data objects are free to use the {@link #finalizeData()} method to generate some additional
* values (like the average).
*
* @author Patrice Bouillet
*
*/
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@NamedQuery(name = DefaultData.DELETE_FOR_PLATFORM_ID, query = "DELETE FROM DefaultData d WHERE d.platformIdent=:platformIdent")
public abstract class DefaultData implements Serializable, Sizeable {
/**
* The serial version UID.
*/
private static final long serialVersionUID = 5195625080367033147L;
/**
* Constant for deleteForPlatformId query.
*/
public static final String DELETE_FOR_PLATFORM_ID = "DefaultData.deleteForPlatformId";
/**
* The id of this instance (if persisted, otherwise <code>null</code>).
*/
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DEFAULT_DATA_SEQUENCE")
@SequenceGenerator(name = "DEFAULT_DATA_SEQUENCE", sequenceName = "DEFAULT_DATA_SEQUENCE")
private long id;
/**
* The unique identifier of the platform.
*/
private long platformIdent;
/**
* The unique identifier of the sensor type.
*/
private long sensorTypeIdent;
/**
* The timestamp which shows when this information was created on the Agent.
*/
@NotNull
private Timestamp timeStamp;
/**
* Default no-args constructor.
*/
public DefaultData() {
}
/**
* Constructor which accepts three parameters to initialize itself.
*
* @param timeStamp
* The timestamp.
* @param platformIdent
* The unique identifier of the platform.
* @param sensorTypeIdent
* The unique identifier of the sensor type.
*/
public DefaultData(Timestamp timeStamp, long platformIdent, long sensorTypeIdent) {
this.timeStamp = timeStamp;
this.platformIdent = platformIdent;
this.sensorTypeIdent = sensorTypeIdent;
}
/**
* Gets {@link #id}.
*
* @return {@link #id}
*/
public long getId() {
return id;
}
/**
* Sets {@link #id}.
*
* @param id
* New value for {@link #id}
*/
public void setId(long id) {
this.id = id;
}
/**
* Gets {@link #platformIdent}.
*
* @return {@link #platformIdent}
*/
public long getPlatformIdent() {
return platformIdent;
}
/**
* Sets {@link #platformIdent}.
*
* @param platformIdent
* New value for {@link #platformIdent}
*/
public void setPlatformIdent(long platformIdent) {
this.platformIdent = platformIdent;
}
/**
* Gets {@link #sensorTypeIdent}.
*
* @return {@link #sensorTypeIdent}
*/
public long getSensorTypeIdent() {
return sensorTypeIdent;
}
/**
* Sets {@link #sensorTypeIdent}.
*
* @param sensorTypeIdent
* New value for {@link #sensorTypeIdent}
*/
public void setSensorTypeIdent(long sensorTypeIdent) {
this.sensorTypeIdent = sensorTypeIdent;
}
/**
* Gets {@link #timeStamp}.
*
* @return {@link #timeStamp}
*/
public Timestamp getTimeStamp() {
return timeStamp;
}
/**
* Sets {@link #timeStamp}.
*
* @param timeStamp
* New value for {@link #timeStamp}
*/
public void setTimeStamp(Timestamp timeStamp) {
this.timeStamp = timeStamp;
}
/**
* This method has to be overridden by every implementation of a value object to return a
* {@link DefaultData} object which can be persisted.
*
* @return Returns a {@link DefaultData} object which can be persisted.
*/
public DefaultData finalizeData() {
return this;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = (prime * result) + (int) (id ^ (id >>> 32));
result = (prime * result) + (int) (platformIdent ^ (platformIdent >>> 32));
result = (prime * result) + (int) (sensorTypeIdent ^ (sensorTypeIdent >>> 32));
result = (prime * result) + ((timeStamp == null) ? 0 : timeStamp.hashCode());
return result;
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
DefaultData other = (DefaultData) obj;
if (id != other.id) {
return false;
}
if (platformIdent != other.platformIdent) {
return false;
}
if (sensorTypeIdent != other.sensorTypeIdent) {
return false;
}
if (timeStamp == null) {
if (other.timeStamp != null) {
return false;
}
} else if (!timeStamp.equals(other.timeStamp)) {
return false;
}
return true;
}
/**
* Returns the approximate size of the object in the memory in bytes.
*
* @param objectSizes
* Appropriate instance of {@link IObjectSizes} depending on the VM architecture.
* @return Approximate object size in bytes.
*/
@Override
public long getObjectSize(IObjectSizes objectSizes) {
return this.getObjectSize(objectSizes, true);
}
/**
* Returns the approximate size of the object in the memory in bytes.
* <p>
* This method needs to be overridden by all subclasses.
*
* @param objectSizes
* Appropriate instance of {@link IObjectSizes} depending on the VM architecture.
* @param doAlign
* Should the align of the bytes occur. Note that super classes objects should never
* align the result because the align occurs only one time per whole object.
* @return Approximate object size in bytes.
*/
@Override
public long getObjectSize(IObjectSizes objectSizes, boolean doAlign) {
long size = objectSizes.getSizeOfObjectHeader();
size += objectSizes.getPrimitiveTypesSize(1, 0, 0, 0, 3, 0);
size += objectSizes.getSizeOf(timeStamp);
if (doAlign) {
return objectSizes.alignTo8Bytes(size);
} else {
return size;
}
}
/**
* Returns if the object is complied with passed {@link IIndexQuery}. This method will only
* return true if the object data correspond to the searching parameters set in
* {@link IIndexQuery}.
*
* @param query
* Query to be check against.
* @return True if the object is complied with query, otherwise false.
*/
public boolean isQueryComplied(IIndexQuery query) {
if ((query.getObjectClasses() != null) && !query.getObjectClasses().contains(this.getClass())) {
return false;
}
if (query.getMinId() > id) {
return false;
}
if ((query.getPlatformIdent() != 0) && (query.getPlatformIdent() != platformIdent)) {
return false;
}
if ((query.getSensorTypeIdent() != 0) && (query.getSensorTypeIdent() != sensorTypeIdent)) {
return false;
}
if (!query.isInInterval(timeStamp)) {
return false;
}
if (!query.areAllRestrictionsFulfilled(this)) {
return false;
}
return true;
}
}