/* * (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.viewpoint; import java.lang.reflect.Type; import java.util.Vector; import java.util.logging.Logger; import org.openflexo.antar.binding.BindingDefinition; import org.openflexo.antar.binding.BindingDefinition.BindingDefinitionType; import org.openflexo.foundation.FlexoModelObject; import org.openflexo.foundation.Inspectors; import org.openflexo.foundation.validation.FixProposal; import org.openflexo.foundation.validation.ValidationError; import org.openflexo.foundation.validation.ValidationIssue; import org.openflexo.foundation.validation.ValidationRule; import org.openflexo.foundation.view.ViewObject; import org.openflexo.foundation.view.ViewShape; import org.openflexo.foundation.view.action.EditionSchemeAction; import org.openflexo.foundation.viewpoint.ViewPoint.ViewPointBuilder; import org.openflexo.foundation.viewpoint.binding.ViewPointDataBinding; /** * This edition primitive addresses the creation of a new shape in a diagram * * @author sylvain * */ public class AddShape extends AddShemaElementAction { private static final Logger logger = Logger.getLogger(AddShape.class.getPackage().getName()); private boolean extendParentBoundsToHostThisShape = false; public AddShape(ViewPointBuilder builder) { super(builder); } @Override public EditionActionType getEditionActionType() { return EditionActionType.AddShape; } /*@Override public List<ShapePatternRole> getAvailablePatternRoles() { if (getEditionPattern() != null) { return getEditionPattern().getPatternRoles(ShapePatternRole.class); } else return null; }*/ @Override public String getInspectorName() { return Inspectors.VPM.ADD_SHAPE_INSPECTOR; } public ViewObject getContainer(EditionSchemeAction action) { if (getPatternRole() != null && !getPatternRole().getParentShapeAsDefinedInAction()) { FlexoModelObject returned = action.getEditionPatternInstance().getPatternActor(getPatternRole().getParentShapePatternRole()); return (ViewObject) action.getEditionPatternInstance().getPatternActor(getPatternRole().getParentShapePatternRole()); } else { return (ViewObject) getContainer().getBindingValue(action); } } @Override public ShapePatternRole getPatternRole() { PatternRole superPatternRole = super.getPatternRole(); if (superPatternRole instanceof ShapePatternRole) { return (ShapePatternRole) superPatternRole; } else if (superPatternRole != null) { // logger.warning("Unexpected pattern role of type " + superPatternRole.getClass().getSimpleName()); return null; } return null; } /*@Override public ShapePatternRole getPatternRole() { try { return super.getPatternRole(); } catch (ClassCastException e) { logger.warning("Unexpected pattern role type"); setPatternRole(null); return null; } }*/ // FIXME: if we remove this useless code, some FIB won't work (see EditionPatternView.fib, inspect an AddIndividual) // Need to be fixed in KeyValueProperty.java /*@Override public void setPatternRole(ShapePatternRole patternRole) { super.setPatternRole(patternRole); }*/ private ViewPointDataBinding container; private BindingDefinition CONTAINER = new BindingDefinition("container", ViewObject.class, BindingDefinitionType.GET, true); public BindingDefinition getContainerBindingDefinition() { return CONTAINER; } public ViewPointDataBinding getContainer() { if (container == null) { container = new ViewPointDataBinding(this, EditionActionBindingAttribute.container, getContainerBindingDefinition()); } return container; } public void setContainer(ViewPointDataBinding container) { if (container != null) { container.setOwner(this); container.setBindingAttribute(EditionActionBindingAttribute.container); container.setBindingDefinition(getContainerBindingDefinition()); } this.container = container; notifyBindingChanged(this.container); } public boolean getExtendParentBoundsToHostThisShape() { return extendParentBoundsToHostThisShape; } public void setExtendParentBoundsToHostThisShape(boolean extendParentBoundsToHostThisShape) { this.extendParentBoundsToHostThisShape = extendParentBoundsToHostThisShape; } @Override public Type getAssignableType() { return ViewShape.class; } @Override public boolean isAssignationRequired() { return true; } public static class AddShapeActionMustAdressAValidShapePatternRole extends ValidationRule<AddShapeActionMustAdressAValidShapePatternRole, AddShape> { public AddShapeActionMustAdressAValidShapePatternRole() { super(AddShape.class, "add_shape_action_must_address_a_valid_shape_pattern_role"); } @Override public ValidationIssue<AddShapeActionMustAdressAValidShapePatternRole, AddShape> applyValidation(AddShape action) { if (action.getPatternRole() == null) { Vector<FixProposal<AddShapeActionMustAdressAValidShapePatternRole, AddShape>> v = new Vector<FixProposal<AddShapeActionMustAdressAValidShapePatternRole, AddShape>>(); for (ShapePatternRole pr : action.getEditionPattern().getShapePatternRoles()) { v.add(new SetsPatternRole(pr)); } return new ValidationError<AddShapeActionMustAdressAValidShapePatternRole, AddShape>(this, action, "add_shape_action_does_not_address_a_valid_shape_pattern_role", v); } return null; } protected static class SetsPatternRole extends FixProposal<AddShapeActionMustAdressAValidShapePatternRole, AddShape> { private ShapePatternRole patternRole; public SetsPatternRole(ShapePatternRole patternRole) { super("assign_action_to_pattern_role_($patternRole.patternRoleName)"); this.patternRole = patternRole; } public ShapePatternRole getPatternRole() { return patternRole; } @Override protected void fixAction() { AddShape action = getObject(); action.setAssignation(new ViewPointDataBinding(patternRole.getPatternRoleName())); } } } public static class AddShapeActionMustHaveAValidContainer extends ValidationRule<AddShapeActionMustHaveAValidContainer, AddShape> { public AddShapeActionMustHaveAValidContainer() { super(AddShape.class, "add_shape_action_must_have_a_valid_container"); } @Override public ValidationIssue<AddShapeActionMustHaveAValidContainer, AddShape> applyValidation(AddShape action) { if (action.getPatternRole() != null && action.getPatternRole().getParentShapeAsDefinedInAction() && !(action.getContainer().isSet() && action.getContainer().isValid())) { Vector<FixProposal<AddShapeActionMustHaveAValidContainer, AddShape>> v = new Vector<FixProposal<AddShapeActionMustHaveAValidContainer, AddShape>>(); if (action.getEditionScheme() instanceof DropScheme) { EditionPattern targetEditionPattern = ((DropScheme) action.getEditionScheme()).getTargetEditionPattern(); if (targetEditionPattern != null) { for (ShapePatternRole pr : action.getEditionPattern().getShapePatternRoles()) { v.add(new SetsContainerToTargetShape(targetEditionPattern, pr)); } } } v.add(new SetsContainerToTopLevel()); for (ShapePatternRole pr : action.getEditionPattern().getShapePatternRoles()) { v.add(new SetsContainerToShape(pr)); } return new ValidationError<AddShapeActionMustHaveAValidContainer, AddShape>(this, action, "add_shape_action_does_not_have_a_valid_container", v); } return null; } protected static class SetsContainerToTopLevel extends FixProposal<AddShapeActionMustHaveAValidContainer, AddShape> { public SetsContainerToTopLevel() { super("sets_container_to_top_level"); } @Override protected void fixAction() { AddShape action = getObject(); action.setContainer(new ViewPointDataBinding(EditionScheme.TOP_LEVEL)); } } protected static class SetsContainerToShape extends FixProposal<AddShapeActionMustHaveAValidContainer, AddShape> { private ShapePatternRole patternRole; public SetsContainerToShape(ShapePatternRole patternRole) { super("sets_container_to_($patternRole.patternRoleName)"); this.patternRole = patternRole; } public ShapePatternRole getPatternRole() { return patternRole; } @Override protected void fixAction() { AddShape action = getObject(); action.setContainer(new ViewPointDataBinding(patternRole.getPatternRoleName())); } } protected static class SetsContainerToTargetShape extends FixProposal<AddShapeActionMustHaveAValidContainer, AddShape> { private EditionPattern target; private ShapePatternRole patternRole; public SetsContainerToTargetShape(EditionPattern target, ShapePatternRole patternRole) { super("sets_container_to_target.($patternRole.patternRoleName)"); this.target = target; this.patternRole = patternRole; } public ShapePatternRole getPatternRole() { return patternRole; } public EditionPattern getTarget() { return target; } @Override protected void fixAction() { AddShape action = getObject(); action.setContainer(new ViewPointDataBinding(EditionScheme.TARGET + "." + patternRole.getPatternRoleName())); } } } }