001 // Copyright Jul 30, 2006 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014 package org.apache.tapestry.dojo.form;
015
016 import org.apache.commons.beanutils.PropertyUtils;
017 import org.apache.hivemind.ApplicationRuntimeException;
018 import org.apache.hivemind.util.Defense;
019
020 import java.util.ArrayList;
021 import java.util.List;
022
023
024 /**
025 * Default simple implementation of {@link IAutocompleteModel}. This class relies
026 * on the java beans specification to resolve key fields of an incoming
027 * {@link List}.
028 *
029 * <p>
030 * If you had an object type of <code>User</code>, with the primary/unique id of
031 * each <code>User</code> object stored as a member with a name of <code>id</code>
032 * you would pass something like this into the model(don't forget that javabeans syntax
033 * requires a corresponding getId() for members):
034 * </p>
035 *
036 * <pre>
037 * IAutocompleteModel model = new DefaultAutocompleteModel(List users, "id", "name");
038 * </pre>
039 *
040 * @see "http://jakarta.apache.org/commons/beanutils/commons-beanutils-1.6.1/docs/api/org/apache/commons/beanutils/PropertyUtils.html"
041 * @author jkuhnert
042 */
043 public class DefaultAutocompleteModel implements IAutocompleteModel
044 {
045
046 private List _values;
047
048 private String _keyExpression;
049
050 private String _labelExpression;
051
052 /**
053 * Create a new model using java beans syntax to access the key/label
054 * for the list using the specified bean expressions.
055 *
056 * @param values
057 * The list of values to manage.
058 * @param keyField
059 * The java beans expression for getting the primary key of each object
060 * in the list. {@link #getPrimaryKey(Object)}.
061 * @param labelField
062 * The java beans expression for getting the label of each object
063 * in the list. {@link #getLabelFor(Object)}.
064 */
065 public DefaultAutocompleteModel(List values, String keyField, String labelField)
066 {
067 Defense.notNull(values, "Value list can't be null.");
068 Defense.notNull(keyField, "Model keyField java beans expression can't be null.");
069 Defense.notNull(labelField, "Model labelField java beans expression can't be null.");
070
071 _values = values;
072 _keyExpression = keyField;
073 _labelExpression = labelField;
074 }
075
076 /**
077 * {@inheritDoc}
078 */
079 public List getValues(String match)
080 {
081 List ret = new ArrayList();
082
083 if (match == null)
084 return ret;
085
086 String filter = match.trim().toLowerCase();
087
088 for (int i = 0; i < _values.size(); i++)
089 {
090 Object value = _values.get(i);
091 String label = getLabelFor(value);
092
093 if (label.toLowerCase().indexOf(filter) > -1)
094 ret.add(value);
095 }
096
097 return ret;
098 }
099
100 /**
101 * {@inheritDoc}
102 */
103 public String getLabelFor(Object value)
104 {
105 try
106 {
107 return PropertyUtils.getProperty(value, _labelExpression).toString();
108 } catch (Exception e)
109 {
110 throw new ApplicationRuntimeException(e);
111 }
112 }
113
114 /**
115 * {@inheritDoc}
116 */
117 public Object getPrimaryKey(Object value)
118 {
119 try
120 {
121 return PropertyUtils.getProperty(value, _keyExpression);
122 } catch (Exception e)
123 {
124 throw new ApplicationRuntimeException(e);
125 }
126 }
127
128 /**
129 * {@inheritDoc}
130 */
131 public Object getValue(Object primaryKey)
132 {
133 for (int i = 0; i < _values.size(); i++)
134 {
135 Object value = _values.get(i);
136
137 if (getPrimaryKey(value).toString().equals(primaryKey.toString()))
138 return value;
139 }
140
141 return null;
142 }
143
144 }