/*
* #%L
* carewebframework
* %%
* Copyright (C) 2008 - 2016 Regenstrief Institute, Inc.
* %%
* 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.
*
* This Source Code Form is also subject to the terms of the Health-Related
* Additional Disclaimer of Warranty and Limitation of Liability available at
*
* http://www.carewebframework.org/licensing/disclaimer.
*
* #L%
*/
package org.carewebframework.shell.layout;
import java.util.HashMap;
import org.carewebframework.shell.plugins.PluginDefinition;
import org.carewebframework.shell.property.IPropertyAccessor;
import org.carewebframework.shell.property.PropertyInfo;
/**
* Proxy for an arbitrary UI element that can store and return property values. This is used by the
* designer to create placeholders for actual UI elements without creating the element itself and
* for deferring property changes to existing UI elements.
*/
public class UIElementProxy extends UIElementBase implements IPropertyAccessor {
private final HashMap<String, Object> properties = new HashMap<>();
private UIElementBase target;
private boolean deleted;
public UIElementProxy(PluginDefinition def) {
super();
setDefinition(def);
revert();
}
public UIElementProxy(UIElementBase target) {
super();
this.target = target;
if (target != null) {
setDefinition(target.getDefinition());
}
revert();
}
/**
* Override to get property value from proxy's property cache.
*
* @see org.carewebframework.shell.property.IPropertyAccessor#getPropertyValue
*/
@Override
public Object getPropertyValue(PropertyInfo propInfo) throws Exception {
return getPropertyValue(propInfo.getId());
}
public Object getPropertyValue(String propName) {
return properties.get(propName);
}
/**
* Overridden to set property value in proxy's property cache.
*
* @see org.carewebframework.shell.property.IPropertyAccessor#setPropertyValue
*/
@Override
public void setPropertyValue(PropertyInfo propInfo, Object value) {
setPropertyValue(propInfo.getId(), value);
}
public Object setPropertyValue(String propName, Object value) {
return properties.put(propName, value);
}
public UIElementBase getTarget() {
return target;
}
protected void revert() {
properties.clear();
syncProperties(true);
}
public void commit() {
syncProperties(false);
}
/**
* Realizes the creation or destruction of the proxied target. In other words, if this is a
* deletion operation and a target exists, the target is removed from its parent. If this is not
* a deletion and the target does not exist, a new target is instantiated as a child to the
* specified parent.
*
* @param parent The parent UI element.
* @throws Exception Unspecified exception.
*/
public void realize(UIElementBase parent) throws Exception {
if (!deleted && target == null) {
target = getDefinition().createElement(parent, null);
} else if (deleted && target != null) {
target.remove(true);
target = null;
}
}
/**
* Synchronizes property values between the proxy and its target.
*
* @param fromTarget If true, property values are copied from the target to the proxy. If false,
* property values are copied from the proxy to the target.
*/
private void syncProperties(boolean fromTarget) {
PluginDefinition def = getDefinition();
for (PropertyInfo propInfo : def.getProperties()) {
try {
if (fromTarget) {
syncProperty(propInfo, target, this);
} else {
syncProperty(propInfo, this, target);
}
} catch (Exception e) {}
}
}
private void syncProperty(PropertyInfo propInfo, Object from, Object to) throws Exception {
if (to != null) {
propInfo.setPropertyValue(to, propInfo.getPropertyValue(from));
}
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public boolean isDeleted() {
return deleted;
}
}