comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/Recommendations.java @ 3468:f37e7e8907cb

merged flys-artifacts/2.8.1
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:39 +0200
parents 2b3c4abe034f
children cbd0fafcb26b
comparison
equal deleted inserted replaced
3387:5ffad8bde8ad 3468:f37e7e8907cb
1 package de.intevation.flys.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
24 import org.hibernate.jdbc.Work;
25
26 import de.intevation.artifacts.common.utils.Config;
27 import de.intevation.artifacts.common.utils.XMLUtils;
28 import de.intevation.artifacts.common.utils.StringUtils;
29
30 import de.intevation.flys.artifacts.FLYSArtifact;
31
32 import de.intevation.flys.backend.SessionHolder;
33
34 import de.intevation.artifactdatabase.data.StateData;
35
36 import de.intevation.flys.artifacts.datacage.templating.Builder;
37
38
39 /**
40 * Also accessible as Singleton with getInstance().
41 */
42 public class Recommendations
43 {
44 private static Logger log = Logger.getLogger(Recommendations.class);
45
46 private static final boolean DEVELOPMENT_MODE =
47 Boolean.getBoolean("flys.datacage.recommendations.development");
48
49 public static final String XPATH_TEMPLATE =
50 "/artifact-database/metadata/template/text()";
51
52 public static final String DEFAULT_TEMPLATE_PATH =
53 "${artifacts.config.dir}/meta-data.xml";
54
55 private static Recommendations INSTANCE;
56
57 public static class BuilderProvider
58 {
59 protected Builder builder;
60
61 public BuilderProvider() {
62 }
63
64 public BuilderProvider(Builder builder) {
65 this.builder = builder;
66 }
67
68 public Builder getBuilder() {
69 return builder;
70 }
71 } // class BuilderProvider
72
73 public static class FileBuilderProvider
74 extends BuilderProvider
75 {
76 protected File file;
77 protected long lastModified;
78
79 public FileBuilderProvider() {
80 }
81
82 public FileBuilderProvider(File file) {
83 this.file = file;
84 lastModified = Long.MIN_VALUE;
85 }
86
87 @Override
88 public synchronized Builder getBuilder() {
89 long modified = file.lastModified();
90 if (modified > lastModified) {
91 lastModified = modified;
92 try {
93 Document template = loadTemplate(file);
94 builder = new Builder(template);
95 }
96 catch (IOException ioe) {
97 log.error(ioe);
98 }
99 }
100 return builder;
101 }
102
103 public BuilderProvider toStaticProvider() {
104 return new BuilderProvider(builder);
105 }
106 } // class BuilderProvider
107
108 protected BuilderProvider builderProvider;
109
110 public Recommendations() {
111 }
112
113 public Recommendations(BuilderProvider builderProvider) {
114 this.builderProvider = builderProvider;
115 }
116
117 public Builder getBuilder() {
118 return builderProvider.getBuilder();
119 }
120
121 protected static void artifactToParameters(
122 FLYSArtifact artifact,
123 Map<String, Object> parameters
124 ) {
125 parameters.put("CURRENT-STATE-ID", artifact.getCurrentStateId());
126 parameters.put("ARTIFACT-ID", artifact.identifier());
127
128 for (StateData sd: artifact.getAllData()) {
129 Object value = sd.getValue();
130 if (value == null) {
131 continue;
132 }
133 String key = sd.getName().replace('.', '-').toUpperCase();
134 parameters.put(key, value);
135 }
136 }
137
138 public static void convertKeysToUpperCase(
139 Map<String, Object> src,
140 Map<String, Object> dst
141 ) {
142 for (Map.Entry<String, Object> entry: src.entrySet()) {
143 dst.put(entry.getKey().toUpperCase(), entry.getValue());
144 }
145 }
146
147
148 /**
149 * Append recommendations to \param result.
150 */
151 public void recommend(
152 FLYSArtifact artifact,
153 String userId,
154 String [] outs,
155 Map<String, Object> extraParameters,
156 Node result
157 ) {
158 Map<String, Object> parameters = new HashMap<String, Object>();
159
160 if (extraParameters != null) {
161 convertKeysToUpperCase(extraParameters, parameters);
162 }
163
164 if (userId != null) {
165 parameters.put("USER-ID", userId);
166 }
167
168 if (artifact != null) {
169 artifactToParameters(artifact, parameters);
170 }
171
172 parameters.put("ARTIFACT-OUTS", StringUtils.toUpperCase(outs));
173
174 parameters.put("PARAMETERS", parameters);
175
176 recommend(parameters, userId, result);
177 }
178
179
180 /**
181 * Append recommendations to \param result.
182 */
183 public void recommend(
184 Map<String, Object> parameters,
185 String userId,
186 Node result
187 ) {
188 recommend(parameters, userId, result, SessionHolder.HOLDER.get());
189 }
190
191 public void recommend(
192 final Map<String, Object> parameters,
193 final String userId,
194 final Node result,
195 Session session
196 ) {
197 session.doWork(new Work() {
198 @Override
199 public void execute(Connection systemConnection)
200 throws SQLException
201 {
202 List<Builder.NamedConnection> connections =
203 new ArrayList<Builder.NamedConnection>(2);
204
205 Connection userConnection = userId != null
206 ? DBConfig
207 .getInstance()
208 .getDBConnection()
209 .getDataSource()
210 .getConnection()
211 : null;
212
213 try {
214 if (userConnection != null) {
215 connections.add(new Builder.NamedConnection(
216 Builder.CONNECTION_USER, userConnection, false));
217 }
218
219 connections.add(new Builder.NamedConnection(
220 Builder.CONNECTION_SYSTEM, systemConnection, true));
221
222 getBuilder().build(connections, result, parameters);
223 }
224 finally {
225 if (userConnection != null) {
226 userConnection.close();
227 }
228 }
229 }
230 });
231 }
232
233
234 /** Get singleton instance. */
235 public static synchronized Recommendations getInstance() {
236 if (INSTANCE == null) {
237 INSTANCE = createRecommendations();
238 }
239 return INSTANCE;
240 }
241
242
243 protected static Document loadTemplate(File file) throws IOException {
244 InputStream in = null;
245
246 try {
247 in = new FileInputStream(file);
248
249 Document template = XMLUtils.parseDocument(in);
250
251 if (template == null) {
252 throw new IOException("cannot load template");
253 }
254 return template;
255 }
256 finally {
257 if (in != null) {
258 try {
259 in.close();
260 }
261 catch (IOException ioe) {
262 log.error(ioe);
263 }
264 }
265 }
266 }
267
268 public static Recommendations createRecommendations(File file) {
269 log.debug("Recommendations.createBuilder");
270
271 if (!file.isFile() || !file.canRead()) {
272 log.error("Cannot open template file '" + file + "'");
273 return null;
274 }
275
276 FileBuilderProvider fbp = new FileBuilderProvider(file);
277
278 if (fbp.getBuilder() == null) {
279 log.error("failed loading builder");
280 return null;
281 }
282
283 BuilderProvider bp = DEVELOPMENT_MODE
284 ? fbp
285 : fbp.toStaticProvider();
286
287 return new Recommendations(bp);
288 }
289
290 protected static Recommendations createRecommendations() {
291 log.debug("Recommendations.createRecommendations");
292
293 String path = Config.getStringXPath(XPATH_TEMPLATE);
294
295 if (path == null) {
296 path = DEFAULT_TEMPLATE_PATH;
297 }
298
299 path = Config.replaceConfigDir(path);
300
301 log.info("Meta data template: " + path);
302
303 return createRecommendations(new File(path));
304 }
305 }
306 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org