1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jadira.usertype.unitsofmeasurement.indriya;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import javax.measure.Quantity;
25 import javax.measure.Unit;
26 import javax.measure.spi.SystemOfUnits;
27
28 import org.hibernate.SessionFactory;
29 import org.jadira.usertype.spi.shared.AbstractParameterizedMultiColumnUserType;
30 import org.jadira.usertype.spi.shared.ColumnMapper;
31 import org.jadira.usertype.spi.shared.ValidTypesConfigured;
32 import org.jadira.usertype.spi.utils.reflection.ArrayUtils;
33 import org.jadira.usertype.spi.utils.reflection.ClassLoaderUtils;
34 import org.jadira.usertype.unitsofmeasurement.indriya.columnmapper.StringColumnStringMapper;
35 import org.jadira.usertype.unitsofmeasurement.indriya.columnmapper.StringColumnUnitMapper;
36
37 import tec.units.indriya.quantity.Quantities;
38 import tec.units.indriya.unit.Units;
39
40
41
42
43
44
45 public class PersistentQuantityAndUnit extends AbstractParameterizedMultiColumnUserType<Quantity<?>> implements ValidTypesConfigured<Unit<?>> {
46
47 private static final long serialVersionUID = -2015829087239519037L;
48
49 private static final SystemOfUnits UNITS = Units.getInstance();
50
51 private final Map<String, Unit<?>> unitsMap = new HashMap<String, Unit<?>>();
52
53 private List<Class<Unit<?>>> validTypes;
54
55 private static final ColumnMapper<?, ?>[] COLUMN_MAPPERS = new ColumnMapper<?, ?>[] { new StringColumnStringMapper(), new StringColumnUnitMapper() };
56
57 private static final String[] PROPERTY_NAMES = new String[]{ "quantity", "unit" };
58
59 public PersistentQuantityAndUnit() {
60 super();
61
62 for (Unit<?> next : UNITS.getUnits()) {
63 unitsMap.put(next.getSymbol(), next);
64 }
65 }
66
67 @Override
68 public void applyConfiguration(SessionFactory sessionFactory) {
69 super.applyConfiguration(sessionFactory);
70 doApplyConfiguration();
71 }
72
73 private <Z> void doApplyConfiguration() {
74
75
76 ValidTypesConfigured<Unit<?>> next = (ValidTypesConfigured<Unit<?>>)this;
77 performValidTypesConfiguration(next);
78
79
80
81
82
83
84
85
86
87 }
88
89 private void performValidTypesConfiguration(ValidTypesConfigured<Unit<?>> next) {
90
91 String validTypesString = null;
92 if (getParameterValues() != null) {
93 validTypesString = getParameterValues().getProperty("validTypes");
94 }
95 if (validTypesString != null) {
96 String[] validTypes = validTypesString.split(",");
97 List<Class<Unit<?>>> units = new ArrayList<>();
98 for (String nextType : validTypes) {
99
100
101 try {
102 @SuppressWarnings("unchecked")
103 Class<Unit<?>> nextClass = (Class<Unit<?>>)(ClassLoaderUtils.classForName(nextType));
104 units.add(nextClass);
105 } catch (ClassNotFoundException e) {
106 throw new IllegalStateException("Cannot find specified class " + nextType, e);
107 }
108
109 }
110 next.setValidTypes(units);
111 }
112 }
113
114 @Override
115 public void setValidTypes(List<Class<Unit<?>>> types) {
116 for (Class<Unit<?>> next : types) {
117 Unit<?> unit;
118 try {
119 unit = next.newInstance();
120 } catch (InstantiationException | IllegalAccessException e) {
121 throw new IllegalStateException("Cannot instantiate " + next.getName() + ": " + e.getMessage(), e);
122 }
123 unitsMap.put(unit.getSymbol(), unit);
124 }
125 this.validTypes = Collections.unmodifiableList(types);
126 }
127
128 @Override
129 public List<Class<Unit<?>>> getValidTypes() {
130 return this.validTypes;
131 }
132
133 @Override
134 protected Quantity<?> fromConvertedColumns(Object[] convertedColumns) {
135
136 String stringPart = (String) convertedColumns[0];
137 Unit<?> unit = (Unit<?>) convertedColumns[1];
138
139 return Quantities.getQuantity(stringPart + " " + unit.getSymbol());
140 }
141
142 @Override
143 protected Object[] toConvertedColumns(Quantity<?> value) {
144 return new Object[] { value.getValue().toString(), value.getUnit() };
145 }
146
147 @Override
148 protected ColumnMapper<?, ?>[] getColumnMappers() {
149 return COLUMN_MAPPERS;
150 }
151
152 @Override
153 public String[] getPropertyNames() {
154 return ArrayUtils.copyOf(PROPERTY_NAMES);
155 }
156
157 }