/*
* Copyright (C) 2007-2012 Argeo GmbH
*
* 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.argeo.cms.ui.workbench.jcr;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.version.VersionManager;
import org.apache.commons.io.IOUtils;
import org.argeo.eclipse.ui.EclipseUiException;
import org.argeo.jcr.JcrUtils;
import org.argeo.node.ArgeoNames;
import org.argeo.node.ArgeoTypes;
import org.argeo.node.NodeUtils;
import org.eclipse.jface.preference.PreferenceStore;
import org.osgi.framework.BundleContext;
/**
* Persist preferences as key/value pairs under ~/argeo:preferences.
* TODO: better integrate JCR and Eclipse:
* - typing
* - use eclipse preferences
* - better integrate with ScopedPreferenceStore
provided by RAP
*/
public class JcrPreferenceStore extends PreferenceStore implements ArgeoNames {
private static final long serialVersionUID = 1854011367784598758L;
private Session session;
private BundleContext bundleContext;
/** Retrieves the preference node */
protected Node getPreferenceNode() {
try {
if (session.hasPendingChanges())
session.save();
Node userHome = NodeUtils.getUserHome(session);
if (userHome == null)
throw new EclipseUiException("No user home for "
+ session.getUserID());
Node preferences;
if (!userHome.hasNode(ARGEO_PREFERENCES)) {
preferences = userHome.addNode(ARGEO_PREFERENCES);
preferences.addMixin(ArgeoTypes.ARGEO_PREFERENCE_NODE);
session.save();
} else
preferences = userHome.getNode(ARGEO_PREFERENCES);
String pluginPreferencesName = bundleContext.getBundle()
.getSymbolicName();
Node pluginPreferences;
if (!preferences.hasNode(pluginPreferencesName)) {
VersionManager vm = session.getWorkspace().getVersionManager();
vm.checkout(preferences.getPath());
pluginPreferences = preferences.addNode(pluginPreferencesName);
pluginPreferences.addMixin(ArgeoTypes.ARGEO_PREFERENCE_NODE);
session.save();
vm.checkin(preferences.getPath());
} else
pluginPreferences = preferences.getNode(pluginPreferencesName);
return pluginPreferences;
} catch (RepositoryException e) {
e.printStackTrace();
JcrUtils.discardQuietly(session);
throw new EclipseUiException("Cannot retrieve preferences", e);
}
}
@Override
public void load() throws IOException {
ByteArrayOutputStream out = null;
ByteArrayInputStream in = null;
try {
Properties props = new Properties();
PropertyIterator it = getPreferenceNode().getProperties();
while (it.hasNext()) {
Property p = it.nextProperty();
if (!p.isMultiple() && !p.getDefinition().isProtected()) {
props.setProperty(p.getName(), p.getValue().getString());
}
}
out = new ByteArrayOutputStream();
props.store(out, "");
in = new ByteArrayInputStream(out.toByteArray());
load(in);
} catch (Exception e) {
e.printStackTrace();
throw new EclipseUiException("Cannot load preferences", e);
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
}
}
@Override
public void save() throws IOException {
ByteArrayOutputStream out = null;
ByteArrayInputStream in = null;
Node pluginPreferences = null;
try {
out = new ByteArrayOutputStream();
save(out, "");
in = new ByteArrayInputStream(out.toByteArray());
Properties props = new Properties();
props.load(in);
pluginPreferences = getPreferenceNode();
VersionManager vm = pluginPreferences.getSession().getWorkspace()
.getVersionManager();
vm.checkout(pluginPreferences.getPath());
for (Object key : props.keySet()) {
String name = key.toString();
String value = props.getProperty(name);
pluginPreferences.setProperty(name, value);
}
JcrUtils.updateLastModified(pluginPreferences);
pluginPreferences.getSession().save();
vm.checkin(pluginPreferences.getPath());
} catch (Exception e) {
JcrUtils.discardUnderlyingSessionQuietly(pluginPreferences);
throw new EclipseUiException("Cannot save preferences", e);
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
}
}
public void init() {
try {
load();
} catch (IOException e) {
throw new EclipseUiException("Cannot initialize preference store", e);
}
}
public void setSession(Session session) {
this.session = session;
}
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
}