package name.abuchen.portfolio.model; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.util.UUID; import name.abuchen.portfolio.money.Values; public final class TaxonomyTemplate { /* package */static final String INDUSTRY_GICS = "industry-gics"; //$NON-NLS-1$ /* package */static final String INDUSTRY_SIMPLE2LEVEL = "industry-simple2level"; //$NON-NLS-1$ private static final List<TaxonomyTemplate> TEMPLATES = Arrays.asList( // new TaxonomyTemplate("assetclasses"), //$NON-NLS-1$ new TaxonomyTemplate(INDUSTRY_GICS), // new TaxonomyTemplate(INDUSTRY_SIMPLE2LEVEL), // new TaxonomyTemplate("kommer"), //$NON-NLS-1$ new TaxonomyTemplate("regions")); //$NON-NLS-1$ private String id; private String name; private TaxonomyTemplate(String id) { this.id = id; ResourceBundle bundle = ResourceBundle.getBundle("/META-INF/taxonomy/" + id); //$NON-NLS-1$ this.name = getString(bundle, "name"); //$NON-NLS-1$ } public static List<TaxonomyTemplate> list() { return Collections.unmodifiableList(TEMPLATES); } public static TaxonomyTemplate byId(String id) { for (TaxonomyTemplate template : TEMPLATES) { if (template.getId().equals(id)) return template; } return null; } public String getId() { return id; } public String getName() { return name; } /** * Builds a taxonomy based on the template. */ public Taxonomy build() { Taxonomy taxonomy = buildFromTemplate(); // classification identifier must be globally unique because they are // used when storing chart configurations, etc. taxonomy.setId(UUID.randomUUID().toString()); taxonomy.foreach(new Taxonomy.Visitor() { @Override public void visit(Classification classification) { classification.setId(UUID.randomUUID().toString()); } }); return taxonomy; } /** * Builds a taxonomy based on the template including the original UUIDs. Use * only for translation purposes. */ public Taxonomy buildOriginal() { return buildFromTemplate(); } /** * Builds a taxonomy with exactly the identifier specified in the template. * Needed to convert legacy (hard-coded) taxonomies such as asset classes * and industry classifications to new style taxonomies. */ /* package */Taxonomy buildFromTemplate() { ResourceBundle bundle = ResourceBundle.getBundle("/META-INF/taxonomy/" + id); //$NON-NLS-1$ Taxonomy taxonomy = new Taxonomy(id, name); Classification root = new Classification(id, name); taxonomy.setRootNode(root); taxonomy.setDimensions(Arrays.asList(getString(bundle, "labels").split(","))); //$NON-NLS-1$ //$NON-NLS-2$ readClassification(bundle, root); String colors = getString(bundle, "colors"); //$NON-NLS-1$ if (colors != null) { String[] hsb = colors.split(","); //$NON-NLS-1$ root.assignRandomColors(Float.parseFloat(hsb[0]), Float.parseFloat(hsb[1]), Float.parseFloat(hsb[2])); } return taxonomy; } private void readClassification(ResourceBundle bundle, Classification parent) { String children = getString(bundle, parent.getId() + ".children"); //$NON-NLS-1$ if (children == null) return; for (String childId : children.split(",")) //$NON-NLS-1$ { String label = getString(bundle, childId + ".label"); //$NON-NLS-1$ if (label == null) continue; String color = getString(bundle, childId + ".color"); //$NON-NLS-1$ Classification child = new Classification(parent, childId, label, color); int weight = getInt(bundle, childId + ".weight"); //$NON-NLS-1$ if (weight >= 0) child.setWeight(weight * Values.Weight.factor()); String description = getString(bundle, childId + ".description"); //$NON-NLS-1$ if (description != null) child.setNote(description); parent.addChild(child); readClassification(bundle, child); } } private String getString(ResourceBundle bundle, String key) { try { return bundle.getString(key); } catch (MissingResourceException e) { return null; } } private int getInt(ResourceBundle bundle, String key) { try { return Integer.parseInt(bundle.getString(key)); } catch (MissingResourceException e) { return -1; } } }