1 package com.vladmihalcea.hibernate.type.util;
2
3 import com.fasterxml.jackson.databind.ObjectMapper;
4 import com.vladmihalcea.hibernate.util.ClassLoaderUtils;
5 import org.hibernate.cfg.Environment;
6
7 import java.io.File;
8 import java.io.IOException;
9 import java.io.InputStream;
10 import java.io.Serializable;
11 import java.net.MalformedURLException;
12 import java.net.URL;
13 import java.util.Properties;
14 import java.util.function.Supplier;
15
16 import static com.vladmihalcea.hibernate.util.LogUtils.LOGGER;
17
18
29 public class Configuration implements Serializable {
30
31 public static final Configuration INSTANCE = new Configuration();
32
33 public static final String PROPERTIES_FILE_PATH = "hibernate-types.properties.path";
34 public static final String PROPERTIES_FILE_NAME = "hibernate-types.properties";
35 public static final String APPLICATION_PROPERTIES_FILE_NAME = "application.properties";
36
37
40 public enum PropertyKey {
41 JACKSON_OBJECT_MAPPER("hibernate.types.jackson.object.mapper"),
42 JSON_SERIALIZER("hibernate.types.json.serializer"),
43 PRINT_BANNER("hibernate.types.print.banner");
44
45 private final String key;
46
47 PropertyKey(String key) {
48 this.key = key;
49 }
50
51 public String getKey() {
52 return key;
53 }
54 }
55
56 private final ObjectMapperWrapper objectMapperWrapper;
57
58 private final Properties properties = Environment.getProperties();
59
60 private Configuration() {
61 load();
62
63 Object objectMapperPropertyInstance = instantiateClass(PropertyKey.JACKSON_OBJECT_MAPPER);
64
65 ObjectMapperWrapper objectMapperWrapper = new ObjectMapperWrapper();
66
67 if (objectMapperPropertyInstance != null) {
68 if (objectMapperPropertyInstance instanceof ObjectMapperSupplier) {
69 ObjectMapperSupplier objectMapperSupplier = (ObjectMapperSupplier) objectMapperPropertyInstance;
70 if (objectMapperSupplier != null) {
71 objectMapperWrapper = new ObjectMapperWrapper(objectMapperSupplier);
72 }
73 } else if (objectMapperPropertyInstance instanceof Supplier) {
74 Supplier<ObjectMapper> objectMapperSupplier = (Supplier<ObjectMapper>) objectMapperPropertyInstance;
75 objectMapperWrapper = new ObjectMapperWrapper((ObjectMapperSupplier) () -> objectMapperSupplier.get());
76 } else if (objectMapperPropertyInstance instanceof ObjectMapper) {
77 ObjectMapper objectMapper = (ObjectMapper) objectMapperPropertyInstance;
78 objectMapperWrapper = new ObjectMapperWrapper(objectMapper);
79 }
80 }
81
82 Object jsonSerializerPropertyInstance = instantiateClass(PropertyKey.JSON_SERIALIZER);
83
84 if (jsonSerializerPropertyInstance != null) {
85 JsonSerializer jsonSerializer = null;
86
87 if (jsonSerializerPropertyInstance instanceof JsonSerializerSupplier) {
88 jsonSerializer = ((JsonSerializerSupplier) jsonSerializerPropertyInstance).get();
89 } else if (jsonSerializerPropertyInstance instanceof Supplier) {
90 Supplier<JsonSerializer> jsonSerializerSupplier = (Supplier<JsonSerializer>) jsonSerializerPropertyInstance;
91 jsonSerializer = jsonSerializerSupplier.get();
92 } else if (jsonSerializerPropertyInstance instanceof JsonSerializer) {
93 jsonSerializer = (JsonSerializer) jsonSerializerPropertyInstance;
94 }
95
96 if (jsonSerializer != null) {
97 objectMapperWrapper.setJsonSerializer(jsonSerializer);
98 }
99 }
100
101 this.objectMapperWrapper = objectMapperWrapper;
102 }
103
104
107 private void load() {
108 String[] propertiesFilePaths = new String[] {
109 APPLICATION_PROPERTIES_FILE_NAME,
110 PROPERTIES_FILE_NAME,
111 System.getProperty(PROPERTIES_FILE_NAME),
112
113 };
114
115 for (String propertiesFilePath : propertiesFilePaths) {
116 if (propertiesFilePath != null) {
117 InputStream propertiesInputStream = null;
118 try {
119 propertiesInputStream = propertiesInputStream(propertiesFilePath);
120 if (propertiesInputStream != null) {
121 properties.load(propertiesInputStream);
122 }
123 } catch (IOException e) {
124 LOGGER.error("Can't load properties", e);
125 } finally {
126 try {
127 if (propertiesInputStream != null) {
128 propertiesInputStream.close();
129 }
130 } catch (IOException e) {
131 LOGGER.error("Can't close the properties InputStream", e);
132 }
133 }
134 }
135 }
136 }
137
138
145 private InputStream propertiesInputStream(String propertiesFilePath) throws IOException {
146 if (propertiesFilePath != null) {
147 URL propertiesFileUrl;
148 try {
149 propertiesFileUrl = new URL(propertiesFilePath);
150 } catch (MalformedURLException ignore) {
151 propertiesFileUrl = ClassLoaderUtils.getResource(propertiesFilePath);
152 if (propertiesFileUrl == null) {
153 File f = new File(propertiesFilePath);
154 if (f.exists() && f.isFile()) {
155 try {
156 propertiesFileUrl = f.toURI().toURL();
157 } catch (MalformedURLException e) {
158 LOGGER.error(
159 "The property " + propertiesFilePath + " can't be resolved to either a URL, " +
160 "a classpath resource or a File"
161 );
162 }
163 }
164 }
165 }
166 if (propertiesFileUrl != null) {
167 return propertiesFileUrl.openStream();
168 }
169 }
170 return ClassLoaderUtils.getResourceAsStream(propertiesFilePath);
171 }
172
173
178 public Properties getProperties() {
179 return properties;
180 }
181
182
187 public ObjectMapperWrapper getObjectMapperWrapper() {
188 return objectMapperWrapper;
189 }
190
191
197 public Integer integerProperty(PropertyKey propertyKey) {
198 Integer value = null;
199 String property = properties.getProperty(propertyKey.getKey());
200 if (property != null) {
201 value = Integer.valueOf(property);
202 }
203 return value;
204 }
205
206
212 public Long longProperty(PropertyKey propertyKey) {
213 Long value = null;
214 String property = properties.getProperty(propertyKey.getKey());
215 if (property != null) {
216 value = Long.valueOf(property);
217 }
218 return value;
219 }
220
221
227 public Boolean booleanProperty(PropertyKey propertyKey) {
228 Boolean value = null;
229 String property = properties.getProperty(propertyKey.getKey());
230 if (property != null) {
231 value = Boolean.valueOf(property);
232 }
233 return value;
234 }
235
236
243 public <T> Class<T> classProperty(PropertyKey propertyKey) {
244 Class<T> clazz = null;
245 String property = properties.getProperty(propertyKey.getKey());
246 if (property != null) {
247 try {
248 return ClassLoaderUtils.loadClass(property);
249 } catch (ClassNotFoundException e) {
250 LOGGER.error("Couldn't load the " + property + " class given by the " + propertyKey + " property", e);
251 }
252 }
253 return clazz;
254 }
255
256
263 private <T> T instantiateClass(PropertyKey propertyKey) {
264 T object = null;
265 String property = properties.getProperty(propertyKey.getKey());
266 if (property != null) {
267 try {
268 Class<T> clazz = ClassLoaderUtils.loadClass(property);
269 LOGGER.debug("Instantiate {}", clazz);
270 object = clazz.newInstance();
271 } catch (ClassNotFoundException e) {
272 LOGGER.error("Couldn't load the " + property + " class given by the " + propertyKey + " property", e);
273 } catch (InstantiationException e) {
274 LOGGER.error("Couldn't instantiate the " + property + " class given by the " + propertyKey + " property", e);
275 } catch (IllegalAccessException e) {
276 LOGGER.error("Couldn't access the " + property + " class given by the " + propertyKey + " property", e);
277 }
278 }
279 return object;
280 }
281 }
282