/* ==================================================================== * * The ObjectStyle Group Software License, Version 1.0 * * Copyright (c) 2005 The ObjectStyle Group, * and individual authors of the software. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * ObjectStyle Group (http://objectstyle.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "ObjectStyle Group" and "Cayenne" * must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact andrus@objectstyle.org. * * 5. Products derived from this software may not be called "ObjectStyle" * nor may "ObjectStyle" appear in their names without prior written * permission of the ObjectStyle Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the ObjectStyle Group. For more * information on the ObjectStyle Group, please see * <http://objectstyle.org/>. * */ package org.objectstyle.wolips.bindings.api; import java.util.List; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.objectstyle.wolips.baseforplugins.util.ComparisonUtils; import org.objectstyle.wolips.bindings.wod.TypeCache; import org.w3c.dom.Element; public class Binding extends AbstractApiModelElement implements IApiBinding { private BindingChangedListener bindingChangedListener; public final static String BINDING = "binding"; public final static String NAME = "name"; private final static String DEFAULTS = "defaults"; private Wo parent; protected Binding(Element element, ApiModel apiModel, Wo parent) { super(element, apiModel); this.parent = parent; } public boolean isAction() { return ApiUtils.isActionBinding(this); } public int compareTo(IApiBinding o) { return (o == null) ? -1 : getName() == null ? -1 : getName().compareTo(o.getName()); } @Override public boolean equals(Object o) { return o instanceof Binding && ComparisonUtils.equals(((Binding) o).getName(), getName()); } @Override public int hashCode() { String name = getName(); return name == null ? 0 : name.hashCode(); } public Wo getElement() { return parent; } public String getName() { synchronized (this.apiModel) { return element.getAttribute(NAME); } } public void setName(String className) { synchronized (this.apiModel) { String oldName = getName(); if (!ComparisonUtils.equals(className, oldName)) { if (className == null || className.length() == 0) { throw new IllegalArgumentException("Binding names cannot be blank."); } if (parent.getBinding(className) != null) { throw new IllegalArgumentException("Binding names must be unique."); } element.setAttribute(NAME, className); for (IValidation validation : parent.getDeepAffectedValidations(oldName)) { if (validation instanceof AbstractNamedValidation) { ((AbstractNamedValidation)validation).setName(className); } } markAsDirty(); } } } public String getDefaults() { synchronized (this.apiModel) { return element.getAttribute(DEFAULTS); } } public int getSelectedDefaults() { return ApiUtils.getSelectedDefaults(this); } public void setDefaults(String defaults) { synchronized (this.apiModel) { element.setAttribute(DEFAULTS, defaults); markAsDirty(); } } public void setDefaults(int defaults) { synchronized (this.apiModel) { if (defaults == 0) { if (getDefaults() == null) { return; } element.removeAttribute(DEFAULTS); } else { if (getDefaults() != null && getDefaults().equals(ALL_DEFAULTS[defaults])) { return; } this.setDefaults(ALL_DEFAULTS[defaults]); } markAsDirty(); } } public boolean isExplicitlyRequired() { synchronized (this.apiModel) { return "YES".equalsIgnoreCase(element.getAttribute("required")); } } public boolean isRequired() { boolean required = isExplicitlyRequired(); if (!required) { List<Validation> validations = parent.getValidations(); for (int i = 0; !required && i < validations.size(); i++) { Validation validation = validations.get(i); List<Unbound> unbounds = validation.getUnbounds(); if (unbounds.size() == 1 && unbounds.get(0).isAffectedByBindingNamed(this.getName())) { required = true; } } } return required; } public void setIsRequired(boolean isRequired) { synchronized (this.apiModel) { if (this.isRequired() == isRequired) { return; } if (element.hasAttribute("required")) { if (isRequired) { element.setAttribute("required", "YES"); } else { element.setAttribute("required", "NO"); } } else if (isRequired) { Unbound.addToWoWithBinding(parent, this); } else { Unbound.removeFromWoWithBinding(parent, this); } markAsDirty(); } } public boolean isExplicitlySettable() { synchronized (this.apiModel) { return "YES".equalsIgnoreCase(element.getAttribute("settable")); } } public boolean isWillSet() { boolean settable = isExplicitlySettable(); if (!settable) { List<Validation> validations = parent.getValidations(); for (Validation validation : validations) { List<Unsettable> unsettables = validation.getUnsettables(); if (unsettables.size() == 1 && unsettables.get(0).isAffectedByBindingNamed(this.getName())) { settable = true; break; } } } return settable; } public void setIsWillSet(boolean isWillSet) { synchronized (this.apiModel) { if (this.isWillSet() == isWillSet) { return; } if (element.hasAttribute("settable")) { if (isWillSet) { element.setAttribute("settable", "YES"); } else { element.setAttribute("settable", "NO"); } } else if (isWillSet) { Unsettable.addToWoWithBinding(parent, this); } else { Unsettable.removeFromWoWithBinding(parent, this); } markAsDirty(); } } public String[] getValidValues(String partialValue, IJavaProject javaProject, IType componentType, TypeCache typeCache) throws JavaModelException { return ApiUtils.getValidValues(this, partialValue, javaProject, componentType, typeCache); } public interface BindingChangedListener { public abstract void bindingChanged(Binding binding); } public void setBindingChangedListener(BindingChangedListener bindingChangedListener) { this.bindingChangedListener = bindingChangedListener; } public void markAsDirty() { apiModel.markAsDirty(); if (bindingChangedListener != null) { bindingChangedListener.bindingChanged(this); } } }