1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sourceforge.domian.repository;
17
18
19 import static java.lang.Boolean.FALSE;
20 import java.lang.reflect.InvocationHandler;
21 import static java.lang.reflect.Proxy.newProxyInstance;
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import static org.apache.commons.lang.SystemUtils.FILE_SEPARATOR;
26 import static org.apache.commons.lang.SystemUtils.USER_HOME;
27 import org.slf4j.Logger;
28 import static org.slf4j.LoggerFactory.getLogger;
29
30 import net.sourceforge.domian.entity.Entity;
31 import net.sourceforge.domian.specification.Specification;
32 import net.sourceforge.domian.specification.SpecificationUtils;
33 import net.sourceforge.domian.util.concurrent.locks.Synchronizer;
34
35
36
37
38
39
40
41
42
43
44
45 public abstract class AbstractDomianCoreRepository<T extends Entity> extends AbstractRepository<T> {
46
47
48
49 public static final String DEFAULT_DOMIAN_ROOT_DIR_NAME = ".domian";
50 public static final String DEFAULT_DOMIAN_ROOT_PATH = USER_HOME + FILE_SEPARATOR + DEFAULT_DOMIAN_ROOT_DIR_NAME;
51
52 protected final Logger log = getLogger(this.getClass());
53
54
55
56
57
58 protected Synchronizer synchronizer;
59
60 protected Synchronizer getSynchronizer() {
61 return this.synchronizer;
62 }
63
64 public void setSynchronizer(final Synchronizer synchronizer) {
65 this.synchronizer = synchronizer;
66 }
67
68 @Override
69 protected Specification<T> createUniqueSpecificationFor(final T entity) {
70 return SpecificationUtils.createUniqueSpecificationFor(entity);
71 }
72
73
74
75
76
77
78
79
80 private InvocationHandler getInvocationHandler() {
81 if (this.usesNativePartitioningSupport) {
82 String repositoryDenomination;
83 if (this instanceof PersistentRepository) {
84 repositoryDenomination = "'" + ((PersistentRepository) this).getRepositoryId() + "'";
85 } else {
86 repositoryDenomination = "[repository.hashCode=" + this.hashCode() + "]";
87 }
88 log.info("Repository partition " + repositoryDenomination + " will be using the same repository instance for all sub-partitions having the same repository type '" + this.getClass().getName() + "'");
89 return new PartitionRepositoryReuseInvocationHandler<T>(this);
90
91 } else {
92 return new PartitionRepositoryInvocationHandler<T>(this, this.synchronizer, FALSE);
93 }
94 }
95
96 @Override
97 public PartitionRepository<T> makePartition() {
98 final InvocationHandler invocationHandler = getInvocationHandler();
99 final Class[] targetRepositoryInterfaces = getAllRelevantRepositoryInterfaces(this);
100 final Object partitionRepositoryObject = newProxyInstance(AbstractDomianCoreRepository.class.getClassLoader(),
101 targetRepositoryInterfaces,
102 invocationHandler);
103 onMakePartition();
104 return (PartitionRepository<T>) partitionRepositoryObject;
105 }
106
107 @Override
108 protected void onMakePartition() {}
109
110 private static Class[] getAllRelevantRepositoryInterfaces(final Repository repository) {
111 final List<Class<? extends Repository>> interfaceList = new ArrayList<Class<? extends Repository>>();
112
113 interfaceList.add(Repository.class);
114 interfaceList.add(PartitionRepository.class);
115
116 if (repository instanceof VolatileRepository) {
117 interfaceList.add(VolatileRepository.class);
118
119 } else if (repository instanceof BinaryFormatRepository) {
120 interfaceList.add(PersistentRepository.class);
121 interfaceList.add(BinaryFormatRepository.class);
122
123 } else if (repository instanceof HumanReadableFormatRepository) {
124 interfaceList.add(PersistentRepository.class);
125 interfaceList.add(TextualFormatRepository.class);
126 interfaceList.add(HumanReadableFormatRepository.class);
127
128 } else if (repository instanceof TextualFormatRepository) {
129 interfaceList.add(PersistentRepository.class);
130 interfaceList.add(TextualFormatRepository.class);
131
132 } else if (repository instanceof FakeRepository) {
133 interfaceList.add(FakeRepository.class);
134 }
135 return interfaceList.toArray(new Class[interfaceList.size()]);
136 }
137 }