/*
* Copyright (c) 2006, 2009 Borland Software Corporation
*
* 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:
* Alexander Fedorov (Borland) - initial API and implementation
* Artem Tikhomirov (Borland) - refactored to use osgi Preferences and context-sensitive scope
*/
package org.eclipse.gmf.internal.bridge.transform;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.gmf.internal.bridge.ui.Plugin;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
public class TransformOptions extends AbstractPreferenceInitializer {
private static final String PREF_GENERATE_RCP = "generate_rcp"; //$NON-NLS-1$
private static final String PREF_USE_MAP_MODE = "use_map_mode"; //$NON-NLS-1$
private static final String PREF_USE_RUNTIME_FIGURES = "use_runtime_figures"; //$NON-NLS-1$
private static final String PREF_USE_IN_TRANSFORMATION_CODE_GEN = "use_in_transfo_code_gen"; //$NON-NLS-1$
private static final String PREF_IGNORE_MAPMODEL_VALIDATION = "ignore_mapmodel_validation"; //$NON-NLS-1$
private static final String PREF_IGNORE_GMFGEN_VALIDATION = "ignore_gmfgen_validation"; //$NON-NLS-1$
private static final String PREF_FIGURE_TEMPLATES = "dynamic_figure_templates"; //$NON-NLS-1$
private static final String PREF_MAIN_TRANSFORM = "main-qvto"; //$NON-NLS-1$
private static final String PREF_PRE_RECONCILE_TRANSFORM = "pre-reconcile-qvto"; //$NON-NLS-1$
private static final String PREF_POST_RECONCILE_TRANSFORM = "post-reconcile-qvto"; //$NON-NLS-1$
private static String[] PROP_NAMES = new String[] {
PREF_GENERATE_RCP,
PREF_USE_MAP_MODE,
PREF_USE_IN_TRANSFORMATION_CODE_GEN,
PREF_USE_RUNTIME_FIGURES,
PREF_IGNORE_MAPMODEL_VALIDATION,
PREF_IGNORE_GMFGEN_VALIDATION,
PREF_FIGURE_TEMPLATES,
PREF_MAIN_TRANSFORM,
PREF_PRE_RECONCILE_TRANSFORM,
PREF_POST_RECONCILE_TRANSFORM,
};
private Preferences myContextPrefs; // may be null
private Preferences myGlobalPrefs;
// null value indicates value was not yet accessed, to indicate value removal, use dedicated myNoValueToken
private final HashMap<String,String> myInMemPrefs = new HashMap<String,String>();
// explicit "no-value" value to indicate absence of the key
// need this when global preferences have e.g. postReconcileTr set, but current transformation cleaned the option,
// hence key absence in the myInMemPrefs map is non-indicative
private final String myNoValueToken = new String("no value"); //$NON-NLS-1$
public TransformOptions() {
}
public void setContext(Preferences contextPrefs) {
if (myContextPrefs != contextPrefs) {
myContextPrefs = contextPrefs;
reset();
}
}
public void reset() {
myInMemPrefs.clear();
}
public void flush() {
try {
for (String k : myInMemPrefs.keySet()) {
// Is it reasonable to always record last used options as global
// (so that next time wizard shows up, last-used options will be used, not defaults)?
String v = myInMemPrefs.get(k);
if (v != myNoValueToken) { // XXX might be reasonable also check for null, though should never happen
getGlobalPrefs().put(k, v);
}
}
getGlobalPrefs().flush();
if (myContextPrefs != null) {
// global preferences may change in the future, so record all values
for (String k : PROP_NAMES) {
String v = getWithContexts(k);
if (v != null && v != myNoValueToken) {
myContextPrefs.put(k, v);
} else {
myContextPrefs.remove(k);
}
}
myContextPrefs.flush();
}
} catch (BackingStoreException ex) {
Plugin.log(ex);
}
}
public boolean getGenerateRCP() {
return getBoolean(PREF_GENERATE_RCP);
}
public boolean getUseMapMode() {
return getBoolean(PREF_USE_MAP_MODE);
}
public boolean getUseRuntimeFigures() {
return getBoolean(PREF_USE_RUNTIME_FIGURES);
}
public boolean getUseInTransformationCodeGen() {
return getBoolean(PREF_USE_IN_TRANSFORMATION_CODE_GEN);
}
public boolean getIgnoreMapModelValidation() {
return getBoolean(PREF_IGNORE_MAPMODEL_VALIDATION);
}
public boolean getIgnoreGMFGenValidation() {
return getBoolean(PREF_IGNORE_GMFGEN_VALIDATION);
}
public URL getFigureTemplatesPath() {
return getURL(PREF_FIGURE_TEMPLATES);
}
public URL getMainTransformation() {
return getURL(PREF_MAIN_TRANSFORM);
}
public URL getPreReconcileTransform() {
return getURL(PREF_PRE_RECONCILE_TRANSFORM);
}
public URL getPostReconcileTransform() {
return getURL(PREF_POST_RECONCILE_TRANSFORM);
}
//
//
//
public void setGenerateRCP(boolean value) {
myInMemPrefs.put(PREF_GENERATE_RCP, Boolean.toString(value));
}
public void setUseMapMode(boolean value) {
myInMemPrefs.put(PREF_USE_MAP_MODE, Boolean.toString(value));
}
public void setUseRuntimeFigures(boolean value) {
myInMemPrefs.put(PREF_USE_RUNTIME_FIGURES, Boolean.toString(value));
}
public void setIgnoreMapModelValidation(boolean value) {
myInMemPrefs.put(PREF_IGNORE_MAPMODEL_VALIDATION, Boolean.toString(value));
}
public void setIgnoreGMFGenValidation(boolean value) {
myInMemPrefs.put(PREF_IGNORE_GMFGEN_VALIDATION, Boolean.toString(value));
}
public void setInTransformationCodeGen(boolean value) {
myInMemPrefs.put(PREF_USE_IN_TRANSFORMATION_CODE_GEN, Boolean.toString(value));
}
public void setFigureTemplatesPath(URL path) {
myInMemPrefs.put(PREF_FIGURE_TEMPLATES, path == null ? myNoValueToken : path.toString());
}
public void setTransformation(URL path) {
myInMemPrefs.put(PREF_MAIN_TRANSFORM, path == null ? myNoValueToken : path.toString());
}
public void setPreReconcileTransform(URL path) {
myInMemPrefs.put(PREF_PRE_RECONCILE_TRANSFORM, path == null ? myNoValueToken : path.toString());
}
public void setPostReconcileTransform(URL path) {
myInMemPrefs.put(PREF_POST_RECONCILE_TRANSFORM, path == null ? myNoValueToken : path.toString());
}
@Override
public void initializeDefaultPreferences() {
Preferences node = getDefaultPrefs();
node.putBoolean(PREF_GENERATE_RCP, false);
node.putBoolean(PREF_USE_MAP_MODE, true);
node.putBoolean(PREF_USE_RUNTIME_FIGURES, true);
node.putBoolean(PREF_IGNORE_MAPMODEL_VALIDATION, false);
node.putBoolean(PREF_IGNORE_GMFGEN_VALIDATION, false);
node.putBoolean(PREF_USE_IN_TRANSFORMATION_CODE_GEN, true);
}
static boolean checkLiteOptionPresent() {
return Platform.getBundle("org.eclipse.gmf.codegen.lite") != null; //$NON-NLS-1$
}
private String getWithContexts(String key) {
String v = myInMemPrefs.get(key);
if (v != null && v != myNoValueToken) {
return v;
}
if (v == myNoValueToken) {
return null;
}
ArrayList<Preferences> scopes = new ArrayList<Preferences>(3);
if (myContextPrefs != null) {
// there may be no context-specific scope
scopes.add(myContextPrefs);
} else {
// respect globals only if there's no context. Otherwise (if we chain both), globals may have postRecoTr set, while context not
// but chaining would give us a result as if it would have been set
scopes.add(getGlobalPrefs());
}
scopes.add(getDefaultPrefs());
// XXX alternative is to use default lookup order, with getString(Plugin.getPluginID, key, null, null))
// but seems like we don't care about other scopes than project, instance and default
return Platform.getPreferencesService().get(key, null, scopes.toArray(new Preferences[scopes.size()]));
}
private boolean getBoolean(String key) {
String value = getWithContexts(key);
assert value != null; // DefaultScope should never fail ;)
return Boolean.parseBoolean(value);
}
private URL getURL(String key) {
final String value = getWithContexts(key);
if (value == null || value.length() == 0) {
return null;
}
try {
return new URL(value);
} catch (MalformedURLException ex) {
Plugin.log(ex);
}
return null;
}
@SuppressWarnings("deprecation")
private Preferences getGlobalPrefs() {
if (myGlobalPrefs == null) {
// no real need to cache, though
myGlobalPrefs = new InstanceScope().getNode(Plugin.getPluginID());
}
return myGlobalPrefs;
}
@SuppressWarnings("deprecation")
private static Preferences getDefaultPrefs() {
return new DefaultScope().getNode(Plugin.getPluginID());
}
}