| /******************************************************************************* |
| * Copyright (c) 2000, 2005 IBM Corporation and others. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.wst.ws.internal.datamodel; |
| |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| import java.util.Vector; |
| |
| public class BasicElement implements Element |
| { |
| |
| // Copyright |
| public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002."; |
| |
| private String fName; |
| private String fMUID; |
| private Model fModel; |
| private Hashtable fRels; |
| private Hashtable fProperties; |
| private Vector fListeners; |
| |
| public BasicElement ( String name, Model model ) |
| { |
| fName = name; |
| setMUID(model.makeMUID(name)); |
| model.addElement(this); |
| fModel = model; |
| fRels = new Hashtable(); |
| fListeners = new Vector(); |
| fProperties = new Hashtable(); |
| fProperties.put(Property.NAME,new BasicProperty(Property.NAME,fName)); |
| } |
| |
| public BasicElement ( String name, Element element, String outboundRelName, String inboundRelName ) |
| { |
| this(name,element.getModel()); |
| connect(element,outboundRelName,inboundRelName); |
| } |
| |
| /** |
| * Returns a clone of this <code>Element</code> |
| * of the same class and with the same name and model, |
| * but with no Properties, Rels or Listeners except for |
| * the {@link Property#NAME NAME} property. |
| * @return Object A new Element. |
| */ |
| public Element shallowClone () |
| { |
| return new BasicElement(fName,fModel); |
| } |
| |
| /** |
| * Returns a clone of this <code>Element</code> |
| * of the same class and with the same name and model |
| * and with a copy of the original Element's Properties. |
| * The Rels and Listeners are not cloned. |
| * @return Element A new Element. |
| */ |
| public final Element deepClone () |
| { |
| Element newElement = shallowClone(); |
| Enumeration e = getProperties(); |
| while (e.hasMoreElements()) |
| { |
| Property property = (Property)e.nextElement(); |
| Property newProperty = (Property)property.shallowClone(); |
| newElement.setProperty(newProperty); |
| } |
| return newElement; |
| } |
| |
| /** |
| * Model-View-Controller: All property changes to the model |
| * (such as those made by a wizard in the role of a Controller) |
| * should yield events to which an interested party can listen |
| * (such as a wizard in the role of a Viewer). |
| * @param tml The listener to add. |
| */ |
| public void addListener ( ElementListener listener ) |
| { |
| fListeners.add(listener); |
| } |
| |
| public Model getModel () |
| { |
| return fModel; |
| } |
| |
| public boolean isValid () |
| { |
| return (fModel != null && fModel.containsElement(this)); |
| } |
| |
| public boolean remove () |
| { |
| return fModel.removeElement(this); |
| } |
| |
| public void setName ( String name ) |
| { |
| fName = name; |
| fProperties.put(Property.NAME,new BasicProperty(Property.NAME,fName)); |
| } |
| |
| public String getName () |
| { |
| return fName; |
| } |
| |
| /* |
| * The getter for the MUID |
| * The MUID is the Model Unique Identifier, made from the name and an |
| * appended unique number |
| * @return String a unique id for this element within the context of the model |
| */ |
| public String getMUID() |
| { |
| return fMUID; |
| } |
| |
| /* |
| * |
| * |
| */ |
| public int getNumberID() |
| { |
| String number = getMUID().substring(getName().length()); |
| return Integer.parseInt(number); |
| } |
| |
| /* |
| * Set the MUID which was made by the model |
| * Should only be settable within this element |
| * Set once upon creation, you can change the name |
| * but the id will remain constant. |
| */ |
| private void setMUID(String MUID) |
| { |
| fMUID = MUID; |
| } |
| |
| public void setProperty ( Property property ) |
| { |
| String propertyName = property.getName(); |
| Property oldProperty = getProperty(propertyName); |
| fProperties.put(propertyName,property); |
| if (oldProperty == null) |
| { |
| PropertyAddEvent event = new PropertyAddEvent(this,property); |
| Enumeration e = fListeners.elements(); |
| while (e.hasMoreElements()) |
| { |
| ((ElementListener)e.nextElement()).propertyAdded(event); |
| } |
| } |
| else |
| { |
| Object oldValue = oldProperty.getValue(); |
| Object newValue = property.getValue(); |
| if (oldValue != newValue) |
| { |
| if (oldValue == null || newValue == null || (!oldValue.equals(newValue))) |
| { |
| PropertyChangeEvent event = new PropertyChangeEvent(this,property,oldProperty); |
| Enumeration e = fListeners.elements(); |
| while (e.hasMoreElements()) |
| { |
| ((ElementListener)e.nextElement()).propertyChanged(event); |
| } |
| } |
| } |
| } |
| if (propertyName.equals(Property.NAME)) fName = property.getValue().toString(); |
| } |
| |
| public void setPropertyAsObject ( String name, Object value ) |
| { |
| setProperty(new BasicProperty(name,value)); |
| } |
| |
| public void setPropertyAsString ( String name, String value ) |
| { |
| setProperty(new BasicProperty(name,value)); |
| } |
| |
| public Property getProperty ( String name ) |
| { |
| return (Property)fProperties.get(name); |
| } |
| |
| public Object getPropertyAsObject ( String name ) |
| { |
| Property property = getProperty(name); |
| return (property == null ? null : property.getValue()); |
| } |
| |
| public String getPropertyAsString ( String name ) |
| { |
| Property property = getProperty(name); |
| return (property == null ? null : property.getValueAsString()); |
| } |
| |
| public Enumeration getProperties () |
| { |
| return fProperties.elements(); |
| } |
| |
| public boolean connect ( Element targetElement, String outboundRelName, String inboundRelName ) |
| { |
| if (fModel == null || fModel != targetElement.getModel()) return false; |
| |
| Element sourceElement = this; |
| Rel outboundRel = sourceElement.getRel(outboundRelName); |
| Rel inboundRel = targetElement.getRel(inboundRelName); |
| Connection[] pair = BasicConnection.createPair(outboundRel,targetElement,inboundRel,sourceElement); |
| outboundRel.addConnection(pair[BasicConnection.OUTBOUND]); |
| inboundRel.addConnection(pair[BasicConnection.INBOUND]); |
| RelAddEvent event = new RelAddEvent(pair); |
| Enumeration eSource = getListeners(); |
| Enumeration eTarget = targetElement.getListeners(); |
| while (eSource.hasMoreElements()) |
| { |
| ((ElementListener)eSource.nextElement()).relAdded(event); |
| } |
| |
| while (eTarget.hasMoreElements()) |
| { |
| ((ElementListener)eTarget.nextElement()).relAdded(event); |
| } |
| |
| |
| return true; |
| } |
| |
| public boolean disconnect ( Element targetElement, String outboundRelName ) |
| { |
| return disconnect(targetElement,getRel(outboundRelName)); |
| } |
| |
| public boolean disconnectRel ( String outboundRelName ) |
| { |
| return disconnectRel(getRel(outboundRelName)); |
| } |
| |
| public boolean disconnectAll () |
| { |
| if (fModel == null) return false; |
| Enumeration e = fRels.elements(); |
| while (e.hasMoreElements()) |
| { |
| Rel rel = (Rel)e.nextElement(); |
| disconnectRel(rel); |
| } |
| return true; |
| } |
| |
| public Enumeration getElements ( String relName ) |
| { |
| return getRel(relName).getTargetElements(); |
| } |
| |
| public int getNumberOfElements ( String relName ) |
| { |
| return getRel(relName).getNumberOfTargetElements(); |
| } |
| |
| public Rel getRel ( String relName ) |
| { |
| Rel rel = (Rel)fRels.get(relName); |
| if (rel == null) |
| { |
| rel = new BasicRel(relName,this); |
| fRels.put(relName,rel); |
| } |
| return rel; |
| } |
| |
| public Enumeration getRels () |
| { |
| return fRels.elements(); |
| } |
| |
| public Enumeration getListeners() |
| { |
| return fListeners.elements(); |
| } |
| |
| protected boolean disconnect ( Element targetElement, Rel outboundRel ) |
| { |
| if (fModel == null || fModel != targetElement.getModel() || outboundRel == null) return false; |
| Connection outboundConnection = outboundRel.getConnectionTo(targetElement); |
| if (outboundConnection == null) return false; |
| Connection inboundConnection = outboundConnection.getOpposingConnection(); |
| RelRemoveEvent event = new RelRemoveEvent(new Connection [] {outboundConnection,inboundConnection}); |
| Enumeration e = fListeners.elements(); |
| while (e.hasMoreElements()) |
| { |
| ((ElementListener)e.nextElement()).relRemoved(event); |
| } |
| |
| Enumeration eTarget = targetElement.getListeners(); |
| while (eTarget.hasMoreElements()) |
| { |
| ((ElementListener)eTarget.nextElement()).relRemoved(event); |
| } |
| |
| Rel inboundRel = inboundConnection.getRel(); |
| boolean done = outboundRel.removeConnection(outboundConnection); |
| inboundRel.removeConnection(inboundConnection); |
| return done; |
| } |
| |
| protected boolean disconnectRel ( Rel outboundRel ) |
| { |
| if (fModel == null || outboundRel == null) return false; |
| Element[] elements = new Element[outboundRel.getNumberOfTargetElements()]; |
| int i = 0; |
| Enumeration e = outboundRel.getTargetElements(); |
| while (e.hasMoreElements()) |
| { |
| elements[i++] = (Element)e.nextElement(); |
| } |
| while (i-- > 0) |
| { |
| disconnect(elements[i],outboundRel); |
| } |
| return true; |
| } |
| |
| public String toString () |
| { |
| return getName(); |
| } |
| } |
| |