package controller; import gui.settings.Settings; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import util.Failure; import db.Database; import db.DatabaseAccessException; /** * The class {@code Subspace} represents a defined set of {@link Feature}s. */ public class Subspace { /** * A unique identifier for this {@code Subspace}, set by the {@link Database}. */ private final int id; /** * The name of this {@code Subspace}. */ private final String name; /** * The list of feature ids belonging to this {@code Subspace}. */ private final Integer[] featureIds; /** * The {@link Database}, where the features are stored. */ private final Database database; /** * The {@link SubspaceController} this {@code Subspace} is managed. */ private final SubspaceController subspaceController; /** * Constructs a new {@code Subspace}. * * @param subspaceController * the {@link SubspaceController} this {@code Subspace} is managed. * @param database * the {@link Database}, where the {@link Feature}s are stored. * @param id * a not negative unique identifier. * @param name * the name of this {@code Subspace}. * @param featureIds * the feature ids belonging to this {@code Subspace}, it may not be {@code null}. */ public Subspace(SubspaceController subspaceController, Database database, int id, String name, Integer[] featureIds) { if (subspaceController == null || database == null || id < 0 || featureIds == null || name == null) { throw new IllegalArgumentException("id is negative, features or name is null"); } this.subspaceController = subspaceController; this.database = database; this.id = id; this.name = name; this.featureIds = featureIds; } /** * Returns the unique identifier of this {@code Subspace}. * * @return the identifier. */ public int getId() { return this.id; } /** * Returns the name of this {@code Subspace}. * * @return the name. */ public String getName() { return this.name; } /** * Returns a list of all {@link Feature}s, belonging to this {@code Subspace} and adds a virtual feature for the * effective outlierness at first position. * * @return the features. * @throws DatabaseAccessException * if read operation failed in {@link Database}. */ public Feature[] getFeatures() throws DatabaseAccessException { ResultSet rs = null; Feature[] features = new Feature[0]; if (featureIds.length > 0) { try { Statement stmt = database.getConnection().createStatement(); rs = stmt.executeQuery("SELECT Name, OutlierFlag, Id, Min, Max FROM Features WHERE Id IN " + requiredFeatures(this.featureIds) + ";"); features = new Feature[featureIds.length + 1]; // add a feature for the effective outlierness features[0] = new Feature(this.subspaceController, this.database, -1, Settings.getInstance() .getResourceBundle().getString("effectOutlierness"), false, true, 0, 0); for (int i = 1; i <= features.length && rs.next(); ++i) { features[i] = new Feature(this.subspaceController, this.database, rs.getInt(3), rs.getString(1), rs.getBoolean(2), false, rs.getFloat("Min"), rs.getFloat("Max")); } stmt.close(); } catch (SQLException e) { throw new DatabaseAccessException(Failure.READ); } } return features; } /** * This method builds a String with all required features, to insert into the sql query. * * @param features * a list of features. * @return the build string. */ private String requiredFeatures(Integer[] features) { // SELECT * FROM Objects WHERE Id IN; // requiredFeatures has to be: "1", "3", "6", .. StringBuilder strB = new StringBuilder(); strB.append("("); for (int currentFeature : features) { strB.append(currentFeature); strB.append(','); } strB.deleteCharAt(strB.lastIndexOf(",")); strB.append(")"); String requiredFeatures = strB.toString(); return requiredFeatures; } @Override public String toString() { return this.getName(); } @Override public boolean equals(Object o) { return ((o instanceof Subspace) ? (((Subspace) o).getId() == this.id) : false); } }