/**
* Copyright (c) 2011 - 2015, Lunifera GmbH (Gross Enzersdorf), Loetz KG (Heidelberg)
* 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:
* Florian Pirchner - Initial implementation
*/
package org.lunifera.dsl.dto.lib;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.lunifera.runtime.common.coordination.CoordinationManager;
import org.lunifera.runtime.common.state.IDataState;
import org.lunifera.runtime.common.state.ISharedStateContext;
/**
* A common context for mappings. The registered entries will be reused. If an
* object for a given key is available, this instance will be returned.
* <p>
* At the end of the mapping process, the cached objects will be forwarded to
* the {@link ISharedStateContext}. The user needs to call {@link #flush()}.
* Calls to {@link #flush()} during the mapping process has no effect, if the
* current level is greater zero.
*/
public class MappingContext {
private int level = 0;
private Map<Object, Object> cache;
private Map<Object, Object> mappingRootCache;
private ISharedStateContext sharedState;
private IDataState dirtyAwareGlobalDataState;
public MappingContext() {
this(true);
}
public MappingContext(boolean useSharedState) {
cache = new HashMap<Object, Object>();
if (useSharedState) {
ISharedStateContext sharedState = (ISharedStateContext) CoordinationManager
.getPropertyFromCurrentCoordination(ISharedStateContext.class);
this.sharedState = sharedState;
if (sharedState != null) {
this.dirtyAwareGlobalDataState = sharedState
.getDirtyAwareGlobalState();
}
}
}
public ISharedStateContext getSharedState() {
return sharedState;
}
protected boolean isUseSharedState() {
return sharedState != null;
}
/**
* Increases the level of the mapping process.
*/
public void increaseLevel() {
level++;
}
/**
* Decreases the level of the mapping process.
*/
public void decreaseLevel() {
level--;
}
/**
* For later use.
*
* @return
*/
public boolean isMaxLevel() {
return false;
}
/**
* Registers the object in the temporary internal cache. If {@link #flush()}
* is called, the internal cache will be cleared and objects are forwarded
* to the {@link ISharedStateContext}.
*
* @param key
* @param target
*/
public void register(Object key, Object target) {
cache.put(key, target);
}
/**
* Registers the object that was used as a template to map the cached
* object.
*
* @param key
* @param target
*/
public void registerMappingRoot(Object key, Object target) {
if (mappingRootCache == null) {
mappingRootCache = new HashMap<Object, Object>();
}
mappingRootCache.put(key, target);
}
@SuppressWarnings("unchecked")
public <A> A get(Object key) {
A result = (A) cache.get(key);
if (result == null) {
if (isUseSharedState()) {
result = (A) dirtyAwareGlobalDataState.get(key);
}
}
return result;
}
@SuppressWarnings("unchecked")
public <A> A getMappingRoot(Object key) {
return (A) mappingRootCache.get(key);
}
/**
* This method flushes the cached entries into the
* {@link ISharedStateContext} if available. The cache will only become
* flushed, if the level is zero.
*/
public void flush() {
if (level > 0) {
return;
}
if (isUseSharedState()) {
IDataState globalState = sharedState.getGlobalDataState();
for (Entry<Object, Object> entry : cache.entrySet()) {
globalState.register(entry.getKey(), entry.getValue());
}
}
cache.clear();
}
}