001// Licensed under the Apache License, Version 2.0 (the "License"); 002// you may not use this file except in compliance with the License. 003// You may obtain a copy of the License at 004// 005// http://www.apache.org/licenses/LICENSE-2.0 006// 007// Unless required by applicable law or agreed to in writing, software 008// distributed under the License is distributed on an "AS IS" BASIS, 009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 010// See the License for the specific language governing permissions and 011// limitations under the License. 012 013package org.apache.tapestry5.beanmodel; 014 015import java.util.List; 016 017import org.apache.tapestry5.beaneditor.DataType; 018import org.apache.tapestry5.beaneditor.RelativePosition; 019 020/** 021 * Provides the information necessary to build a user interface to view, create or edit an instance of a particular 022 * type. 023 * 024 * BeanModels are not thread-safe, they are also not serializable. 025 * 026 * Here, and in {@link org.apache.tapestry5.beanmodel.PropertyModel}, the term "propertyName" is used for simplicitly. 027 * However, a full {@linkplain org.apache.tapestry5.beanmodel.services.PropertyConduitSource#create(Class, String) property 028 * expression} may be utilized when {@linkplain #add(String) adding new properties to an existing BeanModel}. 029 * 030 * @see org.apache.tapestry5.beanmodel.services.BeanModelSource 031 */ 032public interface BeanModel<T> 033{ 034 /** 035 * Returns the type of bean for which this model was initially created. 036 */ 037 Class<T> getBeanType(); 038 039 040 /** 041 * Creates a new bean instance. This is based on {@link org.apache.tapestry5.commons.ObjectLocator#autobuild(Class)}, 042 * so a public constructor will be used, and dependencies injected. 043 * 044 * @return new instance of the bean 045 */ 046 T newInstance(); 047 048 /** 049 * Returns a list of the editable properties of the bean, in <em>presentation</em> order. 050 */ 051 List<String> getPropertyNames(); 052 053 /** 054 * Returns the named model. 055 * 056 * @param propertyName name of property to retrieve model for (case is ignored) 057 * @return the model for the property 058 * @throws RuntimeException if the bean editor model does not have a property model for the provided name 059 */ 060 PropertyModel get(String propertyName); 061 062 /** 063 * Returns the identified model. Property ids are a stripped version of the property name. Case is ignored. 064 * 065 * @param propertyId matched caselessly against {@link org.apache.tapestry5.beanmodel.PropertyModel#getId()} 066 * @throws RuntimeException if the bean editor model does not have a property model with the indicated id 067 */ 068 PropertyModel getById(String propertyId); 069 070 /** 071 * Adds a new property to the model, returning its mutable model for further refinement. The property is added to 072 * the <em>end</em> of the list of properties. The property must be real (but may have been excluded if there was no 073 * {@linkplain org.apache.tapestry5.beaneditor.DataType datatype} associated with the property). To add a synthetic 074 * property, use {@link #add(String, org.apache.tapestry5.beanmodel.PropertyConduit)} 075 * 076 * @param propertyName name of property to add 077 * @return the new property model (for further configuration) 078 * @throws RuntimeException if the property already exists 079 */ 080 PropertyModel add(String propertyName); 081 082 083 /** 084 * Adds a new synthetic property to the model, returning its mutable model for further refinement. The property is added to 085 * the <em>end</em> of the list of properties. 086 * 087 * @param propertyName name of property to add 088 * @param expression expression for the property 089 * @return the new property model (for further configuration) 090 * @throws RuntimeException if the property already exists 091 * @since 5.3 092 */ 093 PropertyModel addExpression(String propertyName, String expression); 094 095 /** 096 * Adds an empty property (one with no property conduit). 097 * 098 * @param propertyName name of property to add 099 * @return the new property model (for further configuration) 100 * @throws RuntimeException if the property already exists 101 * @since 5.3 102 */ 103 PropertyModel addEmpty(String propertyName); 104 105 /** 106 * Adds a new property to the model (as with {@link #add(String)}), ordered before or after an existing property. 107 * 108 * @param position controls whether the new property is ordered before or after the existing property 109 * @param existingPropertyName the name of an existing property (this must exist) 110 * @param propertyName the new property to add 111 * @return the new property model (for further configuration) 112 * @throws RuntimeException if the existing property does not exist, or if the new property already does exist 113 */ 114 PropertyModel add(RelativePosition position, String existingPropertyName, String propertyName); 115 116 /** 117 * Adds a new property to the model, ordered before or after an existing property. 118 * 119 * @param position controls whether the new property is ordered before or after the existing property 120 * @param existingPropertyName the name of an existing property (this must exist) 121 * @param propertyName the new property to add 122 * @param conduit conduit used to read or update the property; this may be null for a synthetic or 123 * placeholder property 124 * @return the new property model (for further configuration) 125 * @throws RuntimeException if the existing property does not exist, or if the new property already does exist 126 */ 127 PropertyModel add(RelativePosition position, String existingPropertyName, String propertyName, 128 PropertyConduit conduit); 129 130 /** 131 * Adds a new, synthetic property to the model, returning its mutable model for further refinement. 132 * 133 * @param propertyName name of property to add 134 * @param conduit the conduit used to read or update the property; this may be null for a synthetic or 135 * placeholder property. Instead of passing null, please invoke {@link #addEmpty(String)}. 136 * @return the model for the property 137 * @throws RuntimeException if the property already exists 138 * @see #addExpression(String, String) 139 */ 140 PropertyModel add(String propertyName, PropertyConduit conduit); 141 142 /** 143 * Removes the named properties from the model, if present. It is not considered an error to remove a property that 144 * does not exist. 145 * 146 * @param propertyNames the names of properties to be removed (case insensitive) 147 * @return the model for further modifications 148 */ 149 BeanModel<T> exclude(String... propertyNames); 150 151 /** 152 * Re-orders the properties of the model into the specified order. Existing properties that are not indicated are 153 * retained, but ordered to the end of the list. 154 * 155 * @param propertyNames property names in order they should be displayed (case insensitive) 156 * @return the model for further modifications 157 */ 158 BeanModel<T> reorder(String... propertyNames); 159 160 /** 161 * Re-orders the properties of the model into the specified order. Existing properties that are not indicated are 162 * removed. 163 * 164 * @param propertyNames the names of properties to be retained 165 * @return the model for further modifications 166 */ 167 BeanModel<T> include(String... propertyNames); 168}