1
2
3
4
5
6
7
8
9
10
11
12
13 package org.abstracthorizon.danube.webdav.java;
14
15 import org.abstracthorizon.danube.beanconsole.BeanAccessException;
16 import org.abstracthorizon.danube.beanconsole.BeanDef;
17 import org.abstracthorizon.danube.beanconsole.BeanHelper;
18 import org.abstracthorizon.danube.http.Status;
19 import org.abstracthorizon.danube.http.util.IOUtils;
20 import org.abstracthorizon.danube.webdav.ResourceAdapter;
21 import org.abstracthorizon.danube.webdav.lock.LockingMechanism;
22 import org.abstracthorizon.danube.webdav.lock.impl.SimpleInMemoryLockingMechanism;
23 import org.abstracthorizon.danube.webdav.util.NamespacesProvider;
24 import org.abstracthorizon.danube.webdav.util.SimpleNamespacesProvider;
25 import org.abstracthorizon.danube.webdav.xml.dav.DAVNamespace;
26 import org.abstracthorizon.danube.webdav.xml.dav.request.properties.RequestProperty;
27 import org.abstracthorizon.danube.webdav.xml.dav.response.properties.DisplayName;
28 import org.abstracthorizon.danube.webdav.xml.dav.response.properties.GetContentLength;
29 import org.abstracthorizon.danube.webdav.xml.dav.response.properties.GetContentType;
30 import org.abstracthorizon.danube.webdav.xml.dav.response.properties.GetETag;
31 import org.abstracthorizon.danube.webdav.xml.dav.response.properties.LockDiscovery;
32 import org.abstracthorizon.danube.webdav.xml.dav.response.properties.ResourceType;
33 import org.abstracthorizon.danube.webdav.xml.dav.response.properties.ResponseProperty;
34 import org.abstracthorizon.danube.webdav.xml.dav.response.properties.SupportedLock;
35
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.io.OutputStream;
39 import java.util.ArrayList;
40 import java.util.HashMap;
41 import java.util.Map;
42 import java.util.Set;
43
44
45
46
47
48
49
50
51
52 public class JavaWebDAVResourceAdapter implements ResourceAdapter {
53
54
55 protected Object rootObject;
56
57
58 protected static ResponseProperty[] filePropertyNames = new ResponseProperty[]{
59 new DisplayName(Status.OK),
60 new GetContentLength(Status.OK),
61 new GetContentType(Status.OK),
62 new GetETag(Status.OK),
63 new LockDiscovery(Status.OK),
64 new ResourceType(Status.OK),
65 new SupportedLock(Status.OK)
66 };
67
68
69 protected static ResponseProperty[] dirPropertyNames = new ResponseProperty[]{
70 new DisplayName(Status.OK),
71 new GetETag(Status.OK),
72 new LockDiscovery(Status.OK),
73 new ResourceType(Status.OK),
74 new SupportedLock(Status.OK)
75 };
76
77
78 protected static RequestProperty[] fileRequestProperties = new RequestProperty[]{
79 new org.abstracthorizon.danube.webdav.xml.dav.request.properties.DisplayName(null),
80 new org.abstracthorizon.danube.webdav.java.properties.GetContentLength(null),
81 new org.abstracthorizon.danube.webdav.java.properties.GetContentType(null),
82 new org.abstracthorizon.danube.webdav.xml.dav.request.properties.GetETag(null),
83 new org.abstracthorizon.danube.webdav.xml.dav.request.properties.LockDiscovery(null),
84 new org.abstracthorizon.danube.webdav.xml.dav.request.properties.ResourceType(null),
85 new org.abstracthorizon.danube.webdav.xml.dav.request.properties.SupportedLock(null, null)
86 };
87
88
89 protected static RequestProperty[] dirRequestProperties = new RequestProperty[]{
90 new org.abstracthorizon.danube.webdav.xml.dav.request.properties.DisplayName(null),
91 new org.abstracthorizon.danube.webdav.xml.dav.request.properties.GetETag(null),
92 new org.abstracthorizon.danube.webdav.xml.dav.request.properties.LockDiscovery(null),
93 new org.abstracthorizon.danube.webdav.xml.dav.request.properties.ResourceType(null),
94 new org.abstracthorizon.danube.webdav.xml.dav.request.properties.SupportedLock(null, null)
95 };
96
97
98 protected NamespacesProvider namespacesProvider = new SimpleNamespacesProvider();
99
100
101 protected LockingMechanism lockingMechanism = new SimpleInMemoryLockingMechanism();
102
103
104 protected DAVNamespace davNamespace = new DAVNamespace();
105
106
107
108
109 public JavaWebDAVResourceAdapter() {
110 initHandlers();
111 }
112
113
114
115
116
117 public JavaWebDAVResourceAdapter(Object rootObject) {
118 setRootObject(rootObject);
119 initHandlers();
120 }
121
122
123
124
125 protected void initHandlers() {
126 davNamespace.setDAVFactory(new JavaDAVFactory());
127 namespacesProvider.addNamespace(davNamespace.getURLString(), davNamespace.getPreferredPrefix(), davNamespace);
128 }
129
130
131
132
133
134 public Object getRootObject() {
135 return rootObject;
136 }
137
138
139
140
141
142 public void setRootObject(Object root) {
143 this.rootObject = root;
144 }
145
146
147
148
149
150 public NamespacesProvider getNamespacesProvider() {
151 return namespacesProvider;
152 }
153
154
155
156
157
158 public void setNamespacesProvider(NamespacesProvider namespacesProvider) {
159 this.namespacesProvider = namespacesProvider;
160 }
161
162
163
164
165
166 public LockingMechanism getLockingMechanism() {
167 return lockingMechanism;
168 }
169
170
171
172
173
174 public void setLockingMechanism(LockingMechanism lockingMechanism) {
175 this.lockingMechanism = lockingMechanism;
176 }
177
178
179
180
181
182
183 public Object findResource(String resourcePath) {
184 String name = IOUtils.lastPathComponent(resourcePath);
185 int i = name.lastIndexOf('.');
186 if (!name.endsWith("]") && (i >= 0)) {
187
188 if (name.equals("object.type")) {
189 return new ObjectType(resourcePath);
190 } else if (name.equals("object.fields")) {
191 } else if (name.equals("object.methods")) {
192 } else if (name.equals("object.properties")) {
193 } else if (name.equals("object.as.collection")) {
194 } else if (name.equals("object.as.map")) {
195 } else if (name.endsWith(".field")) {
196 } else if (name.endsWith(".property")) {
197 return new Property(resourcePath);
198 } else if (name.endsWith(".invoke")) {
199 } else if (name.equals("index.html")) {
200 }
201 }
202 return new Bean(resourcePath);
203
204 }
205
206
207
208
209
210
211 protected Object findObjectImpl(Bean bean) {
212 String resourcePath = bean.getPath();
213
214
215
216
217
218 return findObjectImpl(resourcePath);
219 }
220
221
222
223
224
225
226 protected Object findObjectImpl(String resourcePath) {
227 Object current = getRootObject();
228 if (resourcePath.length() > 0) {
229 try {
230 current = BeanHelper.navigate(current, resourcePath);
231 } catch (BeanAccessException exception) {
232 return null;
233 }
234 }
235 return current;
236 }
237
238
239
240
241
242
243
244
245
246 public Object findParentResource(Object resource) {
247 String path = ((Bean)resource).getPath();
248 if ((path == null) || (path.length() == 0)) {
249 return null;
250 } else {
251 int i = path.lastIndexOf('/');
252 if (i >= 0) {
253 return findResource(path.substring(0, i));
254 } else {
255 return rootObject;
256 }
257 }
258 }
259
260
261
262
263
264 public long resourceLength(Object resource) {
265 if (resource instanceof Delegate) {
266 return ((Delegate)resource).resourceLength(this);
267 } else {
268 return -1;
269 }
270 }
271
272
273
274
275
276 public long resourceLastModified(Object resource) {
277 return -1;
278 }
279
280
281
282
283
284 public long resourceCreated(Object resource) {
285 return -1;
286 }
287
288
289
290
291
292 public String getResourceName(Object resource) {
293 return IOUtils.lastPathComponent(((Bean)resource).getPath());
294 }
295
296
297
298
299
300 public String getResourceETag(Object resource) {
301 if (resource instanceof Delegate) {
302 return ((Delegate)resource).getResourceETag(this);
303 } else {
304 Object object = findObjectImpl((Bean)resource);
305 if (object != null) {
306 String eTag = "W/\"" + Integer.toHexString(System.identityHashCode(object)) + "\"";
307 return eTag;
308 } else {
309 String path = ((Bean)resource).getPath();
310 return "W/\"" + path + "-NULL\"";
311 }
312 }
313 }
314
315
316
317
318
319 public boolean exists(Object resource) {
320 if (resource instanceof Delegate) {
321 return true;
322 } else {
323 return findObjectImpl((Bean)resource) != null;
324 }
325 }
326
327
328
329
330
331 public boolean isCollection(Object resource) {
332 if (resource instanceof Delegate) {
333 return false;
334 } else {
335 return findObjectImpl((Bean)resource) != null;
336 }
337 }
338
339
340
341
342
343
344 public void delete(Object resource) throws IOException {
345 }
346
347
348
349
350
351
352 public void makeCollection(Object resource) throws IOException {
353 }
354
355
356
357
358
359
360
361
362 public void copy(Object source, Object destination, boolean recursive) throws IOException {
363 }
364
365
366
367
368
369
370
371 public void move(Object source, Object destination) throws IOException {
372 }
373
374
375
376
377
378
379
380 @SuppressWarnings("unchecked")
381 public Object[] collectionElements(Object resource) {
382 if (resource instanceof Delegate) {
383 return null;
384 }
385 Bean bean = (Bean)resource;
386 Object object = findObjectImpl(bean);
387 if (object == null) {
388 return null;
389 } else {
390 Map<String, Object> result = new HashMap<String, Object>();
391 BeanHelper.prepare(object, result);
392 ArrayList<Bean> res = new ArrayList<Bean>();
393 Set<BeanDef> beans = (Set<BeanDef>)result.get("beans");
394 if (beans != null) {
395 for (BeanDef beanDef : beans) {
396 if (beanDef.isFollowable()) {
397 Bean b = new Bean(IOUtils.addPaths(bean.getPath(), "[" + beanDef.getName()) + "]");
398 res.add(b);
399 }
400 }
401 }
402 Set<BeanDef> map = (Set<BeanDef>)result.get("map");
403 if (map != null) {
404 for (BeanDef beanDef : map) {
405 if (beanDef.isFollowable()) {
406 Bean b = new Bean(IOUtils.addPaths(bean.getPath(), "[" + beanDef.getName()) + "]");
407 res.add(b);
408 }
409 }
410 }
411 Set<BeanDef> collection = (Set<BeanDef>)result.get("collection");
412 if (collection != null) {
413 int i = 0;
414 for (BeanDef beanDef : collection) {
415 if (beanDef.isFollowable()) {
416 Bean b = new Bean(IOUtils.addPaths(bean.getPath(), "[" + i + "]"));
417 res.add(b);
418 }
419 i = i + 1;
420 }
421 }
422 Set<BeanDef> props = (Set<BeanDef>)result.get("properties");
423 if (props != null) {
424 for (BeanDef beanDef : props) {
425 if (beanDef.isFollowable()) {
426 Bean b = new Bean(IOUtils.addPaths(bean.getPath(), beanDef.getName()));
427 res.add(b);
428 }
429 }
430 }
431 res.add(new ObjectType(IOUtils.addPaths(bean.getPath(), "/object.type")));
432 if (props != null) {
433 for (BeanDef beanDef : props) {
434 Property b = new Property(IOUtils.addPaths(bean.getPath(), beanDef.getName() + ".property"));
435 res.add(b);
436 }
437 }
438 res.add(new Bean(IOUtils.addPaths(bean.getPath(), "index.html")));
439
440 Bean[] r = new Bean[res.size()];
441 r = res.toArray(r);
442 return r;
443 }
444 }
445
446 public RequestProperty[] getDefaultRequestProperties(Object resource) {
447 if (isCollection(resource)) {
448 return dirRequestProperties;
449 } else {
450 return fileRequestProperties;
451 }
452 }
453
454 public ResponseProperty[] getDefaultResponseProperties(Object resource) {
455 if (isCollection(resource)) {
456 return dirPropertyNames;
457 } else {
458 return filePropertyNames;
459 }
460 }
461
462
463
464
465
466 public InputStream getInputStream(Object resource) {
467 if (resource instanceof Delegate) {
468 return ((Delegate)resource).getInputStream(this);
469 } else {
470 return null;
471 }
472 }
473
474
475
476
477
478
479
480 public InputStream getInpusStream(Object resource, long from, long length) {
481 if (resource instanceof Delegate) {
482 return ((Delegate)resource).getInputStream(this, from, length);
483 } else {
484 return null;
485 }
486 }
487
488
489
490
491
492 public OutputStream getOutputStream(Object resource) {
493 if (resource instanceof Delegate) {
494 return ((Delegate)resource).getOutputStream(this);
495 } else {
496 return null;
497 }
498 }
499
500
501
502
503
504
505
506 public OutputStream getOutputStream(Object resource, long from, long length) {
507 if (resource instanceof Delegate) {
508 return ((Delegate)resource).getOutputStream(this, from, length);
509 } else {
510 return null;
511 }
512 }
513
514
515
516
517
518 public String getContentType(Object resource) {
519 if (resource instanceof Delegate) {
520 return ((Delegate)resource).getContentType(this);
521 } else {
522 return "unknown/unknown";
523 }
524 }
525
526 }