/*
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);
}
}
}