package org.codemap.resources; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import org.codemap.Configuration; import org.codemap.Point; import org.codemap.internal.LayoutAlgorithm; import org.codemap.util.MapScheme; import ch.akuhn.hapax.Hapax; import ch.akuhn.hapax.index.LatentSemanticIndex; /** Not thread-safe. * * @author akuhn * */ public class MapBuilder { public static final MapScheme<Double> FILE_LENGTH_SQRT = new MapScheme<Double>() { @Override public Double forLocation(Point location) { return Math.sqrt(new File(location.getDocument()).length()); } }; private LatentSemanticIndex lsi = null; public MapBuilder addCorpus(Hapax hapax) { if (this.lsi != null) throw new IllegalStateException(); this.lsi = hapax.getIndex(); return this; } public Configuration makeMap(Configuration initialConfiguration) { if (this.lsi == null) throw new IllegalStateException(); double[] x = new double[lsi.documentCount()]; double[] y = new double[lsi.documentCount()]; Map<String, Point> cachedPoints = initialConfiguration.asMap(); int n = 0; boolean doLayout = false; for (String document: lsi.documents()) { Point p = cachedPoints.get(document); if (p == null) { p = Point.newRandom(document); doLayout = true; } x[n] = p.x; y[n] = p.y; n++; } Collection<Point> locations = doLayout ? runLayout(lsi, x, y) : loadCached(lsi, x, y); return new Configuration(locations).normalize(); } private Collection<Point> runLayout(LatentSemanticIndex lsi, double[] x, double[] y) { LayoutAlgorithm mds = LayoutAlgorithm.fromCorrelationMatrix(lsi, x, y); mds.normalize(); Collection<Point> locations = new ArrayList<Point>(); int index = 0; for (String each: lsi.documents()) { locations.add(new Point(mds.x[index], mds.y[index], each)); index++; } return locations; } private Collection<Point> loadCached(LatentSemanticIndex lsi2, double[] x, double[] y) { Collection<Point> locations = new ArrayList<Point>(); int index = 0; for (String each: lsi.documents()) { locations.add(new Point(x[index], y[index], each)); index++; } return locations; } public MapBuilder addCorpus(LatentSemanticIndex index) { if (this.lsi != null) throw new IllegalStateException(); this.lsi = index; return this; } }