001 package org.tynamo.services;
002
003 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
004 import org.apache.tapestry5.ioc.internal.util.Defense;
005 import org.apache.tapestry5.ioc.util.StrategyRegistry;
006 import org.tynamo.descriptor.*;
007
008 import java.util.Collection;
009 import java.util.HashMap;
010 import java.util.List;
011 import java.util.Map;
012
013 /**
014 * This class builds and caches TynamoClassDescriptors.
015 * Descriptors are build during application startup.
016 */
017 public class DescriptorServiceImpl implements DescriptorService
018 {
019 private final StrategyRegistry<TynamoClassDescriptor> descriptorsRegistry;
020 private final List<TynamoClassDescriptor> descriptors;
021
022 /**
023 * For each class in types, a descriptor is built by the DescriptorFactory. Next it is decorated
024 * by each DescriptorDecorator in turn. Finally it is cached.
025 *
026 * @param types In the Tynamo default configuration this will be set to all classes in the Hibernate config
027 * @param descriptorFactory In default Tynamo this will be a ReflectionDescriptorFactory
028 * @see DescriptorFactory
029 * @see DescriptorDecorator
030 */
031 public DescriptorServiceImpl(final Collection<Class> types, DescriptorFactory descriptorFactory)
032 {
033 Map<Class, TynamoClassDescriptor> descriptorsMap = new HashMap<Class, TynamoClassDescriptor>();
034 for (Class type : types)
035 {
036 descriptorsMap.put(type, descriptorFactory.buildClassDescriptor(type));
037 }
038
039 this.descriptors = CollectionFactory.newList(descriptorsMap.values());
040 this.descriptorsRegistry = StrategyRegistry.newInstance(TynamoClassDescriptor.class, descriptorsMap, true);
041
042 // second pass to find children
043 for (TynamoClassDescriptor classDescriptor : descriptorsMap.values())
044 {
045 findChildren(classDescriptor);
046 }
047
048 }
049
050 public List<TynamoClassDescriptor> getAllDescriptors()
051 {
052 return descriptors;
053 }
054
055 public TynamoClassDescriptor getClassDescriptor(Class type)
056 {
057 Defense.notNull(type, "type");
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 }