001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.wicket.model;
018:
019: import org.apache.wicket.Component;
020: import org.apache.wicket.util.string.AppendingStringBuffer;
021:
022: /**
023: * A simple compound model which uses the component's name as the property
024: * expression to retrieve properties on the nested model object.
025: *
026: * CompoundPropertyModel is a chaining model so it will call get/setobject
027: * on the given object if the object is an instanceof IModel itself.
028: *
029: * @see org.apache.wicket.model.IModel
030: * @see org.apache.wicket.model.Model
031: * @see org.apache.wicket.model.AbstractDetachableModel
032: * @see IChainingModel
033: *
034: * @author Jonathan Locke
035: */
036: public class CompoundPropertyModel implements IComponentInheritedModel,
037: IChainingModel {
038: private static final long serialVersionUID = 1L;
039:
040: private Object target;
041:
042: /**
043: * Constructor
044: *
045: * @param object
046: * The model object, which may or may not implement IModel
047: */
048: public CompoundPropertyModel(final Object object) {
049: this .target = object;
050: }
051:
052: /**
053: * @see org.apache.wicket.model.IModel#getObject()
054: */
055: public Object getObject() {
056: if (target instanceof IModel) {
057: return ((IModel) target).getObject();
058: }
059: return target;
060: }
061:
062: /**
063: * @see org.apache.wicket.model.IModel#setObject(java.lang.Object)
064: */
065: public void setObject(Object object) {
066: if (target instanceof IModel) {
067: ((IModel) target).setObject(object);
068: } else {
069: this .target = object;
070: }
071: }
072:
073: /**
074: * @see org.apache.wicket.model.IChainingModel#getChainedModel()
075: */
076: public IModel getChainedModel() {
077: if (target instanceof IModel) {
078: return (IModel) target;
079: }
080: return null;
081: }
082:
083: /**
084: * @see org.apache.wicket.model.IChainingModel#setChainedModel(org.apache.wicket.model.IModel)
085: */
086: public void setChainedModel(IModel model) {
087: target = model;
088: }
089:
090: /**
091: * @see org.apache.wicket.model.IDetachable#detach()
092: */
093: public void detach() {
094: if (target instanceof IDetachable) {
095: ((IDetachable) target).detach();
096: }
097: }
098:
099: /**
100: * Returns the property expression that should be used against the target
101: * object
102: *
103: * @param component
104: * @return property expression that should be used against the target object
105: */
106: protected String propertyExpression(Component component) {
107: return component.getId();
108: }
109:
110: /**
111: * @see org.apache.wicket.model.IComponentInheritedModel#wrapOnInheritance(org.apache.wicket.Component)
112: */
113: public IWrapModel wrapOnInheritance(Component component) {
114: return new AttachedCompoundPropertyModel(component);
115: }
116:
117: /**
118: * Binds this model to a special property by returning a model
119: * that has this compound model as its nested/wrapped model and
120: * the property which should be evaluted.
121: * This can be used if the id of the Component isn't a valid property
122: * for the data object.
123: *
124: * @param property
125: * @return The IModel that is a wrapper around the current model and the property
126: */
127: public IModel bind(String property) {
128: return new PropertyModel(this , property);
129: }
130:
131: /**
132: * Component aware variation of the {@link CompoundPropertyModel} that
133: * components that inherit the model get
134: *
135: * @author ivaynberg
136: */
137: private class AttachedCompoundPropertyModel extends
138: AbstractPropertyModel implements IWrapModel {
139: private static final long serialVersionUID = 1L;
140:
141: private final Component owner;
142:
143: /**
144: * Constructor
145: *
146: * @param owner
147: * component that this model has been attached to
148: */
149: public AttachedCompoundPropertyModel(Component owner) {
150: super (CompoundPropertyModel.this );
151: this .owner = owner;
152: }
153:
154: /**
155: * @see org.apache.wicket.model.AbstractPropertyModel#propertyExpression()
156: */
157: protected String propertyExpression() {
158: return CompoundPropertyModel.this .propertyExpression(owner);
159: }
160:
161: /**
162: * @see org.apache.wicket.model.IWrapModel#getWrappedModel()
163: */
164: public IModel getWrappedModel() {
165: return CompoundPropertyModel.this ;
166: }
167:
168: /**
169: * @see org.apache.wicket.model.AbstractPropertyModel#detach()
170: */
171: public void detach() {
172: super .detach();
173: CompoundPropertyModel.this .detach();
174: }
175: }
176:
177: /**
178: * @see java.lang.Object#toString()
179: */
180: public String toString() {
181: AppendingStringBuffer sb = new AppendingStringBuffer()
182: .append("Model:classname=[" + getClass().getName()
183: + "]");
184: sb.append(":nestedModel=[").append(target).append("]");
185: return sb.toString();
186: }
187:
188: // TODO These methods are for helping people upgrade. Remove after
189: // deprecation release.
190: /**
191: * @param component
192: * @return
193: * @deprecated replace by {@link IModel#getObject()}.
194: */
195: public final Object getObject(Component component) {
196: throw new UnsupportedOperationException();
197: }
198:
199: /**
200: * @param component
201: * @param object
202: * @deprecated replace by {@link IModel#setObject(Object)}.
203: */
204: public final void setObject(Component component, Object object) {
205: throw new UnsupportedOperationException();
206: }
207:
208: }
|