001 package org.tynamo.components;
002
003 import org.apache.tapestry5.*;
004 import org.apache.tapestry5.annotations.InjectComponent;
005 import org.apache.tapestry5.annotations.Parameter;
006 import org.apache.tapestry5.annotations.Property;
007 import org.apache.tapestry5.beaneditor.BeanModel;
008 import org.apache.tapestry5.corelib.components.Form;
009 import org.apache.tapestry5.corelib.components.Zone;
010 import org.apache.tapestry5.ioc.Messages;
011 import org.apache.tapestry5.ioc.annotations.Inject;
012 import org.apache.tapestry5.ioc.services.PropertyAccess;
013 import org.apache.tapestry5.ioc.services.TypeCoercer;
014 import org.apache.tapestry5.services.BeanModelSource;
015 import org.apache.tapestry5.services.ValueEncoderSource;
016 import org.tynamo.builder.BuilderDirector;
017 import org.tynamo.descriptor.CollectionDescriptor;
018 import org.tynamo.services.DescriptorService;
019 import org.tynamo.services.PersistenceService;
020 import org.tynamo.util.DisplayNameUtils;
021 import org.tynamo.util.Utils;
022
023 import java.util.Collection;
024 import java.util.List;
025
026 public class Composition
027 {
028
029 @Inject
030 private DescriptorService descriptorService;
031
032 @Inject
033 private PersistenceService persitenceService;
034
035 @Inject
036 private PropertyAccess propertyAccess;
037
038 @Inject
039 private BeanModelSource beanModelSource;
040
041 @Inject
042 private Messages messages;
043
044 @Inject
045 private BuilderDirector builderDirector;
046
047 @Inject
048 private ComponentResources resources;
049
050 @Inject
051 private ValueEncoderSource valueEncoderSource;
052
053 /**
054 * The id used to generate a page-unique client-side identifier for the component. If a component renders multiple
055 * times, a suffix will be appended to the to id to ensure uniqueness. The uniqued value may be accessed via the
056 * {@link #getClientId() clientId property}.
057 */
058 @Parameter(value = "prop:resources.id", defaultPrefix = BindingConstants.LITERAL)
059 @Property(write = false)
060 private String clientId;
061
062 /**
063 * A Block to render when the source is empty. The default is simply the text "There is no data to display".
064 * This parameter is used to customize that message.
065 */
066 @Parameter(value = "block:empty", defaultPrefix = BindingConstants.LITERAL)
067 @Property(write = false)
068 private Block empty;
069
070 @Parameter(required = false)
071 private List instances;
072
073 @Parameter(required = true)
074 @Property(write = false)
075 private Collection collection;
076
077 /**
078 * The object which owns the collection being edited
079 */
080 @Parameter(required = true)
081 private Object owner;
082
083 /**
084 * Ognl expression to invoke on the model to create a new child instance
085 */
086 @Parameter(required = false)
087 private String createExpression;
088
089 /**
090 * @return The CollectionDescriptor for the collection being edited
091 */
092 @Parameter(required = true)
093 @Property(write = false)
094 private CollectionDescriptor collectionDescriptor;
095
096 @Property
097 private Object collectionIterator;
098
099 @Property
100 private Object formBean;
101
102 @Parameter(value = "true")
103 private boolean allowCreate;
104
105 @InjectComponent
106 private Zone compositionZone;
107
108 @InjectComponent
109 @Property(write = false)
110 private Form form;
111
112 @Inject
113 private TypeCoercer typeCoercer;
114
115 public boolean isAllowCreate()
116 {
117 return propertyAccess.get(owner, descriptorService.getClassDescriptor(owner.getClass())
118 .getIdentifierDescriptor().getName()) != null;
119 }
120
121 @Parameter(value = "prop:collectionDescriptor.allowRemove")
122 private boolean allowRemove;
123
124 @Property
125 private int index;
126
127 @Parameter(value = "asset:move_up.gif")
128 @Property(write = false)
129 private Asset upImage;
130
131 @Parameter(value = "asset:move_down.gif")
132 @Property(write = false)
133 private Asset downImage;
134
135 /**
136 * The image to use for the delete icon
137 */
138 @Parameter(value = "asset:delete.png")
139 @Property(write = false)
140 private Asset deleteIcon;
141
142 @Property(write = false)
143 private BeanModel beanModel;
144
145 void onPrepareFromForm()
146 {
147 resources.triggerEvent(EventConstants.PREPARE, null, null);
148
149 if (beanModel == null)
150 {
151 beanModel = beanModelSource.createEditModel(collectionDescriptor.getElementType(), messages);
152 }
153 }
154
155 void setupRender()
156 {
157 beanModel = beanModelSource.createEditModel(collectionDescriptor.getElementType(), messages);
158 formBean = builderDirector.createNewInstance(collectionDescriptor.getElementType());
159 }
160
161 public Object onSuccess()
162 {
163 Utils.executeOgnlExpression(collectionDescriptor.getAddExpression(), formBean, owner);
164 persitenceService.save(owner);
165 return compositionZone.getBody();
166 }
167
168 public Object onActionFromDeleteChild(String elementid)
169 {
170 ValueEncoder valueEncoder = valueEncoderSource.getValueEncoder(collectionDescriptor.getElementType());
171 Object element = valueEncoder.toValue(elementid);
172 Utils.executeOgnlExpression(collectionDescriptor.getRemoveExpression(), element, owner);
173
174 persitenceService.remove(element);
175 persitenceService.save(owner);
176 return compositionZone.getBody();
177 }
178
179
180 /* public boolean isList()
181 {
182 return collection instanceof List;
183 }
184
185 public void moveUp()
186 {
187 List list = (List) collection;
188 for (int i = 1; i < getSelected().size(); i++)
189 {
190 if (getSelected().get(i))
191 {
192 if (collectionDescriptor.getSwapExpression() == null)
193 {
194 Collections.swap(list, i, i - 1);
195 } else
196 {
197 try
198 {
199 Ognl.getValue(collectionDescriptor.getSwapExpression() + "(" + i + "," + (i - 1) + ")", owner);
200 } catch (OgnlException e)
201 {
202 LOGGER.error(e.getMessage());
203 }
204 }
205 }
206 }
207 }
208
209 public void moveDown()
210 {
211 List list = (List) collection;
212 for (int i = 0; i < getSelected().size() - 1; i++)
213 {
214 if (collectionDescriptor.getSwapExpression() == null)
215 {
216 Collections.swap(list, i, i + 1);
217 } else
218 {
219 try
220 {
221 Ognl.getValue(collectionDescriptor.getSwapExpression() + "(" + i + "," + (i + 1) + ")",
222 owner);
223 } catch (OgnlException e)
224 {
225 LOG.error(e.getMessage());
226 }
227 }
228 }
229 }*/
230
231 public Object[] getShowPageContext()
232 {
233 return new Object[]{collectionIterator.getClass(), collectionIterator};
234 }
235
236 public Object[] getDeleteContext()
237 {
238 return new Object[]{collectionIterator};
239 }
240
241 public String getLegendMessage()
242 {
243 return messages.format("org.tynamo.i18n.add",
244 DisplayNameUtils.getDisplayName(collectionDescriptor.getElementType(), messages));
245 }
246
247 }