Skip to content

Package: MapInstanceBuilder

MapInstanceBuilder

nameinstructionbranchcomplexitylinemethod
MapInstanceBuilder(CloneBuilderImpl, UnitOfWork)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
buildClone(Object, Field, Object, Descriptor)
M: 12 C: 46
79%
M: 1 C: 5
83%
M: 1 C: 3
75%
M: 1 C: 10
91%
M: 0 C: 1
100%
buildSingletonClone(Object, Field, Map, Descriptor)
M: 46 C: 61
57%
M: 6 C: 4
40%
M: 5 C: 1
17%
M: 7 C: 11
61%
M: 0 C: 1
100%
cloneMapContent(Object, Field, Map, Map, Descriptor)
M: 25 C: 56
69%
M: 4 C: 6
60%
M: 3 C: 3
50%
M: 5 C: 14
74%
M: 0 C: 1
100%
cloneObject(Object, Field, Object, Descriptor)
M: 10 C: 18
64%
M: 2 C: 2
50%
M: 2 C: 1
33%
M: 2 C: 4
67%
M: 0 C: 1
100%
cloneUsingDefaultConstructor(Object, Field, Class, Map, Descriptor)
M: 0 C: 17
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
createDefaultMap(int)
M: 10 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
createNewInstance(Class, int)
M: 22 C: 42
66%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 9 C: 13
59%
M: 0 C: 1
100%
mergeChanges(Field, Object, Object, Object)
M: 24 C: 82
77%
M: 6 C: 14
70%
M: 6 C: 5
45%
M: 2 C: 20
91%
M: 0 C: 1
100%
static {...}
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%

Coverage

1: /**
2: * Copyright (C) 2016 Czech Technical University in Prague
3: *
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: *
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.jopa.sessions;
16:
17: import cz.cvut.kbss.jopa.adapters.IndirectCollection;
18: import cz.cvut.kbss.jopa.exceptions.OWLPersistenceException;
19: import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
20: import cz.cvut.kbss.jopa.utils.EntityPropertiesUtils;
21:
22: import java.lang.reflect.Constructor;
23: import java.lang.reflect.Field;
24: import java.lang.reflect.InvocationTargetException;
25: import java.security.AccessController;
26: import java.security.PrivilegedActionException;
27: import java.util.Collection;
28: import java.util.Collections;
29: import java.util.HashMap;
30: import java.util.Map;
31: import java.util.Map.Entry;
32:
33: class MapInstanceBuilder extends AbstractInstanceBuilder {
34:
35: private static final Class<?> singletonMapClass = Collections.singletonMap(null, null)
36: .getClass();
37:
38: MapInstanceBuilder(CloneBuilderImpl builder, UnitOfWork uow) {
39: super(builder, uow);
40: this.populates = true;
41: }
42:
43: @Override
44: Object buildClone(Object cloneOwner, Field field, Object original, Descriptor repository) {
45: Map<?, ?> orig = (Map<?, ?>) original;
46:• if (original instanceof IndirectCollection) {
47: orig = ((IndirectCollection<Map<?, ?>>) original).getReferencedCollection();
48: }
49: final Class<?> origCls = orig.getClass();
50: Map<?, ?> clone;
51: clone = cloneUsingDefaultConstructor(cloneOwner, field, origCls, orig, repository);
52:• if (clone == null) {
53:• if (singletonMapClass.isInstance(orig)) {
54: clone = buildSingletonClone(cloneOwner, field, orig, repository);
55: } else {
56: throw new IllegalArgumentException("Unsupported map type " + origCls);
57: }
58: }
59: clone = (Map<?, ?>) builder.createIndirectCollection(clone, cloneOwner, field);
60: return clone;
61:
62: }
63:
64: private Map<?, ?> cloneUsingDefaultConstructor(Object cloneOwner, Field field,
65: Class<?> origCls, Map<?, ?> original, Descriptor repository) {
66: Map<?, ?> result = createNewInstance(origCls, original.size());
67:• if (result != null) {
68: cloneMapContent(cloneOwner, field, original, result, repository);
69: }
70: return result;
71: }
72:
73: private Map<?, ?> createNewInstance(Class<?> type, int size) {
74: Map<?, ?> result = null;
75: final Class<?>[] types = {int.class};
76: Object[] params;
77: Constructor<?> c = getDeclaredConstructorFor(type, types);
78:• if (c != null) {
79: params = new Object[1];
80: params[0] = size;
81: } else {
82: c = getDeclaredConstructorFor(type, null);
83: params = null;
84: }
85:• if (c == null) {
86: return null;
87: }
88: try {
89: result = (Map<?, ?>) c.newInstance(params);
90: } catch (InstantiationException | IllegalArgumentException | InvocationTargetException e) {
91: throw new OWLPersistenceException(e);
92: } catch (IllegalAccessException e) {
93: logConstructorAccessException(c, e);
94: try {
95: result = (Map<?, ?>) AccessController
96: .doPrivileged(new PrivilegedInstanceCreator(c));
97: } catch (PrivilegedActionException ex) {
98: logPrivilegedConstructorAccessException(c, ex);
99: // Do nothing
100: }
101: }
102: return result;
103: }
104:
105: private Map<?, ?> buildSingletonClone(Object cloneOwner, Field field, Map<?, ?> orig,
106: Descriptor repository) {
107: final Constructor<?> c = getFirstDeclaredConstructorFor(singletonMapClass);
108:• if (!c.isAccessible()) {
109: c.setAccessible(true);
110: }
111: Entry<?, ?> e = orig.entrySet().iterator().next();
112:• Object key = CloneBuilderImpl.isImmutable(e.getKey().getClass()) ? e.getKey()
113: : cloneObject(cloneOwner, field, e.getKey(), repository);
114:• Object value = CloneBuilderImpl.isImmutable(e.getValue().getClass()) ? e.getValue()
115: : cloneObject(cloneOwner, field, e.getValue(), repository);
116:• if (value instanceof Collection || value instanceof Map) {
117: value = builder.createIndirectCollection(value, cloneOwner, field);
118: }
119: try {
120: return (Map<?, ?>) c.newInstance(key, value);
121: } catch (IllegalAccessException ex) {
122: logConstructorAccessException(c, ex);
123: try {
124: return (Map<?, ?>) AccessController.doPrivileged(new PrivilegedInstanceCreator(c,
125: key, value));
126: } catch (PrivilegedActionException exx) {
127: throw new OWLPersistenceException(exx);
128: }
129: } catch (InstantiationException | IllegalArgumentException | InvocationTargetException ex) {
130: throw new OWLPersistenceException(ex);
131: }
132: }
133:
134: private void cloneMapContent(Object cloneOwner, Field field, Map<?, ?> source,
135: Map<?, ?> target, Descriptor repository) {
136:• if (source.isEmpty()) {
137: return;
138: }
139: Map<Object, Object> m = (Map<Object, Object>) target;
140: Entry<?, ?> tmp = source.entrySet().iterator().next();
141: boolean keyPrimitive = CloneBuilderImpl.isImmutable(tmp.getKey().getClass());
142: boolean valuePrimitive = CloneBuilderImpl.isImmutable(tmp.getValue().getClass());
143:• for (Entry<?, ?> e : source.entrySet()) {
144: Object key;
145: Object value;
146:• if (keyPrimitive) {
147:• if (valuePrimitive) {
148: m.putAll(source);
149: break;
150: }
151: key = e.getKey();
152: value = cloneObject(cloneOwner, field, e.getValue(), repository);
153: } else {
154: key = cloneObject(cloneOwner, field, e.getKey(), repository);
155:• value = valuePrimitive ? e.getValue() : cloneObject(cloneOwner, field,
156: e.getValue(), repository);
157: }
158: m.put(key, value);
159: }
160: }
161:
162: private Object cloneObject(Object owner, Field field, Object obj, Descriptor repository) {
163: Object clone;
164:• if (obj == null) {
165: clone = null;
166:• } else if (builder.isTypeManaged(obj.getClass())) {
167: clone = uow.registerExistingObject(obj, repository);
168: } else {
169: clone = builder.buildClone(owner, field, obj, repository);
170: }
171: return clone;
172: }
173:
174: @Override
175: void mergeChanges(Field field, Object target, Object originalValue, Object cloneValue) {
176:• assert (originalValue == null) || (originalValue instanceof Map);
177:• assert cloneValue instanceof Map;
178:
179: Map<Object, Object> orig = (Map<Object, Object>) originalValue;
180: Map<Object, Object> clone = (Map<Object, Object>) cloneValue;
181:• if (clone instanceof IndirectCollection) {
182: clone = ((IndirectCollection<Map<Object, Object>>) clone).getReferencedCollection();
183: }
184:• if (orig == null) {
185: orig = (Map<Object, Object>) createNewInstance(clone.getClass(), clone.size());
186:• if (orig == null) {
187: orig = createDefaultMap(clone.size());
188: }
189: EntityPropertiesUtils.setFieldValue(field, target, orig);
190: }
191: orig.clear();
192:• if (clone.isEmpty()) {
193: return;
194: }
195:• for (Entry<?, ?> e : clone.entrySet()) {
196: final Object key = e.getKey();
197: final Object value = e.getValue();
198:• final Object keyToPut = uow.contains(key) ? builder.getOriginal(key) : key;
199:• final Object valueToPut = uow.contains(value) ? builder.getOriginal(value) : value;
200: orig.put(keyToPut, valueToPut);
201: }
202: }
203:
204: private Map<Object, Object> createDefaultMap(int size) {
205:• return new HashMap<>(size > 1 ? size : 16);
206: }
207: }