View Javadoc

1   // Copyright 2008 Thiago H. de Paula Figueiredo
2   //
3   // Licensed under the Apache License, Version 2.0 (the "License");
4   // you may not use this file except in compliance with the License.
5   // You may obtain a copy of the License at
6   //
7   //     http://www.apache.org/licenses/LICENSE-2.0
8   //
9   // Unless required by applicable law or agreed to in writing, software
10  // distributed under the License is distributed on an "AS IS" BASIS,
11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  // See the License for the specific language governing permissions and
13  // limitations under the License.
14  
15  package br.com.arsmachina.tapestrycrud.base;
16  
17  import java.io.Serializable;
18  import java.lang.reflect.ParameterizedType;
19  import java.lang.reflect.Type;
20  
21  import org.apache.tapestry5.Block;
22  import org.apache.tapestry5.ComponentResources;
23  import org.apache.tapestry5.PersistenceConstants;
24  import org.apache.tapestry5.PrimaryKeyEncoder;
25  import org.apache.tapestry5.ValueEncoder;
26  import org.apache.tapestry5.annotations.Persist;
27  import org.apache.tapestry5.annotations.Retain;
28  import org.apache.tapestry5.corelib.components.Zone;
29  import org.apache.tapestry5.ioc.Messages;
30  import org.apache.tapestry5.ioc.annotations.Inject;
31  import org.apache.tapestry5.services.ValueEncoderSource;
32  
33  import br.com.arsmachina.controller.Controller;
34  import br.com.arsmachina.tapestrycrud.Constants;
35  import br.com.arsmachina.tapestrycrud.CrudPage;
36  import br.com.arsmachina.tapestrycrud.encoder.ActivationContextEncoder;
37  import br.com.arsmachina.tapestrycrud.encoder.LabelEncoder;
38  import br.com.arsmachina.tapestrycrud.selectmodel.SelectModelFactory;
39  import br.com.arsmachina.tapestrycrud.services.ActivationContextEncoderSource;
40  import br.com.arsmachina.module.service.ControllerSource;
41  import br.com.arsmachina.tapestrycrud.services.LabelEncoderSource;
42  import br.com.arsmachina.tapestrycrud.services.PrimaryKeyEncoderSource;
43  import br.com.arsmachina.tapestrycrud.services.PrimaryKeyTypeService;
44  
45  /**
46   * Class that implements some common infrastructure for listing and editing pages. This class is not
47   * 
48   * @author Thiago H. de Paula Figueiredo
49   * @param <T> the entity class related to this encoder.
50   * @param <K> the type of the class' primary key property.
51   */
52  public abstract class BasePage<T, K extends Serializable> implements CrudPage<T, K> {
53  
54  	@Inject
55  	private ActivationContextEncoderSource activationContextEncoderSource;
56  
57  	@Inject
58  	private ControllerSource controllerSource;
59  
60  	@Inject
61  	private LabelEncoderSource labelEncoderSource;
62  
63  	@Inject
64  	private ValueEncoderSource valueEncoderSource;
65  
66  	@Inject
67  	private SelectModelFactory selectModelFactory;
68  
69  	@Inject
70  	private PrimaryKeyEncoderSource primaryKeyEncoderSource;
71  
72  	@Inject
73  	private PrimaryKeyTypeService primaryKeyTypeService;
74  
75  	@Retain
76  	private Class<T> entityClass;
77  
78  	@Retain
79  	private Controller<T, K> controller;
80  
81  	@Persist(PersistenceConstants.FLASH)
82  	private String message;
83  
84  	@Inject
85  	private ComponentResources componentResources;
86  
87  	@Inject
88  	private Messages messages;
89  
90  	@Retain
91  	private Class<K> primaryKeyClass;
92  
93  	/**
94  	 * Single constructor of this class.
95  	 */
96  	@SuppressWarnings("unchecked")
97  	public BasePage() {
98  
99  		final Type genericSuperclass = getClass().getGenericSuperclass();
100 		final ParameterizedType parameterizedType = ((ParameterizedType) genericSuperclass);
101 		entityClass = (Class<T>) parameterizedType.getActualTypeArguments()[0];
102 		primaryKeyClass = primaryKeyTypeService.getPrimaryKeyType(entityClass);
103 
104 		controller = controllerSource.get(entityClass);
105 
106 		assert entityClass != null;
107 		assert primaryKeyClass != null;
108 		assert controller != null;
109 
110 	}
111 
112 	// /**
113 	// * Creates a {@link BeanModel} for this entity class using
114 	// * <code>beanModelSource.create(entityClass, false, componentResources)</code>. This method
115 	// * can ve overriden if needed.
116 	// *
117 	// * @return a {@link BeanModel}.
118 	// */
119 	// public BeanModel<T> getBeanModel() {
120 	// return beanModelSource.create(entityClass, filterReadOnlyComponentsInBeanModel(),
121 	// getMessages());
122 	// }
123 
124 	/**
125 	 * Used by {@link #getBeanModel()} to filter read only components or not. This implementation
126 	 * returns <code>true</code>.
127 	 * 
128 	 * @return a <code>boolean</code>.
129 	 */
130 	protected boolean filterReadOnlyComponentsInBeanModel() {
131 		return true;
132 	}
133 
134 	/**
135 	 * Returns the {@link ValueEncoder} for a given class.
136 	 * 
137 	 * @param <V> the class.
138 	 * @param clasz a {@link Class};
139 	 * @return a {@link ValueEncoder}.
140 	 */
141 	protected <V> ValueEncoder<V> getValueEncoder(Class<V> clasz) {
142 		return valueEncoderSource.getValueEncoder(clasz);
143 	}
144 
145 	/**
146 	 * Returns the {@link LabelEncoder} for a given class.
147 	 * 
148 	 * @param <V> the class.
149 	 * @param clasz a {@link Class};
150 	 * @return a {@link LabelEncoder}.
151 	 */
152 	protected <V> LabelEncoder<V> getLabelEncoder(Class<V> clasz) {
153 		return labelEncoderSource.get(clasz);
154 	}
155 
156 	/**
157 	 * Returns the {@link ActivationContextEncoder} for a given class.
158 	 * 
159 	 * @param <V> the class.
160 	 * @param clasz a {@link Class};
161 	 * @return an {@link ActivationContextEncoder}.
162 	 */
163 	protected <V, X extends Serializable> ActivationContextEncoder<V> getActivationContextEncoder(
164 			Class<V> clasz) {
165 		return activationContextEncoderSource.get(clasz);
166 	}
167 
168 	/**
169 	 * Returns the {@link PrimaryKeyEncoder} for a given class.
170 	 * 
171 	 * @param <V> the class.
172 	 * @param <X> the class' primary key field type.
173 	 * @param clasz a {@link Class};
174 	 * @return a {@link PrimaryKeyEncoder}.
175 	 */
176 	protected <V, X extends Serializable> PrimaryKeyEncoder<X, V> getPrimaryKeyEncoder(
177 			Class<V> clasz) {
178 		return primaryKeyEncoderSource.get(clasz);
179 	}
180 
181 	/**
182 	 * @see br.com.arsmachina.tapestrycrud.CrudPage#getMessage()
183 	 */
184 	public String getMessage() {
185 		return message;
186 	}
187 
188 	/**
189 	 * @see br.com.arsmachina.tapestrycrud.CrudPage#setMessage(java.lang.String)
190 	 */
191 	public void setMessage(String message) {
192 		this.message = message;
193 	}
194 
195 	/**
196 	 * Returns the value of the <code>controller</code> property.
197 	 * 
198 	 * @return a {@link Controller<T,K>}.
199 	 */
200 	public final Controller<T, K> getController() {
201 		return controller;
202 	}
203 
204 	public final Class<T> getEntityClass() {
205 		return entityClass;
206 	}
207 
208 	public final Class<K> getPrimaryKeyClass() {
209 		return primaryKeyClass;
210 	}
211 
212 	/**
213 	 * Returns the value of the <code>messages</code> property.
214 	 * 
215 	 * @return a {@link Messages}.
216 	 */
217 	public final Messages getMessages() {
218 		return messages;
219 	}
220 
221 	/**
222 	 * Returns the {@link Zone} that surrounds the form.
223 	 * 
224 	 * @return a {@link Zone}.
225 	 */
226 	public Zone getFormZone() {
227 		return (Zone) componentResources.getEmbeddedComponent(getFormZoneId());
228 	}
229 
230 	/**
231 	 * ID of the {@link Block} that will be returned when a form is submitted via AJAX. This
232 	 * implementation returns {@link #DEFAULT_FORM_BLOCK_ID} (<code>block</code>).
233 	 * 
234 	 * @return a {@link String}.
235 	 */
236 	String getFormBlockId() {
237 		return Constants.DEFAULT_FORM_BLOCK_ID;
238 	}
239 
240 	/**
241 	 * ID of the {@link Zone} that will be returned when a form is submitted via AJAX. This
242 	 * implementation returns {@link #DEFAULT_FORM_ZONE_ID} (<code>zone</code>).
243 	 * 
244 	 * @return a {@link String}.
245 	 */
246 	String getFormZoneId() {
247 		return Constants.DEFAULT_FORM_ZONE_ID;
248 	}
249 
250 	/**
251 	 * Used by {@link #returnFromRemove()} to know whether it must return a {@link Zone} or a
252 	 * {@link Block}. This implementation returns <code>true</code>.
253 	 * 
254 	 * @return a <code>boolean</code>.
255 	 */
256 	protected boolean returnZoneOnXHR() {
257 		return true;
258 	}
259 
260 	/**
261 	 * Returns the value of the <code>selectModelFactory</code> property.
262 	 * 
263 	 * @return a {@link SelectModelFactory}.
264 	 */
265 	final protected SelectModelFactory getSelectModelFactory() {
266 		return selectModelFactory;
267 	}
268 
269 }