001: // Copyright 2007 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:
015: package org.apache.tapestry.corelib.components;
016:
017: import org.apache.tapestry.Block;
018: import org.apache.tapestry.ComponentResources;
019: import org.apache.tapestry.MarkupWriter;
020: import org.apache.tapestry.annotations.Inject;
021: import org.apache.tapestry.annotations.Parameter;
022: import org.apache.tapestry.beaneditor.PropertyModel;
023: import org.apache.tapestry.ioc.Messages;
024: import org.apache.tapestry.services.BeanBlockSource;
025: import org.apache.tapestry.services.Environment;
026: import org.apache.tapestry.services.PropertyDisplayContext;
027:
028: /**
029: * Part of {@link Grid} that renders a single data cell. GridCell is used inside a pair of loops;
030: * the outer loop for each row, the inner loop for each property of the row.
031: */
032: public class GridCell {
033: /** Model for property displayed by the cell. */
034: @Parameter(required=true)
035: private PropertyModel _model;
036:
037: /**
038: * Resources used to search for block parameter overrides (this is normally the enclosing Grid
039: * component's resources).
040: */
041: @Parameter(required=true)
042: private ComponentResources _resources;
043:
044: /**
045: * Identifies the object being rendered. The GridCell will extract a property from the row and
046: * render its value (or delegate to a {@link Block} that will do so).
047: */
048: @Parameter(required=true)
049: private Object _row;
050:
051: @Inject
052: private ComponentResources _gridCellResources;
053:
054: @Inject
055: private BeanBlockSource _beanBlockSource;
056:
057: @Inject
058: private Environment _environment;
059:
060: private boolean _mustPopEnvironment;
061:
062: Object beginRender(MarkupWriter writer) {
063: Block override = _resources.getBlockParameter(_model.getId()
064: + "Cell");
065:
066: if (override != null)
067: return override;
068:
069: String datatype = _model.getDataType();
070:
071: if (_beanBlockSource.hasDisplayBlock(datatype)) {
072: PropertyDisplayContext context = new PropertyDisplayContext() {
073: public Messages getContainerMessages() {
074: return GridCell.this .getContainerMessages();
075: }
076:
077: public Object getPropertyValue() {
078: return readPropertyForRow();
079: }
080: };
081:
082: _environment.push(PropertyDisplayContext.class, context);
083: _mustPopEnvironment = true;
084:
085: return _beanBlockSource.getDisplayBlock(datatype);
086: }
087:
088: Block block = _gridCellResources.findBlock(datatype);
089:
090: if (block != null)
091: return block;
092:
093: Object value = _model.getConduit().get(_row);
094:
095: if (value == null) {
096: writer.writeRaw(" ");
097: return false;
098: }
099:
100: writer.write(value.toString());
101:
102: // Don't render anything else
103:
104: return false;
105: }
106:
107: private Object readPropertyForRow() {
108: return _model.getConduit().get(_row);
109: }
110:
111: private Messages getContainerMessages() {
112: return _resources.getMessages();
113: }
114:
115: /*
116: * When rendering a Block instead of a literal value, the template will start to render but its
117: * is effectively just some whitespace and we want to skip it entirely.
118: */
119: boolean beforeRenderTemplate() {
120: return false;
121: }
122:
123: void afterRender() {
124: if (_mustPopEnvironment) {
125: _environment.pop(PropertyDisplayContext.class);
126: _mustPopEnvironment = false;
127: }
128: }
129: }
|