blob: 2554e45dd27c1537c008d74ad5384aafdccfc8d6 [file] [log] [blame]
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.groovy.binding;
import groovy.lang.GroovyObjectSupport;
import groovy.lang.ReadOnlyPropertyException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:shemnon@yahoo.com">Danno Ferrin</a>
* @version $Revision$
* @since Groovy 1.1
*/
public class ModelBinding extends GroovyObjectSupport implements BindingUpdatable {
Object model;
boolean bound;
final Map/*<String, PropertyBinding>*/ propertyBindings = new HashMap/*<String, PropertyBinding>*/();
final List/*<FullBinding>*/ generatedBindings = new ArrayList/*<FullBinding>*/();
public ModelBinding(Object model) {
this.model = model;
}
public Object getModel() {
return model;
}
public synchronized void setModel(Object model) {
// should we use a finer grained lock than this?
this.model = model;
//TODO see if bound, mark if so
unbind();
Iterator iter = propertyBindings.values().iterator();
while (iter.hasNext()) {
((PropertyBinding)iter.next()).setBean(model);
}
//TODO only bind if already bound
rebind();
update();
}
public Object getProperty(String property) {
PropertyBinding pb;
synchronized (propertyBindings) {
// should we verify the property is valid?
Object o = propertyBindings.get(property);
if (o == null) {
o = new ModelBindingPropertyBinding(model, property);
propertyBindings.put(property, o);
}
pb = (PropertyBinding)o;
}
FullBinding fb = pb.createBinding(pb, null);
if (bound) {
fb.bind();
}
return fb;
}
public void setProperty(String property, Object value) {
throw new ReadOnlyPropertyException(property, model.getClass());
}
public void bind() {
synchronized (generatedBindings) {
if (!bound) {
bound = true;
Iterator iter = generatedBindings.iterator();
while (iter.hasNext()) {
((FullBinding)iter.next()).bind();
// should we trap exceptions and do an each?
}
}
}
}
public void unbind() {
synchronized (generatedBindings) {
if (bound) {
bound = false;
Iterator iter = generatedBindings.iterator();
while (iter.hasNext()) {
((FullBinding)iter.next()).unbind();
// should we trap exceptions and do an each?
}
}
}
}
public void rebind() {
synchronized (generatedBindings) {
if (bound) {
Iterator iter = generatedBindings.iterator();
while (iter.hasNext()) {
((FullBinding)iter.next()).rebind();
// should we trap exceptions and do an each?
}
}
}
}
public void update() {
synchronized (generatedBindings) {
Iterator iter = generatedBindings.iterator();
while (iter.hasNext()) {
((FullBinding)iter.next()).update();
// should we trap exceptions and do an each?
}
}
}
public void reverseUpdate() {
synchronized (generatedBindings) {
Iterator iter = generatedBindings.iterator();
while (iter.hasNext()) {
((FullBinding)iter.next()).reverseUpdate();
// should we trap exceptions and do an each?
}
}
}
class ModelBindingPropertyBinding extends PropertyBinding {
public ModelBindingPropertyBinding(Object bean, String propertyName) {
super(bean, propertyName);
}
public FullBinding createBinding(SourceBinding source, TargetBinding target) {
FullBinding fb = super.createBinding(source, target);
generatedBindings.add(fb);
return fb;
}
}
}