001: // Copyright 2006, 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 static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
018: import static org.apache.tapestry.ioc.internal.util.Defense.cast;
019: import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
020: import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
021:
022: import java.io.IOException;
023: import java.io.ObjectOutputStream;
024: import java.util.List;
025:
026: import org.apache.tapestry.ComponentAction;
027: import org.apache.tapestry.ioc.internal.util.IdAllocator;
028: import org.apache.tapestry.runtime.Component;
029: import org.apache.tapestry.services.FormSupport;
030:
031: /**
032: * Provides support to components enclosed by a form when the form is rendering (allowing the
033: * components to registry form submit callback commands), and also during form submission time.
034: * <p>
035: * TODO: Most methods should only be invokable depending on whether the form is rendering or
036: * processing a submission.
037: */
038: class FormSupportImpl implements FormSupport {
039: private final IdAllocator _idAllocator = new IdAllocator();
040:
041: private final String _clientId;
042:
043: private final ObjectOutputStream _actions;
044:
045: private List<Runnable> _commands;
046:
047: private String _encodingType;
048:
049: /** Constructor used when processing a form submission. */
050: public FormSupportImpl() {
051: this (null, null);
052: }
053:
054: /** Constructor used when rendering. */
055: public FormSupportImpl(String clientId, ObjectOutputStream actions) {
056: _clientId = clientId;
057: _actions = actions;
058: }
059:
060: public String allocateElementName(String id) {
061: return _idAllocator.allocateId(id);
062: }
063:
064: public <T> void store(T component, ComponentAction<T> action) {
065: Component castComponent = cast(component, Component.class,
066: "component");
067: notNull(action, "action");
068:
069: String completeId = castComponent.getComponentResources()
070: .getCompleteId();
071:
072: try {
073: // Writing the complete id is not very efficient, but the GZip filter
074: // should help out there.
075: _actions.writeUTF(completeId);
076: _actions.writeObject(action);
077: } catch (IOException ex) {
078: throw new RuntimeException(ComponentMessages
079: .componentActionNotSerializable(completeId, ex), ex);
080: }
081: }
082:
083: public <T> void storeAndExecute(T component,
084: ComponentAction<T> action) {
085: store(component, action);
086:
087: action.execute(component);
088: }
089:
090: public void defer(Runnable command) {
091: if (_commands == null)
092: _commands = newList();
093:
094: _commands.add(notNull(command, "command"));
095: }
096:
097: void executeDeferred() {
098: if (_commands == null)
099: return;
100:
101: for (Runnable r : _commands)
102: r.run();
103:
104: _commands.clear();
105: }
106:
107: public String getClientId() {
108: return _clientId;
109: }
110:
111: String getEncodingType() {
112: return _encodingType;
113: }
114:
115: public void setEncodingType(String encodingType) {
116: notBlank(encodingType, "encodingType");
117:
118: if (_encodingType != null
119: && !_encodingType.equals(encodingType))
120: throw new IllegalStateException(ComponentMessages
121: .conflictingEncodingType(_encodingType,
122: encodingType));
123:
124: _encodingType = encodingType;
125: }
126:
127: }
|