/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.foundation.ie;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openflexo.foundation.CodeType;
import org.openflexo.foundation.DataModification;
import org.openflexo.foundation.FlexoModelObject;
import org.openflexo.foundation.FlexoObservable;
import org.openflexo.foundation.FlexoObserver;
import org.openflexo.foundation.TargetType;
import org.openflexo.foundation.bindings.AbstractBinding;
import org.openflexo.foundation.bindings.Bindable;
import org.openflexo.foundation.bindings.BindingDefinition;
import org.openflexo.foundation.bindings.BindingModel;
import org.openflexo.foundation.bindings.BindingValue;
import org.openflexo.foundation.bindings.BindingVariable;
import org.openflexo.foundation.bindings.ComponentBindingDefinition;
import org.openflexo.foundation.bindings.StaticBinding;
import org.openflexo.foundation.dm.ComponentDMEntity;
import org.openflexo.foundation.dm.DMEntity;
import org.openflexo.foundation.dm.DMProperty;
import org.openflexo.foundation.dm.DMPropertyImplementationType;
import org.openflexo.foundation.dm.DMType;
import org.openflexo.foundation.ie.cl.ComponentDefinition;
import org.openflexo.foundation.ie.dm.BindingAdded;
import org.openflexo.foundation.ie.dm.BindingRemoved;
import org.openflexo.foundation.ie.widget.IEWidget;
import org.openflexo.foundation.param.ChoiceListParameter;
import org.openflexo.foundation.param.DMEntityParameter;
import org.openflexo.foundation.param.ParameterDefinition;
import org.openflexo.foundation.param.TextFieldParameter;
import org.openflexo.foundation.rm.FlexoProject;
import org.openflexo.foundation.rm.XMLStorageResourceData;
import org.openflexo.foundation.validation.CompoundIssue;
import org.openflexo.foundation.validation.FixProposal;
import org.openflexo.foundation.validation.ParameteredFixProposal;
import org.openflexo.foundation.validation.Validable;
import org.openflexo.foundation.validation.ValidationError;
import org.openflexo.foundation.validation.ValidationIssue;
import org.openflexo.foundation.validation.ValidationModel;
import org.openflexo.foundation.validation.ValidationReport;
import org.openflexo.foundation.validation.ValidationRule;
import org.openflexo.foundation.xml.FlexoComponentBuilder;
import org.openflexo.foundation.xml.FlexoNavigationMenuBuilder;
import org.openflexo.foundation.xml.FlexoProcessBuilder;
import org.openflexo.localization.FlexoLocalization;
import org.openflexo.toolbox.EmptyVector;
/**
* A ComponentInstance represents an instance (a use case) of a ComponentDefinition in a given context (this context can be determined with
* the type of resource data: {@link #getXMLResourceData()} Note that a component instance owner has 3 notifications to forward to its
* component instance(s): 1) When the owner changes of resource data--> updateDependancies() 2) When the owner is deleted-->delete (perform
* this call asap so that resource data is still set on the calling owner) 3) When the component instance is removed from the owner-->delete
*
* @author bmangez, gpolet
*/
public abstract class ComponentInstance extends IEObject implements Bindable, FlexoObserver, Validable {
private static final Logger logger = Logger.getLogger(ComponentInstance.class.getPackage().getName());
private Vector<ComponentInstanceBinding> _bindings;
private ComponentDefinition _componentDefinition;
private String xmlComponentName;
private transient ComponentInstanceOwner _owner;
/* This variable should not be used, but instead, use the getXMLResourceData() method */
private XMLStorageResourceData container;
// ==========================================================================
// ============================= Constructor ================================
// ==========================================================================
private ComponentInstance(FlexoProject project, XMLStorageResourceData aContainer) {
super(project);
container = aContainer;
_bindings = new Vector<ComponentInstanceBinding>();
}
protected ComponentInstance(ComponentDefinition componentDef, XMLStorageResourceData aContainer) {
this(componentDef != null ? componentDef.getProject() : /*(aContainer!=null?*/aContainer.getProject()/*:null)*/, aContainer);
if (componentDef != null) {// -->ie, we are creating this component instance, we are not deserializing it.
setComponentDefinition(componentDef);
updateDependancies(null, aContainer);
}
}
public ComponentInstance(FlexoProcessBuilder builder) {
this(builder.isCloner ? null : builder.getProject(), builder.isCloner ? null : builder.process);
initializeDeserialization(builder);
}
public ComponentInstance(FlexoNavigationMenuBuilder builder) {
this(builder.getProject(), builder.navigationMenu);
initializeDeserialization(builder);
}
public ComponentInstance(FlexoComponentBuilder builder) {
this(builder.getProject(), builder.woComponent);
initializeDeserialization(builder);
}
@Override
public void finalizeDeserialization(Object builder) {
super.finalizeDeserialization(builder);
updateBindings();
}
public void updateDependancies(XMLStorageResourceData oldResourceData, XMLStorageResourceData newResourceData) {
if (oldResourceData == newResourceData) {
return;
}
if (oldResourceData != null && getComponentDefinition() != null) {
ComponentDefinition cd = getComponentDefinition();
Iterator<ComponentInstance> i = cd.getComponentInstances().iterator();
boolean removeDependancy = true;
while (i.hasNext() && removeDependancy) {
ComponentInstance ci = i.next();
if (ci != this) {
if (ci.getXMLResourceData() == oldResourceData) {
removeDependancy = false;
}
}
}
if (removeDependancy) {
oldResourceData.getFlexoResource().removeFromDependentResources(cd.getComponentResource());
}
}
rebuildDependancy(newResourceData);
}
/**
* @param newResourceData
*/
private void rebuildDependancy(XMLStorageResourceData newResourceData) {
if (newResourceData != null && getComponentDefinition() != null) {
newResourceData.getFlexoResource().addToDependentResources(getComponentDefinition().getComponentResource());
} else {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Could not rebuid dependancy for resource data: " + newResourceData + " and component definition is "
+ getComponentDefinition() + " named: " + getComponentName());
}
}
}
@Override
public final void delete() {
if (_componentDefinition != null) {
_componentDefinition.removeFromComponentInstances(this);
_componentDefinition.deleteObserver(this);
}
super.delete();
updateDependancies(getXMLResourceData(), null);
container = null;
_owner = null;
_knownBindings = null;
_componentDefinition = null;
xmlComponentName = null;
}
// ==========================================================================
// =========================== Instance methods =============================
// ==========================================================================
@Override
public IEObject getParent() {
if (_owner instanceof IEObject) {
return (IEObject) _owner;
}
return null;
}
@Override
public BindingModel getBindingModel() {
if (getXMLResourceData() instanceof Bindable) {
return ((Bindable) getXMLResourceData()).getBindingModel();
}
return null;
}
/**
* Returns reference to the main object in which this XML-serializable object is contained relating to storing scheme: here it's the
* object declared as the container
*
* @return container of this object
*/
@Override
public XMLStorageResourceData getXMLResourceData() {
if (getOwner() != null) {
return getOwner().getXMLResourceData();
}
return container;
}
public String getInspectorName() {
return null;
}
@Override
public void setName(String value) {
setComponentName(value);
}
@Override
public String getName() {
return getComponentName();
}
public final String getComponentName() {
return xmlComponentName;
}
public void setComponentName(String value) {
xmlComponentName = value;
}
public ComponentDefinition getComponentDefinition() {
if (_componentDefinition == null && xmlComponentName != null) {
if (getProject() == null) {
if (isDeserializing()) {
return null;
}
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Project not set for ComponentInstance ! Owner is " + getOwner());
}
return null;
}
ComponentDefinition aComponentDefinition = getProject().getFlexoComponentLibrary().getComponentNamed(xmlComponentName);
if (aComponentDefinition == null) {
if (logger.isLoggable(Level.INFO)) {
logger.info("A ComponentInstance with component name : " + xmlComponentName + " has no component def. Owner is "
+ getOwner());
}
} else {
setComponentDefinition(aComponentDefinition, false);
}
}
return _componentDefinition;
}
public IEWOComponent getWOComponent() {
return getComponentDefinition().getWOComponent();
}
public void setComponentDefinition(ComponentDefinition aComponentDefinition) {
setComponentDefinition(aComponentDefinition, true);
}
public void setComponentDefinition(ComponentDefinition aComponentDefinition, boolean notify) {
if (aComponentDefinition == null) {
if (logger.isLoggable(Level.SEVERE)) {
logger.severe("Attempt to set a null component definition on a component instance! Track this call and make sure this never happens ever again.");
}
return;
}
xmlComponentName = aComponentDefinition.getComponentName();
if (_componentDefinition != aComponentDefinition) {
if (_componentDefinition != null && !(this instanceof DummyComponentInstance)) {
_componentDefinition.deleteObserver(this);
_componentDefinition.removeFromComponentInstances(this);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Removing " + this + " as observer of " + _componentDefinition);
}
}
_componentDefinition = aComponentDefinition;
_componentDefinition.addObserver(this);
if (!(this instanceof DummyComponentInstance)) {
_componentDefinition.addToComponentInstances(this, notify);
}
if (logger.isLoggable(Level.FINE)) {
logger.fine("Adding " + this + " as observer of " + _componentDefinition);
}
if (notify) {
setChanged();
}
}
}
public void notifyComponentNameChanged(ComponentDefinition aComponentDefinition) {
setComponentDefinition(aComponentDefinition);
setChanged();
}
@Override
public void setChanged() {
if (getOwner() != null) {
getOwner().setChanged();
}
super.setChanged();
}
public void addToBindings(ComponentInstanceBinding value) {
value.setComponentInstance(this);
_bindings.add(value);
}
public void removeFromBindings(ComponentInstanceBinding value) {
value.setComponentInstance(null);
_bindings.remove(value);
}
public void setBindings(Vector<ComponentInstanceBinding> value) {
_bindings = value;
}
public Vector<ComponentInstanceBinding> getBindings() {
/*if (isBeingCloned())
return EmptyVector.EMPTY_VECTOR(ComponentInstanceBinding.class);*/
if (_bindings != null && getComponentDefinition() != null
&& _bindings.size() != getComponentDefinition().getBindingDefinitions().size()) {
updateBindings();
}
return _bindings;
}
private boolean isRegistered(ComponentBindingDefinition bd) {
for (Enumeration en = _bindings.elements(); en.hasMoreElements();) {
ComponentInstanceBinding next = (ComponentInstanceBinding) en.nextElement();
if (next.getBindingDefinition() == bd) {
return true;
}
}
return false;
}
public ComponentInstanceBinding getBinding(ComponentBindingDefinition bd) {
for (Enumeration en = _bindings.elements(); en.hasMoreElements();) {
ComponentInstanceBinding next = (ComponentInstanceBinding) en.nextElement();
if (next.getBindingDefinition() == bd) {
return next;
}
}
return null;
}
public ComponentInstanceBinding getBinding(String bindingName) {
for (Enumeration en = _bindings.elements(); en.hasMoreElements();) {
ComponentInstanceBinding next = (ComponentInstanceBinding) en.nextElement();
if (next.getBindingDefinition().getVariableName().equals(bindingName)) {
return next;
}
}
return null;
}
private void updateBindings() {
if (getComponentDefinition() == null) {
return;
}
if (logger.isLoggable(Level.FINE)) {
logger.fine("updateBindings() in ComponentInstance");
}
Vector<ComponentInstanceBinding> toRemove = new Vector<ComponentInstanceBinding>();
toRemove.addAll(_bindings);
for (Enumeration en = getComponentDefinition().getBindingDefinitions().elements(); en.hasMoreElements();) {
ComponentBindingDefinition next = (ComponentBindingDefinition) en.nextElement();
if (!isRegistered(next)) {
// addToBindings(new ComponentInstanceBinding(this, next, null));
addToBindings(getComponentInstanceBindingForComponentBindingDefinition(next));
} else {
toRemove.remove(getBinding(next));
}
}
for (Enumeration en = toRemove.elements(); en.hasMoreElements();) {
ComponentInstanceBinding next = (ComponentInstanceBinding) en.nextElement();
removeFromBindings(next);
}
Collections.sort(_bindings, ComponentInstanceBinding.componentInstanceBindingComparator);
}
/**
* Stores in an hashtable ComponentInstanceBinding related to a ComponentBindingDefinition Ensure that no new ComponentInstanceBinding
* is created if a component binding definition is renamed for example
*/
private transient Hashtable<ComponentBindingDefinition, ComponentInstanceBinding> _knownBindings = new Hashtable<ComponentBindingDefinition, ComponentInstanceBinding>();
private ComponentInstanceBinding getComponentInstanceBindingForComponentBindingDefinition(ComponentBindingDefinition bd) {
// TODO: add bindings when deserializing to knownBindings.
ComponentInstanceBinding returned = _knownBindings.get(bd);
if (returned == null) {
ComponentInstanceBinding newBindingDefinition = new ComponentInstanceBinding(this, bd, null);
_knownBindings.put(bd, newBindingDefinition);
return newBindingDefinition;
} else {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Retrieve known ComponentInstanceBinding !");
}
return returned;
}
}
@Override
public void update(FlexoObservable o, DataModification dataModification) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("received update in ComponentInstance " + dataModification);
}
if (o == getComponentDefinition() && (dataModification instanceof BindingAdded || dataModification instanceof BindingRemoved)) {
updateBindings();
}
}
public Vector<IObject> getWOComponentEmbeddedIEObjects() {
return getWOComponent().getAllEmbeddedIEObjects();
}
/**
* Return a Vector of embedded IEObjects at this level. NOTE1: that this is NOT a recursive method NOTE2: return EMPTY_VECTOR, since
* there is no embedded IEObject
*
* @return EMPTY_VECTOR
*/
@Override
public Vector<IObject> getEmbeddedIEObjects() {
return EmptyVector.EMPTY_VECTOR(IObject.class);
}
public ComponentInstanceBinding createNewBinding() {
if (getComponentDefinition() != null) {
ComponentBindingDefinition newBD = getComponentDefinition().createNewBinding();
return getBinding(newBD);
} else {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Could not create binding: cannot access ComponentDefinition !");
}
return null;
}
}
public void deleteBinding(ComponentInstanceBinding cib) {
if (getComponentDefinition() != null) {
getComponentDefinition().deleteBinding(cib.getBindingDefinition());
} else {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Could not delete binding: cannot access ComponentDefinition !");
}
}
}
public boolean isBindingDeletable(ComponentInstanceBinding cib) {
if (getComponentDefinition() != null) {
return getComponentDefinition().isBindingDefinitionDeletable(cib.getBindingDefinition());
} else {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Could not access binding: cannot access ComponentDefinition !");
}
}
return false;
}
@Override
public String getFullyQualifiedName() {
if (getOwner() instanceof IEWidget && ((IEWidget) getOwner()).getWOComponent() != null) {
return "COMPONENT_INSTANCE." + getName() + " in " + ((IEWidget) getOwner()).getWOComponent().getName();
} else if (getOwner() != null) {
return "COMPONENT_INSTANCE." + getName() + " in " + getOwner().getFullyQualifiedName();
} else {
return "COMPONENT_INSTANCE." + getName();
}
}
/**
* Returns owner for this component instance, if it has been set. The owner of a ComponentInstance is the FlexoModelObject which emmbed
* this instance.
*/
public final ComponentInstanceOwner getOwner() {
return _owner;
}
/**
* Sets owner for this component instance. The owner of a ComponentInstance is the FlexoModelObject which emmbed this instance.
*
* @param owner
*/
public final void setOwner(ComponentInstanceOwner owner) {
if (_owner == owner) {
return;
}
XMLStorageResourceData oldResourceData = getXMLResourceData();
if (owner == null) {
delete();
}
container = null;
_owner = owner;
_componentDefinition = null;// We reset the _componentDefinition so that in case of conversion we will try to retrieve the component
// definition again.
// We need to notify the component instance bindings (because now we can retrieve the component definition)
for (ComponentInstanceBinding b : _bindings) {
b.setComponentInstance(this);
}
if (owner != null) {
updateDependancies(oldResourceData, getXMLResourceData());
}
}
public boolean isValidInstance() {
return getComponentDefinition() != null;
}
public void rebuildDependancies() {
if (getXMLResourceData() != null) {
rebuildDependancy(getXMLResourceData());
} else {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Cannot rebuild dependancies because XMLResourceData=" + getXMLResourceData() + " and ComponentDefinition="
+ getComponentDefinition());
}
}
}
// ==========================================================================
// ============================== Validation ================================
// ==========================================================================
/**
* Returns a flag indicating if this object is valid according to default validation model
*
* @return boolean
*/
@Override
public boolean isValid() {
return isValid(getDefaultValidationModel());
}
/**
* Returns a flag indicating if this object is valid according to specified validation model
*
* @return boolean
*/
@Override
public boolean isValid(ValidationModel validationModel) {
return validationModel.isValid(this);
}
/**
* Validates this object by building new ValidationReport object Default validation model is used to perform this validation.
*/
@Override
public ValidationReport validate() {
return validate(getDefaultValidationModel());
}
/**
* Validates this object by building new ValidationReport object Supplied validation model is used to perform this validation.
*/
@Override
public ValidationReport validate(ValidationModel validationModel) {
return validationModel.validate(this);
}
/**
* Validates this object by appending eventual issues to supplied ValidationReport. Default validation model is used to perform this
* validation.
*
* @param report
* , a ValidationReport object on which found issues are appened
*/
@Override
public void validate(ValidationReport report) {
validate(report, getDefaultValidationModel());
}
/**
* Validates this object by appending eventual issues to supplied ValidationReport. Supplied validation model is used to perform this
* validation.
*
* @param report
* , a ValidationReport object on which found issues are appened
*/
@Override
public void validate(ValidationReport report, ValidationModel validationModel) {
validationModel.validate(this, report);
}
public static class DefinedBindingsMustBeValid extends CheckAllBindingsRule {
public DefinedBindingsMustBeValid() {
super("defined_bindings_must_be_valid");
}
@Override
public ValidationIssue<CheckAllBindingsRule, ComponentInstance> applyValidation(final ComponentInstance ci) {
CompoundIssue<CheckAllBindingsRule, ComponentInstance> errors = null;
Enumeration en = ci.getBindings().elements();
while (en.hasMoreElements()) {
ComponentInstanceBinding ciBinding = (ComponentInstanceBinding) en.nextElement();
AbstractBinding bv = ciBinding.getBindingValue();
if (bv != null && !bv.isBindingValid()) {
ValidationError<CheckAllBindingsRule, ComponentInstance> error;
error = new MissingRequiredBinding(ci, ciBinding) {
@Override
public String getLocalizedMessage() {
return getLocalizedErrorMessageForInvalidValue();
}
};
if (errors == null) {
errors = new CompoundIssue<CheckAllBindingsRule, ComponentInstance>(ci);
}
errors.addToContainedIssues(error);
}
}
return errors;
}
}
public static class MandatoryBindingsMustHaveAValue extends CheckAllBindingsRule {
public MandatoryBindingsMustHaveAValue() {
super("mandatory_bindings_must_have_a_value");
}
@Override
public ValidationIssue<CheckAllBindingsRule, ComponentInstance> applyValidation(final ComponentInstance ci) {
CompoundIssue<CheckAllBindingsRule, ComponentInstance> errors = null;
Enumeration en = ci.getBindings().elements();
while (en.hasMoreElements()) {
ComponentInstanceBinding ciBinding = (ComponentInstanceBinding) en.nextElement();
if (ciBinding.getBindingDefinition() != null && ciBinding.getBindingDefinition().getIsMandatory()) {
AbstractBinding bv = ciBinding.getBindingValue();
if (bv == null || !bv.isBindingValid()) {
ValidationError<CheckAllBindingsRule, ComponentInstance> error;
if (bv == null) {
error = new MissingRequiredBinding(ci, ciBinding) {
@Override
public String getLocalizedMessage() {
return getLocalizedErrorMessageForUndefinedAndRequiredValue();
}
};
} else { // !bv.isBindingValid()
error = new MissingRequiredBinding(ci, ciBinding) {
@Override
public String getLocalizedMessage() {
return getLocalizedErrorMessageForInvalidAndRequiredValue();
}
};
}
if (errors == null) {
errors = new CompoundIssue<CheckAllBindingsRule, ComponentInstance>(ci);
}
errors.addToContainedIssues(error);
}
}
}
return errors;
}
}
public abstract static class CheckAllBindingsRule extends ValidationRule<CheckAllBindingsRule, ComponentInstance> {
public CheckAllBindingsRule(String message) {
super(ComponentInstance.class, message);
}
/**
* Overrides isValidForTarget
*
* @see org.openflexo.foundation.validation.ValidationRule#isValidForTarget(TargetType)
*/
@Override
public boolean isValidForTarget(TargetType targetType) {
return targetType != CodeType.PROTOTYPE;
}
@Override
public abstract ValidationIssue<CheckAllBindingsRule, ComponentInstance> applyValidation(final ComponentInstance object);
public class MissingRequiredBinding extends ValidationError<CheckAllBindingsRule, ComponentInstance> {
public ComponentInstanceBinding componentInstanceBinding;
public String bindingName;
public String componentName;
public String ownerIdentifier;
public MissingRequiredBinding(ComponentInstance ci, ComponentInstanceBinding aComponentInstanceBinding) {
super(CheckAllBindingsRule.this, ci, null);
componentInstanceBinding = aComponentInstanceBinding;
bindingName = componentInstanceBinding.getBindingDefinitionName();
componentName = componentInstanceBinding.getComponentInstance().getComponentName();
ownerIdentifier = componentInstanceBinding.getComponentInstance().getOwner() != null ? ((FlexoModelObject) componentInstanceBinding
.getComponentInstance().getOwner()).getFullyQualifiedName() : "undentified button or link";
BindingDefinition bd = aComponentInstanceBinding.getBindingDefinition();
if (bd != null) {
if (ci.getOwner() instanceof IEWidget) {
addToFixProposals(new AddEntryToComponentAndSetBinding(componentInstanceBinding));
}
Vector<BindingValue> allAvailableBV = bd.searchMatchingBindingValue(ci, 2);
for (int i = 0; i < allAvailableBV.size(); i++) {
BindingValue proposal = allAvailableBV.elementAt(i);
addToFixProposals(new SetBinding(aComponentInstanceBinding, proposal));
}
}
}
public String getLocalizedErrorMessageForUndefinedAndRequiredValue() {
return FlexoLocalization.localizedForKeyWithParams(
"binding_named_($bindingName)_required_by_component_($componentName)_is_not_defined_for_widget($ownerIdentifier)",
this);
}
public String getLocalizedErrorMessageForInvalidAndRequiredValue() {
return FlexoLocalization
.localizedForKeyWithParams(
"binding_named_($bindingName)_required_by_component_($componentName)_has_invalid_value_for_widget($ownerIdentifier)",
this);
}
public String getLocalizedErrorMessageForInvalidValue() {
return FlexoLocalization.localizedForKeyWithParams("binding_named_($bindingName)_has_invalid_value", this);
}
@Override
public FlexoModelObject getSelectableObject() {
return (FlexoModelObject) componentInstanceBinding.getComponentInstance().getOwner();
}
}
public class SetBinding extends FixProposal<CheckAllBindingsRule, ComponentInstance> {
private ComponentInstanceBinding componentInstanceBinding;
public BindingValue bindingValue;
public String bindingName;
public SetBinding(ComponentInstanceBinding aComponentInstanceBinding, BindingValue aBindingValue) {
super("set_binding_($bindingName)_to_($bindingValue.stringRepresentation)");
bindingValue = aBindingValue;
bindingName = aComponentInstanceBinding.getBindingDefinitionName();
componentInstanceBinding = aComponentInstanceBinding;
}
@Override
protected void fixAction() {
componentInstanceBinding.setBindingValue(bindingValue);
}
public String getBindingName() {
return bindingName;
}
public void setBindingName() {
}
}
public static class AddEntryToComponentAndSetBinding extends ParameteredFixProposal<CheckAllBindingsRule, ComponentInstance> {
public BindingDefinition bindingDefinition;
public String bindingName;
private ComponentInstanceBinding componentInstanceBinding;
public AddEntryToComponentAndSetBinding(ComponentInstanceBinding aComponentInstanceBinding) {
super("add_entry_and_set_($bindingName)_onto", buildParameters(aComponentInstanceBinding.getBindingDefinition()));
componentInstanceBinding = aComponentInstanceBinding;
this.bindingName = componentInstanceBinding.getBindingDefinitionName();
this.bindingDefinition = componentInstanceBinding.getBindingDefinition();
}
private static ParameterDefinition[] buildParameters(BindingDefinition bd) {
ParameterDefinition[] returned = new ParameterDefinition[3];
returned[0] = new TextFieldParameter("variableName", "variable_name", "");
returned[1] = new DMEntityParameter("variableType", "variable_type", bd.getType() != null ? bd.getType().getBaseEntity()
: null);
returned[2] = new ChoiceListParameter<DMPropertyImplementationType>("implementationType", "implementation_type",
DMPropertyImplementationType.PUBLIC_FIELD);
returned[2].addParameter("format", "localizedName");
return returned;
}
@Override
protected void fixAction() {
ComponentInstance ci = getObject();
IEWidget widget = (IEWidget) ci.getOwner();
String newVariableName = (String) getValueForParameter("variableName");
DMEntity newVariableType = (DMEntity) getValueForParameter("variableType");
DMPropertyImplementationType implementationType = (DMPropertyImplementationType) getValueForParameter("implementationType");
widget.createsBindingVariable(newVariableName, DMType.makeResolvedDMType(newVariableType), implementationType, false);
DMProperty property = null;
ComponentDMEntity componentDMEntity = widget.getComponentDMEntity();
if (componentDMEntity != null) {
property = componentDMEntity.getDMProperty(newVariableName);
}
if (property != null) {
BindingVariable var = widget.getBindingModel().bindingVariableNamed("component");
BindingValue newBindingValue = new BindingValue(bindingDefinition, widget);
newBindingValue.setBindingVariable(var);
newBindingValue.addBindingPathElement(property);
newBindingValue.connect();
componentInstanceBinding.setBindingValue(newBindingValue);
}
}
}
}
public Hashtable<String, String> getStaticBindingValues() {
Hashtable<String, String> reply = new Hashtable<String, String>();
for (ComponentInstanceBinding cibd : getBindings()) {
if (cibd.getBindingValue() != null && cibd.getBindingValue().isStaticValue()) {
reply.put(cibd.getBindingDefinitionName(), ((StaticBinding) cibd.getBindingValue()).getStringRepresentation());
}
}
reply.put("ci", Long.toString(getFlexoID()));
return reply;
}
}