/* * DBeaver - Universal Database Manager * Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jkiss.dbeaver.registry.formatter; import org.eclipse.core.runtime.Platform; import org.jkiss.dbeaver.Log; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionRegistry; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.core.DBeaverActivator; import org.jkiss.dbeaver.core.DBeaverCore; import org.jkiss.dbeaver.model.data.DBDDataFormatterProfile; import org.jkiss.dbeaver.model.impl.preferences.SimplePreferenceStore; import org.jkiss.dbeaver.registry.RegistryConstants; import org.jkiss.dbeaver.utils.GeneralUtils; import org.jkiss.utils.CommonUtils; import org.jkiss.utils.xml.SAXListener; import org.jkiss.utils.xml.SAXReader; import org.jkiss.utils.xml.XMLBuilder; import org.jkiss.utils.xml.XMLException; import org.xml.sax.Attributes; import java.io.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class DataFormatterRegistry { private static final Log log = Log.getLog(DataFormatterRegistry.class); public static final String CONFIG_FILE_NAME = "dataformat-profiles.xml"; //$NON-NLS-1$ private static DataFormatterRegistry instance = null; public synchronized static DataFormatterRegistry getInstance() { if (instance == null) { instance = new DataFormatterRegistry(Platform.getExtensionRegistry()); } return instance; } private final List<DataFormatterDescriptor> dataFormatterList = new ArrayList<>(); private final Map<String, DataFormatterDescriptor> dataFormatterMap = new HashMap<>(); private DBDDataFormatterProfile globalProfile; private List<DBDDataFormatterProfile> customProfiles = null; private DataFormatterRegistry(IExtensionRegistry registry) { // Load data formatters from external plugins { IConfigurationElement[] extElements = registry.getConfigurationElementsFor(DataFormatterDescriptor.EXTENSION_ID); for (IConfigurationElement ext : extElements) { DataFormatterDescriptor formatterDescriptor = new DataFormatterDescriptor(ext); dataFormatterList.add(formatterDescriptor); dataFormatterMap.put(formatterDescriptor.getId(), formatterDescriptor); } } } public void dispose() { this.dataFormatterList.clear(); this.dataFormatterMap.clear(); this.globalProfile = null; } //////////////////////////////////////////////////// // Data formatters public List<DataFormatterDescriptor> getDataFormatters() { return dataFormatterList; } public DataFormatterDescriptor getDataFormatter(String typeId) { return dataFormatterMap.get(typeId); } public synchronized DBDDataFormatterProfile getGlobalProfile() { if (globalProfile == null) { globalProfile = new DataFormatterProfile( "Global", DBeaverCore.getGlobalPreferenceStore()); } return globalProfile; } @Nullable public DBDDataFormatterProfile getCustomProfile(String name) { for (DBDDataFormatterProfile profile : getCustomProfiles()) { if (profile.getProfileName().equals(name)) { return profile; } } return null; } public synchronized List<DBDDataFormatterProfile> getCustomProfiles() { if (customProfiles == null) { loadProfiles(); } return customProfiles; } private void loadProfiles() { customProfiles = new ArrayList<>(); File storeFile = DBeaverActivator.getConfigurationFile(CONFIG_FILE_NAME); if (!storeFile.exists()) { return; } try { try (InputStream is = new FileInputStream(storeFile)) { SAXReader parser = new SAXReader(is); try { parser.parse(new FormattersParser()); } catch (XMLException ex) { throw new DBException("Datasource config parse error", ex); } } catch (DBException ex) { log.warn("Can't load profiles config from " + storeFile.getPath(), ex); } } catch (IOException ex) { log.warn("IO error", ex); } } private void saveProfiles() { if (customProfiles == null) { return; } File storeFile = DBeaverActivator.getConfigurationFile(CONFIG_FILE_NAME); try (OutputStream os = new FileOutputStream(storeFile)) { XMLBuilder xml = new XMLBuilder(os, GeneralUtils.UTF8_ENCODING); xml.setButify(true); xml.startElement(RegistryConstants.TAG_PROFILES); for (DBDDataFormatterProfile profile : customProfiles) { xml.startElement(RegistryConstants.TAG_PROFILE); xml.addAttribute(RegistryConstants.ATTR_NAME, profile.getProfileName()); SimplePreferenceStore store = (SimplePreferenceStore) profile.getPreferenceStore(); Map<String, String> props = store.getProperties(); if (props != null) { for (Map.Entry<String,String> entry : props.entrySet()) { xml.startElement(RegistryConstants.TAG_PROPERTY); xml.addAttribute(RegistryConstants.ATTR_NAME, entry.getKey()); xml.addAttribute(RegistryConstants.ATTR_VALUE, entry.getValue()); xml.endElement(); } } xml.endElement(); } xml.endElement(); xml.flush(); } catch (IOException ex) { log.warn("IO error", ex); } } public DBDDataFormatterProfile createCustomProfile(String profileName) { getCustomProfiles(); DBDDataFormatterProfile profile = new DataFormatterProfile(profileName, new CustomProfileStore()); customProfiles.add(profile); saveProfiles(); return profile; } public void deleteCustomProfile(DBDDataFormatterProfile profile) { getCustomProfiles(); if (customProfiles.remove(profile)) { saveProfiles(); } } private class CustomProfileStore extends SimplePreferenceStore { private CustomProfileStore() { super(DBeaverCore.getGlobalPreferenceStore()); } @Override public void save() throws IOException { saveProfiles(); } } private class FormattersParser extends SAXListener.BaseListener { private String profileName; private SimplePreferenceStore curStore; @Override public void saxStartElement(SAXReader reader, String namespaceURI, String localName, Attributes atts) throws XMLException { if (localName.equals(RegistryConstants.TAG_PROFILE)) { curStore = new CustomProfileStore(); profileName = atts.getValue(RegistryConstants.ATTR_NAME); } else if (localName.equals(RegistryConstants.TAG_PROPERTY)) { if (curStore != null) { curStore.setValue( atts.getValue(RegistryConstants.ATTR_NAME), atts.getValue(RegistryConstants.ATTR_VALUE)); } } } @Override public void saxEndElement(SAXReader reader, String namespaceURI, String localName) throws XMLException { if (localName.equals(RegistryConstants.TAG_PROFILE)) { if (!CommonUtils.isEmpty(profileName)) { DataFormatterProfile profile = new DataFormatterProfile(profileName, curStore); customProfiles.add(profile); } } } } }