package com.kennycason.kumo.cli; import com.beust.jcommander.JCommander; import com.kennycason.kumo.LayeredWordCloud; import com.kennycason.kumo.PolarWordCloud; import com.kennycason.kumo.WordCloud; import com.kennycason.kumo.WordFrequency; import com.kennycason.kumo.bg.Background; import com.kennycason.kumo.bg.PixelBoundryBackground; import com.kennycason.kumo.cli.CliParameters.FontScalarType; import com.kennycason.kumo.cli.CliParameters.NormalizerType; import com.kennycason.kumo.cli.CliParameters.WordStartType; import com.kennycason.kumo.font.FontWeight; import com.kennycason.kumo.font.KumoFont; import com.kennycason.kumo.font.scale.FontScalar; import com.kennycason.kumo.font.scale.LinearFontScalar; import com.kennycason.kumo.font.scale.LogFontScalar; import com.kennycason.kumo.font.scale.SqrtFontScalar; import com.kennycason.kumo.nlp.FrequencyAnalyzer; import com.kennycason.kumo.nlp.normalize.*; import com.kennycason.kumo.nlp.tokenizer.ChineseWordTokenizer; import com.kennycason.kumo.nlp.tokenizer.EnglishWordTokenizer; import com.kennycason.kumo.nlp.tokenizer.WhiteSpaceWordTokenizer; import com.kennycason.kumo.nlp.tokenizer.WordTokenizer; import com.kennycason.kumo.palette.ColorPalette; import com.kennycason.kumo.wordstart.CenterWordStart; import com.kennycason.kumo.wordstart.RandomWordStart; import com.kennycason.kumo.wordstart.WordStartStrategy; import java.awt.*; import java.io.*; import java.net.URL; import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.jar.Manifest; import static org.apache.commons.lang3.StringUtils.isNotBlank; /** * Created by kenny on 6/12/16. */ public class KumoCli { private final CliParameters cliParameters = new CliParameters(); public static void main(final String[] args) { new KumoCli().runWithArguments(args); } public void runWithArguments(final String[] args) { if (args.length > 0 && args[0].equals("--version")) { printVersion(); return; } new JCommander(cliParameters).parse(args); switch (cliParameters.getType()) { case STANDARD: buildStandardWordCloud(); break; case POLAR: buildPolarWordCloud(); break; case LAYERED: buildLayeredWordCloud(); break; default: throw new UnsupportedOperationException("Unsupported type: " + cliParameters.getType()); } } private void printVersion() { try { final Enumeration<URL> resources = getClass() .getClassLoader() .getResources("META-INF/MANIFEST.MF"); while (resources.hasMoreElements()) { final Manifest manifest = new Manifest(resources.nextElement().openStream()); if (isNotBlank(manifest.getMainAttributes().getValue("Implementation-Version"))) { System.out.println("Kumo Version: " + manifest.getMainAttributes().getValue("Implementation-Version")); return; } } throw new RuntimeException("Failed to load version from manifest"); } catch (final IOException e) { System.out.println(e.getMessage()); e.printStackTrace(); } } private void buildLayeredWordCloud() { if (cliParameters.getInputSources().size() == 1) { buildStandardWordCloud(); return; } if (cliParameters.getInputSources().size() != cliParameters.getBackgrounds().size()) { throw new IllegalArgumentException("Number of input sources does not equal the number of backgrounds."); } if (cliParameters.getInputSources().size() != cliParameters.getLayeredColors().size()) { throw new IllegalArgumentException("Number of input sources does not equal the number of colors."); } final LayeredWordCloud wordCloud = new LayeredWordCloud( cliParameters.getInputSources().size(), new Dimension(cliParameters.getWidth(), cliParameters.getHeight()), cliParameters.getCollisionMode() ); wordCloud.setBackgroundColor(cliParameters.getBackgroundColor()); for (int i = 0; i < cliParameters.getInputSources().size(); i++) { wordCloud.setBackground(i, buildBackground(cliParameters.getBackgrounds().get(i))); wordCloud.setColorPalette(i, new ColorPalette(cliParameters.getLayeredColors().get(i))); wordCloud.setFontScalar(i, buildFontScalar(cliParameters.getFontScalarType())); wordCloud.setPadding(i, cliParameters.getPadding()); wordCloud.setKumoFont(i, buildKumoFont(cliParameters.getFontWeight())); wordCloud.build(i, loadFrequencies(cliParameters.getInputSources().get(i))); } wordCloud.writeToFile(cliParameters.getOutputSource()); } private void buildPolarWordCloud() { if (cliParameters.getInputSources().size() != 2) { throw new IllegalArgumentException("Polar word clouds require exactly 2 input sources. Found: " + cliParameters.getInputSources().size()); } final PolarWordCloud wordCloud = new PolarWordCloud( new Dimension(cliParameters.getWidth(), cliParameters.getHeight()), cliParameters.getCollisionMode(), cliParameters.getPolarBlendMode() ); if (!cliParameters.getBackgrounds().isEmpty()) { wordCloud.setBackground(buildBackground(cliParameters.getBackgrounds().get(0))); } wordCloud.setBackgroundColor(cliParameters.getBackgroundColor()); if (cliParameters.getLayeredColors().size() >= 1) { wordCloud.setColorPalette(new ColorPalette(cliParameters.getLayeredColors().get(0))); } if (cliParameters.getLayeredColors().size() >= 2) { wordCloud.setColorPalette2(new ColorPalette(cliParameters.getLayeredColors().get(1))); } wordCloud.setFontScalar(buildFontScalar(cliParameters.getFontScalarType())); wordCloud.setPadding(cliParameters.getPadding()); wordCloud.setWordStartStrategy(buildWordStart(cliParameters.getWordStartType())); wordCloud.setKumoFont(buildKumoFont(cliParameters.getFontWeight())); wordCloud.build(loadFrequencies(cliParameters.getInputSources().get(0)), loadFrequencies(cliParameters.getInputSources().get(1))); wordCloud.writeToFile(cliParameters.getOutputSource()); } private void buildStandardWordCloud() { final WordCloud wordCloud = new WordCloud( new Dimension(cliParameters.getWidth(), cliParameters.getHeight()), cliParameters.getCollisionMode() ); if (!cliParameters.getBackgrounds().isEmpty()) { wordCloud.setBackground(buildBackground(cliParameters.getBackgrounds().get(0))); } wordCloud.setBackgroundColor(cliParameters.getBackgroundColor()); if (!cliParameters.getColors().isEmpty()) { wordCloud.setColorPalette(new ColorPalette(cliParameters.getColors())); } wordCloud.setFontScalar(buildFontScalar(cliParameters.getFontScalarType())); wordCloud.setPadding(cliParameters.getPadding()); wordCloud.setWordStartStrategy(buildWordStart(cliParameters.getWordStartType())); wordCloud.setKumoFont(buildKumoFont(cliParameters.getFontWeight())); wordCloud.build(loadFrequencies(cliParameters.getInputSources().get(0))); wordCloud.writeToFile(cliParameters.getOutputSource()); } private List<WordFrequency> loadFrequencies(final String input) { try { final FrequencyAnalyzer frequencyAnalyzer = new FrequencyAnalyzer(); frequencyAnalyzer.setWordFrequenciesToReturn(cliParameters.getWordCount()); frequencyAnalyzer.setMinWordLength(cliParameters.getMinWordLength()); frequencyAnalyzer.setStopWords(cliParameters.getStopWords()); frequencyAnalyzer.setCharacterEncoding(cliParameters.getCharacterEncoding()); if (cliParameters.getNormalizers().isEmpty()) { cliParameters.getNormalizers().addAll(Arrays.asList(NormalizerType.TRIM, NormalizerType.CHARACTER_STRIPPING, NormalizerType.LOWERCASE)); } for (final NormalizerType normalizer : cliParameters.getNormalizers()) { frequencyAnalyzer.addNormalizer(buildNormalizer(normalizer)); } frequencyAnalyzer.setWordTokenizer(buildTokenizer()); return frequencyAnalyzer.load(toInputStream(input)); } catch (final IOException e) { throw new RuntimeException(e.getMessage(), e); } } private WordTokenizer buildTokenizer() { switch (cliParameters.getTokenizer()) { case WHITE_SPACE: return new WhiteSpaceWordTokenizer(); case ENGLISH: return new EnglishWordTokenizer(); case CHINESE: return new ChineseWordTokenizer(); } throw new IllegalStateException("Unknown tokenizer: " + cliParameters.getTokenizer()); } private Normalizer buildNormalizer(final NormalizerType normalizer) { switch (normalizer) { case LOWERCASE: return new LowerCaseNormalizer(); case UPPERCASE: return new UpperCaseNormalizer(); case BUBBLE: return new BubbleTextNormalizer(); case CHARACTER_STRIPPING: return new CharacterStrippingNormalizer(); case UPSIDE_DOWN: return new UpsideDownNormalizer(); case TRIM: return new TrimToEmptyNormalizer(); } throw new IllegalStateException("Unknown normalizer: " + normalizer); } private KumoFont buildKumoFont(final FontWeight fontWeight) { return new KumoFont(cliParameters.getFontType(), fontWeight); } private static WordStartStrategy buildWordStart(final WordStartType wordStartType) { switch (wordStartType) { case CENTER: return new CenterWordStart(); case RANDOM: return new RandomWordStart(); } throw new IllegalStateException("Unknown word start: " + wordStartType); } private FontScalar buildFontScalar(final FontScalarType fontScalarType) { switch (fontScalarType) { case LINEAR: return new LinearFontScalar(cliParameters.getFontSizeMin(), cliParameters.getFontSizeMax()); case SQRT: return new SqrtFontScalar(cliParameters.getFontSizeMin(), cliParameters.getFontSizeMax()); case LOG: return new LogFontScalar(cliParameters.getFontSizeMin(), cliParameters.getFontSizeMax()); } throw new IllegalStateException("Unknown font scalar type: " + fontScalarType); } private static Background buildBackground(final String background) { try { return new PixelBoundryBackground(toInputStream(background)); } catch (final IOException e) { throw new RuntimeException(e.getMessage(), e); } } private static InputStream toInputStream(final String path) { final File file = new File(path); if (file.exists() && !file.isDirectory()) { try { return new FileInputStream(file); } catch (final FileNotFoundException e) { throw new RuntimeException(e.getMessage(), e); } } try { return new URL(path).openStream(); } catch (final IOException ignored) { } throw new RuntimeException("Input path [" + path + "] not a file or url."); } }