1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.treetank.service.jaxrx.implementation;
29
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import java.util.Map;
34
35 import javax.ws.rs.core.StreamingOutput;
36
37 import org.jaxrx.core.JaxRxException;
38 import org.jaxrx.core.QueryParameter;
39 import org.treetank.access.NodeReadTrx;
40 import org.treetank.access.NodeWriteTrx;
41 import org.treetank.access.NodeWriteTrx.HashKind;
42 import org.treetank.access.conf.SessionConfiguration;
43 import org.treetank.access.conf.StandardSettings;
44 import org.treetank.api.IStorage;
45 import org.treetank.api.INodeReadTrx;
46 import org.treetank.api.INodeWriteTrx;
47 import org.treetank.api.ISession;
48 import org.treetank.exception.TTException;
49 import org.treetank.node.interfaces.IStructNode;
50 import org.treetank.service.jaxrx.enums.EIdAccessType;
51 import org.treetank.service.jaxrx.util.RestXPathProcessor;
52 import org.treetank.service.jaxrx.util.WorkerHelper;
53 import org.treetank.service.xml.serialize.XMLSerializer;
54 import org.treetank.service.xml.serialize.XMLSerializer.XMLSerializerBuilder;
55 import org.treetank.service.xml.serialize.XMLSerializerProperties;
56 import org.treetank.service.xml.shredder.EShredderInsert;
57
58
59
60
61
62
63
64
65
66
67 public class NodeIdRepresentation {
68
69
70
71
72 private static final transient byte[] BEGINRESULT = "<jaxrx:result xmlns:jaxrx=\"http://jaxrx.org/\">"
73 .getBytes();
74
75
76
77
78 private static final transient byte[] ENDRESULT = "</jaxrx:result>".getBytes();
79
80 private static final transient String NOTFOUND = "Node id not found";
81
82
83
84
85 private static final transient String YESSTRING = "yes";
86
87
88
89
90 private final IStorage mDatabase;
91
92
93
94
95
96
97
98
99 public NodeIdRepresentation(final IStorage pDatabase) {
100 mDatabase = pDatabase;
101 }
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 public StreamingOutput getResource(final String resourceName, final long nodeId,
118 final Map<QueryParameter, String> queryParams) throws JaxRxException {
119 final StreamingOutput sOutput = new StreamingOutput() {
120 @Override
121 public void write(final OutputStream output) throws IOException, JaxRxException {
122
123
124 final String revision = queryParams.get(QueryParameter.REVISION);
125 final String wrap = queryParams.get(QueryParameter.WRAP);
126 final String doNodeId = queryParams.get(QueryParameter.OUTPUT);
127 final boolean wrapResult = (wrap == null) ? false : wrap.equalsIgnoreCase(YESSTRING);
128 final boolean nodeid = (doNodeId == null) ? false : doNodeId.equalsIgnoreCase(YESSTRING);
129 final Long rev = revision == null ? null : Long.valueOf(revision);
130 serialize(resourceName, nodeId, rev, nodeid, output, wrapResult);
131 }
132 };
133
134 return sOutput;
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154 public StreamingOutput getResourceByAT(final String resourceName, final long nodeId,
155 final Map<QueryParameter, String> queryParams, final EIdAccessType accessType) throws JaxRxException {
156 final StreamingOutput sOutput = new StreamingOutput() {
157 @Override
158 public void write(final OutputStream output) throws IOException, JaxRxException {
159
160
161 final String revision = queryParams.get(QueryParameter.REVISION);
162 final String wrap = queryParams.get(QueryParameter.WRAP);
163 final String doNodeId = queryParams.get(QueryParameter.OUTPUT);
164 final boolean wrapResult = (wrap == null) ? false : wrap.equalsIgnoreCase(YESSTRING);
165 final boolean nodeid = (doNodeId == null) ? false : doNodeId.equalsIgnoreCase(YESSTRING);
166 final Long rev = revision == null ? null : Long.valueOf(revision);
167 serializeAT(resourceName, nodeId, rev, nodeid, output, wrapResult, accessType);
168 }
169 };
170
171 return sOutput;
172 }
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188 public StreamingOutput performQueryOnResource(final String resourceName, final long nodeId,
189 final String query, final Map<QueryParameter, String> queryParams) {
190
191 final StreamingOutput sOutput = new StreamingOutput() {
192 @Override
193 public void write(final OutputStream output) throws IOException, JaxRxException {
194
195 final String revision = queryParams.get(QueryParameter.REVISION);
196 final String wrap = queryParams.get(QueryParameter.WRAP);
197 final String doNodeId = queryParams.get(QueryParameter.OUTPUT);
198 final boolean wrapResult = (wrap == null) ? true : wrap.equalsIgnoreCase(YESSTRING);
199 final boolean nodeid = (doNodeId == null) ? false : doNodeId.equalsIgnoreCase(YESSTRING);
200 final Long rev = revision == null ? null : Long.valueOf(revision);
201 final RestXPathProcessor xpathProcessor = new RestXPathProcessor(mDatabase);
202 try {
203 xpathProcessor.getXpathResource(resourceName, nodeId, query, nodeid, rev, output,
204 wrapResult);
205 } catch (final TTException exce) {
206 throw new JaxRxException(exce);
207 }
208 }
209 };
210
211 return sOutput;
212 }
213
214
215
216
217
218
219
220
221
222
223
224
225 public void deleteResource(final String resourceName, final long nodeId) throws JaxRxException {
226 synchronized (resourceName) {
227 ISession session = null;
228 INodeWriteTrx wtx = null;
229 boolean abort = false;
230 if (mDatabase.existsResource(resourceName)) {
231 try {
232
233 session =
234 mDatabase.getSession(new SessionConfiguration(resourceName, StandardSettings.KEY));
235
236 wtx = new NodeWriteTrx(session, session.beginBucketWtx(), HashKind.Rolling);
237
238 if (wtx.moveTo(nodeId)) {
239 wtx.remove();
240 wtx.commit();
241 } else {
242
243 throw new JaxRxException(404, NOTFOUND);
244 }
245 } catch (final TTException exce) {
246 abort = true;
247 throw new JaxRxException(exce);
248 } finally {
249 try {
250 WorkerHelper.closeWTX(abort, wtx, session);
251 } catch (final TTException exce) {
252 throw new JaxRxException(exce);
253 }
254 }
255 } else {
256 throw new JaxRxException(404, "DB not found");
257 }
258 }
259 }
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274 public void modifyResource(final String resourceName, final long nodeId, final InputStream newValue)
275 throws JaxRxException {
276 synchronized (resourceName) {
277 ISession session = null;
278 INodeWriteTrx wtx = null;
279 boolean abort = false;
280 if (mDatabase.existsResource(resourceName)) {
281 try {
282
283 session =
284 mDatabase.getSession(new SessionConfiguration(resourceName, StandardSettings.KEY));
285
286 wtx = new NodeWriteTrx(session, session.beginBucketWtx(), HashKind.Rolling);
287
288 if (wtx.moveTo(nodeId)) {
289 final long parentKey = wtx.getNode().getParentKey();
290 wtx.remove();
291 wtx.moveTo(parentKey);
292 WorkerHelper.shredInputStream(wtx, newValue, EShredderInsert.ADDASFIRSTCHILD);
293
294 } else {
295
296 throw new JaxRxException(404, NOTFOUND);
297 }
298
299 } catch (final TTException exc) {
300 abort = true;
301 throw new JaxRxException(exc);
302 } finally {
303 try {
304 WorkerHelper.closeWTX(abort, wtx, session);
305 } catch (final TTException exce) {
306 throw new JaxRxException(exce);
307 }
308 }
309 } else {
310 throw new JaxRxException(404, "Requested resource not found");
311 }
312 }
313 }
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332 public void addSubResource(final String resourceName, final long nodeId, final InputStream input,
333 final EIdAccessType type) throws JaxRxException {
334 ISession session = null;
335 INodeWriteTrx wtx = null;
336 synchronized (resourceName) {
337 boolean abort;
338 if (mDatabase.existsResource(resourceName)) {
339 abort = false;
340 try {
341
342 session =
343 mDatabase.getSession(new SessionConfiguration(resourceName, StandardSettings.KEY));
344
345 wtx = new NodeWriteTrx(session, session.beginBucketWtx(), HashKind.Rolling);
346 final boolean exist = wtx.moveTo(nodeId);
347 if (exist) {
348 if (type == EIdAccessType.FIRSTCHILD) {
349 WorkerHelper.shredInputStream(wtx, input, EShredderInsert.ADDASFIRSTCHILD);
350 } else if (type == EIdAccessType.RIGHTSIBLING) {
351 WorkerHelper.shredInputStream(wtx, input, EShredderInsert.ADDASRIGHTSIBLING);
352 } else if (type == EIdAccessType.LASTCHILD) {
353 if (wtx.moveTo(((IStructNode)wtx.getNode()).getFirstChildKey())) {
354 long last = wtx.getNode().getDataKey();
355 while (wtx.moveTo(((IStructNode)wtx.getNode()).getRightSiblingKey())) {
356 last = wtx.getNode().getDataKey();
357 }
358 wtx.moveTo(last);
359 WorkerHelper.shredInputStream(wtx, input, EShredderInsert.ADDASRIGHTSIBLING);
360
361 } else {
362 throw new JaxRxException(404, NOTFOUND);
363 }
364
365 } else if (type == EIdAccessType.LEFTSIBLING
366 && wtx.moveTo(((IStructNode)wtx.getNode()).getLeftSiblingKey())) {
367
368 WorkerHelper.shredInputStream(wtx, input, EShredderInsert.ADDASRIGHTSIBLING);
369
370 }
371 } else {
372 throw new JaxRxException(404, NOTFOUND);
373 }
374 } catch (final JaxRxException exce) {
375 abort = true;
376 throw exce;
377 } catch (final Exception exce) {
378 abort = true;
379 throw new JaxRxException(exce);
380 } finally {
381 try {
382 WorkerHelper.closeWTX(abort, wtx, session);
383 } catch (final TTException exce) {
384 throw new JaxRxException(exce);
385 }
386 }
387 }
388 }
389 }
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409 private void serialize(final String resource, final long nodeId, final Long revision,
410 final boolean doNodeId, final OutputStream output, final boolean wrapResult) {
411 if (mDatabase.existsResource(resource)) {
412 ISession session = null;
413 try {
414 session = mDatabase.getSession(new SessionConfiguration(resource, StandardSettings.KEY));
415 if (wrapResult) {
416 output.write(BEGINRESULT);
417 final XMLSerializerProperties props = new XMLSerializerProperties();
418 final XMLSerializerBuilder builder =
419 new XMLSerializerBuilder(session, nodeId, output, props);
420 builder.setREST(doNodeId);
421 builder.setID(doNodeId);
422 builder.setDeclaration(false);
423 final XMLSerializer serializer = builder.build();
424 serializer.call();
425 output.write(ENDRESULT);
426 } else {
427 final XMLSerializerProperties props = new XMLSerializerProperties();
428 final XMLSerializerBuilder builder =
429 new XMLSerializerBuilder(session, nodeId, output, props);
430 builder.setREST(doNodeId);
431 builder.setID(doNodeId);
432 builder.setDeclaration(false);
433 final XMLSerializer serializer = builder.build();
434 serializer.call();
435
436 }
437 } catch (final TTException ttExcep) {
438 throw new JaxRxException(ttExcep);
439 } catch (final IOException ioExcep) {
440 throw new JaxRxException(ioExcep);
441 } catch (final Exception globExcep) {
442 if (globExcep instanceof JaxRxException) {
443
444
445
446
447 throw (JaxRxException)globExcep;
448 } else {
449 throw new JaxRxException(globExcep);
450 }
451 } finally {
452 try {
453 WorkerHelper.closeRTX(null, session);
454 } catch (final TTException exce) {
455 throw new JaxRxException(exce);
456 }
457 }
458
459 } else {
460 throw new JaxRxException(404, "Resource does not exist");
461 }
462
463 }
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486 private void serializeAT(final String resource, final long nodeId, final Long revision,
487 final boolean doNodeId, final OutputStream output, final boolean wrapResult,
488 final EIdAccessType accessType) {
489 if (mDatabase.existsResource(resource)) {
490 ISession session = null;
491 INodeReadTrx rtx = null;
492 try {
493 session = mDatabase.getSession(new SessionConfiguration(resource, StandardSettings.KEY));
494 if (revision == null) {
495 rtx = new NodeReadTrx(session.beginBucketRtx(session.getMostRecentVersion()));
496 } else {
497 rtx = new NodeReadTrx(session.beginBucketRtx(revision));
498 }
499
500 if (rtx.moveTo(nodeId)) {
501
502 switch (accessType) {
503 case FIRSTCHILD:
504 if (!rtx.moveTo(((IStructNode)rtx.getNode()).getFirstChildKey()))
505 throw new JaxRxException(404, NOTFOUND);
506 break;
507 case LASTCHILD:
508 if (rtx.moveTo(((IStructNode)rtx.getNode()).getFirstChildKey())) {
509 long last = rtx.getNode().getDataKey();
510 while (rtx.moveTo(((IStructNode)rtx.getNode()).getRightSiblingKey())) {
511 last = rtx.getNode().getDataKey();
512 }
513 rtx.moveTo(last);
514 } else {
515 throw new JaxRxException(404, NOTFOUND);
516 }
517 break;
518 case RIGHTSIBLING:
519 if (!rtx.moveTo(((IStructNode)rtx.getNode()).getRightSiblingKey()))
520 throw new JaxRxException(404, NOTFOUND);
521 break;
522 case LEFTSIBLING:
523 if (!rtx.moveTo(((IStructNode)rtx.getNode()).getLeftSiblingKey()))
524 throw new JaxRxException(404, NOTFOUND);
525 break;
526 default:
527 }
528 if (wrapResult) {
529 output.write(BEGINRESULT);
530 final XMLSerializerProperties props = new XMLSerializerProperties();
531 final XMLSerializerBuilder builder =
532 new XMLSerializerBuilder(session, rtx.getNode().getDataKey(), output, props);
533 builder.setREST(doNodeId);
534 builder.setID(doNodeId);
535 builder.setDeclaration(false);
536 builder.setIndend(false);
537 final XMLSerializer serializer = builder.build();
538 serializer.call();
539
540 output.write(ENDRESULT);
541 } else {
542 final XMLSerializerProperties props = new XMLSerializerProperties();
543 final XMLSerializerBuilder builder =
544 new XMLSerializerBuilder(session, rtx.getNode().getDataKey(), output, props);
545 builder.setREST(doNodeId);
546 builder.setID(doNodeId);
547 builder.setDeclaration(false);
548 builder.setIndend(false);
549 final XMLSerializer serializer = builder.build();
550 serializer.call();
551 }
552 } else {
553 throw new JaxRxException(404, NOTFOUND);
554 }
555 } catch (final TTException ttExcep) {
556 throw new JaxRxException(ttExcep);
557 } catch (final IOException ioExcep) {
558 throw new JaxRxException(ioExcep);
559 } catch (final Exception globExcep) {
560 if (globExcep instanceof JaxRxException) {
561
562
563
564
565 throw (JaxRxException)globExcep;
566 } else {
567 throw new JaxRxException(globExcep);
568 }
569 } finally {
570 try {
571 WorkerHelper.closeRTX(rtx, session);
572 } catch (final TTException exce) {
573 throw new JaxRxException(exce);
574 }
575 }
576
577 } else {
578 throw new JaxRxException(404, "Resource does not exist");
579 }
580
581 }
582 }