View Javadoc

1   /**********************************************
2    * Copyright (C) 2011 Lukas Laag
3    * This file is part of svgreal.
4    * 
5    * svgreal is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    * 
10   * svgreal is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License
16   * along with svgreal.  If not, see http://www.gnu.org/licenses/
17   **********************************************/package org.vectomatic.svg.edit.client.model;
18  
19  import java.util.Collection;
20  import java.util.Map;
21  
22  import com.extjs.gxt.ui.client.data.ChangeEvent;
23  import com.extjs.gxt.ui.client.data.ChangeEventSupport;
24  import com.extjs.gxt.ui.client.data.ChangeListener;
25  import com.extjs.gxt.ui.client.data.Model;
26  import com.extjs.gxt.ui.client.data.PropertyChangeEvent;
27  import com.extjs.gxt.ui.client.store.Store;
28  import com.extjs.gxt.ui.client.util.Util;
29  import com.google.gwt.core.client.GWT;
30  
31  /**
32   * Base class for GXT {@link com.extjs.gxt.ui.client.data.Model}
33   * implementations which rely on a {@link MetaModel} to supply
34   * the model properties.
35   * @author laaglu
36   */
37  public abstract class AbstractModel<U> implements Model {
38  	/**
39  	 * To implement ChangeEventSource
40  	 */
41  	protected transient ChangeEventSupport changeEventSupport;
42  	/**
43  	 * The native object backing this model
44  	 */
45  	protected U element;
46  
47  	public AbstractModel(U element) {
48  	    this.element = element;
49  	    changeEventSupport = new ChangeEventSupport();
50  	}
51  	
52  	public abstract MetaModel<U> getMetaModel();
53  	
54  	public U getElement() {
55  		return element;
56  	}
57  	
58  	/**
59  	 * Returns the store which contains this model
60  	 * @return
61  	 */
62  	public abstract Store getStore();
63  
64  	///////////////////////////////////////////////////
65  	// Implementation of the ModelData interface
66  	///////////////////////////////////////////////////
67  	
68  	@Override
69  	public <X> X get(String property) {
70  		IMetadata propertyDefinition = getMetaModel().getMetadata(property);
71  		assert propertyDefinition != null : "Undefined property " + property;
72  		return (X)propertyDefinition.get(element);
73  	}
74  
75  	@Override
76  	public Map<String, Object> getProperties() {
77  		return getMetaModel().getProperties(element);
78  	}
79  
80  	@Override
81  	public Collection<String> getPropertyNames() {
82  		return getMetaModel().getPropertyNames();
83  	}
84  
85  	@Override
86  	public <X> X remove(String property) {
87  		IMetadata propertyDefinition = getMetaModel().getMetadata(property);
88  		assert propertyDefinition != null : "Undefined property " + property;
89  		X oldValue = (X)propertyDefinition.remove(element);
90  		notifyPropertyChanged(propertyDefinition.getName(), null, oldValue);
91  		return oldValue;
92  	}
93  
94  	@Override
95  	public <X> X set(String property, X value) {
96  		IMetadata propertyDefinition = getMetaModel().getMetadata(property);
97  		assert propertyDefinition != null : "Undefined property " + property;
98  		X oldValue = (X)propertyDefinition.set(element, value);
99  		GWT.log("AbstractModel.set(" + property + ") = " + oldValue + ", " + value);
100 		notifyPropertyChanged(propertyDefinition.getName(), value, oldValue);
101 		return oldValue;
102 	}
103 	
104 	///////////////////////////////////////////////////
105 	// Implementation of the ChangeEventSource interface
106 	///////////////////////////////////////////////////
107 	@Override
108 	public void addChangeListener(ChangeListener... listener) {
109 	    changeEventSupport.addChangeListener(listener);
110 	}
111 
112 	@Override
113 	public void removeChangeListener(ChangeListener... listener) {
114 	    changeEventSupport.removeChangeListener(listener);
115 	}
116 
117 	@Override
118 	public void removeChangeListeners() {
119 	    changeEventSupport.removeChangeListeners();
120 	}
121 
122 	@Override
123 	public void setSilent(boolean silent) {
124 	    changeEventSupport.setSilent(silent);
125 	}
126 
127 	@Override
128 	public void notify(ChangeEvent event) {
129 	    changeEventSupport.notify(event);
130 	}
131 	
132 	protected void notifyPropertyChanged(String name, Object value, Object oldValue) {
133 		if (!Util.equalWithNull(value, oldValue)) {
134 			notify(new PropertyChangeEvent(Update, this, name, oldValue, value));
135 		}
136 	}
137 	
138 	public boolean isSilent() {
139 	    return changeEventSupport.isSilent();
140 	}
141 
142 	protected void fireEvent(int type) {
143 		notify(new ChangeEvent(type, this));
144 	}
145 
146 	protected void fireEvent(int type, Model item) {
147 		notify(new ChangeEvent(type, this, item));
148 	}
149 }