diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/result')
63 files changed, 538 insertions, 533 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/result/AbstractHierarchicalResult.java b/src/de/lmu/ifi/dbs/elki/result/AbstractHierarchicalResult.java index 0eba9564..203e8395 100644 --- a/src/de/lmu/ifi/dbs/elki/result/AbstractHierarchicalResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/AbstractHierarchicalResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/AprioriResult.java b/src/de/lmu/ifi/dbs/elki/result/AprioriResult.java index 6b289f11..45e82b92 100644 --- a/src/de/lmu/ifi/dbs/elki/result/AprioriResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/AprioriResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/BasicResult.java b/src/de/lmu/ifi/dbs/elki/result/BasicResult.java index 0e3bc571..f2d10149 100644 --- a/src/de/lmu/ifi/dbs/elki/result/BasicResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/BasicResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/CollectionResult.java b/src/de/lmu/ifi/dbs/elki/result/CollectionResult.java index a43c6fd6..76e35e48 100644 --- a/src/de/lmu/ifi/dbs/elki/result/CollectionResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/CollectionResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/DBIDSelection.java b/src/de/lmu/ifi/dbs/elki/result/DBIDSelection.java index d504ecbc..97459a6a 100644 --- a/src/de/lmu/ifi/dbs/elki/result/DBIDSelection.java +++ b/src/de/lmu/ifi/dbs/elki/result/DBIDSelection.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java b/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java index 2499ff6a..847e22fb 100644 --- a/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java +++ b/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java b/src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java index 695ba1aa..28841ddf 100644 --- a/src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/HistogramResult.java b/src/de/lmu/ifi/dbs/elki/result/HistogramResult.java index 406eeffc..6e3fc745 100644 --- a/src/de/lmu/ifi/dbs/elki/result/HistogramResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/HistogramResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/IterableResult.java b/src/de/lmu/ifi/dbs/elki/result/IterableResult.java index b53b4bb0..e7a6f35c 100644 --- a/src/de/lmu/ifi/dbs/elki/result/IterableResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/IterableResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/KMLOutputHandler.java b/src/de/lmu/ifi/dbs/elki/result/KMLOutputHandler.java index 19a50b28..11391036 100644 --- a/src/de/lmu/ifi/dbs/elki/result/KMLOutputHandler.java +++ b/src/de/lmu/ifi/dbs/elki/result/KMLOutputHandler.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,7 +30,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; -import java.util.Iterator; import java.util.LinkedList; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -53,6 +52,7 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.ArrayListIter; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; @@ -64,6 +64,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; import de.lmu.ifi.dbs.elki.utilities.scaling.outlier.OutlierLinearScaling; import de.lmu.ifi.dbs.elki.utilities.scaling.outlier.OutlierScalingFunction; +import de.lmu.ifi.dbs.elki.workflow.OutputStep; /** * Class to handle KML output. @@ -130,10 +131,10 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { @Override public void processNewResult(HierarchicalResult baseResult, Result newResult) { ArrayList<OutlierResult> ors = ResultUtil.filterResults(newResult, OutlierResult.class); - if(ors.size() > 1) { + if (ors.size() > 1) { throw new AbortException("More than one outlier result found. The KML writer only supports a single outlier result!"); } - if(ors.size() == 1) { + if (ors.size() == 1) { Database database = ResultUtil.findDatabase(baseResult); try { XMLOutputFactory factory = XMLOutputFactory.newInstance(); @@ -146,27 +147,25 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { out.closeEntry(); out.flush(); out.close(); - if(autoopen) { + if (autoopen) { Desktop.getDesktop().open(filename); } - } - catch(XMLStreamException e) { + } catch (XMLStreamException e) { LOG.exception(e); throw new AbortException("XML error in KML output.", e); - } - catch(IOException e) { + } catch (IOException e) { LOG.exception(e); throw new AbortException("IO error in KML output.", e); } } } - private void writeKMLData(XMLStreamWriter out, OutlierResult outlierResult, Database database) throws XMLStreamException { + private void writeKMLData(XMLStreamWriter xmlw, OutlierResult outlierResult, Database database) throws XMLStreamException { Relation<Double> scores = outlierResult.getScores(); Relation<PolygonsObject> polys = database.getRelation(TypeUtil.POLYGON_TYPE); Relation<String> labels = DatabaseUtil.guessObjectLabelRepresentation(database); - Collection<Relation<?>> otherrel = new LinkedList<Relation<?>>(database.getRelations()); + Collection<Relation<?>> otherrel = new LinkedList<>(database.getRelations()); otherrel.remove(scores); otherrel.remove(polys); otherrel.remove(labels); @@ -176,130 +175,137 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { scaling.prepare(outlierResult); - out.writeStartDocument(); - out.writeCharacters("\n"); - out.writeStartElement("kml"); - out.writeDefaultNamespace("http://earth.google.com/kml/2.2"); - out.writeStartElement("Document"); + xmlw.writeStartDocument(); + xmlw.writeCharacters("\n"); + xmlw.writeStartElement("kml"); + xmlw.writeDefaultNamespace("http://earth.google.com/kml/2.2"); + xmlw.writeStartElement("Document"); { // TODO: can we automatically generate more helpful data here? - out.writeStartElement("name"); - out.writeCharacters("ELKI KML output for " + outlierResult.getLongName()); - out.writeEndElement(); // name - writeNewlineOnDebug(out); + xmlw.writeStartElement("name"); + xmlw.writeCharacters("ELKI KML output for " + outlierResult.getLongName()); + xmlw.writeEndElement(); // name + writeNewlineOnDebug(xmlw); // TODO: e.g. list the settings in the description? - out.writeStartElement("description"); - out.writeCharacters("ELKI KML output for " + outlierResult.getLongName()); - out.writeEndElement(); // description - writeNewlineOnDebug(out); + xmlw.writeStartElement("description"); + xmlw.writeCharacters("ELKI KML output for " + outlierResult.getLongName()); + xmlw.writeEndElement(); // description + writeNewlineOnDebug(xmlw); } { // TODO: generate styles from color scheme - for(int i = 0; i < NUMSTYLES; i++) { + for (int i = 0; i < NUMSTYLES; i++) { Color col = getColorForValue(i / (NUMSTYLES - 1.0)); - out.writeStartElement("Style"); - out.writeAttribute("id", "s" + i); - writeNewlineOnDebug(out); + xmlw.writeStartElement("Style"); + xmlw.writeAttribute("id", "s" + i); + writeNewlineOnDebug(xmlw); { - out.writeStartElement("LineStyle"); - out.writeStartElement("width"); - out.writeCharacters("0"); - out.writeEndElement(); // width + xmlw.writeStartElement("LineStyle"); + xmlw.writeStartElement("width"); + xmlw.writeCharacters("0"); + xmlw.writeEndElement(); // width - out.writeEndElement(); // LineStyle + xmlw.writeEndElement(); // LineStyle } - writeNewlineOnDebug(out); + writeNewlineOnDebug(xmlw); { - out.writeStartElement("PolyStyle"); - out.writeStartElement("color"); + xmlw.writeStartElement("PolyStyle"); + xmlw.writeStartElement("color"); // KML uses AABBGGRR format! - out.writeCharacters(String.format("%02x%02x%02x%02x", col.getAlpha(), col.getBlue(), col.getGreen(), col.getRed())); - out.writeEndElement(); // color + xmlw.writeCharacters(String.format("%02x%02x%02x%02x", col.getAlpha(), col.getBlue(), col.getGreen(), col.getRed())); + xmlw.writeEndElement(); // color // out.writeStartElement("fill"); // out.writeCharacters("1"); // Default 1 // out.writeEndElement(); // fill - out.writeStartElement("outline"); - out.writeCharacters("0"); - out.writeEndElement(); // outline - out.writeEndElement(); // PolyStyle + xmlw.writeStartElement("outline"); + xmlw.writeCharacters("0"); + xmlw.writeEndElement(); // outline + xmlw.writeEndElement(); // PolyStyle } - writeNewlineOnDebug(out); - out.writeEndElement(); // Style - writeNewlineOnDebug(out); + writeNewlineOnDebug(xmlw); + xmlw.writeEndElement(); // Style + writeNewlineOnDebug(xmlw); } } for (DBIDIter iter = outlierResult.getOrdering().iter(ids).iter(); iter.valid(); iter.advance()) { Double score = scores.get(iter); PolygonsObject poly = polys.get(iter); String label = labels.get(iter); - if(score == null) { + if (score == null) { LOG.warning("No score for object " + DBIDUtil.toString(iter)); } - if(poly == null) { + if (poly == null) { LOG.warning("No polygon for object " + DBIDUtil.toString(iter) + " - skipping."); continue; } - out.writeStartElement("Placemark"); + xmlw.writeStartElement("Placemark"); { - out.writeStartElement("name"); - out.writeCharacters(score + " " + label); - out.writeEndElement(); // name + xmlw.writeStartElement("name"); + xmlw.writeCharacters(score + " " + label); + xmlw.writeEndElement(); // name StringBuilder buf = makeDescription(otherrel, iter); - out.writeStartElement("description"); - out.writeCData("<div>" + buf.toString() + "</div>"); - out.writeEndElement(); // description - out.writeStartElement("styleUrl"); + xmlw.writeStartElement("description"); + xmlw.writeCData("<div>" + buf.toString() + "</div>"); + xmlw.writeEndElement(); // description + xmlw.writeStartElement("styleUrl"); int style = (int) (scaling.getScaled(score) * NUMSTYLES); style = Math.max(0, Math.min(style, NUMSTYLES - 1)); - out.writeCharacters("#s" + style); - out.writeEndElement(); // styleUrl + xmlw.writeCharacters("#s" + style); + xmlw.writeEndElement(); // styleUrl } { - out.writeStartElement("Polygon"); - writeNewlineOnDebug(out); - if(compat) { - out.writeStartElement("altitudeMode"); - out.writeCharacters("relativeToGround"); - out.writeEndElement(); // close altitude mode - writeNewlineOnDebug(out); + xmlw.writeStartElement("Polygon"); + writeNewlineOnDebug(xmlw); + if (compat) { + xmlw.writeStartElement("altitudeMode"); + xmlw.writeCharacters("relativeToGround"); + xmlw.writeEndElement(); // close altitude mode + writeNewlineOnDebug(xmlw); } // First polygon clockwise? boolean first = true; - for(Polygon p : poly.getPolygons()) { - if(first) { - out.writeStartElement("outerBoundaryIs"); - } - else { - out.writeStartElement("innerBoundaryIs"); + for (Polygon p : poly.getPolygons()) { + if (first) { + xmlw.writeStartElement("outerBoundaryIs"); + } else { + xmlw.writeStartElement("innerBoundaryIs"); } - out.writeStartElement("LinearRing"); - out.writeStartElement("coordinates"); + xmlw.writeStartElement("LinearRing"); + xmlw.writeStartElement("coordinates"); // Reverse anti-clockwise polygons. boolean reverse = (p.testClockwise() >= 0); - Iterator<Vector> it = reverse ? p.descendingIterator() : p.iterator(); - while(it.hasNext()) { - Vector v = it.next(); - out.writeCharacters(FormatUtil.format(v.getArrayRef(), ",")); - if(compat && (v.getDimensionality() == 2)) { - out.writeCharacters(",500"); + ArrayListIter<Vector> it = p.iter(); + if (reverse) { + it.seek(p.size() - 1); + } + while (it.valid()) { + Vector v = it.get(); + xmlw.writeCharacters(FormatUtil.format(v.getArrayRef(), ",")); + if (compat && (v.getDimensionality() == 2)) { + xmlw.writeCharacters(",500"); + } + xmlw.writeCharacters(" "); + if (!reverse) { + it.advance(); + } else { + it.retract(); } - out.writeCharacters(" "); } - out.writeEndElement(); // close coordinates - out.writeEndElement(); // close LinearRing - out.writeEndElement(); // close *BoundaryIs + xmlw.writeEndElement(); // close coordinates + xmlw.writeEndElement(); // close LinearRing + xmlw.writeEndElement(); // close *BoundaryIs first = false; } - writeNewlineOnDebug(out); - out.writeEndElement(); // Polygon + writeNewlineOnDebug(xmlw); + xmlw.writeEndElement(); // Polygon } - out.writeEndElement(); // Placemark - writeNewlineOnDebug(out); + xmlw.writeEndElement(); // Placemark + writeNewlineOnDebug(xmlw); } - out.writeEndElement(); // Document - out.writeEndElement(); // kml - out.writeEndDocument(); + xmlw.writeEndElement(); // Document + xmlw.writeEndElement(); // kml + xmlw.writeEndDocument(); } /** @@ -311,15 +317,15 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { */ private StringBuilder makeDescription(Collection<Relation<?>> relations, DBIDRef id) { StringBuilder buf = new StringBuilder(); - for(Relation<?> rel : relations) { + for (Relation<?> rel : relations) { Object o = rel.get(id); - if(o == null) { + if (o == null) { continue; } String s = o.toString(); // FIXME: strip html characters - if(s != null) { - if(buf.length() > 0) { + if (s != null) { + if (buf.length() > 0) { buf.append("<br />"); } buf.append(s); @@ -335,7 +341,7 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { * @throws XMLStreamException */ private void writeNewlineOnDebug(XMLStreamWriter out) throws XMLStreamException { - if(LOG.isDebugging()) { + if (LOG.isDebugging()) { out.writeCharacters("\n"); } } @@ -352,12 +358,12 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { // Colors at these positions Color[] cols = new Color[] { new Color(0.0f, 0.0f, 0.0f, 0.6f), new Color(0.0f, 0.0f, 1.0f, 0.8f), new Color(1.0f, 0.0f, 0.0f, 0.9f), new Color(1.0f, 1.0f, 0.0f, 1.0f) }; assert (pos.length == cols.length); - if(val < pos[0]) { + if (val < pos[0]) { val = pos[0]; } // Linear interpolation: - for(int i = 1; i < pos.length; i++) { - if(val <= pos[i]) { + for (int i = 1; i < pos.length; i++) { + if (val <= pos[i]) { Color prev = cols[i - 1]; Color next = cols[i]; final double mix = (val - pos[i - 1]) / (pos[i] - pos[i - 1]); @@ -430,24 +436,24 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); - FileParameter outputP = new FileParameter(OptionID.OUTPUT, FileParameter.FileType.OUTPUT_FILE); + FileParameter outputP = new FileParameter(OutputStep.Parameterizer.OUTPUT_ID, FileParameter.FileType.OUTPUT_FILE); outputP.setShortDescription("Filename the KMZ file (compressed KML) is written to."); - if(config.grab(outputP)) { + if (config.grab(outputP)) { filename = outputP.getValue(); } - ObjectParameter<OutlierScalingFunction> scalingP = new ObjectParameter<OutlierScalingFunction>(SCALING_ID, OutlierScalingFunction.class, OutlierLinearScaling.class); - if(config.grab(scalingP)) { + ObjectParameter<OutlierScalingFunction> scalingP = new ObjectParameter<>(SCALING_ID, OutlierScalingFunction.class, OutlierLinearScaling.class); + if (config.grab(scalingP)) { scaling = scalingP.instantiateClass(config); } Flag compatF = new Flag(COMPAT_ID); - if(config.grab(compatF)) { + if (config.grab(compatF)) { compat = compatF.getValue(); } Flag autoopenF = new Flag(AUTOOPEN_ID); - if(config.grab(autoopenF)) { + if (config.grab(autoopenF)) { autoopen = autoopenF.getValue(); } } @@ -457,4 +463,4 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { return new KMLOutputHandler(filename, scaling, compat, autoopen); } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/result/KNNDistanceOrderResult.java b/src/de/lmu/ifi/dbs/elki/result/KNNDistanceOrderResult.java index 0e5782bc..bbe21b0a 100644 --- a/src/de/lmu/ifi/dbs/elki/result/KNNDistanceOrderResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/KNNDistanceOrderResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java b/src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java index 61fae67a..4224ae0a 100644 --- a/src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java +++ b/src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -51,10 +51,10 @@ public class LogResultStructureResultHandler implements ResultHandler { @Override public void processNewResult(HierarchicalResult baseResult, Result newResult) { - if(LOG.isVerbose()) { - if(newResult instanceof HierarchicalResult) { + if (LOG.isVerbose()) { + if (newResult instanceof HierarchicalResult) { Hierarchy<Result> hier = ((HierarchicalResult) newResult).getHierarchy(); - if(hier != null) { + if (hier != null) { StringBuilder buf = new StringBuilder(); recursiveLogResult(buf, hier, newResult, 0); LOG.verbose(buf.toString()); @@ -71,24 +71,24 @@ public class LogResultStructureResultHandler implements ResultHandler { * @param depth Depth */ private void recursiveLogResult(StringBuilder buf, Hierarchy<Result> hier, Result result, int depth) { - if(result == null) { + if (result == null) { buf.append("null"); LOG.warning("null result!"); return; } - if(depth > 50) { + if (depth > 50) { LOG.warning("Probably infinitely nested results, aborting!"); return; } - for(int i = 0; i < depth; i++) { + for (int i = 0; i < depth; i++) { buf.append(" "); } buf.append(result.getClass().getSimpleName()).append(": ").append(result.getLongName()); buf.append(" (").append(result.getShortName()).append(")\n"); - if(hier.getChildren(result).size() > 0) { - for(Result r : hier.getChildren(result)) { - recursiveLogResult(buf, hier, r, depth + 1); + if (hier.numChildren(result) > 0) { + for (Hierarchy.Iter<Result> iter = hier.iterChildren(result); iter.valid(); iter.advance()) { + recursiveLogResult(buf, hier, iter.get(), depth + 1); } } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/result/OrderingFromDataStore.java b/src/de/lmu/ifi/dbs/elki/result/OrderingFromDataStore.java index 65713b11..74eb5323 100644 --- a/src/de/lmu/ifi/dbs/elki/result/OrderingFromDataStore.java +++ b/src/de/lmu/ifi/dbs/elki/result/OrderingFromDataStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/OrderingResult.java b/src/de/lmu/ifi/dbs/elki/result/OrderingResult.java index 8e4e9e5f..b3261e61 100644 --- a/src/de/lmu/ifi/dbs/elki/result/OrderingResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/OrderingResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/PixmapResult.java b/src/de/lmu/ifi/dbs/elki/result/PixmapResult.java index 776753e2..f6b4512b 100644 --- a/src/de/lmu/ifi/dbs/elki/result/PixmapResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/PixmapResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/RangeSelection.java b/src/de/lmu/ifi/dbs/elki/result/RangeSelection.java index f70c1771..b4cc092f 100644 --- a/src/de/lmu/ifi/dbs/elki/result/RangeSelection.java +++ b/src/de/lmu/ifi/dbs/elki/result/RangeSelection.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/ReferencePointsResult.java b/src/de/lmu/ifi/dbs/elki/result/ReferencePointsResult.java index 3964c418..92f59101 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ReferencePointsResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/ReferencePointsResult.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/Result.java b/src/de/lmu/ifi/dbs/elki/result/Result.java index ebd0bed1..99f68402 100644 --- a/src/de/lmu/ifi/dbs/elki/result/Result.java +++ b/src/de/lmu/ifi/dbs/elki/result/Result.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/ResultAdapter.java b/src/de/lmu/ifi/dbs/elki/result/ResultAdapter.java index be81a508..fa02b57b 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/ResultHandler.java b/src/de/lmu/ifi/dbs/elki/result/ResultHandler.java index 1fef628f..56e25d27 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultHandler.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultHandler.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java b/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java index 2aba395b..52b63d3b 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,12 +23,11 @@ package de.lmu.ifi.dbs.elki.result; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.List; - import javax.swing.event.EventListenerList; import de.lmu.ifi.dbs.elki.logging.Logging; -import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.HierarchyHashmapList; +import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.HashMapHierarchy; +import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy; import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.ModifiableHierarchy; /** @@ -37,12 +36,12 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.ModifiableHierarch * @author Erich Schubert */ // TODO: add listener merging! -public class ResultHierarchy extends HierarchyHashmapList<Result> { +public class ResultHierarchy extends HashMapHierarchy<Result> { /** * Logger */ private static final Logging LOG = Logging.getLogger(ResultHierarchy.class); - + /** * Holds the listener. */ @@ -58,15 +57,16 @@ public class ResultHierarchy extends HierarchyHashmapList<Result> { @Override public void add(Result parent, Result child) { super.add(parent, child); - if(child instanceof HierarchicalResult) { + if (child instanceof HierarchicalResult) { HierarchicalResult hr = (HierarchicalResult) child; ModifiableHierarchy<Result> h = hr.getHierarchy(); // Merge hierarchy hr.setHierarchy(this); // Add children of child - for(Result desc : h.getChildren(hr)) { + for (Hierarchy.Iter<Result> iter = h.iterChildren(hr); iter.valid(); iter.advance()) { + Result desc = iter.get(); this.add(hr, desc); - if(desc instanceof HierarchicalResult) { + if (desc instanceof HierarchicalResult) { ((HierarchicalResult) desc).setHierarchy(this); } } @@ -80,12 +80,6 @@ public class ResultHierarchy extends HierarchyHashmapList<Result> { fireResultRemoved(child, parent); } - @Override - public void put(Result obj, List<Result> parents, List<Result> children) { - // TODO: can we support this somehow? Or reduce visibility? - throw new UnsupportedOperationException(); - } - /** * Register a result listener. * @@ -120,10 +114,10 @@ public class ResultHierarchy extends HierarchyHashmapList<Result> { * @param parent Parent result that was added to */ private void fireResultAdded(Result child, Result parent) { - if(LOG.isDebugging()) { + if (LOG.isDebugging()) { LOG.debug("Result added: " + child + " <- " + parent); } - for(ResultListener l : listenerList.getListeners(ResultListener.class)) { + for (ResultListener l : listenerList.getListeners(ResultListener.class)) { l.resultAdded(child, parent); } } @@ -134,10 +128,10 @@ public class ResultHierarchy extends HierarchyHashmapList<Result> { * @param current Result that has changed */ private void fireResultChanged(Result current) { - if(LOG.isDebugging()) { + if (LOG.isDebugging()) { LOG.debug("Result changed: " + current); } - for(ResultListener l : listenerList.getListeners(ResultListener.class)) { + for (ResultListener l : listenerList.getListeners(ResultListener.class)) { l.resultChanged(current); } } @@ -150,11 +144,11 @@ public class ResultHierarchy extends HierarchyHashmapList<Result> { * @param parent Parent result that has been removed */ private void fireResultRemoved(Result child, Result parent) { - if(LOG.isDebugging()) { + if (LOG.isDebugging()) { LOG.debug("Result removed: " + child + " <- " + parent); } - for(ResultListener l : listenerList.getListeners(ResultListener.class)) { + for (ResultListener l : listenerList.getListeners(ResultListener.class)) { l.resultRemoved(child, parent); } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/result/ResultListener.java b/src/de/lmu/ifi/dbs/elki/result/ResultListener.java index d675af28..899aa008 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultListener.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultListener.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/ResultProcessor.java b/src/de/lmu/ifi/dbs/elki/result/ResultProcessor.java index 47273b89..88eb3607 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultProcessor.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultProcessor.java @@ -1,12 +1,10 @@ package de.lmu.ifi.dbs.elki.result; -import de.lmu.ifi.dbs.elki.utilities.InspectionUtilFrequentlyScanned; - /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,8 +23,6 @@ import de.lmu.ifi.dbs.elki.utilities.InspectionUtilFrequentlyScanned; along with this program. If not, see <http://www.gnu.org/licenses/>. */ - - /** * Interface for any class that can handle results * @@ -34,7 +30,7 @@ import de.lmu.ifi.dbs.elki.utilities.InspectionUtilFrequentlyScanned; * * @apiviz.uses Result oneway - - processes */ -public interface ResultProcessor extends InspectionUtilFrequentlyScanned { +public interface ResultProcessor { /** * Process a result. * diff --git a/src/de/lmu/ifi/dbs/elki/result/ResultUtil.java b/src/de/lmu/ifi/dbs/elki/result/ResultUtil.java index d081bc2e..e0e59482 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultUtil.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,7 +26,6 @@ package de.lmu.ifi.dbs.elki.result; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; import java.util.List; import de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm; @@ -38,6 +37,7 @@ import de.lmu.ifi.dbs.elki.database.Database; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy; /** * Utilities for handling result objects @@ -54,12 +54,12 @@ public class ResultUtil { * @return List of all annotation results */ public static List<Relation<?>> getRelations(Result r) { - if(r instanceof Relation<?>) { - List<Relation<?>> anns = new ArrayList<Relation<?>>(1); + if (r instanceof Relation<?>) { + List<Relation<?>> anns = new ArrayList<>(1); anns.add((Relation<?>) r); return anns; } - if(r instanceof HierarchicalResult) { + if (r instanceof HierarchicalResult) { return ClassGenericsUtil.castWithGenericsOrNull(List.class, filterResults((HierarchicalResult) r, Relation.class)); } return Collections.emptyList(); @@ -72,12 +72,12 @@ public class ResultUtil { * @return List of ordering results */ public static List<OrderingResult> getOrderingResults(Result r) { - if(r instanceof OrderingResult) { - List<OrderingResult> ors = new ArrayList<OrderingResult>(1); + if (r instanceof OrderingResult) { + List<OrderingResult> ors = new ArrayList<>(1); ors.add((OrderingResult) r); return ors; } - if(r instanceof HierarchicalResult) { + if (r instanceof HierarchicalResult) { return filterResults((HierarchicalResult) r, OrderingResult.class); } return Collections.emptyList(); @@ -90,12 +90,12 @@ public class ResultUtil { * @return List of clustering results */ public static List<Clustering<? extends Model>> getClusteringResults(Result r) { - if(r instanceof Clustering<?>) { - List<Clustering<?>> crs = new ArrayList<Clustering<?>>(1); + if (r instanceof Clustering<?>) { + List<Clustering<?>> crs = new ArrayList<>(1); crs.add((Clustering<?>) r); return crs; } - if(r instanceof HierarchicalResult) { + if (r instanceof HierarchicalResult) { return ClassGenericsUtil.castWithGenericsOrNull(List.class, filterResults((HierarchicalResult) r, Clustering.class)); } return Collections.emptyList(); @@ -108,12 +108,12 @@ public class ResultUtil { * @return List of collection results */ public static List<CollectionResult<?>> getCollectionResults(Result r) { - if(r instanceof CollectionResult<?>) { - List<CollectionResult<?>> crs = new ArrayList<CollectionResult<?>>(1); + if (r instanceof CollectionResult<?>) { + List<CollectionResult<?>> crs = new ArrayList<>(1); crs.add((CollectionResult<?>) r); return crs; } - if(r instanceof HierarchicalResult) { + if (r instanceof HierarchicalResult) { return ClassGenericsUtil.castWithGenericsOrNull(List.class, filterResults((HierarchicalResult) r, CollectionResult.class)); } return Collections.emptyList(); @@ -126,12 +126,12 @@ public class ResultUtil { * @return List of iterable results */ public static List<IterableResult<?>> getIterableResults(Result r) { - if(r instanceof IterableResult<?>) { - List<IterableResult<?>> irs = new ArrayList<IterableResult<?>>(1); + if (r instanceof IterableResult<?>) { + List<IterableResult<?>> irs = new ArrayList<>(1); irs.add((IterableResult<?>) r); return irs; } - if(r instanceof HierarchicalResult) { + if (r instanceof HierarchicalResult) { return ClassGenericsUtil.castWithGenericsOrNull(List.class, filterResults((HierarchicalResult) r, IterableResult.class)); } return Collections.emptyList(); @@ -144,12 +144,12 @@ public class ResultUtil { * @return List of outlier results */ public static List<OutlierResult> getOutlierResults(Result r) { - if(r instanceof OutlierResult) { - List<OutlierResult> ors = new ArrayList<OutlierResult>(1); + if (r instanceof OutlierResult) { + List<OutlierResult> ors = new ArrayList<>(1); ors.add((OutlierResult) r); return ors; } - if(r instanceof HierarchicalResult) { + if (r instanceof HierarchicalResult) { return filterResults((HierarchicalResult) r, OutlierResult.class); } return Collections.emptyList(); @@ -162,12 +162,12 @@ public class ResultUtil { * @return List of settings results */ public static List<SettingsResult> getSettingsResults(Result r) { - if(r instanceof SettingsResult) { - List<SettingsResult> ors = new ArrayList<SettingsResult>(1); + if (r instanceof SettingsResult) { + List<SettingsResult> ors = new ArrayList<>(1); ors.add((SettingsResult) r); return ors; } - if(r instanceof HierarchicalResult) { + if (r instanceof HierarchicalResult) { return filterResults((HierarchicalResult) r, SettingsResult.class); } return Collections.emptyList(); @@ -183,14 +183,14 @@ public class ResultUtil { // We can't ensure that restrictionClass matches C. @SuppressWarnings("unchecked") public static <C> ArrayList<C> filterResults(Result r, Class<?> restrictionClass) { - ArrayList<C> res = new ArrayList<C>(); - if(restrictionClass.isInstance(r)) { + ArrayList<C> res = new ArrayList<>(); + if (restrictionClass.isInstance(r)) { res.add((C) restrictionClass.cast(r)); } - if(r instanceof HierarchicalResult) { - for(Iterator<Result> iter = ((HierarchicalResult) r).getHierarchy().iterDescendants(r); iter.hasNext();) { - Result result = iter.next(); - if(restrictionClass.isInstance(result)) { + if (r instanceof HierarchicalResult) { + for (Hierarchy.Iter<Result> iter = ((HierarchicalResult) r).getHierarchy().iterDescendants(r); iter.valid(); iter.advance()) { + Result result = iter.get(); + if (restrictionClass.isInstance(result)) { res.add((C) restrictionClass.cast(result)); } } @@ -207,7 +207,7 @@ public class ResultUtil { */ public static <O> void ensureClusteringResult(final Database db, final Result result) { Collection<Clustering<?>> clusterings = ResultUtil.filterResults(result, Clustering.class); - if(clusterings.size() == 0) { + if (clusterings.size() == 0) { ClusteringAlgorithm<Clustering<Model>> split = new ByLabelOrAllInOneClustering(); Clustering<Model> c = split.run(db); addChildResult(db, c); @@ -222,7 +222,7 @@ public class ResultUtil { */ public static SelectionResult ensureSelectionResult(final Database db) { List<SelectionResult> selections = ResultUtil.filterResults(db, SelectionResult.class); - if(!selections.isEmpty()) { + if (!selections.isEmpty()) { return selections.get(0); } SelectionResult sel = new SelectionResult(); @@ -238,7 +238,7 @@ public class ResultUtil { */ public static SamplingResult getSamplingResult(final Relation<?> rel) { Collection<SamplingResult> selections = ResultUtil.filterResults(rel, SamplingResult.class); - if(selections.size() == 0) { + if (selections.size() == 0) { final SamplingResult newsam = new SamplingResult(rel); addChildResult(rel, newsam); return newsam; @@ -254,7 +254,7 @@ public class ResultUtil { */ public static ScalesResult getScalesResult(final Relation<? extends NumberVector<?>> rel) { Collection<ScalesResult> scas = ResultUtil.filterResults(rel, ScalesResult.class); - if(scas.size() == 0) { + if (scas.size() == 0) { final ScalesResult newsca = new ScalesResult(rel); addChildResult(rel, newsca); return newsca; @@ -280,10 +280,9 @@ public class ResultUtil { */ public static Database findDatabase(Result baseResult) { final List<Database> dbs = filterResults(baseResult, Database.class); - if(!dbs.isEmpty()) { + if (!dbs.isEmpty()) { return dbs.get(0); - } - else { + } else { return null; } } @@ -295,11 +294,11 @@ public class ResultUtil { * @param child Result to remove */ public static void removeRecursive(ResultHierarchy hierarchy, Result child) { - for(Result parent : hierarchy.getParents(child)) { - hierarchy.remove(parent, child); + for (Hierarchy.Iter<Result> iter = hierarchy.iterParents(child); iter.valid(); iter.advance()) { + hierarchy.remove(iter.get(), child); } - for(Result sub : hierarchy.getChildren(child)) { - removeRecursive(hierarchy, sub); + for (Hierarchy.Iter<Result> iter = hierarchy.iterChildren(child); iter.valid(); iter.advance()) { + removeRecursive(hierarchy, iter.get()); } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/result/ResultWriter.java b/src/de/lmu/ifi/dbs/elki/result/ResultWriter.java index 45475dd2..f3b39580 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultWriter.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultWriter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,6 +25,7 @@ package de.lmu.ifi.dbs.elki.result; import java.io.File; import java.io.IOException; +import java.util.regex.Pattern; import de.lmu.ifi.dbs.elki.database.Database; import de.lmu.ifi.dbs.elki.logging.Logging; @@ -38,9 +39,13 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.PatternParameter; +import de.lmu.ifi.dbs.elki.workflow.OutputStep; /** - * Result handler that feeds the data into a TextWriter + * Result handler that feeds the data into a TextWriter. + * + * Note: these classes need to be rewritten. Contributions welcome! * * @author Erich Schubert */ @@ -51,22 +56,6 @@ public class ResultWriter implements ResultHandler { private static final Logging LOG = Logging.getLogger(ResultWriter.class); /** - * Flag to control GZIP compression. - * <p> - * Key: {@code -out.gzip} - * </p> - */ - public static final OptionID GZIP_OUTPUT_ID = new OptionID("out.gzip", "Enable gzip compression of output files."); - - /** - * Flag to suppress overwrite warning. - * <p> - * Key: {@code -out.silentoverwrite} - * </p> - */ - public static final OptionID OVERWRITE_OPTION_ID = new OptionID("out.silentoverwrite", "Silently overwrite output files."); - - /** * Holds the file to print results to. */ private File out; @@ -82,17 +71,24 @@ public class ResultWriter implements ResultHandler { private boolean warnoverwrite = true; /** + * Result filter pattern. Optional! + */ + private Pattern filter = null; + + /** * Constructor. * - * @param out - * @param gzip - * @param warnoverwrite + * @param out Output file + * @param gzip Gzip compression + * @param warnoverwrite Warn before overwriting files + * @param filter Filter pattern */ - public ResultWriter(File out, boolean gzip, boolean warnoverwrite) { + public ResultWriter(File out, boolean gzip, boolean warnoverwrite, Pattern filter) { super(); this.out = out; this.gzip = gzip; this.warnoverwrite = warnoverwrite; + this.filter = filter; } @Override @@ -101,42 +97,35 @@ public class ResultWriter implements ResultHandler { StreamFactory output; try { - if(out == null) { + if (out == null) { output = new SingleStreamOutput(gzip); - } - else if(out.exists()) { - if(out.isDirectory()) { - if(warnoverwrite && out.listFiles().length > 0) { + } else if (out.exists()) { + if (out.isDirectory()) { + if (warnoverwrite && out.listFiles().length > 0) { LOG.warning("Output directory specified is not empty. Files will be overwritten and old files may be left over."); } output = new MultipleFilesOutput(out, gzip); - } - else { - if(warnoverwrite) { + } else { + if (warnoverwrite) { LOG.warning("Output file exists and will be overwritten!"); } output = new SingleStreamOutput(out, gzip); } - } - else { + } else { // If it doesn't exist yet, make a MultipleFilesOutput. output = new MultipleFilesOutput(out, gzip); } - } - catch(IOException e) { + } catch (IOException e) { throw new IllegalStateException("Error opening output.", e); } try { Database db = ResultUtil.findDatabase(baseresult); - writer.output(db, result, output); - } - catch(IOException e) { + writer.output(db, result, output, filter); + } catch (IOException e) { throw new IllegalStateException("Input/Output error while writing result.", e); - } - catch(UnableToComplyException e) { + } catch (UnableToComplyException e) { throw new IllegalStateException("Unable to comply while writing result.", e); } - output.closeAllStreams(); } /** @@ -148,6 +137,30 @@ public class ResultWriter implements ResultHandler { */ public static class Parameterizer extends AbstractParameterizer { /** + * Flag to control GZIP compression. + * <p> + * Key: {@code -out.gzip} + * </p> + */ + public static final OptionID GZIP_OUTPUT_ID = new OptionID("out.gzip", "Enable gzip compression of output files."); + + /** + * Flag to suppress overwrite warning. + * <p> + * Key: {@code -out.silentoverwrite} + * </p> + */ + public static final OptionID OVERWRITE_OPTION_ID = new OptionID("out.silentoverwrite", "Silently overwrite output files."); + + /** + * Pattern to filter the output + * <p> + * Key: {@code -out.filter} + * </p> + */ + public static final OptionID FILTER_PATTERN_ID = new OptionID("out.filter", "Filter pattern for output selection. Only output streams that match the given pattern will be written."); + + /** * Holds the file to print results to. */ private File out = null; @@ -162,29 +175,40 @@ public class ResultWriter implements ResultHandler { */ private boolean warnoverwrite = true; + /** + * Result filter pattern. Optional! + */ + private Pattern filter = null; + @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); - FileParameter outputP = new FileParameter(OptionID.OUTPUT, FileParameter.FileType.OUTPUT_FILE, true); - if(config.grab(outputP)) { + FileParameter outputP = new FileParameter(OutputStep.Parameterizer.OUTPUT_ID, FileParameter.FileType.OUTPUT_FILE, true); + if (config.grab(outputP)) { out = outputP.getValue(); } Flag gzipF = new Flag(GZIP_OUTPUT_ID); - if(config.grab(gzipF)) { + if (config.grab(gzipF)) { gzip = gzipF.getValue(); } Flag overwriteF = new Flag(OVERWRITE_OPTION_ID); - if(config.grab(overwriteF)) { + if (config.grab(overwriteF)) { // note: inversed meaning warnoverwrite = !overwriteF.getValue(); } + + PatternParameter filterP = new PatternParameter(FILTER_PATTERN_ID); + filterP.setOptional(true); + if (config.grab(filterP)) { + filter = filterP.getValue(); + } } @Override protected ResultWriter makeInstance() { - return new ResultWriter(out, gzip, warnoverwrite); + return new ResultWriter(out, gzip, warnoverwrite, filter); } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/result/SamplingResult.java b/src/de/lmu/ifi/dbs/elki/result/SamplingResult.java index 5e6c3df2..17471b9a 100644 --- a/src/de/lmu/ifi/dbs/elki/result/SamplingResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/SamplingResult.java @@ -7,7 +7,7 @@ import de.lmu.ifi.dbs.elki.database.relation.Relation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/ScalesResult.java b/src/de/lmu/ifi/dbs/elki/result/ScalesResult.java index eca62474..8f9653d8 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ScalesResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/ScalesResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/SelectionResult.java b/src/de/lmu/ifi/dbs/elki/result/SelectionResult.java index a8fb4ed5..fda68c68 100644 --- a/src/de/lmu/ifi/dbs/elki/result/SelectionResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/SelectionResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/SettingsResult.java b/src/de/lmu/ifi/dbs/elki/result/SettingsResult.java index d8c24737..ea6664e8 100644 --- a/src/de/lmu/ifi/dbs/elki/result/SettingsResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/SettingsResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderEntry.java b/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderEntry.java index 06e4766f..fab3a8c3 100644 --- a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderEntry.java +++ b/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderEntry.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.optics; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java b/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java index 66b53dd2..bd500dfa 100644 --- a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.optics; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -87,7 +87,7 @@ public class ClusterOrderResult<D extends Distance<D>> extends BasicResult imple */ public ClusterOrderResult(String name, String shortname) { super(name, shortname); - clusterOrder = new ArrayList<ClusterOrderEntry<D>>(); + clusterOrder = new ArrayList<>(); dbids = DBIDUtil.newHashSet(); map = DataStoreUtil.makeStorage(dbids, DataStoreFactory.HINT_DB, ClusterOrderEntry.class); @@ -121,7 +121,7 @@ public class ClusterOrderResult<D extends Distance<D>> extends BasicResult imple * @param reachability Reachability distance */ public void add(DBID id, DBID predecessor, D reachability) { - add(new GenericClusterOrderEntry<D>(id, predecessor, reachability)); + add(new GenericClusterOrderEntry<>(id, predecessor, reachability)); dbids.add(id); } @@ -279,7 +279,7 @@ public class ClusterOrderResult<D extends Distance<D>> extends BasicResult imple @Override public SimpleTypeInformation<D> getDataTypeInformation() { - return new SimpleTypeInformation<D>(Distance.class); + return new SimpleTypeInformation<>(Distance.class); } @Override diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/DoubleDistanceClusterOrderEntry.java b/src/de/lmu/ifi/dbs/elki/result/optics/DoubleDistanceClusterOrderEntry.java index f2ebcce3..74f65e73 100644 --- a/src/de/lmu/ifi/dbs/elki/result/optics/DoubleDistanceClusterOrderEntry.java +++ b/src/de/lmu/ifi/dbs/elki/result/optics/DoubleDistanceClusterOrderEntry.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.optics; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/GenericClusterOrderEntry.java b/src/de/lmu/ifi/dbs/elki/result/optics/GenericClusterOrderEntry.java index b04d35ea..7af8a3ec 100644 --- a/src/de/lmu/ifi/dbs/elki/result/optics/GenericClusterOrderEntry.java +++ b/src/de/lmu/ifi/dbs/elki/result/optics/GenericClusterOrderEntry.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.optics; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/package-info.java b/src/de/lmu/ifi/dbs/elki/result/optics/package-info.java index a61eb417..e74b3c7b 100644 --- a/src/de/lmu/ifi/dbs/elki/result/optics/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/result/optics/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java b/src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java index 5d56117c..4dc64b2c 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/InvertedOutlierScoreMeta.java b/src/de/lmu/ifi/dbs/elki/result/outlier/InvertedOutlierScoreMeta.java index 8658c938..d4ea456a 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/InvertedOutlierScoreMeta.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/InvertedOutlierScoreMeta.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/OrderingFromRelation.java b/src/de/lmu/ifi/dbs/elki/result/outlier/OrderingFromRelation.java index a60bda3d..2950a2f8 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/OrderingFromRelation.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/OrderingFromRelation.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java index 5c4a58ae..13d5c1a0 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java index c71f20ce..a17bade5 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/ProbabilisticOutlierScore.java b/src/de/lmu/ifi/dbs/elki/result/outlier/ProbabilisticOutlierScore.java index 844bb919..36cd081e 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/ProbabilisticOutlierScore.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/ProbabilisticOutlierScore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/QuotientOutlierScoreMeta.java b/src/de/lmu/ifi/dbs/elki/result/outlier/QuotientOutlierScoreMeta.java index e0dc36ec..3ac643e6 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/QuotientOutlierScoreMeta.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/QuotientOutlierScoreMeta.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/package-info.java b/src/de/lmu/ifi/dbs/elki/result/outlier/package-info.java index f72e5366..7007c8b4 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/package-info.java @@ -6,7 +6,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/package-info.java b/src/de/lmu/ifi/dbs/elki/result/package-info.java index 70894b93..0f3e3aa8 100644 --- a/src/de/lmu/ifi/dbs/elki/result/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/result/package-info.java @@ -12,7 +12,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/MultipleFilesOutput.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/MultipleFilesOutput.java index 2e089274..22bde5be 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/MultipleFilesOutput.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/MultipleFilesOutput.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -28,7 +28,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; -import java.util.HashMap; import java.util.zip.GZIPOutputStream; import de.lmu.ifi.dbs.elki.logging.Logging; @@ -50,25 +49,15 @@ public class MultipleFilesOutput implements StreamFactory { private static final String GZIP_EXTENSION = ".gz"; /** - * Default stream to write to when no name is supplied. - */ - private PrintStream defaultStream = null; - - /** * Base file name. */ private File basename; /** - * HashMap of open print streams. - */ - private HashMap<String, PrintStream> map = new HashMap<String, PrintStream>(); - - /** * Control gzip compression of output. */ private boolean usegzip = false; - + /** * Logger for debugging. */ @@ -95,20 +84,6 @@ public class MultipleFilesOutput implements StreamFactory { } /** - * Retrieve/open the default output stream. - * - * @return default output stream - * @throws IOException - */ - private PrintStream getDefaultStream() throws IOException { - if(defaultStream != null) { - return defaultStream; - } - defaultStream = newStream("default"); - return defaultStream; - } - - /** * Open a new stream of the given name * * @param name file name (which will be appended to the base name) @@ -117,14 +92,10 @@ public class MultipleFilesOutput implements StreamFactory { */ private PrintStream newStream(String name) throws IOException { if (LOG.isDebuggingFiner()) { - LOG.debugFiner("Requested stream: "+name); - } - PrintStream res = map.get(name); - if(res != null) { - return res; + LOG.debugFiner("Requested stream: " + name); } // Ensure the directory exists: - if(!basename.exists()) { + if (!basename.exists()) { basename.mkdirs(); } String fn = basename.getAbsolutePath() + File.separator + name + EXTENSION; @@ -137,12 +108,11 @@ public class MultipleFilesOutput implements StreamFactory { // wrap into gzip stream. os = new GZIPOutputStream(os); } - res = new PrintStream(os); + PrintStream res = new PrintStream(os); if (LOG.isDebuggingFiner()) { - LOG.debugFiner("Opened new output stream:"+fn); + LOG.debugFiner("Opened new output stream:" + fn); } // cache. - map.put(name, res); return res; } @@ -151,12 +121,14 @@ public class MultipleFilesOutput implements StreamFactory { */ @Override public PrintStream openStream(String filename) throws IOException { - if(filename == null) { - return getDefaultStream(); - } return newStream(filename); } + @Override + public void closeStream(PrintStream stream) { + stream.close(); + } + /** * Get GZIP compression flag. * @@ -174,15 +146,4 @@ public class MultipleFilesOutput implements StreamFactory { protected void setGzipCompression(boolean usegzip) { this.usegzip = usegzip; } - - /** - * Close (and forget) all output streams. - */ - @Override - public synchronized void closeAllStreams() { - for (PrintStream s : map.values()) { - s.close(); - } - map.clear(); - } } diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/SingleStreamOutput.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/SingleStreamOutput.java index 46472f52..eb2b6170 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/SingleStreamOutput.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/SingleStreamOutput.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -35,32 +35,32 @@ import java.util.zip.GZIPOutputStream; * Class to output all result data to a single stream (e.g. Stdout, single file) * * @author Erich Schubert - * */ public class SingleStreamOutput implements StreamFactory { /** * Output stream */ private PrintStream stream; - + /** * Constructor using stdout. + * * @throws IOException on IO error */ - public SingleStreamOutput() throws IOException { + public SingleStreamOutput() throws IOException { this(FileDescriptor.out); } - + /** * Constructor using stdout * * @param gzip Use gzip compression * @throws IOException on IO error */ - public SingleStreamOutput(boolean gzip) throws IOException { + public SingleStreamOutput(boolean gzip) throws IOException { this(FileDescriptor.out, gzip); } - + /** * Constructor with given file name. * @@ -91,7 +91,7 @@ public class SingleStreamOutput implements StreamFactory { public SingleStreamOutput(FileDescriptor out) throws IOException { this(new FileOutputStream(out)); } - + /** * Constructor with given FileDescriptor * @@ -102,7 +102,7 @@ public class SingleStreamOutput implements StreamFactory { public SingleStreamOutput(FileDescriptor out, boolean gzip) throws IOException { this(new FileOutputStream(out), gzip); } - + /** * Constructor with given FileOutputStream. * @@ -132,18 +132,16 @@ public class SingleStreamOutput implements StreamFactory { /** * Return the objects shared print stream. * - * @param filename ignored filename for SingleStreamOutput, as the name suggests + * @param filename ignored filename for SingleStreamOutput, as the name + * suggests */ @Override public PrintStream openStream(String filename) { return stream; } - /** - * Close output stream. - */ @Override - public void closeAllStreams() { - stream.close(); + public void closeStream(PrintStream stream) { + // Do NOT close. We may still need it. } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/StreamFactory.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/StreamFactory.java index 0f27b354..431fdc2c 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/StreamFactory.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/StreamFactory.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,22 +29,27 @@ import java.io.PrintStream; /** * Interface for output handling (single file, multiple files, ...) * + * Note: these classes need to be rewritten. Contributions welcome! + * * @author Erich Schubert */ public interface StreamFactory { /** - * Retrieve a print stream for output using the given label. - * Note that multiple labels MAY result in the same PrintStream, so you - * should be printing to only one stream at a time to avoid mixing outputs. + * Retrieve a print stream for output using the given label. Note that + * multiple labels MAY result in the same PrintStream, so you should be + * printing to only one stream at a time to avoid mixing outputs. * * @param label Output label. * @return stream object for the given label * @throws IOException on IO error */ public PrintStream openStream(String label) throws IOException; - + /** - * Close (and forget) all streams the factory has opened. + * Close the given output stream (Note: when writing to a single stream + * output, it will actually not be closed!) + * + * @param stream Stream to close */ - public void closeAllStreams(); -}
\ No newline at end of file + public void closeStream(PrintStream stream); +} diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriteable.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriteable.java index a8de4c46..5b56cee6 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriteable.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriteable.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java index e5b05883..0cbc81f2 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -33,6 +33,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.regex.Pattern; import de.lmu.ifi.dbs.elki.data.Cluster; import de.lmu.ifi.dbs.elki.data.Clustering; @@ -62,13 +63,13 @@ import de.lmu.ifi.dbs.elki.result.textwriter.naming.NamingScheme; import de.lmu.ifi.dbs.elki.result.textwriter.naming.SimpleEnumeratingScheme; import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterDoubleDoublePair; import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterObjectArray; -import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterObjectComment; import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterObjectInline; import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterPair; import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterTextWriteable; import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterTriple; import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterVector; import de.lmu.ifi.dbs.elki.utilities.HandlerList; +import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy; import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.SerializedParameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter; @@ -78,7 +79,9 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; import de.lmu.ifi.dbs.elki.utilities.pairs.Triple; /** - * Class to write a result to human-readable text output + * Class to write a result to human-readable text output. + * + * Note: these classes need to be rewritten. Contributions welcome! * * @author Erich Schubert * @@ -96,14 +99,13 @@ public class TextWriter { /** * Hash map for supported classes in writer. */ - public static final HandlerList<TextWriterWriterInterface<?>> writers = new HandlerList<TextWriterWriterInterface<?>>(); + public static final HandlerList<TextWriterWriterInterface<?>> writers = new HandlerList<>(); /** * Add some default handlers */ static { TextWriterObjectInline trivialwriter = new TextWriterObjectInline(); - writers.insertHandler(Object.class, new TextWriterObjectComment()); writers.insertHandler(Pair.class, new TextWriterPair()); writers.insertHandler(DoubleDoublePair.class, new TextWriterDoubleDoublePair()); writers.insertHandler(Triple.class, new TextWriterTriple()); @@ -129,7 +131,7 @@ public class TextWriter { /** * For producing unique filenames. */ - protected Map<String, Object> filenames = new HashMap<String, Object>(); + protected Map<String, Object> filenames = new HashMap<>(); /** * Try to find a unique file name. @@ -139,20 +141,19 @@ public class TextWriter { * @return unique filename */ protected String getFilename(Object result, String filenamepre) { - if(filenamepre == null || filenamepre.length() == 0) { + if (filenamepre == null || filenamepre.length() == 0) { filenamepre = "result"; } int i = 0; - while(true) { + while (true) { String filename; - if(i > 0) { + if (i > 0) { filename = filenamepre + "-" + i; - } - else { + } else { filename = filenamepre; } Object existing = filenames.get(filename); - if(existing == null || existing == result) { + if (existing == null || existing == result) { filenames.put(filename, result); return filename; } @@ -161,102 +162,54 @@ public class TextWriter { } /** - * Writes a header providing information concerning the underlying database - * and the specified parameter-settings. - * - * @param out the print stream where to write - * @param sr the settings to be written into the header - */ - protected void printSettings(TextWriterStream out, List<SettingsResult> sr) { - out.commentPrintSeparator(); - out.commentPrintLn("Settings:"); - - if(sr != null) { - for(SettingsResult settings : sr) { - Object last = null; - for(Pair<Object, Parameter<?>> setting : settings.getSettings()) { - if(setting.first != last && setting.first != null) { - if(last != null) { - out.commentPrintLn(""); - } - String name; - try { - if(setting.first instanceof Class) { - name = ((Class<?>) setting.first).getName(); - } - else { - name = setting.first.getClass().getName(); - } - if(ClassParameter.class.isInstance(setting.first)) { - name = ((ClassParameter<?>) setting.first).getValue().getName(); - } - } - catch(NullPointerException e) { - name = "[null]"; - } - out.commentPrintLn(name); - last = setting.first; - } - String name = setting.second.getOptionID().getName(); - String value = "[unset]"; - try { - if(setting.second.isDefined()) { - value = setting.second.getValueAsString(); - } - } - catch(NullPointerException e) { - value = "[null]"; - } - out.commentPrintLn(SerializedParameterization.OPTION_PREFIX + name + " " + value); - } - } - } - - out.commentPrintSeparator(); - out.flush(); - } - - /** * Stream output. * * @param db Database object * @param r Result class * @param streamOpener output stream manager + * @param filter Filter pattern * @throws UnableToComplyException when no usable results were found * @throws IOException on IO error */ - public void output(Database db, Result r, StreamFactory streamOpener) throws UnableToComplyException, IOException { - List<Relation<?>> ra = new LinkedList<Relation<?>>(); - List<OrderingResult> ro = new LinkedList<OrderingResult>(); - List<Clustering<?>> rc = new LinkedList<Clustering<?>>(); - List<IterableResult<?>> ri = new LinkedList<IterableResult<?>>(); - List<SettingsResult> rs = new LinkedList<SettingsResult>(); - List<Result> otherres = new LinkedList<Result>(); + @SuppressWarnings("unchecked") + public void output(Database db, Result r, StreamFactory streamOpener, Pattern filter) throws UnableToComplyException, IOException { + List<Relation<?>> ra = new LinkedList<>(); + List<OrderingResult> ro = new LinkedList<>(); + List<Clustering<?>> rc = new LinkedList<>(); + List<IterableResult<?>> ri = new LinkedList<>(); + List<SettingsResult> rs = new LinkedList<>(); + List<Result> otherres = new LinkedList<>(); - // collect other results + // Split result objects in different known types: { List<Result> results = ResultUtil.filterResults(r, Result.class); - for(Result res : results) { - if(res instanceof Database) { + for (Result res : results) { + if (filter != null) { + final String nam = res.getShortName(); + if (nam == null || !filter.matcher(nam).find()) { + continue; + } + } + if (res instanceof Database) { continue; } - if(res instanceof Relation) { + if (res instanceof Relation) { ra.add((Relation<?>) res); continue; } - if(res instanceof OrderingResult) { + if (res instanceof OrderingResult) { ro.add((OrderingResult) res); continue; } - if(res instanceof Clustering) { + if (res instanceof Clustering) { rc.add((Clustering<?>) res); continue; } - if(res instanceof IterableResult) { + if (res instanceof IterableResult) { ri.add((IterableResult<?>) res); continue; } - if(res instanceof SettingsResult) { + if (res instanceof SettingsResult) { rs.add((SettingsResult) res); continue; } @@ -264,36 +217,38 @@ public class TextWriter { } } - for(IterableResult<?> rii : ri) { - writeIterableResult(streamOpener, rii, rs); + writeSettingsResult(streamOpener, rs); + + for (IterableResult<?> rii : ri) { + writeIterableResult(streamOpener, rii); } - for(Clustering<?> c : rc) { + for (Clustering<?> c : rc) { NamingScheme naming = new SimpleEnumeratingScheme(c); - for(Cluster<?> clus : c.getAllClusters()) { - writeClusterResult(db, streamOpener, clus, ra, naming, rs); + for (Cluster<?> clus : c.getAllClusters()) { + writeClusterResult(db, streamOpener, (Clustering<Model>) c, (Cluster<Model>) clus, ra, naming); } } - for(OrderingResult ror : ro) { - writeOrderingResult(db, streamOpener, ror, ra, rs); + for (OrderingResult ror : ro) { + writeOrderingResult(db, streamOpener, ror, ra); } - for(Result otherr : otherres) { - writeOtherResult(streamOpener, otherr, rs); + for (Result otherr : otherres) { + writeOtherResult(streamOpener, otherr); } } private void printObject(TextWriterStream out, Database db, final DBIDRef objID, List<Relation<?>> ra) throws UnableToComplyException, IOException { SingleObjectBundle bundle = db.getBundle(objID); // Write database element itself. - for(int i = 0; i < bundle.metaLength(); i++) { + for (int i = 0; i < bundle.metaLength(); i++) { Object obj = bundle.data(i); - if(obj != null) { + if (obj != null) { TextWriterWriterInterface<?> owriter = out.getWriterFor(obj); - if(owriter == null) { + if (owriter == null) { throw new UnableToComplyException("No handler for database object itself: " + obj.getClass().getSimpleName()); } String lbl = null; // TODO: ugly compatibility hack... - if(TypeUtil.DBID.isAssignableFromType(bundle.meta(i))) { + if (TypeUtil.DBID.isAssignableFromType(bundle.meta(i))) { lbl = "ID"; } owriter.writeObject(out, lbl, obj); @@ -302,19 +257,19 @@ public class TextWriter { Collection<Relation<?>> dbrels = db.getRelations(); // print the annotations - if(ra != null) { - for(Relation<?> a : ra) { + if (ra != null) { + for (Relation<?> a : ra) { // Avoid duplicated output. - if(dbrels.contains(a)) { + if (dbrels.contains(a)) { continue; } String label = a.getShortName(); Object value = a.get(objID); - if(value == null) { + if (value == null) { continue; } TextWriterWriterInterface<?> writer = out.getWriterFor(value); - if(writer == null) { + if (writer == null) { // Ignore continue; } @@ -322,56 +277,41 @@ public class TextWriter { } } out.flush(); - out.flush(); - } - - private void writeOtherResult(StreamFactory streamOpener, Result r, List<SettingsResult> rs) throws UnableToComplyException, IOException { - PrintStream outStream = streamOpener.openStream(getFilename(r, r.getShortName())); - TextWriterStream out = new TextWriterStream(outStream, writers); - TextWriterWriterInterface<?> owriter = out.getWriterFor(r); - if(owriter == null) { - throw new UnableToComplyException("No handler for result class: " + r.getClass().getSimpleName()); - } - // Write settings preamble - printSettings(out, rs); - // Write data - owriter.writeObject(out, null, r); - out.flush(); } - private void writeClusterResult(Database db, StreamFactory streamOpener, Cluster<?> clus, List<Relation<?>> ra, NamingScheme naming, List<SettingsResult> sr) throws FileNotFoundException, UnableToComplyException, IOException { + private void writeClusterResult(Database db, StreamFactory streamOpener, Clustering<Model> clustering, Cluster<Model> clus, List<Relation<?>> ra, NamingScheme naming) throws FileNotFoundException, UnableToComplyException, IOException { String filename = null; - if(naming != null) { + if (naming != null) { filename = filenameFromLabel(naming.getNameFor(clus)); - } - else { + } else { filename = "cluster"; } PrintStream outStream = streamOpener.openStream(getFilename(clus, filename)); TextWriterStream out = new TextWriterStream(outStream, writers); - printSettings(out, sr); // Write cluster information out.commentPrintLn("Cluster: " + naming.getNameFor(clus)); Model model = clus.getModel(); - if(model != ClusterModel.CLUSTER && model != null) { - TextWriterWriterInterface<?> mwri = writers.getHandler(model); - mwri.writeObject(out, null, model); + if (model != ClusterModel.CLUSTER && model != null) { + TextWriterWriterInterface<?> mwri = out.getWriterFor(model); + if (mwri != null) { + mwri.writeObject(out, null, model); + } } - if(clus.getParents().size() > 0) { + if (clustering.getClusterHierarchy().numParents(clus) > 0) { StringBuilder buf = new StringBuilder(); buf.append("Parents:"); - for(Cluster<?> parent : clus.getParents()) { - buf.append(" ").append(naming.getNameFor(parent)); + for (Hierarchy.Iter<Cluster<Model>> iter = clustering.getClusterHierarchy().iterParents(clus); iter.valid(); iter.advance()) { + buf.append(' ').append(naming.getNameFor(iter.get())); } out.commentPrintLn(buf.toString()); } - if(clus.getChildren().size() > 0) { + if (clustering.getClusterHierarchy().numChildren(clus) > 0) { StringBuilder buf = new StringBuilder(); buf.append("Children:"); - for(Cluster<?> child : clus.getChildren()) { - buf.append(" ").append(naming.getNameFor(child)); + for (Hierarchy.Iter<Cluster<Model>> iter = clustering.getClusterHierarchy().iterChildren(clus); iter.valid(); iter.advance()) { + buf.append(' ').append(naming.getNameFor(iter.get())); } out.commentPrintLn(buf.toString()); } @@ -382,48 +322,112 @@ public class TextWriter { for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { printObject(out, db, iter, ra); } - out.commentPrintSeparator(); out.flush(); + streamOpener.closeStream(outStream); } - private void writeIterableResult(StreamFactory streamOpener, IterableResult<?> ri, List<SettingsResult> sr) throws UnableToComplyException, IOException { + private void writeIterableResult(StreamFactory streamOpener, IterableResult<?> ri) throws UnableToComplyException, IOException { PrintStream outStream = streamOpener.openStream(getFilename(ri, ri.getShortName())); TextWriterStream out = new TextWriterStream(outStream, writers); - printSettings(out, sr); // hack to print collectionResult header information - if(ri instanceof CollectionResult<?>) { + if (ri instanceof CollectionResult<?>) { final Collection<String> hdr = ((CollectionResult<?>) ri).getHeader(); - if(hdr != null) { - for(String header : hdr) { + if (hdr != null) { + for (String header : hdr) { out.commentPrintLn(header); } out.flush(); } } Iterator<?> i = ri.iterator(); - while(i.hasNext()) { + while (i.hasNext()) { Object o = i.next(); TextWriterWriterInterface<?> writer = out.getWriterFor(o); - if(writer != null) { + if (writer != null) { writer.writeObject(out, null, o); } out.flush(); } - out.commentPrintSeparator(); out.flush(); + streamOpener.closeStream(outStream); } - private void writeOrderingResult(Database db, StreamFactory streamOpener, OrderingResult or, List<Relation<?>> ra, List<SettingsResult> sr) throws IOException, UnableToComplyException { + private void writeOrderingResult(Database db, StreamFactory streamOpener, OrderingResult or, List<Relation<?>> ra) throws IOException, UnableToComplyException { PrintStream outStream = streamOpener.openStream(getFilename(or, or.getShortName())); TextWriterStream out = new TextWriterStream(outStream, writers); - printSettings(out, sr); for (DBIDIter i = or.iter(or.getDBIDs()).iter(); i.valid(); i.advance()) { printObject(out, db, i, ra); } - out.commentPrintSeparator(); out.flush(); + streamOpener.closeStream(outStream); + } + + private void writeSettingsResult(StreamFactory streamOpener, List<SettingsResult> rs) throws UnableToComplyException, IOException { + if (rs.size() < 1) { + return; + } + SettingsResult r = rs.get(0); + PrintStream outStream = streamOpener.openStream(getFilename(r, r.getShortName())); + TextWriterStream out = new TextWriterStream(outStream, writers); + // Write settings preamble + out.commentPrintLn("Settings:"); + + if (rs != null) { + for (SettingsResult settings : rs) { + Object last = null; + for (Pair<Object, Parameter<?>> setting : settings.getSettings()) { + if (setting.first != last && setting.first != null) { + if (last != null) { + out.commentPrintLn(""); + } + String name; + try { + if (setting.first instanceof Class) { + name = ((Class<?>) setting.first).getName(); + } else { + name = setting.first.getClass().getName(); + } + if (ClassParameter.class.isInstance(setting.first)) { + name = ((ClassParameter<?>) setting.first).getValue().getName(); + } + } catch (NullPointerException e) { + name = "[null]"; + } + out.commentPrintLn(name); + last = setting.first; + } + String name = setting.second.getOptionID().getName(); + String value = "[unset]"; + try { + if (setting.second.isDefined()) { + value = setting.second.getValueAsString(); + } + } catch (NullPointerException e) { + value = "[null]"; + } + out.commentPrintLn(SerializedParameterization.OPTION_PREFIX + name + " " + value); + } + } + } + out.flush(); + streamOpener.closeStream(outStream); + } + + private void writeOtherResult(StreamFactory streamOpener, Result r) throws UnableToComplyException, IOException { + if (writers.getHandler(r) != null) { + PrintStream outStream = streamOpener.openStream(getFilename(r, r.getShortName())); + TextWriterStream out = new TextWriterStream(outStream, writers); + TextWriterWriterInterface<?> owriter = out.getWriterFor(r); + if (owriter == null) { + throw new UnableToComplyException("No handler for result class: " + r.getClass().getSimpleName()); + } + // Write data + owriter.writeObject(out, null, r); + out.flush(); + streamOpener.closeStream(outStream); + } } /** diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java index 7c905fb3..542be099 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,14 +25,16 @@ package de.lmu.ifi.dbs.elki.result.textwriter; import java.io.PrintStream; +import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterObjectComment; import de.lmu.ifi.dbs.elki.utilities.HandlerList; /** * Representation of an output stream to a text file. * * @author Erich Schubert - * - * @apiviz.uses de.lmu.ifi.dbs.elki.result.textwriter.StreamFactory oneway - - wraps + * + * @apiviz.uses de.lmu.ifi.dbs.elki.result.textwriter.StreamFactory oneway - - + * wraps */ public class TextWriterStream { /** @@ -66,8 +68,8 @@ public class TextWriterStream { public static final String QUOTE = "# "; /** - * Comment separator line. - * Since this will be printed without {@link #QUOTE} infront, it should be quoted string itself. + * Comment separator line. Since this will be printed without {@link #QUOTE} + * infront, it should be quoted string itself. */ public static final String COMMENTSEP = "###############################################################"; @@ -80,12 +82,17 @@ public class TextWriterStream { * Marker used in text serialization (and re-parsing) */ public static final String SER_MARKER = "Serialization class:"; - + /** * Force incomments flag */ // TODO: solve this more gracefully - private boolean forceincomments = false; + private boolean forceincomments = false; + + /** + * Fallback writer, using toString. + */ + private TextWriterObjectComment fallbackwriter = new TextWriterObjectComment(); /** * Constructor. @@ -99,7 +106,7 @@ public class TextWriterStream { inline = new StringBuilder(); comment = new StringBuilder(); } - + /** * Print an object into the comments section * @@ -122,22 +129,21 @@ public class TextWriterStream { /** * Print a newline into the comments section. */ - public void commentPrintLn() { + public void commentPrintLn() { comment.append(NEWLINE); } - /** - * Print a separator line in the comments section. - */ + /** + * Print a separator line in the comments section. + */ public void commentPrintSeparator() { comment.append(COMMENTSEP + NEWLINE); } /** - * Print data into the inline part of the file. - * Data is sanitized: newlines are replaced with spaces, and text - * containing separators is put in quotes. Quotes and escape characters - * are escaped. + * Print data into the inline part of the file. Data is sanitized: newlines + * are replaced with spaces, and text containing separators is put in quotes. + * Quotes and escape characters are escaped. * * @param o object to print */ @@ -150,19 +156,19 @@ public class TextWriterStream { inline.append(SEPARATOR); } // remove newlines - String str = o.toString().replace(NEWLINE," "); + String str = o.toString().replace(NEWLINE, " "); // escaping - str = str.replace("\\","\\\\").replace("\"","\\\""); + str = str.replace("\\", "\\\\").replace("\"", "\\\""); // when needed, add quotes. if (str.contains(SEPARATOR)) { - str = "\""+str+"\""; + str = "\"" + str + "\""; } inline.append(str); } /** - * Print data into the inline part of the file WITHOUT checking for - * separators (and thus quoting). + * Print data into the inline part of the file WITHOUT checking for separators + * (and thus quoting). * * @param o object to print. */ @@ -175,15 +181,14 @@ public class TextWriterStream { inline.append(SEPARATOR); } // remove newlines - String str = o.toString().replace(NEWLINE," "); + String str = o.toString().replace(NEWLINE, " "); // escaping - str = str.replace("\\","\\\\").replace("\"","\\\""); + str = str.replace("\\", "\\\\").replace("\"", "\\\""); inline.append(str); } /** - * Flush output: - * write inline data, then write comment section. Reset streams. + * Flush output: write inline data, then write comment section. Reset streams. */ public void flush() { if (inline.length() > 0) { @@ -220,13 +225,26 @@ public class TextWriterStream { * @return appropriate write, if available */ public TextWriterWriterInterface<?> getWriterFor(Object o) { - return writers.getHandler(o); + if (o == null) { + return null; + } + TextWriterWriterInterface<?> writer = writers.getHandler(o); + if (writer == null) { + try { + if (o.getClass().getMethod("toString").getDeclaringClass() != Object.class) { + return fallbackwriter; + } + } catch (Exception e) { + return null; + } + } + return writer; } /** - * Restore a vector undoing any normalization that was applied. - * (This class does not support normalization, it is only provided - * by derived classes, which will then have to use generics.) + * Restore a vector undoing any normalization that was applied. (This class + * does not support normalization, it is only provided by derived classes, + * which will then have to use generics.) * * @param <O> Object class * @param v vector to restore diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterWriterInterface.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterWriterInterface.java index cfaa3373..35fa487f 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterWriterInterface.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterWriterInterface.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/NamingScheme.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/NamingScheme.java index 4b2c099f..a63d3726 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/NamingScheme.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/NamingScheme.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.naming; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/SimpleEnumeratingScheme.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/SimpleEnumeratingScheme.java index c1d0f8e5..dacb342b 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/SimpleEnumeratingScheme.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/SimpleEnumeratingScheme.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.naming; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -47,12 +47,12 @@ public class SimpleEnumeratingScheme implements NamingScheme { /** * count how often each name occurred so far. */ - private Map<String, Integer> namecount = new HashMap<String, Integer>(); + private Map<String, Integer> namecount = new HashMap<>(); /** * Assigned cluster names. */ - private Map<Cluster<?>, String> names = new HashMap<Cluster<?>, String>(); + private Map<Cluster<?>, String> names = new HashMap<>(); /** * This is the postfix added to the first cluster, which will be removed when diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/package-info.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/package-info.java index 600e731e..ab4b93d0 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/package-info.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/package-info.java index 872df780..60f2f534 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/package-info.java @@ -6,7 +6,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterDoubleDoublePair.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterDoubleDoublePair.java index 4af9d8a4..a9975195 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterDoubleDoublePair.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterDoubleDoublePair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectArray.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectArray.java index be195648..34d5b419 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectArray.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectArray.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectComment.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectComment.java index d4da18f5..d3de4ff3 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectComment.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectComment.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectInline.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectInline.java index a621ab4b..28c549d7 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectInline.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectInline.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterPair.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterPair.java index 3c1440bc..1705f5cc 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterPair.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterPair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTextWriteable.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTextWriteable.java index 87a3661b..04e56ae5 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTextWriteable.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTextWriteable.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -32,7 +32,7 @@ import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterWriterInterface; * * @author Erich Schubert * - * @apiviz.uses TextWriteable + * @apiviz.has TextWriteable */ public class TextWriterTextWriteable extends TextWriterWriterInterface<TextWriteable> { /** diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTriple.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTriple.java index 55dd7106..1efde342 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTriple.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTriple.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java index 1452c432..46197e21 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/package-info.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/package-info.java index c83dd767..da527a67 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/package-info.java @@ -6,7 +6,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team |