/************************************************************************** OmegaT - Computer Assisted Translation (CAT) tool with fuzzy matching, translation memory, keyword search, glossaries, and translation leveraging into updated projects. Copyright (C) 2000-2006 Keith Godfrey and Maxym Mykhalchuk 2009-2010 Alex Buloichik 2013 Alex Buloichik 2015 Didier Briel Home page: http://www.omegat.org/ Support center: http://groups.yahoo.com/group/OmegaT/ This file is part of OmegaT. OmegaT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OmegaT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. **************************************************************************/ package org.omegat.gui.glossary; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.omegat.core.Core; import org.omegat.core.glossaries.IGlossary; import org.omegat.filters2.master.PluginUtils; import org.omegat.util.DirectoryMonitor; import org.omegat.util.Language; import org.omegat.util.Log; import org.omegat.util.OConsts; import org.omegat.util.Preferences; /** * Class that loads glossary files and adds glossary entries to strings of the source files. * * This class don't need any threads synchronization code, since it only set and clear 'glossaryEntries' var. * * @author Keith Godfrey * @author Maxym Mykhalchuk * @author Alex Buloichik <alex73mail@gmail.com> * @author Didier Briel */ public class GlossaryManager implements DirectoryMonitor.Callback { protected DirectoryMonitor monitor; private final GlossaryTextArea pane; private final Map<String, List<GlossaryEntry>> glossaries = new TreeMap<String, List<GlossaryEntry>>(); protected File priorityGlossary; protected IGlossary[] externalGlossaries; public GlossaryManager(final GlossaryTextArea pane) { this.pane = pane; List<IGlossary> gl = new ArrayList<IGlossary>(); for (Class<?> glc : PluginUtils.getGlossaryClasses()) { try { gl.add((IGlossary) glc.newInstance()); } catch (Exception ex) { Log.log(ex); } } externalGlossaries = gl.toArray(new IGlossary[gl.size()]); Preferences.addPropertyChangeListener(e -> { if (Core.getProject().isProjectLoaded()) { switch (e.getPropertyName()) { case Preferences.GLOSSARY_TBX_DISPLAY_CONTEXT: forceReloadTBX(); break; case Preferences.GLOSSARY_NOT_EXACT_MATCH: case Preferences.GLOSSARY_STEMMING: forceUpdateGlossary(); break; } } }); } public void addGlossaryProvider(IGlossary provider) { List<IGlossary> providers = new ArrayList<IGlossary>(Arrays.asList(externalGlossaries)); providers.add(provider); externalGlossaries = providers.toArray(new IGlossary[providers.size()]); } public void start() { File dir = new File(Core.getProject().getProjectProperties().getGlossaryRoot()); priorityGlossary = new File(Core.getProject().getProjectProperties().getWriteableGlossary()); monitor = new DirectoryMonitor(dir, this); monitor.start(); } public void stop() { monitor.fin(); synchronized (this) { glossaries.clear(); } } @Override public void fileChanged(File file) { synchronized (this) { glossaries.remove(file.getPath()); } if (file.exists()) { try { List<GlossaryEntry> entries = loadGlossaryFile(file); if (entries != null) { synchronized (this) { Log.logRB("CT_LOADING_GLOSSARY_DETAILS", entries.size(), file.getName()); glossaries.put(file.getPath(), entries); } } } catch (Exception ex) { Log.logRB("CT_ERROR_ACCESS_GLOSSARY_DIR"); Log.log(ex); } } pane.refresh(); } public void forceReloadTBX() { Set<File> files = monitor.getExistFiles(); for (File f : files) { if (f.getName().toLowerCase().endsWith(OConsts.EXT_TBX)) { fileChanged(f); } } } public void forceUpdateGlossary() { pane.refresh(); } /** * Loads one glossary file. It choose and calls required required reader. */ private List<GlossaryEntry> loadGlossaryFile(final File file) throws Exception { boolean isPriority = priorityGlossary.equals(file); String fname_lower = file.getName().toLowerCase(); if (fname_lower.endsWith(OConsts.EXT_TSV_DEF)) { Log.logRB("CT_LOADING_GLOSSARY", file.getName()); return GlossaryReaderTSV.read(file, isPriority); } else if (fname_lower.endsWith(OConsts.EXT_TSV_UTF8) || fname_lower.endsWith(OConsts.EXT_TSV_TXT)) { Log.logRB("CT_LOADING_GLOSSARY", file.getName()); return GlossaryReaderTSV.read(file, isPriority); } else if (fname_lower.endsWith(OConsts.EXT_CSV_UTF8)) { Log.logRB("CT_LOADING_GLOSSARY", file.getName()); return GlossaryReaderCSV.read(file, isPriority); } else if (fname_lower.endsWith(OConsts.EXT_TBX)) { Log.logRB("CT_LOADING_GLOSSARY", file.getName()); return GlossaryReaderTBX.read(file, isPriority); } else { return null; } } /** * Get glossary entries. * * @return all entries * @param src */ public List<GlossaryEntry> getGlossaryEntries(String src) { List<GlossaryEntry> result = new ArrayList<GlossaryEntry>(); synchronized (this) { for (List<GlossaryEntry> en : glossaries.values()) { result.addAll(en); } } addExternalGlossaryEntries(result, src); return result; } /** * Get glossary entries for search operation. Almost the same as getGlossaryEntries(), except search * usually executed for every segment in project, i.e. should work enough fast. Then, search should be * produced by local files only. * * @return all entries * @param src */ public List<GlossaryEntry> search(String src) { List<GlossaryEntry> result = new ArrayList<GlossaryEntry>(); synchronized (this) { for (List<GlossaryEntry> en : glossaries.values()) { result.addAll(en); } } return result; } private void addExternalGlossaryEntries(List<GlossaryEntry> result, String src) { Language source = Core.getProject().getProjectProperties().getSourceLanguage(); Language target = Core.getProject().getProjectProperties().getTargetLanguage(); for (IGlossary gl : externalGlossaries) { try { result.addAll(gl.search(source, target, src)); } catch (Exception ex) { Log.log(ex); } } } }