001 package org.tynamo.services;
002
003 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
004
005 import org.apache.tapestry5.ioc.util.StrategyRegistry;
006 import org.tynamo.descriptor.*;
007 import org.tynamo.descriptor.factories.DescriptorFactory;
008
009 import java.util.Collection;
010 import java.util.HashMap;
011 import java.util.List;
012 import java.util.Map;
013
014 /**
015 * This class builds and caches TynamoClassDescriptors.
016 * Descriptors are build during application startup.
017 */
018 public class DescriptorServiceImpl implements DescriptorService
019 {
020 private final StrategyRegistry<TynamoClassDescriptor> descriptorsRegistry;
021 private final List<TynamoClassDescriptor> descriptors;
022
023 /**
024 * For each class in types, a descriptor is built by the DescriptorFactory. Next it is decorated
025 * by each DescriptorDecorator in turn. Finally it is cached.
026 *
027 * @param types In the Tynamo default configuration this will be set to all classes in the Hibernate config
028 * @param descriptorFactory In default Tynamo this will be a ReflectionDescriptorFactory
029 * @see org.tynamo.descriptor.factories.DescriptorFactory
030 * @see org.tynamo.descriptor.decorators.DescriptorDecorator
031 */
032 public DescriptorServiceImpl(final Collection<Class> types, DescriptorFactory descriptorFactory)
033 {
034 Map<Class, TynamoClassDescriptor> descriptorsMap = new HashMap<Class, TynamoClassDescriptor>();
035 for (Class type : types)
036 {
037 descriptorsMap.put(type, descriptorFactory.buildClassDescriptor(type));
038 }
039
040 this.descriptors = CollectionFactory.newList(descriptorsMap.values());
041 this.descriptorsRegistry = StrategyRegistry.newInstance(TynamoClassDescriptor.class, descriptorsMap, true);
042
043 // second pass to find children
044 for (TynamoClassDescriptor classDescriptor : descriptorsMap.values())
045 {
046 findChildren(classDescriptor);
047 }
048
049 }
050
051 public List<TynamoClassDescriptor> getAllDescriptors()
052 {
053 return descriptors;
054 }
055
056 public TynamoClassDescriptor getClassDescriptor(Class type)
057 {
058 return descriptorsRegistry.get(type);
059 }
060
061 private void findChildren(TynamoClassDescriptor classDescriptor)
062 {
063 for (TynamoPropertyDescriptor propertyDescriptor : classDescriptor.getPropertyDescriptors())
064 {
065 if (propertyDescriptor.isCollection())
066 {
067 if (((CollectionDescriptor) propertyDescriptor).isChildRelationship())
068 {
069 TynamoClassDescriptor collectionClassDescriptor = getClassDescriptor(((CollectionDescriptor) propertyDescriptor).getElementType());
070 collectionClassDescriptor.setChild(true);
071 }
072 if (((CollectionDescriptor) propertyDescriptor).getInverseProperty() != null)
073 {
074 classDescriptor.setHasCyclicRelationships(true);
075 }
076 }
077 }
078 }
079
080 }