comparison flys-artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/Recommendations.java @ 5831:bd047b71ab37

Repaired internal references
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 12:06:39 +0200
parents flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/Recommendations.java@ebec12def170
children
comparison
equal deleted inserted replaced
5830:160f53ee0870 5831:bd047b71ab37
1 package org.dive4elements.river.artifacts.datacage;
2
3 import java.util.Map;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.ArrayList;
7
8 import java.io.InputStream;
9 import java.io.IOException;
10 import java.io.File;
11
12 import java.io.FileInputStream;
13
14 import java.sql.Connection;
15 import java.sql.SQLException;
16
17 import org.apache.log4j.Logger;
18
19 import org.w3c.dom.Document;
20 import org.w3c.dom.Node;
21
22 import org.hibernate.Session;
23 import org.hibernate.SessionFactory;
24
25 import org.hibernate.jdbc.Work;
26
27 import org.dive4elements.artifacts.common.utils.Config;
28 import org.dive4elements.artifacts.common.utils.XMLUtils;
29 import org.dive4elements.artifacts.common.utils.StringUtils;
30
31 import org.dive4elements.river.artifacts.FLYSArtifact;
32
33 import org.dive4elements.river.backend.SessionFactoryProvider;
34 import org.dive4elements.river.backend.SessionHolder;
35
36 import org.dive4elements.artifactdatabase.data.StateData;
37
38 import org.dive4elements.river.artifacts.datacage.templating.Builder;
39 import org.dive4elements.river.artifacts.datacage.templating.BuilderPool;
40
41
42 /**
43 * Also accessible as Singleton with getInstance().
44 */
45 public class Recommendations
46 {
47 public static final String CONNECTION_USER = "user";
48 public static final String CONNECTION_SYSTEM = "system";
49 public static final String CONNECTION_SEDDB = "seddb";
50
51 public static final String DEFAULT_CONNECTION_NAME = CONNECTION_SYSTEM;
52
53 private static Logger log = Logger.getLogger(Recommendations.class);
54
55 private static final boolean DEVELOPMENT_MODE =
56 Boolean.getBoolean("flys.datacage.recommendations.development");
57
58 public static final String XPATH_TEMPLATE =
59 "/artifact-database/metadata/template/text()";
60
61 public static final String DEFAULT_TEMPLATE_PATH =
62 "${artifacts.config.dir}/meta-data.xml";
63
64 private static Recommendations INSTANCE;
65
66 public static class BuilderPoolProvider
67 {
68 protected BuilderPool builderPool;
69
70 public BuilderPoolProvider() {
71 }
72
73 public BuilderPoolProvider(BuilderPool builderPool) {
74 this.builderPool = builderPool;
75 }
76
77 public BuilderPool getBuilderPool() {
78 return builderPool;
79 }
80 } // class BuilderProvider
81
82 public static class FileBuilderPoolProvider
83 extends BuilderPoolProvider
84 {
85 protected File file;
86 protected long lastModified;
87
88 public FileBuilderPoolProvider() {
89 }
90
91 public FileBuilderPoolProvider(File file) {
92 this.file = file;
93 lastModified = Long.MIN_VALUE;
94 }
95
96 @Override
97 public synchronized BuilderPool getBuilderPool() {
98 long modified = file.lastModified();
99 if (modified > lastModified) {
100 lastModified = modified;
101 try {
102 Document template = loadTemplate(file);
103 builderPool = new BuilderPool(template);
104 }
105 catch (IOException ioe) {
106 log.error(ioe);
107 }
108 }
109 return builderPool;
110 }
111
112 public BuilderPoolProvider toStaticProvider() {
113 return new BuilderPoolProvider(builderPool);
114 }
115 } // class BuilderProvider
116
117 protected BuilderPoolProvider builderPoolProvider;
118
119 public Recommendations() {
120 }
121
122 public Recommendations(BuilderPoolProvider builderPoolProvider) {
123 this.builderPoolProvider = builderPoolProvider;
124 }
125
126 public BuilderPool getBuilderPool() {
127 return builderPoolProvider.getBuilderPool();
128 }
129
130 protected static void artifactToParameters(
131 FLYSArtifact artifact,
132 Map<String, Object> parameters
133 ) {
134 parameters.put("CURRENT-STATE-ID", artifact.getCurrentStateId());
135 parameters.put("ARTIFACT-ID", artifact.identifier());
136
137 for (StateData sd: artifact.getAllData()) {
138 Object value = sd.getValue();
139 if (value == null) {
140 continue;
141 }
142 String key = sd.getName().replace('.', '-').toUpperCase();
143 parameters.put(key, value);
144 }
145 }
146
147 /**
148 * Put Key/Values from \param src to \param dst, but uppercase
149 * both Keys and Values.
150 */
151 public static void convertKeysToUpperCase(
152 Map<String, Object> src,
153 Map<String, Object> dst
154 ) {
155 for (Map.Entry<String, Object> entry: src.entrySet()) {
156 dst.put(entry.getKey().toUpperCase(), entry.getValue());
157 }
158 }
159
160
161 /**
162 * Append recommendations to \param result.
163 * @param extraParameters parameters (typicall example: 'recommended')
164 */
165 public void recommend(
166 FLYSArtifact artifact,
167 String userId,
168 String [] outs,
169 Map<String, Object> extraParameters,
170 Node result
171 ) {
172 Map<String, Object> parameters = new HashMap<String, Object>();
173
174 if (extraParameters != null) {
175 convertKeysToUpperCase(extraParameters, parameters);
176 }
177
178 if (userId != null) {
179 parameters.put("USER-ID", userId);
180 }
181
182 if (artifact != null) {
183 artifactToParameters(artifact, parameters);
184 }
185
186 parameters.put("ARTIFACT-OUTS", StringUtils.toUpperCase(outs));
187
188 parameters.put("PARAMETERS", parameters);
189
190 recommend(parameters, userId, result);
191 }
192
193
194 /**
195 * Append recommendations to \param result.
196 */
197 public void recommend(
198 Map<String, Object> parameters,
199 String userId,
200 Node result
201 ) {
202 recommend(parameters, userId, result, SessionHolder.HOLDER.get());
203 }
204
205 public void recommend(
206 final Map<String, Object> parameters,
207 final String userId,
208 final Node result,
209 Session systemSession
210 ) {
211 systemSession.doWork(new Work() {
212 @Override
213 public void execute(final Connection systemConnection)
214 throws SQLException
215 {
216 SessionFactory sedDBFactory =
217 SessionFactoryProvider.getSedDBSessionFactory();
218
219 Session sedDBSession = sedDBFactory.openSession();
220 try {
221 sedDBSession.doWork(new Work() {
222 @Override
223 public void execute(Connection sedDBConnection)
224 throws SQLException
225 {
226 recommend(
227 parameters, userId, result,
228 systemConnection,
229 sedDBConnection);
230 }
231 });
232 }
233 finally {
234 sedDBSession.close();
235 }
236 }
237 });
238 }
239
240 public void recommend(
241 Map<String, Object> parameters,
242 String userId,
243 Node result,
244 Connection systemConnection,
245 Connection seddbConnection
246 ) throws SQLException
247 {
248 List<Builder.NamedConnection> connections =
249 new ArrayList<Builder.NamedConnection>(3);
250
251 Connection userConnection = userId != null
252 ? DBConfig
253 .getInstance()
254 .getDBConnection()
255 .getDataSource()
256 .getConnection()
257 : null;
258
259 try {
260 connections.add(new Builder.NamedConnection(
261 CONNECTION_SYSTEM, systemConnection, true));
262
263 if (seddbConnection != null) {
264 connections.add(new Builder.NamedConnection(
265 CONNECTION_SEDDB, seddbConnection, true));
266 }
267
268 if (userConnection != null) {
269 connections.add(new Builder.NamedConnection(
270 CONNECTION_USER, userConnection, false));
271 }
272
273 getBuilderPool().build(connections, result, parameters);
274 }
275 finally {
276 if (userConnection != null) {
277 userConnection.close();
278 }
279 }
280 }
281
282 /** Get singleton instance. */
283 public static synchronized Recommendations getInstance() {
284 if (INSTANCE == null) {
285 INSTANCE = createRecommendations();
286 }
287 return INSTANCE;
288 }
289
290
291 protected static Document loadTemplate(File file) throws IOException {
292 InputStream in = new FileInputStream(file);
293
294 try {
295 Document template = XMLUtils.parseDocument(in);
296 if (template == null) {
297 throw new IOException("cannot load template");
298 }
299 return template;
300 }
301 finally {
302 in.close();
303 }
304 }
305
306 public static Recommendations createRecommendations(File file) {
307 log.debug("Recommendations.createBuilder");
308
309 if (!file.isFile() || !file.canRead()) {
310 log.error("Cannot open template file '" + file + "'");
311 return null;
312 }
313
314 FileBuilderPoolProvider fbp = new FileBuilderPoolProvider(file);
315
316 if (fbp.getBuilderPool() == null) {
317 log.error("failed loading builder");
318 return null;
319 }
320
321 BuilderPoolProvider bp = DEVELOPMENT_MODE
322 ? fbp
323 : fbp.toStaticProvider();
324
325 return new Recommendations(bp);
326 }
327
328 protected static Recommendations createRecommendations() {
329 log.debug("Recommendations.createRecommendations");
330
331 String path = Config.getStringXPath(XPATH_TEMPLATE);
332
333 if (path == null) {
334 path = DEFAULT_TEMPLATE_PATH;
335 }
336
337 path = Config.replaceConfigDir(path);
338
339 log.info("Meta data template: " + path);
340
341 return createRecommendations(new File(path));
342 }
343 }
344 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org