001: /*
002: * $Id: AbstractPropertyModel.java 461173 2006-06-27 16:18:57Z ivaynberg $
003: * $Revision: 461173 $ $Date: 2006-06-27 18:18:57 +0200 (Tue, 27 Jun 2006) $
004: *
005: * ==============================================================================
006: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007: * use this file except in compliance with the License. You may obtain a copy of
008: * the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015: * License for the specific language governing permissions and limitations under
016: * the License.
017: */
018: package wicket.model;
019:
020: import wicket.Component;
021: import wicket.util.lang.PropertyResolver;
022: import wicket.util.string.Strings;
023:
024: /**
025: * Serves as a base class for different kinds of property models.
026: *
027: * @see wicket.model.AbstractDetachableModel
028: *
029: * @author Chris Turner
030: * @author Eelco Hillenius
031: * @author Jonathan Locke
032: */
033: public abstract class AbstractPropertyModel extends
034: AbstractDetachableModel {
035: /** Any model object (which may or may not implement IModel) */
036: private Object nestedModel;
037:
038: /**
039: * Constructor
040: *
041: * @param modelObject
042: * The nested model object
043: */
044: public AbstractPropertyModel(final Object modelObject) {
045: if (modelObject == null) {
046: throw new IllegalArgumentException(
047: "Parameter modelObject cannot be null");
048: }
049:
050: this .nestedModel = modelObject;
051: }
052:
053: /**
054: * Gets the nested model.
055: *
056: * @return The nested model, <code>null</code> when this is the final
057: * model in the hierarchy
058: */
059: public final IModel getNestedModel() {
060: if (nestedModel instanceof IModel) {
061: return ((IModel) nestedModel);
062: }
063: return null;
064: }
065:
066: /**
067: * @param component
068: * The component to get the model object for
069: * @return The model for this property
070: */
071: protected Object modelObject(final Component component) {
072: if (nestedModel instanceof IModel) {
073: final IModel model = (IModel) nestedModel;
074: if (model instanceof ICompoundModel) {
075: return model.getObject(null);
076: } else {
077: return model.getObject(component);
078: }
079:
080: }
081: return nestedModel;
082: }
083:
084: /**
085: * @param component
086: * The component to get a property expression for
087: * @return The property expression for the component
088: */
089: protected abstract String propertyExpression(Component component);
090:
091: /**
092: * @see wicket.model.AbstractDetachableModel#onAttach()
093: */
094: protected void onAttach() {
095: }
096:
097: /**
098: * Unsets this property model's instance variables and detaches the model.
099: *
100: * @see AbstractDetachableModel#onDetach()
101: */
102: protected void onDetach() {
103: // Detach nested object if it's an IModel
104: if (nestedModel instanceof IModel) {
105: ((IModel) nestedModel).detach();
106: }
107: }
108:
109: /**
110: * @see wicket.model.AbstractDetachableModel#onGetObject(wicket.Component)
111: */
112: protected Object onGetObject(final Component component) {
113: final String expression = propertyExpression(component);
114: if (Strings.isEmpty(expression)) {
115: // Return a meaningful value for an empty property expression
116: return modelObject(component);
117: }
118:
119: final Object modelObject = modelObject(component);
120: if (modelObject != null) {
121: return PropertyResolver.getValue(expression, modelObject);
122: }
123: return null;
124: }
125:
126: /**
127: * Applies the property expression on the model object using the given
128: * object argument.
129: *
130: * @param object
131: * The object that will be used when setting a value on the model
132: * object
133: * @see AbstractDetachableModel#onSetObject(Component, Object)
134: */
135: protected void onSetObject(final Component component, Object object) {
136: final String expression = propertyExpression(component);
137: if (Strings.isEmpty(expression)) {
138: if (nestedModel instanceof IModel) {
139: ((IModel) nestedModel).setObject(null, object);
140: } else {
141: nestedModel = object;
142: }
143: } else {
144: // Get the real object
145: Object modelObject = modelObject(component);
146:
147: // If the object is a String
148: if (object instanceof String) {
149: // and that String is not empty
150: final String string = (String) object;
151: if (!Strings.isEmpty(string)) {
152: // and there is a non-null property type for the component
153: final Class propertyType = propertyType(component);
154: if (propertyType != null) {
155: // convert the String to the right type
156: object = component.getConverter().convert(
157: string, propertyType);
158: }
159: }
160: }
161:
162: PropertyResolver
163: .setValue(expression, modelObject, object,
164: component == null ? null : component
165: .getConverter());
166: }
167: }
168:
169: /**
170: * @param component
171: * The component
172: * @return The property type
173: */
174: protected abstract Class propertyType(Component component);
175:
176: /**
177: * @see java.lang.Object#toString()
178: */
179: public String toString() {
180: StringBuffer sb = new StringBuffer(super .toString());
181: sb.append(":nestedModel=[").append(nestedModel).append("]");
182: return sb.toString();
183: }
184: }
|