/* * 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.ui.controls; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.core.DBeaverActivator; import org.jkiss.dbeaver.model.runtime.AbstractJob; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; 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.*; /** * Viewer columns registry */ class ViewerColumnRegistry { private static final Log log = Log.getLog(ViewerColumnRegistry.class); private static final String COLUMNS_CONFIG_FILE = "column_settings.xml"; private static ViewerColumnRegistry instance; public static synchronized ViewerColumnRegistry getInstance() { if (instance == null) { instance = new ViewerColumnRegistry(); } return instance; } public static class ColumnState { String name; boolean visible; int order; int width; public ColumnState() { } public ColumnState(ColumnState source) { this.name = source.name; this.visible = source.visible; this.order = source.order; this.width = source.width; } @Override public String toString() { return name + ":" + order; } } private final Map<String, List<ColumnState>> columnsConfig = new TreeMap<>(); private volatile ConfigSaver saver = null; public ViewerColumnRegistry() { File columnsConfig = DBeaverActivator.getConfigurationFile(COLUMNS_CONFIG_FILE); if (columnsConfig.exists()) { loadConfiguration(columnsConfig); } } Collection<ColumnState> getSavedConfig(String controlId) { synchronized (columnsConfig) { return columnsConfig.get(controlId); } } void updateConfig(String controlId, Collection<? extends ColumnState> columns) { synchronized (columnsConfig) { List<ColumnState> newStates = new ArrayList<>(columns.size()); for (ColumnState state : columns) { newStates.add(new ColumnState(state)); } columnsConfig.put(controlId, newStates); if (saver == null) { saver = new ConfigSaver(); saver.schedule(3000); } } } private void loadConfiguration(File configFile) { columnsConfig.clear(); try (InputStream in = new FileInputStream(configFile)) { SAXReader parser = new SAXReader(in); final ColumnsParser dsp = new ColumnsParser(); parser.parse(dsp); } catch (Exception e) { log.error("Error loading columns configuration", e); } } private class ConfigSaver extends AbstractJob { protected ConfigSaver() { super("Columns configuration save"); } @Override protected IStatus run(DBRProgressMonitor monitor) { synchronized (columnsConfig) { //log.debug("Save column config " + System.currentTimeMillis()); flushConfig(); saver = null; } return Status.OK_STATUS; } private void flushConfig() { File configFile = DBeaverActivator.getConfigurationFile(COLUMNS_CONFIG_FILE); try (OutputStream out = new FileOutputStream(configFile)) { XMLBuilder xml = new XMLBuilder(out, GeneralUtils.UTF8_ENCODING); xml.setButify(true); try (final XMLBuilder.Element e = xml.startElement("items")) { for (Map.Entry<String, List<ColumnState>> entry : columnsConfig.entrySet()) { try (final XMLBuilder.Element e2 = xml.startElement("item")) { xml.addAttribute("id", entry.getKey()); for (ColumnState column : entry.getValue()) { try (final XMLBuilder.Element e3 = xml.startElement("column")) { xml.addAttribute("name", column.name); xml.addAttribute("visible", column.visible); xml.addAttribute("order", column.order); xml.addAttribute("width", column.width); } } } } } xml.flush(); } catch (Exception e) { log.error("Error saving columns configuration", e); } } } private class ColumnsParser extends SAXListener.BaseListener { private List<ColumnState> curColumnState = null; private ColumnsParser() { } @Override public void saxStartElement(SAXReader reader, String namespaceURI, String localName, Attributes atts) throws XMLException { switch (localName) { case "items": break; case "item": curColumnState = new ArrayList<>(); columnsConfig.put(atts.getValue("id"), curColumnState); break; case "column": if (curColumnState != null) { ColumnState col = new ColumnState(); col.name = atts.getValue("name"); col.visible = CommonUtils.getBoolean(atts.getValue("visible"), true); col.order = CommonUtils.toInt(atts.getValue("order"), 0); col.width = CommonUtils.toInt(atts.getValue("width"), 0); curColumnState.add(col); } break; } } } }