package org.tynamo.descriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.tapestry5.func.F;
import org.apache.tapestry5.func.Predicate;
/**
* This represents all the Tynamo metadata for a single class.
*/
public class TynamoClassDescriptorImpl extends TynamoDescriptor implements TynamoClassDescriptor
{
private List<TynamoPropertyDescriptor> propertyDescriptors = new ArrayList<TynamoPropertyDescriptor>();
private List<IMethodDescriptor> methodDescriptors = new ArrayList<IMethodDescriptor>();
// private BeanDescriptor beanDescriptor;
private boolean child;
boolean hasCyclicRelationships;
boolean allowRemove = true;
boolean allowSave = true;
boolean searchable = false;
/**
* This is a copy constructor. These need to be clonable for the security
* aspect to be able to copy them, so if new properties are added they
* should be added here too.
*/
public TynamoClassDescriptorImpl(TynamoClassDescriptor descriptor)
{
super(descriptor);
copyPropertyDescriptorsFrom(descriptor);
copyMethodDescriptorsFrom(descriptor);
}
public TynamoClassDescriptorImpl(Class beanType)
{
super(beanType);
}
/**
* @param dto
*/
public TynamoClassDescriptorImpl(TynamoClassDescriptorImpl dto)
{
super(dto);
try
{
BeanUtils.copyProperties(this, dto);
} catch (IllegalAccessException e)
{
LOGGER.error(e.getMessage(), e);
} catch (InvocationTargetException e)
{
LOGGER.error(e.getMessage(), e);
} catch (Exception e)
{
LOGGER.error(e.toString(), e);
}
}
private void copyMethodDescriptorsFrom(TynamoClassDescriptor descriptor)
{
for (IMethodDescriptor methodDescriptor : descriptor.getMethodDescriptors())
{
getMethodDescriptors().add(IMethodDescriptor.class.cast(methodDescriptor.clone()));
}
}
protected void copyPropertyDescriptorsFrom(TynamoClassDescriptor descriptor)
{
for (TynamoPropertyDescriptor propertyDescriptor : descriptor.getPropertyDescriptors())
{
getPropertyDescriptors().add(TynamoPropertyDescriptor.class.cast(propertyDescriptor.clone()));
}
}
public TynamoPropertyDescriptor getPropertyDescriptor(final String name)
{
return F.flow(propertyDescriptors).filter(new Predicate<TynamoPropertyDescriptor>()
{
public boolean accept(TynamoPropertyDescriptor descriptor)
{
return descriptor.getName().equals(name);
}
}).first();
}
public List<TynamoPropertyDescriptor> getPropertyDescriptors(List<String> properties)
{
ArrayList<TynamoPropertyDescriptor> descriptors = new ArrayList<TynamoPropertyDescriptor>();
for (String property : properties)
{
descriptors.add(getPropertyDescriptor(property));
}
return descriptors;
}
/**
* @return Returns the methodDescriptors.
*/
public List<IMethodDescriptor> getMethodDescriptors()
{
return methodDescriptors;
}
/**
* @param methodDescriptors The methodDescriptors to set.
*/
public void setMethodDescriptors(List<IMethodDescriptor> methodDescriptors)
{
this.methodDescriptors = methodDescriptors;
}
/**
* @return Returns the propertyDescriptors.
*/
public List<TynamoPropertyDescriptor> getPropertyDescriptors()
{
return propertyDescriptors;
}
/**
* @param propertyDescriptors The propertyDescriptors to set.
*/
public void setPropertyDescriptors(List<TynamoPropertyDescriptor> propertyDescriptors)
{
this.propertyDescriptors = propertyDescriptors;
}
public TynamoPropertyDescriptor getIdentifierDescriptor()
{
return F.flow(propertyDescriptors).filter(new Predicate<TynamoPropertyDescriptor>()
{
public boolean accept(TynamoPropertyDescriptor descriptor)
{
return descriptor.isIdentifier();
}
}).first();
}
/**
* @return Returns the child.
*/
public boolean isChild()
{
return child;
}
/**
* @param child The child to set.
*/
public void setChild(boolean child)
{
this.child = child;
}
@Override
public Object clone()
{
return new TynamoClassDescriptorImpl(this);
}
@Override
public void copyFrom(Descriptor descriptor)
{
super.copyFrom(descriptor);
if (descriptor instanceof TynamoClassDescriptorImpl)
{
try
{
BeanUtils.copyProperties(this, (TynamoClassDescriptorImpl) descriptor);
copyPropertyDescriptorsFrom((TynamoClassDescriptorImpl) descriptor);
copyMethodDescriptorsFrom((TynamoClassDescriptorImpl) descriptor);
} catch (IllegalAccessException e)
{
LOGGER.error(e.getMessage(), e);
} catch (InvocationTargetException e)
{
LOGGER.error(e.getMessage(), e);
} catch (Exception e)
{
LOGGER.error(e.toString(), e);
}
}
}
public boolean isAllowRemove()
{
return allowRemove;
}
public void setAllowRemove(boolean allowRemove)
{
this.allowRemove = allowRemove;
}
public boolean isAllowSave()
{
return allowSave;
}
public void setAllowSave(boolean allowSave)
{
this.allowSave = allowSave;
}
public boolean isSearchable() {
return searchable;
}
public void setSearchable(boolean searchable)
{
this.searchable = searchable;
}
public boolean getHasCyclicRelationships()
{
return hasCyclicRelationships;
}
public void setHasCyclicRelationships(boolean hasBidirectionalRelationship)
{
this.hasCyclicRelationships = hasBidirectionalRelationship;
}
/**
* Added toString method to help with unit testing debugging.
*/
public String toString()
{
return "{TynamoClassDescriptor - Type: " + getBeanType() + "}";
}
}