/******************************************************************************* * Copyright (c) 2010 Philipp Kursawe. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Philipp Kursawe (phil.kursawe@gmail.com) - initial API and implementation ******************************************************************************/ package eclipseutils.jface.preferences; import java.util.Iterator; import org.eclipse.core.runtime.preferences.DefaultScope; import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.swt.widgets.Composite; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; /** * Implementation of a table viewer editor that saves items in a hierarchical * tree. * * <p> * It create nodes with the items ID (returned by {@link #getId(Object)} under * the <code>preferencePath</code> * * @author <a href="mailto:phil.kursawe@gmail.com">Philipp Kursawe</a> * * @param <T> * type of the items in the table */ public abstract class TableViewerFieldEditor<T> extends AbstractTableViewerFieldEditor<T> { protected TableViewerFieldEditor(final String preferencePath, final String labelText, final Composite parent) { super(preferencePath, labelText, parent); } /** * @param item * to get the id from. Must <b>not</b> be <code>null</code>. * @return the id for the item. */ protected abstract String getId(T item); /** * Creates a new item. * * <p> * Implementors should not call {@link #add(T)} themselves. It's called by * the caller of this method. * * @param preferences * to create the item from * @return the newly created item or <code>null</code> if no item could be * constructed from the given <i>preferences</i>. * */ protected abstract T loadItem(Preferences preferences); protected IScopeContext getScopeContext() { return new InstanceScope(); } @Override protected void doStore() { final IScopeContext instanceScope = getScopeContext(); Preferences node = instanceScope.getNode(getPreferenceName()); try { node.removeNode(); if (!presentsDefaultValue()) { node = instanceScope.getNode(getPreferenceName()); final Iterator<T> it = getItems().iterator(); while (it.hasNext()) { final T item = it.next(); store(item, node.node(getId(item))); } node.flush(); } } catch (final BackingStoreException e) { } } protected abstract void store(T item, Preferences node); @Override protected void doLoad() { final Preferences node = getScopeContext().getNode(getPreferenceName()); try { doLoad(node, node.childrenNames()); } catch (final BackingStoreException e) { } } @Override protected void doLoadDefault() { final Preferences node = new DefaultScope() .getNode(getPreferenceName()); try { doLoad(node, node.childrenNames()); } catch (final BackingStoreException e) { } } /** * The default implementation calls {@link #loadItem(Preferences)} with each * child node of the given <i>instanceNode</i>. * * Sub-classes may overwrite to provide a different behavior. * * @param instanceNode * @param childrenNames */ protected void doLoad(final Preferences instanceNode, final String... childrenNames) { for (final String key : childrenNames) { final T item = loadItem(instanceNode.node(key)); if (item != null) { add(item); } } } /** * The default implementation just calls * {@link #doLoad(Preferences, String...)} * * @param defaultNode * @param childrenNames */ protected void doLoadDefault(final Preferences defaultNode, final String... childrenNames) { doLoad(); } }