package importexport.exporting; import importexport.util.FileInfo; import importexport.util.InvalidFileException; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Arrays; import controller.DataHub; import controller.ElementData; import controller.Feature; import controller.SelectionController; import controller.Subspace; import controller.SubspaceController; import db.DatabaseAccessException; /** * Exporter provided an interface for exporting data into an arbitrary file format. */ public abstract class Exporter { /** * Says that file-write-stream gets flushed every 20th element */ protected static int FLASH_AT = 20; /** * {@link DataHub} accessing needed {@link ElementData} */ private final DataHub datahub; /** * {@link SelecitonController} which contains current selection. */ private final SelectionController selectionController; /** * {@link SubspaceController} for getting subspaces corresponded data. */ private final SubspaceController subspaceController; /** * {@link FileInfoInjector} which adds {@link FileInfo} */ private final FileInfoInjector injector; /** * Creates an concrete instance of an Exporter. * * @param dataHub * the preinitialized DataHub * @param selectionController * the preinitialized SelectionController * @param subspaceController * the preinitialized SubspaceController * @param concreteInjector * injector which injects {@link FileInfo} in newly created File. */ public Exporter(final DataHub dataHub, final SelectionController selectionController, final SubspaceController subspaceController, final FileInfoInjector concreteInjector) { if (dataHub == null || selectionController == null || subspaceController == null || concreteInjector == null) { throw new IllegalArgumentException(); } this.datahub = dataHub; this.selectionController = selectionController; this.subspaceController = subspaceController; this.injector = concreteInjector; } /** * Exports data of the current selection into an arbitrary supported file format. * * @param f * File which will containing the exported data. * @param woOutlierness * * @throws IOException * thrown if IO-Operation failed. * @throws InvalidFileException * threw if output file is in any case invalid. * @throws DatabaseAccessException * threw if access to database failed. */ public abstract void exportFile(final File f, final boolean woOutlierness) throws IOException, InvalidFileException, DatabaseAccessException; /** * Creates an adapted SSD-File by demand. * * @param f * new SSD-File reference. * @throws IOException * thrown if IO-Operation failed. * @throws DatabaseAccessException * threw if access to database failed. */ protected final void exportSSD(final File f) throws IOException, DatabaseAccessException { if (f == null) { throw new IllegalArgumentException(); } if (!f.exists()) { f.createNewFile(); } BufferedWriter bw = new BufferedWriter(new FileWriter(f)); Subspace[] subspaces = this.subspaceController.getSubspaces(); Feature[] curFeatures = subspaces[0].getFeatures(); int[] curSelection = this.selectionController.getSelection(); ElementData[] data = this.datahub.getData(); Integer[] featIDs = null; int beginOutliernesses = 0; for (Feature feat : curFeatures) { if (!feat.isOutlier()) { beginOutliernesses++; } } int loopTally = 0; for (int i = 1; i < subspaces.length; ++i) { Feature tmp = null; Integer[] featsOfSS = null; int noVirtFeats = 0; curFeatures = subspaces[i].getFeatures(); featIDs = new Integer[curFeatures.length]; for (int j = 0; j < featIDs.length; ++j) { tmp = curFeatures[j]; if (tmp != null && !tmp.isOutlier() && !tmp.isVirtual()) { featIDs[j] = tmp.getId(); } else { noVirtFeats++; } } //festsOfSS => current set of features in corresponding subspace. featsOfSS = new Integer[featIDs.length - noVirtFeats]; int x = 0; for (int j = 0; j < featIDs.length && x < featsOfSS.length; ++j, ++x) { if (featIDs[j] == null) { --x; continue; } featsOfSS[x] = featIDs[j] - 1; } bw.append("subspace " + (subspaces[i].getId() - 1) + " dimension = " + featsOfSS.length + " " + Arrays.deepToString(featsOfSS)); bw.newLine(); //you need to flush the buffer for successful export. if (++loopTally == FLASH_AT) { bw.flush(); loopTally = 0; } } bw.append("@data"); bw.newLine(); bw.flush(); curFeatures = subspaces[0].getFeatures(); for (int k = 0; k < subspaces.length - 1; ++k) { loopTally = 0; int newId = 0; if (selectionController.isSomethingSelected()) { for (int i : curSelection) { bw.append(newId++ + ";" + k + ";" + data[i - 1].getValue(curFeatures[beginOutliernesses + k])); bw.newLine(); if (++loopTally == 20) { loopTally = 0; bw.flush(); } } } else { for (ElementData d : data) { bw.append(newId++ + ";" + k + ";" + d.getValue(curFeatures[beginOutliernesses + k])); bw.newLine(); if (++loopTally == FLASH_AT) { loopTally = 0; bw.flush(); } } } bw.flush(); } bw.close(); } /** * Returns the used {@link Datahub}. * * @return currently used DataHub. */ protected final DataHub getDatahub() { return datahub; } /** * Returns the used {@link FileInfoInjector}. * * @return currently used FileInfoInjector. */ protected final FileInfoInjector getInjector() { return injector; } /** * Returns the used {@link SelectionController}. * * @return currently used SelectionController. */ protected final SelectionController getSelectionController() { return selectionController; } /** * Returns the used {@link SubspaceController}. * * @return currently used SubspaceController. */ protected final SubspaceController getSubspaceController() { return subspaceController; } }