Mercurial > dive4elements > river
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 : |