// Copyright 2015 Thomas Müller // This file is part of MarMoT, which is licensed under GPLv3. package lemming.lemma; import java.io.Serializable; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Random; public abstract class LemmaOptions implements Serializable { private static final long serialVersionUID = 1L; protected Map<String, Object> map_; public final static String SEED = "seed"; public final static String NUM_ITERATIONS = "num-iterations"; public static final String VERBOSITY = "verbosity"; public static final String USE_POS = "use-pos"; public static final String AVERAGING = "averaging"; public static final String LIMIT = "limit"; public static final String USE_MORPH = "use-morph"; private Random random_; public LemmaOptions() { map_ = new HashMap<>(); map_.put(SEED, 42L); map_.put(NUM_ITERATIONS, 10); map_.put(VERBOSITY, 0); map_.put(AVERAGING, true); map_.put(USE_POS, true); map_.put(USE_MORPH, false); map_.put(LIMIT, -1); } public Random getRandom() { if (random_ == null) { random_ = new Random((Long) getOption(SEED)); } return random_; } public int getNumIterations() { return (Integer) getOption(NUM_ITERATIONS); } public int getVerbosity() { return (Integer) getOption(VERBOSITY); } public boolean getUsePos() { return (Boolean) getOption(USE_POS); } public boolean getUseMorph() { return (Boolean) getOption(USE_MORPH); } public boolean getAveraging() { return (Boolean) getOption(AVERAGING); } public Object getOption(String name) { Object current_value = map_.get(name); if (current_value == null) { throw new RuntimeException("Unknown option: " + name); } return current_value; } private static final String BSLASH_SYM = "%%BSLASH%%"; private static final String COMMA_SYM = "%%COMMA%%"; private static final String SEMICOL_SYM = "%%SEMICOL%%"; public void readArguments(String options_string) { if (options_string.equals("_")) return; options_string = options_string.replace("\\,", COMMA_SYM).replace("\\;", SEMICOL_SYM).replace("\\\\", BSLASH_SYM); for (String option : options_string.split(",")) { option = option.replace(COMMA_SYM, ",").replace(SEMICOL_SYM, ";").replace(BSLASH_SYM, "\\"); int index = option.indexOf('='); if (index < 0) { throw new RuntimeException(String.format("Not = in " + option)); } String name = option.substring(0, index); String value = option.substring(index + 1); setOption(name, value); } } @SuppressWarnings("unchecked") protected Object getValue(Object current_value, Object value) { Object new_value = null; if (current_value instanceof List) { new_value = getListValue((List<Object>) current_value, value); } else if (current_value.getClass() == value.getClass()) { new_value = value; } else { if (value.getClass() != String.class) { throw new RuntimeException(String.format( "Value is of type %s expected type %s.", value.getClass(), current_value.getClass())); } String value_as_string = (String) value; if (current_value.getClass() == Integer.class) { new_value = Integer.valueOf(value_as_string); } else if (current_value.getClass() == Double.class) { new_value = Double.valueOf(value_as_string); } else if (current_value.getClass() == Long.class) { new_value = Long.valueOf(value_as_string); } else if (current_value.getClass() == Boolean.class) { new_value = Boolean.valueOf(value_as_string); } else if (current_value.getClass() == Class.class){ try { new_value = Class.forName(value_as_string); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } else { throw new RuntimeException("Not implemented: " + current_value.getClass()); } } return new_value; } public LemmaOptions setOption(String name, Object value) { Object current_value = getOption(name); Object new_value = getValue(current_value, value); map_.put(name, new_value); return this; } protected Object getListValue(List<Object> current_value, Object value) { if (value instanceof List) { return value; } if (value.getClass() != String.class) { throw new RuntimeException("Value should be list or string: " + value); } Object first_elem = current_value.get(0); List<Object> list = new LinkedList<>(); String value_as_string = (String) value; for (String element : value_as_string.split(";")) { list.add(getValue(first_elem, element)); } return list; } public String report() { StringBuilder sb = new StringBuilder(); for (Map.Entry<String, Object> entry : map_.entrySet()) { sb.append(String.format("%s: %s\n", entry.getKey(), entry.getValue())); } return sb.toString(); } public Object toInstance(Class<?> klass) { try { return klass.newInstance(); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } public Object getInstance(String name) { Class<?> klass = (Class<?>) getOption(name); return toInstance(klass); } public int getLimit() { return (Integer) getOption(LIMIT); } }