001 // Copyright 2006, 2007, 2008, 2009, 2010 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.tapestry5.corelib.internal; 016 017 import java.util.List; 018 019 import org.apache.tapestry5.ComponentAction; 020 import org.apache.tapestry5.ComponentResources; 021 import org.apache.tapestry5.Field; 022 import org.apache.tapestry5.ioc.Locatable; 023 import org.apache.tapestry5.ioc.Location; 024 import org.apache.tapestry5.ioc.internal.util.CollectionFactory; 025 import org.apache.tapestry5.ioc.internal.util.InternalUtils; 026 import org.apache.tapestry5.ioc.util.IdAllocator; 027 import org.apache.tapestry5.services.ClientBehaviorSupport; 028 029 /** 030 * Provides support to components enclosed by a form when the form is rendering (allowing the components to registry 031 * form submit callback commands), and also during form submission time. 032 * <p/> 033 * TODO: Most methods should only be invokable depending on whether the form is rendering or processing a submission. 034 */ 035 public class FormSupportImpl implements InternalFormSupport, Locatable 036 { 037 private final ComponentResources resources; 038 039 private final ClientBehaviorSupport clientBehaviorSupport; 040 041 private final boolean clientValidationEnabled; 042 043 private final IdAllocator idAllocator; 044 045 private final String clientId; 046 047 private final ComponentActionSink actionSink; 048 049 private final String formValidationId; 050 051 private List<Runnable> commands; 052 053 private String encodingType; 054 055 /** 056 * Constructor used when processing a form submission. 057 */ 058 public FormSupportImpl(ComponentResources resources, String formValidationId) 059 { 060 this(resources, null, null, null, false, null, formValidationId); 061 } 062 063 /** 064 * Full constructor (specifically constructor for render time). 065 */ 066 public FormSupportImpl(ComponentResources resources, String clientId, ComponentActionSink actionSink, 067 ClientBehaviorSupport clientBehaviorSupport, boolean clientValidationEnabled, IdAllocator idAllocator, 068 String formValidationId) 069 { 070 this.resources = resources; 071 this.clientId = clientId; 072 this.actionSink = actionSink; 073 this.clientBehaviorSupport = clientBehaviorSupport; 074 this.clientValidationEnabled = clientValidationEnabled; 075 this.idAllocator = idAllocator; 076 this.formValidationId = formValidationId; 077 } 078 079 public Location getLocation() 080 { 081 return resources.getLocation(); 082 } 083 084 public String getFormComponentId() 085 { 086 return resources.getCompleteId(); 087 } 088 089 public String allocateControlName(String id) 090 { 091 return idAllocator.allocateId(id); 092 } 093 094 public <T> void store(T component, ComponentAction<T> action) 095 { 096 actionSink.store(component, action); 097 } 098 099 public <T> void storeAndExecute(T component, ComponentAction<T> action) 100 { 101 actionSink.store(component, action); 102 103 action.execute(component); 104 } 105 106 public void defer(Runnable command) 107 { 108 assert command != null; 109 110 if (commands == null) 111 commands = CollectionFactory.newList(); 112 113 commands.add(command); 114 } 115 116 public void executeDeferred() 117 { 118 if (commands == null) 119 return; 120 121 for (Runnable r : commands) 122 r.run(); 123 124 commands.clear(); 125 } 126 127 public String getClientId() 128 { 129 return clientId; 130 } 131 132 public String getEncodingType() 133 { 134 return encodingType; 135 } 136 137 public void setEncodingType(String encodingType) 138 { 139 assert InternalUtils.isNonBlank(encodingType); 140 141 if (this.encodingType != null && !this.encodingType.equals(encodingType)) 142 throw new IllegalStateException(InternalMessages.conflictingEncodingType(this.encodingType, encodingType)); 143 144 this.encodingType = encodingType; 145 } 146 147 public void addValidation(Field field, String validationName, String message, Object constraint) 148 { 149 if (clientValidationEnabled) 150 clientBehaviorSupport.addValidation(field, validationName, message, constraint); 151 } 152 153 public boolean isClientValidationEnabled() 154 { 155 return clientValidationEnabled; 156 } 157 158 public String getFormValidationId() 159 { 160 return formValidationId; 161 } 162 }