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 ) {

http://dive4elements.wald.intevation.org