001 package org.tynamo.pages;
002
003 import org.apache.commons.collections.CollectionUtils;
004 import org.apache.tapestry5.*;
005 import org.apache.tapestry5.annotations.Component;
006 import org.apache.tapestry5.annotations.Environmental;
007 import org.apache.tapestry5.annotations.Property;
008 import org.apache.tapestry5.beaneditor.BeanModel;
009 import org.apache.tapestry5.corelib.components.Select;
010 import org.apache.tapestry5.corelib.components.TextField;
011 import org.apache.tapestry5.corelib.data.BlankOption;
012 import org.apache.tapestry5.internal.BeanValidationContext;
013 import org.apache.tapestry5.ioc.Messages;
014 import org.apache.tapestry5.ioc.annotations.Inject;
015 import org.apache.tapestry5.services.BeanEditContext;
016 import org.apache.tapestry5.services.BeanModelSource;
017 import org.apache.tapestry5.services.PropertyEditContext;
018 import org.apache.tapestry5.services.ValueEncoderSource;
019 import org.apache.tapestry5.util.EnumSelectModel;
020 import org.tynamo.components.EditComposition;
021 import org.tynamo.descriptor.CollectionDescriptor;
022 import org.tynamo.descriptor.IdentifierDescriptor;
023 import org.tynamo.descriptor.TynamoPropertyDescriptor;
024 import org.tynamo.services.DescriptorService;
025 import org.tynamo.services.PersistenceService;
026 import org.tynamo.util.GenericSelectionModel;
027
028 import java.util.ArrayList;
029 import java.util.Collection;
030 import java.util.List;
031
032 /**
033 * A page that exists to contain blocks used to edit different types of properties. The blocks on this page are
034 * contributed into the {@link org.apache.tapestry5.services.BeanBlockSource} service configuration.
035 *
036 * @see org.apache.tapestry5.services.BeanBlockContribution
037 * @see org.apache.tapestry5.corelib.components.BeanEditForm
038 */
039 public class PropertyEditBlocks
040 {
041
042 @Environmental
043 @Property(write = false)
044 private BeanEditContext beanEditContext;
045
046 @Environmental
047 @Property(write = false)
048 private PropertyEditContext propertyEditContext;
049
050 @Environmental
051 @Property(write = false)
052 private BeanValidationContext tynamoBeanContext;
053
054 @Inject
055 private PersistenceService persistenceService;
056
057 @Inject
058 private DescriptorService descriptorService;
059
060 @Inject
061 private ValueEncoderSource valueEncoderSource;
062
063 @Inject
064 private BeanModelSource beanModelSource;
065
066 @Component(parameters = {"value=propertyEditContext.propertyValue", "label=prop:propertyEditContext.label",
067 "translate=prop:textFieldTranslator", "validate=prop:textFieldValidator",
068 "clientId=prop:propertyEditContext.propertyId", "annotationProvider=propertyEditContext"})
069 private TextField textField;
070
071 @Component(parameters = {"collection=propertyEditContext.propertyValue", "label=prop:propertyEditContext.label",
072 "clientId=prop:propertyEditContext.propertyId", "collectionDescriptor=propertyDescriptor",
073 "owner=tynamoBeanContext.beanInstance"})
074 private EditComposition editComposition;
075
076 @Component(parameters = {"model=tynamoBeanContext.beanInstance", "propertyDescriptor=propertyDescriptor"})
077 private org.tynamo.components.Blob blob;
078
079 @Component(
080 parameters = {"value=propertyEditContext.propertyValue", "label=prop:propertyEditContext.label",
081 "encoder=valueEncoderForProperty", "model=selectModelForProperty", "validate=prop:selectValidator",
082 "clientId=prop:propertyEditContext.propertyId", "blankOption=prop:blankOption"})
083 private Select select;
084
085 public TynamoPropertyDescriptor getPropertyDescriptor()
086 {
087 return descriptorService.getClassDescriptor(beanEditContext.getBeanClass()).getPropertyDescriptor(propertyEditContext.getPropertyId());
088 }
089
090 @SuppressWarnings({"unchecked"})
091 public SelectModel getSelectModelForProperty()
092 {
093 TynamoPropertyDescriptor propertyDescriptor = getPropertyDescriptor();
094
095 Class type = propertyDescriptor.isCollection() ? ((CollectionDescriptor) propertyDescriptor).getElementType() : propertyDescriptor.getPropertyType();
096 if (type.isEnum()) return new EnumSelectModel(type, getMessages());
097
098 if (propertyDescriptor.isCollection() && ((CollectionDescriptor) propertyDescriptor).isOneToMany())
099 {
100 return new GenericSelectionModel(persistenceService.getOrphanInstances((CollectionDescriptor) propertyDescriptor, tynamoBeanContext.getBeanInstance()));
101 }
102
103 return new GenericSelectionModel(persistenceService.getInstances(type));
104 }
105
106 /**
107 * Provide a value encoder for a type.
108 *
109 * @return
110 */
111 public ValueEncoder getValueEncoderForProperty()
112 {
113 TynamoPropertyDescriptor propertyDescriptor = getPropertyDescriptor();
114 if (propertyDescriptor.isCollection())
115 {
116 CollectionDescriptor collectionDescriptor = (CollectionDescriptor) propertyDescriptor;
117 return valueEncoderSource.getValueEncoder(collectionDescriptor.getElementType());
118 } else
119 {
120 return valueEncoderSource.getValueEncoder(propertyEditContext.getPropertyType());
121 }
122 }
123
124 public FieldTranslator getTextFieldTranslator()
125 {
126 return propertyEditContext.getTranslator(textField);
127 }
128
129 public FieldValidator getTextFieldValidator()
130 {
131 return propertyEditContext.getValidator(textField);
132 }
133
134 public FieldValidator getSelectValidator()
135 {
136 return propertyEditContext.getValidator(select);
137 }
138
139 public boolean isPropertyValueInstanceOfList()
140 {
141 return propertyEditContext.getPropertyValue() instanceof List;
142 }
143
144 /**
145 * Palette's parameter "selected" only accepts java.util.List If the collection is a java.util.Set it needs to get
146 * converted
147 */
148 public List getSelected()
149 {
150 if (isPropertyValueInstanceOfList())
151 {
152 return (List) propertyEditContext.getPropertyValue();
153 } else
154 {
155 ArrayList selectedList = new ArrayList();
156 selectedList.addAll((Collection) propertyEditContext.getPropertyValue());
157 return selectedList;
158 }
159 }
160
161 public void setSelected(List selected)
162 {
163 Collection collection = (Collection) propertyEditContext.getPropertyValue();
164 CollectionDescriptor descriptor = (CollectionDescriptor) getPropertyDescriptor();
165
166 for (Object o : CollectionUtils.subtract(selected, collection))
167 {
168 persistenceService.addToCollection(descriptor, o, tynamoBeanContext.getBeanInstance());
169 }
170
171 for (Object o : CollectionUtils.subtract(collection, selected))
172 {
173 persistenceService.removeFromCollection(descriptor, o, tynamoBeanContext.getBeanInstance());
174 }
175
176 }
177
178 public boolean isNotEditable()
179 {
180 IdentifierDescriptor descriptor = (IdentifierDescriptor) getPropertyDescriptor();
181 return descriptor.isGenerated() || propertyEditContext.getPropertyValue() != null;
182 }
183
184 public BeanModel getEmbeddedModel()
185 {
186 return beanModelSource.createEditModel(propertyEditContext.getPropertyType(), getMessages());
187 }
188
189 private Messages getMessages()
190 {
191 return propertyEditContext.getContainerMessages();
192 }
193
194 /**
195 * Looks for a help message within the messages based on the id.
196 */
197 public String getHelpMessage()
198 {
199 Messages messages = getMessages();
200 String key = propertyEditContext.getPropertyId() + "-help";
201 if (messages.contains(key)) return messages.get(key);
202 return null;
203 }
204
205 public BlankOption getBlankOption()
206 {
207 return getPropertyDescriptor().isRequired() ? BlankOption.NEVER : BlankOption.ALWAYS;
208 }
209
210 }