package controller;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import util.Failure;
import db.Database;
import db.DatabaseAccessException;
import db.DatabaseConfiguration;
/**
* The class {@code Feature} represents one measured feature within the data record.
*/
public class Feature {
/**
* A unique identifier, set by the {@link Database}.
*/
private final int id;
/**
* The name of the {@code Feature}, shown in the UI.
*/
private String name;
/**
* The outlier flag of the {@code Feature}, shown in the UI.
*/
private final boolean outlier;
/**
* The flag indicates, that this {@code Feature} doesn't exist in database.
*/
private final boolean virtual;
/**
* Stores minimum value of all elements data for this feature.
*/
private final float min;
/**
* Stores maximum value of all elements data for this feature.
*/
private final float max;
/**
* The {@link Database}, where this {@code Feature} is stored.
*/
private final Database database;
/**
* The {@link SubspaceController} the {@link Subspace}, this {@code Feature} belongs to, is managed.
*/
private final SubspaceController subspaceController;
/**
* Constructs a new {@code Feature} with identifier and name.
*
* @param subspaceController
* the {@link SubspaceController} the {@link Subspace} ,this {@code Feature} belongs to, is managed. The
* information is used to trigger the right observer.
* @param database
* the {@link Database}, where this {@code Feature} is stored.
* @param id
* a not negative unique identifier.
* @param name
* the name of the {@code Feature}, may not be {@code null}.
* @param outlier
* the outlier flag of the {@code Feature}.
* @param virtual
* true, if the {@code Feature} doesn't exist in database.
* @param min
* minimum value of all elements data for this feature.
* @param max
* maximum value of all elements data for this feature.
*/
public Feature(SubspaceController subspaceController, Database database, int id, String name, boolean outlier,
boolean virtual, float min, float max) {
if (subspaceController == null || database == null || name == null
|| DatabaseConfiguration.VARCHARLENGTH < name.length()) {
throw new IllegalArgumentException("subspaceController, database, name is null or to long");
}
this.subspaceController = subspaceController;
this.database = database;
this.id = id;
this.name = name;
this.outlier = outlier;
this.virtual = virtual;
this.min = min;
this.max = max;
}
/**
* Returns the identifier of this {@code Feature}.
*
* @return the identifier.
*/
public int getId() {
return this.id;
}
/**
* Returns the name of this {@code Feature}.
*
* @return the name.
*/
public String getName() {
return this.name;
}
/**
* Returns true if this {@code Feature} is a outlier indicator.
*
* @return the outlier flag.
*/
public boolean isOutlier() {
return this.outlier;
}
/**
* Indicates if the {@code Feature} is virtual and doesn't exist in database.
*
* @return true, if it is virtual.
*/
public boolean isVirtual() {
return this.virtual;
}
/**
* Change the name of this {@code Feature}.
*
* @param name
* the new name, it may not be {@code null}.
* @throws DatabaseAccessException
* if write operation failed in {@link Database}.
*/
public void setName(String name) throws DatabaseAccessException {
if (name == null || DatabaseConfiguration.VARCHARLENGTH < name.length()) {
throw new IllegalArgumentException("name is null or to long");
}
// do not act on a virtual feature
if (this.id > 0) {
try {
PreparedStatement prepStmt = this.database.getConnection().prepareStatement(
"UPDATE Features SET Name=? WHERE Id=?;");
prepStmt.setString(1, name);
prepStmt.setInt(2, id);
prepStmt.execute();
prepStmt.close();
this.subspaceController.informObservers();
} catch (SQLException e) {
throw new DatabaseAccessException(Failure.WRITE);
}
}
this.name = name;
}
/**
* Returns the max length for a {@code String} handled by the {@code Database}.
*
* @return the max length.
*/
public int maxStringLength() {
return DatabaseConfiguration.VARCHARLENGTH;
}
/**
* Returns the max value emerging in this {@code Feature}. If the id of this {@code Feature} is negative, the value
* is get from {@link SubspaceController} {@code getEOMaxValue}.
*
* @return the max value.
*/
public float getMaxValue() {
if (this.id < 0) {
return this.subspaceController.getEOMaxValue();
} else {
return this.max;
}
}
/**
* Returns the min value emerging in this {@code Feature}. If the id of this {@code Feature} is negative, the value
* is get from {@link SubspaceController} {@code getEOMinValue}.
*
* @return the min value.
*/
public float getMinValue() {
if (this.id < 0) {
return this.subspaceController.getEOMinValue();
} else {
return this.min;
}
}
@Override
public String toString() {
return this.getName();
}
}