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 }