Mercurial > dive4elements > framework
comparison artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java @ 92:73d0ebae81d7
Last bunch of javadoc
artifacts/trunk@848 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Sun, 28 Mar 2010 14:16:05 +0000 |
parents | b2e0cb83631c |
children | 5332d956729c |
comparison
equal
deleted
inserted
replaced
91:730ff077a58c | 92:73d0ebae81d7 |
---|---|
32 | 32 |
33 import org.w3c.dom.Document; | 33 import org.w3c.dom.Document; |
34 import org.w3c.dom.Element; | 34 import org.w3c.dom.Element; |
35 | 35 |
36 /** | 36 /** |
37 * The core implementation of artifact database. This layer exposes | |
38 * the needed methods to the artifact runtime system which e.g. may | |
39 * expose them via REST. The concrete persistent representation of the | |
40 * artifacts is handled by the {@link Backend backend}. | |
37 * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> | 41 * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> |
38 */ | 42 */ |
39 public class ArtifactDatabaseImpl | 43 public class ArtifactDatabaseImpl |
40 implements ArtifactDatabase, Id.Filter, Backend.FactoryLookup | 44 implements ArtifactDatabase, Id.Filter, Backend.FactoryLookup |
41 { | 45 { |
42 private static Logger logger = | 46 private static Logger logger = |
43 Logger.getLogger(ArtifactDatabaseImpl.class); | 47 Logger.getLogger(ArtifactDatabaseImpl.class); |
44 | 48 |
49 /** | |
50 * Error message issued if a requested artifact factory | |
51 * is not registered to this database. | |
52 */ | |
45 public static final String NO_SUCH_FACTORY = | 53 public static final String NO_SUCH_FACTORY = |
46 "No such factory"; | 54 "No such factory"; |
47 | 55 |
56 /** | |
57 * Error message issued if a requested artifact is not found | |
58 * in this database. | |
59 */ | |
48 public static final String NO_SUCH_ARTIFACT = | 60 public static final String NO_SUCH_ARTIFACT = |
49 "No such artifact"; | 61 "No such artifact"; |
50 | 62 |
63 /** | |
64 * Error message issued if one tries to remove a requested artifact | |
65 * from the list of artifacts running in background which is | |
66 * not in this list. | |
67 */ | |
51 public static final String NOT_IN_BACKGROUND = | 68 public static final String NOT_IN_BACKGROUND = |
52 "Not in background"; | 69 "Not in background"; |
53 | 70 |
71 /** | |
72 * Error message issued if an artifact wants to translate itself | |
73 * into a none valid persistent state. | |
74 */ | |
54 public static final String INVALID_CALL_STATE = | 75 public static final String INVALID_CALL_STATE = |
55 "Invalid after call state"; | 76 "Invalid after call state"; |
56 | 77 |
78 /** | |
79 * Error message issued if the creation of an artifact failed. | |
80 */ | |
57 public static final String CREATION_FAILED = | 81 public static final String CREATION_FAILED = |
58 "Creation of artifact failed"; | 82 "Creation of artifact failed"; |
59 | 83 |
84 /** | |
85 * Error message if an severe internal error occurred. | |
86 */ | |
60 public static final String INTERNAL_ERROR = | 87 public static final String INTERNAL_ERROR = |
61 "Creation of artifact failed"; | 88 "Creation of artifact failed"; |
62 | 89 |
90 /** | |
91 * Error message issued if a requested service is not | |
92 * offered by this database. | |
93 */ | |
63 public static final String NO_SUCH_SERVICE = | 94 public static final String NO_SUCH_SERVICE = |
64 "No such service"; | 95 "No such service"; |
65 | 96 |
97 /** | |
98 * Default digest hash to be used while im-/exporting artifacts. | |
99 */ | |
66 public static final String DIGEST_ALGORITHM = | 100 public static final String DIGEST_ALGORITHM = |
67 "SHA-1"; | 101 "SHA-1"; |
68 | 102 |
103 /** | |
104 * XPath to get the checksum from an XML representation of | |
105 * an exported artifact. | |
106 */ | |
69 public static final String XPATH_IMPORT_CHECKSUM = | 107 public static final String XPATH_IMPORT_CHECKSUM = |
70 "/art:action/art:data/@checksum"; | 108 "/art:action/art:data/@checksum"; |
71 | 109 |
110 /** | |
111 * XPath to get the name of the factory which should be | |
112 * used to revive an antrifact that is going to be imported. | |
113 */ | |
72 public static final String XPATH_IMPORT_FACTORY = | 114 public static final String XPATH_IMPORT_FACTORY = |
73 "/art:action/art:data/@factory"; | 115 "/art:action/art:data/@factory"; |
74 | 116 |
117 /** | |
118 * XPath to get the base64 encoded data of an artifact | |
119 * that is going to be imported. | |
120 */ | |
75 public static final String XPATH_IMPORT_DATA = | 121 public static final String XPATH_IMPORT_DATA = |
76 "/art:action/art:data/text()"; | 122 "/art:action/art:data/text()"; |
77 | 123 |
124 /** | |
125 * Error message issued if the checksum of an | |
126 * artifact to be imported has an invalid syntax. | |
127 */ | |
78 public static final String INVALID_CHECKSUM = | 128 public static final String INVALID_CHECKSUM = |
79 "Invalid checksum"; | 129 "Invalid checksum"; |
80 | 130 |
131 /** | |
132 * Error message issued the checksum validation | |
133 * of an artifact to be imported fails. | |
134 */ | |
81 public static final String CHECKSUM_MISMATCH = | 135 public static final String CHECKSUM_MISMATCH = |
82 "Mismatching checksum"; | 136 "Mismatching checksum"; |
83 | 137 |
138 /** | |
139 * Error message issued if an artifact to be imported | |
140 * does not have any data. | |
141 */ | |
84 public static final String NO_DATA = | 142 public static final String NO_DATA = |
85 "No data"; | 143 "No data"; |
86 | 144 |
145 /** | |
146 * Error message issued if the deserialization of | |
147 * an artifact to be imported fails. | |
148 */ | |
87 public static final String INVALID_ARTIFACT = | 149 public static final String INVALID_ARTIFACT = |
88 "Invalid artifact"; | 150 "Invalid artifact"; |
89 | 151 |
152 /** | |
153 * Inner class that implements the call context handed | |
154 * to the methods calls describe(), feed(), etc. of the artifact. | |
155 */ | |
90 public class CallContextImpl | 156 public class CallContextImpl |
91 implements CallContext | 157 implements CallContext |
92 { | 158 { |
159 /** | |
160 * The persistence wrapper around the living artifact | |
161 */ | |
93 protected PersistentArtifact artifact; | 162 protected PersistentArtifact artifact; |
163 /** | |
164 * The action to be performed after the artifact calls | |
165 * desribe(), feed(), etc. return. | |
166 */ | |
94 protected int action; | 167 protected int action; |
168 /** | |
169 * The meta information of the concrete call | |
170 * (preferred languages et. al.) | |
171 */ | |
95 protected CallMeta callMeta; | 172 protected CallMeta callMeta; |
173 /** | |
174 * Map to act like a clipboard when nesting calls | |
175 * like a proxy artifact. | |
176 */ | |
96 protected HashMap customValues; | 177 protected HashMap customValues; |
97 | 178 |
179 /** | |
180 * Constructor to create a call context with a given | |
181 * persistent artifact, a default action and meta informations. | |
182 * @param artifact The persistent wrapper around a living artifact. | |
183 * @param action The action to be performed after the concrete | |
184 * artifact call has returned. | |
185 * @param callMeta The meta information for this call context. | |
186 */ | |
98 public CallContextImpl( | 187 public CallContextImpl( |
99 PersistentArtifact artifact, | 188 PersistentArtifact artifact, |
100 int action, | 189 int action, |
101 CallMeta callMeta | 190 CallMeta callMeta |
102 ) { | 191 ) { |
133 | 222 |
134 public Long getTimeToLive() { | 223 public Long getTimeToLive() { |
135 return artifact.getTTL(); | 224 return artifact.getTTL(); |
136 } | 225 } |
137 | 226 |
227 /** | |
228 * Dispatches and executes the persistence action after | |
229 * the return of the concrete artifact call. | |
230 */ | |
138 public void postCall() { | 231 public void postCall() { |
139 switch (action) { | 232 switch (action) { |
140 case NOTHING: | 233 case NOTHING: |
141 break; | 234 break; |
142 case TOUCH: | 235 case TOUCH: |
167 } | 260 } |
168 return customValues.put(key, value); | 261 return customValues.put(key, value); |
169 } | 262 } |
170 } // class CallContextImpl | 263 } // class CallContextImpl |
171 | 264 |
265 /** | |
266 * This inner class allows the deferral of writing the output | |
267 * of the artifact's out() call. | |
268 */ | |
172 public class DeferredOutputImpl | 269 public class DeferredOutputImpl |
173 implements DeferredOutput | 270 implements DeferredOutput |
174 { | 271 { |
272 /** | |
273 * The persistence wrapper around a living artifact. | |
274 */ | |
175 protected PersistentArtifact artifact; | 275 protected PersistentArtifact artifact; |
276 /** | |
277 * The input document for the artifact's out() call. | |
278 */ | |
176 protected Document format; | 279 protected Document format; |
280 /** | |
281 * The meta information of the artifact's out() call. | |
282 */ | |
177 protected CallMeta callMeta; | 283 protected CallMeta callMeta; |
178 | 284 |
285 /** | |
286 * Default constructor. | |
287 */ | |
179 public DeferredOutputImpl() { | 288 public DeferredOutputImpl() { |
180 } | 289 } |
181 | 290 |
291 /** | |
292 * Constructor to create a deferred execution unit for | |
293 * the artifact's out() call given an artifact, an input document | |
294 * an the meta information. | |
295 * @param artifact The persistence wrapper around a living artifact. | |
296 * @param format The input document for the artifact's out() call. | |
297 * @param callMeta The meta information of the artifact's out() call. | |
298 */ | |
182 public DeferredOutputImpl( | 299 public DeferredOutputImpl( |
183 PersistentArtifact artifact, | 300 PersistentArtifact artifact, |
184 Document format, | 301 Document format, |
185 CallMeta callMeta | 302 CallMeta callMeta |
186 ) { | 303 ) { |
201 cc.postCall(); | 318 cc.postCall(); |
202 } | 319 } |
203 } | 320 } |
204 } // class DeferredOutputImpl | 321 } // class DeferredOutputImpl |
205 | 322 |
323 /** | |
324 * List of name/description pairs needed for | |
325 * {@link #artifactFactoryNamesAndDescriptions() }. | |
326 */ | |
206 protected String [][] factoryNamesAndDescription; | 327 protected String [][] factoryNamesAndDescription; |
328 /** | |
329 * Map to access artifact factories by there name. | |
330 */ | |
207 protected HashMap name2factory; | 331 protected HashMap name2factory; |
208 | 332 |
333 /** | |
334 * List of name/description pairs needed for | |
335 * {@link #serviceNamesAndDescriptions() }. | |
336 */ | |
209 protected String [][] serviceNamesAndDescription; | 337 protected String [][] serviceNamesAndDescription; |
338 /** | |
339 * Map to access services by there name. | |
340 */ | |
210 protected HashMap name2service; | 341 protected HashMap name2service; |
211 | 342 |
343 /** | |
344 * Reference to the storage backend. | |
345 */ | |
212 protected Backend backend; | 346 protected Backend backend; |
347 /** | |
348 * Reference of the global context of the artifact runtime system. | |
349 */ | |
213 protected Object context; | 350 protected Object context; |
214 | 351 |
352 /** | |
353 * The signing secret to be used for ex-/importing artifacts. | |
354 */ | |
215 protected byte [] exportSecret; | 355 protected byte [] exportSecret; |
216 | 356 |
357 /** | |
358 * A set of ids of artifact which currently running in background. | |
359 * This artifacts should not be removed from the database by the | |
360 * database cleaner. | |
361 */ | |
217 protected HashSet backgroundIds; | 362 protected HashSet backgroundIds; |
218 | 363 |
364 /** | |
365 * Default constructor. | |
366 */ | |
219 public ArtifactDatabaseImpl() { | 367 public ArtifactDatabaseImpl() { |
220 } | 368 } |
221 | 369 |
370 /** | |
371 * Constructor to create a artifact database with the given | |
372 * bootstrap parameters like artifact- and service factories et. al. | |
373 * Created this way the artifact database has no backend. | |
374 * @param bootstrap The parameters to start this artifact database. | |
375 */ | |
222 public ArtifactDatabaseImpl(FactoryBootstrap bootstrap) { | 376 public ArtifactDatabaseImpl(FactoryBootstrap bootstrap) { |
223 this(bootstrap, null); | 377 this(bootstrap, null); |
224 } | 378 } |
225 | 379 |
380 /** | |
381 * Constructor to create a artifact database with the a given | |
382 * backend and | |
383 * bootstrap parameters like artifact- and service factories et. al. | |
384 * @param bootstrap The parameters to start this artifact database. | |
385 * @param backend The storage backend. | |
386 */ | |
226 public ArtifactDatabaseImpl(FactoryBootstrap bootstrap, Backend backend) { | 387 public ArtifactDatabaseImpl(FactoryBootstrap bootstrap, Backend backend) { |
227 | 388 |
228 backgroundIds = new HashSet(); | 389 backgroundIds = new HashSet(); |
229 | 390 |
230 setupArtifactFactories(bootstrap); | 391 setupArtifactFactories(bootstrap); |
234 exportSecret = bootstrap.getExportSecret(); | 395 exportSecret = bootstrap.getExportSecret(); |
235 | 396 |
236 wireWithBackend(backend); | 397 wireWithBackend(backend); |
237 } | 398 } |
238 | 399 |
400 /** | |
401 * Used to extract the artifact factories from the bootstrap | |
402 * parameters and building the internal lookup tables. | |
403 * @param bootstrap The bootstrap parameters. | |
404 */ | |
239 protected void setupArtifactFactories(FactoryBootstrap bootstrap) { | 405 protected void setupArtifactFactories(FactoryBootstrap bootstrap) { |
240 name2factory = new HashMap(); | 406 name2factory = new HashMap(); |
241 | 407 |
242 ArtifactFactory [] factories = bootstrap.getArtifactFactories(); | 408 ArtifactFactory [] factories = bootstrap.getArtifactFactories(); |
243 factoryNamesAndDescription = new String[factories.length][]; | 409 factoryNamesAndDescription = new String[factories.length][]; |
254 | 420 |
255 name2factory.put(name, factory); | 421 name2factory.put(name, factory); |
256 } | 422 } |
257 } | 423 } |
258 | 424 |
425 /** | |
426 * Used to extract the service factories from the bootstrap | |
427 * parameters, setting up the services and building the internal | |
428 * lookup tables. | |
429 * @param bootstrap The bootstrap parameters. | |
430 */ | |
259 protected void setupServices(FactoryBootstrap bootstrap) { | 431 protected void setupServices(FactoryBootstrap bootstrap) { |
260 | 432 |
261 name2service = new HashMap(); | 433 name2service = new HashMap(); |
262 | 434 |
263 ServiceFactory [] serviceFactories = | 435 ServiceFactory [] serviceFactories = |
280 factory.createService(bootstrap.getContext())); | 452 factory.createService(bootstrap.getContext())); |
281 } | 453 } |
282 | 454 |
283 } | 455 } |
284 | 456 |
457 /** | |
458 * Wires a storage backend to this artifact database and | |
459 * establishes a callback to be able to revive artifacts | |
460 * via the serializers of this artifact factories. | |
461 * @param backend The backend to be wired with this artifact database. | |
462 */ | |
285 public void wireWithBackend(Backend backend) { | 463 public void wireWithBackend(Backend backend) { |
286 if (backend != null) { | 464 if (backend != null) { |
287 this.backend = backend; | 465 this.backend = backend; |
288 backend.setFactoryLookup(this); | 466 backend.setFactoryLookup(this); |
289 } | 467 } |
290 } | 468 } |
291 | 469 |
470 /** | |
471 * Called after an backgrounded artifact signals its | |
472 * will to be written back to the backend. | |
473 * @param artifact The persistence wrapper around | |
474 * the backgrounded artifact. | |
475 * @param action The action to be performed. | |
476 */ | |
292 protected void fromBackground(PersistentArtifact artifact, int action) { | 477 protected void fromBackground(PersistentArtifact artifact, int action) { |
293 logger.warn("BACKGROUND processing is not fully implemented, yet!"); | 478 logger.warn("BACKGROUND processing is not fully implemented, yet!"); |
294 switch (action) { | 479 switch (action) { |
295 case CallContext.NOTHING: | 480 case CallContext.NOTHING: |
296 break; | 481 break; |
304 logger.warn("operation not allowed in fromBackground"); | 489 logger.warn("operation not allowed in fromBackground"); |
305 } | 490 } |
306 removeIdFromBackground(artifact.getId()); | 491 removeIdFromBackground(artifact.getId()); |
307 } | 492 } |
308 | 493 |
494 /** | |
495 * Removes an artifact's database id from the set of backgrounded | |
496 * artifacts. The database cleaner is now able to remove it safely | |
497 * from the database again. | |
498 * @param id The database id of the artifact. | |
499 */ | |
309 protected void removeIdFromBackground(int id) { | 500 protected void removeIdFromBackground(int id) { |
310 synchronized (backgroundIds) { | 501 synchronized (backgroundIds) { |
311 backgroundIds.remove(Integer.valueOf(id)); | 502 backgroundIds.remove(Integer.valueOf(id)); |
312 } | 503 } |
313 } | 504 } |
314 | 505 |
506 /** | |
507 * Adds an artifact's database id to the set of artifacts | |
508 * running in backgroound. To be in this set prevents the | |
509 * artifact to be removed from the database by the database cleaner. | |
510 * @param id The database id of the artifact to be protected | |
511 * from being removed from the database. | |
512 */ | |
315 protected void addIdToBackground(int id) { | 513 protected void addIdToBackground(int id) { |
316 synchronized (backgroundIds) { | 514 synchronized (backgroundIds) { |
317 backgroundIds.add(Integer.valueOf(id)); | 515 backgroundIds.add(Integer.valueOf(id)); |
318 } | 516 } |
319 } | 517 } |
322 int N = ids.size(); | 520 int N = ids.size(); |
323 ArrayList out = new ArrayList(N); | 521 ArrayList out = new ArrayList(N); |
324 synchronized (backgroundIds) { | 522 synchronized (backgroundIds) { |
325 for (int i = 0; i < N; ++i) { | 523 for (int i = 0; i < N; ++i) { |
326 Id id = (Id)ids.get(i); | 524 Id id = (Id)ids.get(i); |
525 // only delete artifact if its not in background. | |
327 if (!backgroundIds.contains(Integer.valueOf(id.getId()))) { | 526 if (!backgroundIds.contains(Integer.valueOf(id.getId()))) { |
328 out.add(id); | 527 out.add(id); |
329 } | 528 } |
330 } | 529 } |
331 } | 530 } |
499 factoryName[0], | 698 factoryName[0], |
500 bytes, | 699 bytes, |
501 exportSecret); | 700 exportSecret); |
502 } | 701 } |
503 | 702 |
703 /** | |
704 * Creates an exteral XML representation of an artifact. | |
705 * @param factoryName The name of the factory which is responsible | |
706 * for the serialized artifact. | |
707 * @param artifact The byte data of the artifact itself. | |
708 * @param secret The signing secret. | |
709 * @return An XML document containing the external representation | |
710 * of the artifact. | |
711 */ | |
504 protected static Document createExportDocument( | 712 protected static Document createExportDocument( |
505 String factoryName, | 713 String factoryName, |
506 byte [] artifact, | 714 byte [] artifact, |
507 byte [] secret | 715 byte [] secret |
508 ) { | 716 ) { |