Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Created on Jul 13, 2010, 3:41:56 PM
  
  package com.dmurph.mvc.model;
  
  import java.util.HashMap;
  import java.util.Iterator;
 
Model that stores all properties in a HashMap, so all com.dmurph.mvc.IDirtyable, com.dmurph.mvc.ICloneable, and com.dmurph.mvc.IRevertible functionality is handled internally.

This class also will forward all calls to it's members if implement the associated interface. For example, if revertChanges() is called, then, after reverting any changes to this model, it will call com.dmurph.mvc.IRevertible.revertChanges() on any property that is com.dmurph.mvc.IRevertible. This can get dangerous if your property tree goes in a loop (you'll get infinite calls). In that case override cloneImpl(java.lang.String,java.lang.Object), revertChangesImpl(java.lang.String,com.dmurph.mvc.IRevertible), isDirtyImpl(java.lang.String,com.dmurph.mvc.IDirtyable), or saveChangesImpl(java.lang.String,com.dmurph.mvc.IRevertible) to prevent this.

Author(s):
Daniel Murphy
 
 public class HashModel extends AbstractRevertibleModel implements IDirtyableICloneableIRevertible{
 	private static final long serialVersionUID = 2L;
 	
 	private final HashMap<StringModelPropertypropertyMap = new HashMap<StringModelProperty>();
 	
 	public enum PropertyType{
 
 		READ_ONLY,
Property that can be read and written to by the HashModel.getProperty(java.lang.String) and HashModel.setProperty(java.lang.String,java.lang.Object) methods.
 
 		READ_WRITE,
Property that, after registration, cannot be set again by either accessing classes or the implementing class. This guarantees that the object returned from HashModel.getProperty(java.lang.String) will always be the correct reference.
 
 		FINAL
 	}
 	
 	// for listening to dirty updates from children
 		public void propertyChange(PropertyChangeEvent argEvt) {
 				if(argEvt.getNewValue() == .){
 				}
 			}
 		}
 	};

Constructs a hash model with an com.dmurph.mvc.IModel.DIRTY property.
 
 	public HashModel(){
 	}

Constructs a hash model with an com.dmurph.mvc.IModel.DIRTY property, and the given properties all with property type of HashModel.PropertyType.READ_WRITE.

Parameters:
argProperties
 
 	public HashModel(String[] argProperties){
 		this();
 	}
 	
 	
 	private void addListener(Object argObject){
 		if(argObject instanceof IModel){
 		}
 	}
 	
 	private void removeListener(Object argObject){
 		if(argObject instanceof IModel){
 		}
	}

Register a property

Parameters:
argKey
argType
	protected void registerProperty(String argKeyPropertyType argType){
		registerProperty(argKeyargTypenull);
	}

Register a property with an initial value

Parameters:
argKey
argType
argInitial
	protected synchronized void registerProperty(String argKeyPropertyType argTypeObject argInitial){
			mp = .get(argKey);
			if(mp.type == .){
				return;
			}
		}else{
			mp = new ModelProperty();
		}
		mp.type = argType;
		mp.prop = argInitial;
		addListener(mp.prop);
		.put(argKeymp);
	}

Register an array of properties all of the same property type

Parameters:
argKeys
argType
	protected synchronized void registerProperty(String[] argKeysPropertyType argType){
		for(String sargKeys){
			registerProperty(sargTypenull);
		}
	}

Sets a property, and will only set the property if it's HashModel.PropertyType is HashModel.PropertyType.READ_WRITE. If the property isn't defined, it will be registered and set with the property type of HashModel.PropertyType.READ_WRITE.

	public synchronized Object setProperty(String argKeyObject argProperty){
			ModelProperty mp = .get(argKey);
			if(mp.type == .){
				if(mp.prop == argProperty){
					return argProperty;
				}
				Object old = mp.prop;
				mp.prop = argProperty;
				addListener(mp.prop);
				firePropertyChange(argKeyoldargProperty);
				if(!argProperty.equals()){
				}
				return old;
			}else{
				return mp.prop;
			}
		}else{
			return setProperty(argKeyargProperty);
		}
	}

Get a property

Parameters:
argKey
Returns:
	public synchronized Object getProperty(String argKey){
		ModelProperty mp = .get(argKey);
		if(mp != null){
			return mp.prop;
		}else{
			return null;
		}
	}

Get the HashModel.PropertyType for a property.

Parameters:
argKey
Returns:
	public synchronized PropertyType getPropertyType(String argKey){
		ModelProperty mp = .get(argKey);
		if(mp != null){
			return mp.type;
		}else{
			return null;
		}
	}

	public ICloneable clone(){
		HashModel model = new HashModel();
		model.cloneFrom(this);
		return model;
	}
	// clears properties of the model, making sure the remove listeners
	// from any properties that are IModels
	private void clear(){
		while(it.hasNext()){
			it.remove();
		}
	}

Clones from another HashModel, and makes sure to copy any values in the model that are com.dmurph.mvc.ICloneable. It watches for references to argOther and sets them to this.

	public synchronized void cloneFrom(ICloneable argOther) {
		if(argOther instanceof HashModel){
			HashModel other = (HashModelargOther;
			for(String keyother.propertyMap.keySet()){
				ModelProperty mp = other.propertyMap.get(key);
				registerProperty(keymp.type);
				if(mp.prop == argOther){
					setProperty(keythis);
					continue;
				}
				setProperty(keycloneImpl(keymp.prop));
			}
		}else{
			throw new RuntimeException("Not a HashModel");
		}
	}

Default just calls com.dmurph.mvc.ICloneable.clone() (if the object is com.dmurph.mvc.ICloneable), but override to implement your own cloning and to protect against loops (if the property tree goes in a loop).

Parameters:
argRevertable
Returns:
	protected Object cloneImpl(String argPropertyObject o){
		if(o instanceof ICloneable){
			return ((ICloneableo).clone();
		}else{
			return o;
		}
	}

	public synchronized boolean isDirty() {
		boolean ret = super.isDirty();
		if(ret){
			return ret;
		}
		for(String key.keySet()){
			if(mp.prop instanceof IDirtyable){
				ret = ret || isDirtyImpl(key, (IDirtyablemp.prop);
				if(ret){
					return ret;
				}
			}
		}
		return ret;
	}

Default just calls com.dmurph.mvc.IDirtyable.isDirty(), but override to protect against loops (if the property tree goes in a loop).

Parameters:
argRevertable
Returns:
	public boolean isDirtyImpl(String argPropertyIDirtyable argDirtyable){
		return argDirtyable.isDirty();
	}

	public synchronized boolean revertChanges() {
		boolean ret = super.revertChanges();
		for(String key.keySet()){
			if(mp.prop instanceof IRevertible){
				ret = ret || revertChangesImpl(key, (IRevertiblemp.prop);
			}
		}
		return ret;
	}

Default just calls com.dmurph.mvc.IRevertible.revertChanges(), but override to protect against loops (if the property tree goes in a loop).

Parameters:
argRevertable
Returns:
	protected boolean revertChangesImpl(String argPropertyIRevertible argRevertible){
		return argRevertible.revertChanges();
	}

	public synchronized boolean saveChanges() {
		boolean ret = super.saveChanges();
		for(String key.keySet()){
			if(mp.prop instanceof IRevertible){
				ret = ret || saveChangesImpl(key, (IRevertiblemp.prop);
			}
		}
		return ret;
	}

Default just calls com.dmurph.mvc.IRevertible.saveChanges(), but override to protect against loops (if the property tree goes in a loop).

Parameters:
argRevertible
Returns:
	protected boolean saveChangesImpl(String argPropertyIRevertible argRevertible){
		return argRevertible.saveChanges();
	}
	private static class ModelProperty{
	}
New to GrepCode? Check out our FAQ X