/* PseudoCode Interpreted Language (PCIL): Part of the algoviz@vt collection of algorithm visualizations. Copyright (C) 2008 Brandon Malone, Frank Hadlock This file is part of the PseudoCode Interpreted Language. PseudoCode Interpreted Language 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. PseudoCode Interpreted Language 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 PseudoCode Interpreted Language. If not, see . */ /* * Primitive.java * * Created on February 4, 2008, 10:47 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package dynamicmvc; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JPanel; /** * * @author Brandon */ public abstract class Primitive implements IAddPropertyViewCaller, Serializable { public abstract String getType(); public Primitive getThis() { return this; } public PrimitivePointer getPointer() throws DynamicMVCException { return PrimitiveFactory.getPointer(this); } private HashMap definedProperties; public Primitive() { setDefinedProperties(new HashMap()); } public void set(String name, PrimitivePointer p) { getDefinedProperties().put(name, p); } public PrimitivePointer get(String name) throws DynamicMVCException { PrimitivePointer p = getDefinedProperties().get(name); if (p == null) { p = PrimitiveFactory.create(PrimitiveNull.pseudocodeTypeName(), name); set(name, p); } return p; } public HashMap getDefinedProperties() { return definedProperties; } public PrimitivePointer getDefinedPropertyByAddress(int address) { for(PrimitivePointer p : definedProperties.values()) { if (p.getAddress() == address) { return p; } } return null; } public HashMap getDefinedPropertiesCopy() { HashMap copy = new HashMap(); for(String name : definedProperties.keySet()) { PrimitivePointer p = definedProperties.get(name); copy.put(name, p); } return copy; } public boolean hasDefinedPrimitives(HashMap combination) { for(String key : combination.keySet()) { if(definedProperties.containsKey(key)) { PrimitivePointer p = definedProperties.get(key); Primitive otherP = combination.get(key); if(!p.valueEquals(otherP)) { return false; } } else { return false; } } return true; } public boolean hasDefinedProperties(HashMap combination) { for(String key : combination.keySet()) { if(definedProperties.containsKey(key)) { PrimitivePointer p = definedProperties.get(key); PrimitivePointer otherP = combination.get(key); if(!p.valueEquals(otherP)) { return false; } } else { return false; } } return true; } public JComponent getReadOnlyDefinedPropertiesComponent() { JPanel wrapper = new JPanel(); for(String name : definedProperties.keySet()) { PrimitivePointer p = definedProperties.get(name); String originalName = p.getName(); p.setName(name); wrapper.add(p.getReadOnlyComponent()); p.setName(originalName); } return wrapper; } public String getPropertiesComponentName() { return this.getEditComponentWrapperName() + "properties"; } public JComponent getEditPropertiesComponent() { JPanel wrapper = new JPanel(); wrapper.setName(getPropertiesComponentName()); for(String name : definedProperties.keySet()) { PrimitivePointer p = definedProperties.get(name); String originalName = p.getName(); p.setName(name); wrapper.add(p.getEditComponent()); p.setName(originalName); } //wrapper.add(getNewPropertyComponent()); return wrapper; } public void populateDefinedProperties(JComponent propertiesComponent) throws DynamicMVCException { for(String name : definedProperties.keySet()) { PrimitivePointer p = definedProperties.get(name); String childComponentName = p.getEditComponentName(); JComponent child = (JComponent)View.getComponent(propertiesComponent, childComponentName); if (child != null) { p.populateFromEditComponentWrapper(child); } } } public JComponent getNewPropertyComponent() { JButton addButton = new JButton(); addButton.setText("Add a Property"); addButton.addActionListener(new AddHandler()); return addButton; } class AddHandler implements ActionListener { public void actionPerformed(ActionEvent e) { // show an AddPropertyView dialog AddPropertyView v = new AddPropertyView("Add a property to : " + getType(), getThis(), null); v.setVisible(true); } } public void okClicked(AddPropertyView sender, Object callerFlag) { String dataTypeName = sender.getDataTypeName(); String propertyName = sender.getPropertyName(); PrimitivePointer p = PrimitiveFactory.create(dataTypeName, propertyName); set(propertyName, p); View.updateView(); sender.dispose(); } public void cancelClicked(AddPropertyView sender, Object callerFlag) { sender.dispose(); } public void addEditDefinedProperties(JPanel pnl) { JComponent definedPropertiesWrapper = getEditPropertiesComponent(); if (definedPropertiesWrapper != null) { pnl.add(definedPropertiesWrapper); } } public void addDefinedProperties(JPanel pnl) { JComponent definedPropertiesWrapper = getReadOnlyDefinedPropertiesComponent(); if (definedPropertiesWrapper != null) { pnl.add(definedPropertiesWrapper); } } public abstract JComponent getReadOnlyComponent(); public abstract JComponent getEditComponent(); public abstract String getEditComponentWrapperName(); public abstract void populateFromEditComponentWrapper(JComponent editComponentWrapper) throws DynamicMVCException; public abstract void setName(String name); public abstract String getName(); //public abstract Primitive copy() throws DynamicMVCException; public abstract Primitive deepCopy(HashMap alreadyCopiedAddresses) throws DynamicMVCException; public void deepCopyDefinedProperties(Primitive other, HashMap alreadyCopiedAddresses) throws DynamicMVCException { // copy my defined properties to other for(String n : getDefinedProperties().keySet()) { PrimitivePointer pp = getDefinedProperties().get(n); PrimitivePointer copy = pp.deepCopy(alreadyCopiedAddresses); copy.setName(pp.getName()); other.set(pp.getName(), copy); } } public abstract Object execute(String methodName, ArrayList arguments) throws DynamicMVCException; public int compareTo(Primitive p) throws DynamicMVCException { return getName().compareTo(p.getName()); } public abstract boolean deepEquals(Primitive p) throws DynamicMVCException; public boolean deepEqualsDefinedProperties(Primitive other) throws DynamicMVCException { for(String n : getDefinedProperties().keySet()) { PrimitivePointer otherP = other.definedProperties.get(n); PrimitivePointer myP = definedProperties.get(n); if (otherP == null) { return myP.dereference().isNullable(); } if(!myP.deepEquals(otherP)) { return false; } } return true; } public boolean isNullable() { return false; } public boolean isResizable() { return false; } public void setDefinedProperties(HashMap definedProperties) { this.definedProperties = definedProperties; } public PrimitiveString toPrimitiveString() { PrimitiveString s = (PrimitiveString)(PrimitiveFactory.create(PrimitiveString.pseudocodeTypeName(), "s").dereference()); s.setValue(getName()); return s; } public boolean valueEquals(Primitive p) { return this == p; } private String updateVariableName; public String getUpdateVariableName() { return updateVariableName; } public void setUpdateVariableName(String updateVariableName) { this.updateVariableName = updateVariableName; } public void setEmptyProperties(PrimitivePointer other) throws DynamicMVCException { setEmptyProperties(other.dereference()); } public void setEmptyProperties(Primitive other) throws DynamicMVCException { // make sure that other has each one of the properties that I have for(PrimitivePointer myP : this.getDefinedProperties().values()) { // even if other does not contain this property, // the call to get will create a null value for the property PrimitivePointer otherP = other.get(myP.getName()); // also, ensure that the properties are of the same type if(!myP.dereference().getType().equals(otherP.dereference().getType())) { // if not, just erase the old variable // in general, this should only happen when setting a null value to an actual value PrimitivePointer newP = PrimitiveFactory.create(myP.dereference().getType(), myP.getName()); other.set(newP.getName(), newP); } // recursively call this function on all of the properties myP.setEmptyProperties(otherP); } } }