package org.tynamo.components;
import org.apache.tapestry5.Asset;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.beaneditor.BeanModel;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.services.PropertyAccess;
import org.apache.tapestry5.services.BeanModelSource;
import org.slf4j.Logger;
import org.tynamo.descriptor.CollectionDescriptor;
import org.tynamo.descriptor.TynamoClassDescriptor;
import org.tynamo.services.DescriptorService;
import org.tynamo.services.PersistenceService;
import java.util.Collection;
import java.util.List;
/**
* This component produces a editor for a Composition (child collection).
* It allows a user to edit a collection property
*/
public class EditComposition
{
@Inject
private Logger logger;
@Inject
private DescriptorService descriptorService;
@Inject
private PersistenceService persitenceService;
@Inject
private PropertyAccess propertyAccess;
@Inject
private BeanModelSource beanModelSource;
@Inject
private Messages messages;
/**
* The id used to generate a page-unique client-side identifier for the component. If a component renders multiple
* times, a suffix will be appended to the to id to ensure uniqueness. The uniqued value may be accessed via the
* {@link #getClientId() clientId property}.
*/
@Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL)
@Property(write = false)
private String clientId;
/**
* The user presentable label for the field. If not provided, a reasonable label is generated from the component's
* id, first by looking for a message key named "id-label" (substituting the component's actual id), then by
* converting the actual id to a presentable string (for example, "userId" to "User Id").
*/
@Parameter(defaultPrefix = BindingConstants.LITERAL)
@Property(write = false)
private String label;
@Parameter(required = false)
private List instances;
@Parameter(required = true)
@Property(write = false)
private Collection collection;
/**
* The object which owns the collection being edited
*/
@Parameter(required = false)
private Object owner;
/**
* Ognl expression to invoke on the model to create a new child instance
*/
@Parameter(required = false)
private String createExpression;
/**
* @return The CollectionDescriptor for the collection being edited
*/
@Parameter(required = true)
@Property(write = false)
private CollectionDescriptor collectionDescriptor;
@Property
private Object collectionIterator;
@Parameter(value = "true")
private boolean allowCreate;
public boolean isAllowCreate()
{
return propertyAccess.get(owner, descriptorService.getClassDescriptor(owner.getClass())
.getIdentifierDescriptor().getName()) != null;
}
@Parameter(value = "prop:collectionDescriptor.allowRemove")
private boolean allowRemove;
@Property
private int index;
@Parameter(value = "asset:move_up.gif")
@Property(write = false)
private Asset upImage;
@Parameter(value = "asset:move_down.gif")
@Property(write = false)
private Asset downImage;
@Property(write = false)
private BeanModel beanModel;
void setupRender()
{
beanModel = beanModelSource.create(collectionDescriptor.getElementType(), false, messages);
for (String propertyName : (List<String>) beanModel.getPropertyNames())
{
beanModel.get(propertyName).sortable(false);
}
}
/* public void remove()
{
int i = 0;
// TODO CN - This code stinks (I wrote it). Isn't there a better way??
ArrayList deleting = new ArrayList();
for (Object element : getCollection())
{
if (getSelected().get(i))
{
deleting.add(element);
}
i++;
}
for (Object element : deleting)
{
Utils.executeOgnlExpression(collectionDescriptor.getRemoveExpression(), element, owner);
persitenceService.remove(element);
}
}
public boolean isList()
{
return collection instanceof List;
}
public void moveUp()
{
List list = (List) collection;
for (int i = 1; i < getSelected().size(); i++)
{
if (getSelected().get(i))
{
if (collectionDescriptor.getSwapExpression() == null)
{
Collections.swap(list, i, i - 1);
} else
{
try
{
Ognl.getValue(collectionDescriptor.getSwapExpression() + "(" + i + "," + (i - 1) + ")", owner);
} catch (OgnlException e)
{
LOGGER.error(e.getMessage());
}
}
}
}
}
public void moveDown()
{
List list = (List) collection;
for (int i = 0; i < getSelected().size() - 1; i++)
{
if (collectionDescriptor.getSwapExpression() == null)
{
Collections.swap(list, i, i + 1);
} else
{
try
{
Ognl.getValue(collectionDescriptor.getSwapExpression() + "(" + i + "," + (i + 1) + ")",
owner);
} catch (OgnlException e)
{
LOG.error(e.getMessage());
}
}
}
}*/
public Object[] getEditCompositionPageContext()
{
return new Object[]{collectionDescriptor.getBeanType(), owner, collectionDescriptor.getName(), collectionIterator};
}
public Object[] getAddCompositionPageContext()
{
return new Object[]{collectionDescriptor.getBeanType(), owner, collectionDescriptor.getName()};
}
public final String getModelId()
{
TynamoClassDescriptor classDescriptor =
descriptorService.getClassDescriptor(collectionDescriptor.getElementType());
return propertyAccess.get(collectionIterator, classDescriptor.getIdentifierDescriptor().getName()).toString();
}
}