001 // Copyright 2006-2007 Daniel Gredler
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 net.sf.beanform;
016
017 import java.util.Map;
018
019 import net.sf.beanform.prop.BeanProperty;
020
021 import org.apache.hivemind.ApplicationRuntimeException;
022 import org.apache.tapestry.BaseComponent;
023 import org.apache.tapestry.IBinding;
024 import org.apache.tapestry.IComponent;
025 import org.apache.tapestry.IRequestCycle;
026 import org.apache.tapestry.components.Block;
027 import org.apache.tapestry.form.IFormComponent;
028 import org.apache.tapestry.form.IPropertySelectionModel;
029
030 /**
031 * Superclass for low level BeanForm components which must be wrapped by
032 * a {@link BeanForm} component.
033 *
034 * @see BeanFormRows
035 * @see BeanFormLabel
036 * @see BeanFormField
037 * @see BeanFormButtons
038 *
039 * @author Daniel Gredler
040 */
041 public abstract class BeanFormComponent extends BaseComponent {
042
043 final static String CUSTOM_FIELD_BLOCK_SUFFIX = "_BeanFieldBlock";
044 final static String CUSTOM_FIELD_SUFFIX = "_BeanField";
045
046 final static String BINDING_OVERRIDE_SEPARATOR = "_";
047 final static String MODEL = "model";
048 final static String MODEL_SUFFIX = BINDING_OVERRIDE_SEPARATOR + MODEL;
049
050 protected BeanForm getBeanForm() {
051 IRequestCycle cycle = this.getPage().getRequestCycle();
052 BeanForm beanForm = (BeanForm) cycle.getAttribute( BeanForm.BEAN_FORM_ATTRIBUTE );
053 if( beanForm == null ) throw new ApplicationRuntimeException( BeanFormMessages.noBeanForm( this ) );
054 return beanForm;
055 }
056
057 protected boolean hasCustomField( BeanProperty property ) {
058 return ( this.getCustomFieldBlock( property ) != null &&
059 this.getCustomField( property ) != null );
060 }
061
062 protected Block getCustomFieldBlock( BeanProperty property ) {
063 String name = this.getCustomFieldBlockName( property );
064 return this.getSiblingComponent( name, Block.class );
065 }
066
067 protected String getCustomFieldBlockName( BeanProperty property ) {
068 return this.getBeanForm().getId() + "_" + property.getName() + CUSTOM_FIELD_BLOCK_SUFFIX;
069 }
070
071 protected IFormComponent getCustomField( BeanProperty property ) {
072 String name = this.getCustomFieldName( property );
073 return this.getSiblingComponent( name, IFormComponent.class );
074 }
075
076 protected String getCustomFieldName( BeanProperty property ) {
077 return this.getBeanForm().getId() + "_" + property.getName() + CUSTOM_FIELD_SUFFIX;
078 }
079
080 @SuppressWarnings( "unchecked" )
081 protected <T extends IComponent> T getSiblingComponent( String id, Class<T> clazz ) {
082 IComponent component = null;
083 IComponent container = this.getBeanForm().getContainer();
084 Map components = container.getComponents();
085 if( components.containsKey( id ) ) {
086 IComponent candidate = (IComponent) components.get( id );
087 if( clazz.isAssignableFrom( candidate.getClass() ) ) {
088 component = candidate;
089 }
090 else {
091 String msg = BeanFormMessages.componentUnexpectedType( candidate, clazz );
092 throw new ApplicationRuntimeException( msg );
093 }
094 }
095 return (T) component;
096 }
097
098 protected boolean hasPropertySelectionModel( BeanProperty prop, boolean useCache ) {
099 return this.getPropertySelectionModel( prop, useCache ) != null;
100 }
101
102 protected IPropertySelectionModel getPropertySelectionModel( BeanProperty prop, boolean useCache ) {
103
104 IBinding binding;
105 if( useCache ) binding = this.getBeanForm().getFieldBindingsFor( prop ).get( MODEL );
106 else binding = this.getBeanForm().getBinding( prop.getName() + MODEL_SUFFIX );
107
108 IPropertySelectionModel model = null;
109 if( binding != null ) {
110 Object value = binding.getObject();
111 if( value instanceof IPropertySelectionModel ) {
112 model = (IPropertySelectionModel) value;
113 }
114 }
115
116 return model;
117 }
118
119 }