001/* 002 * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Jean-Marc Orliaguet, Chalmers 018 * 019 */ 020 021package org.nuxeo.theme.vocabularies; 022 023import java.io.IOException; 024import java.io.InputStream; 025import java.io.InputStreamReader; 026import java.util.ArrayList; 027import java.util.HashMap; 028import java.util.List; 029import java.util.Map; 030 031import org.apache.commons.csv.CSVFormat; 032import org.apache.commons.csv.CSVParser; 033import org.apache.commons.csv.CSVRecord; 034import org.apache.commons.io.Charsets; 035import org.apache.commons.logging.Log; 036import org.apache.commons.logging.LogFactory; 037 038import org.nuxeo.theme.Manager; 039import org.nuxeo.theme.Registrable; 040import org.nuxeo.theme.types.TypeFamily; 041 042public final class VocabularyManager implements Registrable { 043 044 private static final Log log = LogFactory.getLog(VocabularyManager.class); 045 046 private final Map<String, Vocabulary> vocabularies = new HashMap<>(); 047 048 public List<VocabularyItem> getItems(String name) { 049 VocabularyType vocabularyType = (VocabularyType) Manager.getTypeRegistry().lookup(TypeFamily.VOCABULARY, name); 050 if (vocabularyType == null) { 051 return null; 052 } 053 final String path = vocabularyType.getPath(); 054 final String className = vocabularyType.getClassName(); 055 056 if (path == null && className == null) { 057 log.error("Must specify a class name or a path for vocabulary: " + name); 058 return null; 059 } 060 if (path != null && className != null) { 061 log.error("Cannot specify both a class name and a path for vocabulary: " + name); 062 return null; 063 } 064 065 if (className != null) { 066 Vocabulary vocabulary = getInstance(className); 067 if (vocabulary == null) { 068 log.error("Vocabulary class not found: " + className); 069 return null; 070 } 071 return vocabulary.getItems(); 072 } 073 074 if (path != null) { 075 if (!path.endsWith(".csv")) { 076 log.error("Only .csv vocabularies are supported: " + path); 077 return null; 078 } 079 final List<VocabularyItem> items = new ArrayList<>(); 080 try (InputStream is = getClass().getClassLoader().getResourceAsStream(path)) { 081 if (is == null) { 082 log.error("Vocabulary file not found: " + path); 083 return null; 084 } 085 try (CSVParser reader = new CSVParser(new InputStreamReader(is, Charsets.UTF_8), CSVFormat.DEFAULT)) { 086 for (CSVRecord record : reader) { 087 final String value = record.get(0); 088 String label = value; 089 if (record.size() >= 2) { 090 label = record.get(1); 091 } 092 items.add(new VocabularyItem(value, label)); 093 } 094 } 095 } catch (IOException e) { 096 log.error("Could not read vocabulary file: " + path, e); 097 } 098 return items; 099 } 100 return null; 101 } 102 103 private Vocabulary getInstance(String className) { 104 Vocabulary vocabulary = vocabularies.get(className); 105 if (vocabulary == null) { 106 try { 107 vocabulary = (Vocabulary) Class.forName(className).newInstance(); 108 } catch (InstantiationException e) { 109 log.error("Could not instantiate vocabulary: " + className); 110 } catch (IllegalAccessException e) { 111 log.error("Could not instantiate vocabulary: " + className); 112 } catch (ClassNotFoundException e) { 113 log.error("Could not instantiate vocabulary: " + className); 114 } 115 } 116 if (vocabulary != null) { 117 vocabularies.put(className, vocabulary); 118 } 119 return vocabulary; 120 } 121 122 @Override 123 public void clear() { 124 // FIXME: should call vocabularies.clear() ? 125 } 126 127}