blob: bf15e0a52d6f952e47b8ae03ba990a916b51e0c7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 BestSolution.at and others.
* 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:
* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
*******************************************************************************/
package org.eclipse.fx.ui.workbench.base.internal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.e4.core.contexts.ContextFunction;
import org.eclipse.e4.core.contexts.IContextFunction;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.MApplicationElement;
import org.eclipse.fx.core.Memento;
import org.eclipse.fx.core.ObjectSerializer;
import org.eclipse.jdt.annotation.NonNull;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
/**
* Context function creating a memento instance backed by the
* {@link MApplicationElement}
*/
@Component(service = { IContextFunction.class },property={"service.context.key=org.eclipse.fx.core.Memento"})
public class MementoCF extends ContextFunction {
List<ObjectSerializer> serializers = new ArrayList<ObjectSerializer>();
/**
* Register a new serializer
*
* @param serializer
* the new serializer
*/
@Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality=ReferenceCardinality.MULTIPLE)
public void registerObjectSerializer(ObjectSerializer serializer) {
synchronized (this.serializers) {
this.serializers.add(serializer);
}
}
/**
* Unregister a new serializer
*
* @param serializer
* the serializer to remove
*/
public void unregisterObjectSerializer(ObjectSerializer serializer) {
synchronized (this.serializers) {
this.serializers.remove(serializer);
}
}
@Override
public Object compute(IEclipseContext context) {
MApplicationElement mApplicationElement = context.get(MApplicationElement.class);
if (mApplicationElement == null) {
return null;
} else {
return new MementoImpl(mApplicationElement.getPersistedState());
}
}
class MementoImpl implements Memento {
private final Map<String, String> map;
private static final String TYPE_PREFIX = "__type_"; //$NON-NLS-1$
public MementoImpl(Map<String, String> map) {
this.map = map;
}
private void _put(String key, Object value, String type) {
this.map.put(key, value == null ? null : value.toString());
this.map.put(TYPE_PREFIX + key, type);
}
public String _get(String key, String defaultValue, String type) {
String rv = defaultValue;
rv = this.map.get(key);
if (rv == null) {
rv = defaultValue;
}
return rv;
}
@Override
public void put(String key, String value) {
_put(key, value, String.class.getName());
}
@Override
public void put(String key, boolean value) {
_put(key, Boolean.valueOf(value), boolean.class.getName());
}
@Override
public void put(String key, int value) {
_put(key, Integer.valueOf(value), int.class.getName());
}
@Override
public void put(String key, double value) {
_put(key, Double.valueOf(value), double.class.getName());
}
@Override
public void remove(String key) {
this.map.remove(key);
this.map.remove(TYPE_PREFIX + key);
}
@Override
public boolean exists(String key) {
return this.map.containsKey(key);
}
@Override
public String get(String key, String defaultValue) {
return _get(key, defaultValue, String.class.getName());
}
@Override
public boolean get(String key, boolean defaultValue) {
String rv = _get(key, Boolean.valueOf(defaultValue).toString(), boolean.class.getName());
return Boolean.parseBoolean(rv);
}
@Override
public int get(String key, int defaultValue) {
String rv = _get(key, Integer.valueOf(defaultValue).toString(), int.class.getName());
return Integer.parseInt(rv);
}
@Override
public double get(String key, double defaultValue) {
String rv = _get(key, Double.valueOf(defaultValue).toString(), double.class.getName());
return Double.parseDouble(rv);
}
@Override
public <O> O get(String key, Class<O> clazz, O defaultValue) {
synchronized (MementoCF.this.serializers) {
String serializer = this.map.get(TYPE_PREFIX+key);
if( serializer == null ) {
return defaultValue;
}
String value = this.map.get(key);
if( value == null ) {
return defaultValue;
}
serializer = serializer.substring("serialized:".length()); //$NON-NLS-1$
for( ObjectSerializer s : MementoCF.this.serializers ) {
if( s.getId().equals(serializer) ) {
return s.deserialize(clazz, value);
}
}
throw new IllegalArgumentException("The serializer '"+serializer+"' is not known"); //$NON-NLS-1$//$NON-NLS-2$
}
}
@Override
public void put(@NonNull String key, Object value, String serializer) {
if( value == null ) {
_put(key, null, "serialized:"+serializer); //$NON-NLS-1$
}
synchronized (MementoCF.this.serializers) {
for( ObjectSerializer s : MementoCF.this.serializers ) {
if( s.getId().equals(serializer) ) {
_put(key, s.serialize(value), "serialized:"+serializer); //$NON-NLS-1$
return;
}
}
}
throw new IllegalArgumentException("The serializer '"+serializer+"' is not known"); //$NON-NLS-1$//$NON-NLS-2$
}
}
}