/******************************************************************************* * Copyright (c) 2007, 2008 Spring IDE Developers * 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: * Spring IDE Developers - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.webflow.core.internal.model; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IResource; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; import org.springframework.ide.eclipse.core.model.IModelElement; import org.springframework.ide.eclipse.core.model.IResourceModelElement; import org.springframework.ide.eclipse.webflow.core.model.IAttribute; import org.springframework.ide.eclipse.webflow.core.model.IAttributeEnabled; import org.springframework.ide.eclipse.webflow.core.model.IWebflowModelElement; import org.springframework.util.ClassUtils; import org.w3c.dom.NodeList; /** * @author Christian Dupuis * @since 2.0 */ @SuppressWarnings("restriction") public abstract class AbstractModelElement extends WebflowModelElement implements IAttributeEnabled { private static final Map<Class, Integer> ELEMENT_TYPE_MAPPING; static { ELEMENT_TYPE_MAPPING = new HashMap<Class, Integer>(); ELEMENT_TYPE_MAPPING.put(WebflowModel.class, 1); ELEMENT_TYPE_MAPPING.put(WebflowProject.class, 2); ELEMENT_TYPE_MAPPING.put(WebflowConfig.class, 3); ELEMENT_TYPE_MAPPING.put(WebflowState.class, 4); ELEMENT_TYPE_MAPPING.put(Action.class, 5); ELEMENT_TYPE_MAPPING.put(ActionState.class, 6); ELEMENT_TYPE_MAPPING.put(Argument.class, 7); ELEMENT_TYPE_MAPPING.put(Attribute.class, 8); ELEMENT_TYPE_MAPPING.put(AttributeMapper.class, 9); ELEMENT_TYPE_MAPPING.put(BeanAction.class, 10); ELEMENT_TYPE_MAPPING.put(DecisionState.class, 11); ELEMENT_TYPE_MAPPING.put(EndState.class, 12); ELEMENT_TYPE_MAPPING.put(EntryActions.class, 13); ELEMENT_TYPE_MAPPING.put(EvaluateAction.class, 14); ELEMENT_TYPE_MAPPING.put(EvaluationResult.class, 15); ELEMENT_TYPE_MAPPING.put(ExceptionHandler.class, 16); ELEMENT_TYPE_MAPPING.put(ExitActions.class, 17); ELEMENT_TYPE_MAPPING.put(GlobalTransitions.class, 18); ELEMENT_TYPE_MAPPING.put(If.class, 19); ELEMENT_TYPE_MAPPING.put(IfTransition.class, 20); ELEMENT_TYPE_MAPPING.put(Import.class, 21); ELEMENT_TYPE_MAPPING.put(InlineFlowState.class, 22); ELEMENT_TYPE_MAPPING.put(InputAttribute.class, 23); ELEMENT_TYPE_MAPPING.put(InputMapper.class, 34); ELEMENT_TYPE_MAPPING.put(Mapping.class, 25); ELEMENT_TYPE_MAPPING.put(MethodArguments.class, 26); ELEMENT_TYPE_MAPPING.put(MethodResult.class, 27); ELEMENT_TYPE_MAPPING.put(OutputAttribute.class, 28); ELEMENT_TYPE_MAPPING.put(RenderActions.class, 29); ELEMENT_TYPE_MAPPING.put(Set.class, 30); ELEMENT_TYPE_MAPPING.put(StateTransition.class, 31); ELEMENT_TYPE_MAPPING.put(SubflowState.class, 32); ELEMENT_TYPE_MAPPING.put(Variable.class, 33); ELEMENT_TYPE_MAPPING.put(ViewState.class, 34); } /** * The attributes. */ protected List<IAttribute> attributes; /** * Init. * @param node the node * @param parent the parent */ @Override public void init(IDOMNode node, IWebflowModelElement parent) { super.init(node, parent); this.attributes = new ArrayList<IAttribute>(); if (node != null) { NodeList children = node.getChildNodes(); if (children != null && children.getLength() > 0) { for (int i = 0; i < children.getLength(); i++) { IDOMNode child = (IDOMNode) children.item(i); if ("attribute".equals(child.getLocalName())) { Attribute p = new Attribute(); p.init(child, this); this.attributes.add(p); } } } } } /** * Adds the attribute. * @param property the property */ public void addAttribute(IAttribute property) { if (!this.attributes.contains(property)) { WebflowModelXmlUtils.insertNode(property.getNode(), getNode()); this.attributes.add(property); super.firePropertyChange(ADD_CHILDREN, new Integer(this.attributes .indexOf(property)), property); } } /** * Adds the attribute. * @param index the index * @param property the property */ public void addAttribute(IAttribute property, int index) { if (!this.attributes.contains(property)) { this.attributes.add(index, property); WebflowModelXmlUtils.determineNodeToInsert(property.getNode(), getNode()); super .firePropertyChange(ADD_CHILDREN, new Integer(index), property); } } /** * Gets the attributes. * @return the attributes */ public List<IAttribute> getAttributes() { return this.attributes; } /** * Removes the attribute. * @param property the property */ public void removeAttribute(IAttribute property) { if (this.attributes.contains(property)) { this.attributes.remove(property); getNode().removeChild(property.getNode()); super.fireStructureChange(REMOVE_CHILDREN, property); } } /** * Adds the property. * @param value the value * @param name the name */ public void addProperty(String name, String value) { } /** Character used for delimiting nodes within an element's unique id */ char ID_DELIMITER = '|'; /** * Character used separate an element's type and name within an element's * unique id */ char ID_SEPARATOR = ':'; public final String getElementID() { StringBuffer id = new StringBuffer(); if (getElementParent() != null) { id.append(getElementParent().getElementID()); id.append(ID_DELIMITER); } id.append(getElementType()); id.append(ID_SEPARATOR); if (getElementName() != null) { id.append(getElementName()); } else { id.append(super.hashCode()); } return id.toString(); } /** * Returns the element for the given element ID. * @param id the element's unique ID */ public IModelElement getElement(String id) { int sepPos = id.indexOf(ID_SEPARATOR); if (sepPos > 0) { try { int type = Integer.valueOf(id.substring(0, sepPos)).intValue(); if (type == getElementType()) { int delPos = id.indexOf(ID_DELIMITER); if (delPos > 0) { String name = id.substring(sepPos + 1, delPos); if (name.equals(getElementName())) { // Ask children for remaining part of id id = id.substring(delPos + 1); for (IModelElement child : getElementChildren()) { if (child instanceof AbstractModelElement) { IModelElement element = ((AbstractModelElement) child) .getElement(id); if (element != null) { return element; } } } } } else { String name = id.substring(sepPos + 1); if (name.equals(getElementName())) { return this; } } } } catch (NumberFormatException e) { // ignore } } return null; } public int getElementType() { return ELEMENT_TYPE_MAPPING.get(getClass()); } public String getElementName() { return ClassUtils.getShortName(getClass()) + " (" + getElementStartLine() + ")"; } public IResource getElementResource() { IResource resource = null; IResourceModelElement parent = (IResourceModelElement) getElementParent(); while (resource == null && parent != null) { resource = parent.getElementResource(); parent = (IResourceModelElement) getElementParent(); } return resource; } public boolean isElementArchived() { return false; } public boolean isExternal() { return false; } }