1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.jdbc.delegate;
25
26 import java.sql.DriverPropertyInfo;
27 import java.sql.SQLException;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.HashMap;
31 import java.util.HashSet;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Properties;
36 import java.util.Set;
37
38 import javax.jcr.RepositoryException;
39 import javax.jcr.Value;
40 import javax.jcr.nodetype.NodeDefinition;
41 import javax.jcr.nodetype.NodeType;
42 import javax.jcr.nodetype.NodeTypeIterator;
43 import javax.jcr.nodetype.PropertyDefinition;
44 import javax.jcr.query.QueryResult;
45
46 import org.modeshape.jdbc.JcrDriver;
47 import org.modeshape.jdbc.JdbcI18n;
48 import org.modeshape.jdbc.JcrDriver.JcrContextFactory;
49 import org.modeshape.web.jcr.rest.client.domain.QueryRow;
50 import org.modeshape.web.jcr.rest.client.domain.Server;
51 import org.modeshape.web.jcr.rest.client.domain.Workspace;
52 import org.modeshape.web.jcr.rest.client.json.JsonRestClient;
53
54
55
56
57
58 public class HttpRepositoryDelegate extends AbstractRepositoryDelegate {
59 private static final String HTTP_EXAMPLE_URL = JcrDriver.HTTP_URL_PREFIX + "{hostname}:{port}/{context root}";
60
61 private static final String URL_PATH = "/jcr:system/jcr:nodeTypes";
62 private static final String URL_DEPTH = "?depth=5";
63
64 private JsonRestClient restClient;
65 private Workspace workspace = null;
66 private Map<String, NodeType> nodeTypes;
67
68 public HttpRepositoryDelegate(String url, Properties info, JcrContextFactory contextFactory) {
69 super(url, info);
70 }
71
72 @Override
73 protected ConnectionInfo createConnectionInfo(String url, Properties info) {
74 return new HttpConnectionInfo(url, info);
75 }
76
77 @Override
78 public QueryResult execute(String query, String language) throws RepositoryException {
79 LOGGER.trace("Executing query: {0}" + query );
80
81 try {
82 List<QueryRow> results = this.restClient.query(workspace, language, query);
83 Iterator<QueryRow> resultsIt = results.iterator();
84 while (resultsIt.hasNext()) {
85 final QueryRow row = resultsIt.next();
86
87 }
88
89 } catch (Exception e) {
90 }
91
92 return null;
93 }
94
95
96
97
98
99
100 @Override
101 public String getDescriptor(String descriptorKey) {
102 return "";
103 }
104
105 @Override
106 public synchronized NodeType nodeType( String name ) throws RepositoryException {
107 if (nodeTypes == null) nodeTypes();
108
109 NodeType nodetype = nodeTypes.get(name);
110 if (nodetype == null) {
111 throw new RepositoryException(JdbcI18n.unableToGetNodeType.text(name));
112 }
113
114 return nodetype;
115 }
116
117 @Override
118 public synchronized List<NodeType> nodeTypes() throws RepositoryException {
119 if (nodeTypes == null) {
120 Collection<org.modeshape.web.jcr.rest.client.domain.NodeType> results;
121 try {
122 results = this.restClient.getNodeTypes(workspace, URL_PATH, URL_DEPTH);
123 if (results == null || results.size() == 0) {
124 String msg = JdbcI18n.noNodeTypesReturned.text(this.workspace.getServer().getUrl() + "/" +
125 this.workspace.getRepository().getName() + "/" +
126 this.workspace.getName() +
127 URL_PATH + URL_DEPTH);
128 throw new RepositoryException(msg);
129 }
130 Map<String, NodeType> loadingNodeTypes = new HashMap<String, NodeType>(results.size());
131 Iterator<org.modeshape.web.jcr.rest.client.domain.NodeType> resultsIt = results.iterator();
132 while (resultsIt.hasNext()) {
133 org.modeshape.web.jcr.rest.client.domain.NodeType nodetype = resultsIt.next();
134 if (nodetype != null) {
135
136 HttpNodeType localnodetype = new HttpNodeType(nodetype);
137
138 loadingNodeTypes.put(localnodetype.getName(), localnodetype);
139 }
140
141 }
142 this.nodeTypes = loadingNodeTypes;
143
144 } catch (Exception e) {
145 throw new RepositoryException(JdbcI18n.unableToGetNodeTypes.text(this.workspace.getRepository().getName()), e);
146 }
147 }
148
149 return new ArrayList<NodeType>(nodeTypes.values());
150 }
151
152 @Override
153 protected void createRepository() throws SQLException {
154 LOGGER.debug("Creating repository for HttpRepositoryDelegte" );
155
156 ConnectionInfo info = getConnectionInfo();
157 assert info != null;
158
159 String path = info.getRepositoryPath();
160 if (path == null) {
161 throw new SQLException("Missing repo path from " +info.getUrl());
162 }
163 if (info.getUsername() == null) {
164 throw new SQLException("Missing username from " +info.getUrl());
165 }
166 if (info.getPassword() == null) {
167 throw new SQLException("Missing password path from " +info.getUrl());
168 }
169 if (info.getRepositoryName() == null) {
170 throw new SQLException("Missing repo name from " +info.getUrl());
171 }
172 Server server = new Server("http://" + path, info.getUsername(), new String(info.getPassword()));
173 org.modeshape.web.jcr.rest.client.domain.Repository repo = new org.modeshape.web.jcr.rest.client.domain.Repository(info.getRepositoryName(), server);
174 workspace = new Workspace(info.getWorkspaceName(), repo);
175
176 restClient = new JsonRestClient();
177
178
179 try {
180 restClient.getRepositories(server ) ;
181 } catch (Exception e) {
182 throw new SQLException(JdbcI18n.noRepositoryNamesFound.text(), e);
183 }
184
185 Set<String> repositoryNames = new HashSet<String>(1);
186 repositoryNames.add(info.getRepositoryName());
187
188 this.setRepositoryNames(repositoryNames);
189
190 }
191
192
193
194
195
196 @Override
197 public boolean isValid( final int timeout ) throws RepositoryException {
198 return false;
199 }
200
201
202
203
204
205
206 @Override
207 public void commit() throws RepositoryException {
208 }
209
210
211
212
213
214
215 @Override
216 public void rollback() throws RepositoryException {
217 }
218
219
220
221
222
223
224 @Override
225 public void close() {
226 restClient = null;
227 workspace = null;
228 if (nodeTypes != null) nodeTypes.clear();
229 }
230
231 class HttpConnectionInfo extends ConnectionInfo {
232
233
234
235
236 protected HttpConnectionInfo(String url, Properties properties) {
237 super(url, properties);
238
239 }
240
241 @Override
242 protected void init() {
243
244
245
246
247 super.init();
248
249
250
251
252
253 StringBuilder url = new StringBuilder();
254 String[] urlsections = repositoryPath.split("/");
255
256 if (urlsections.length < 3) {
257 return;
258 }
259
260
261
262
263
264 int workspacePos = -1;
265 int repositoryPos = -1;
266 int repoPos = 1;
267 if (this.getWorkspaceName() == null && urlsections.length > 3) {
268 workspacePos = urlsections.length -1;
269 String workspaceName = urlsections[workspacePos];
270 this.setWorkspaceName(workspaceName);
271
272 repoPos = 2;
273
274 }
275 if (this.getRepositoryName() == null && urlsections.length > 2) {
276 repositoryPos = urlsections.length - repoPos;
277 String repositoryName = urlsections[repositoryPos];
278 this.setRepositoryName(repositoryName);
279 }
280
281
282
283 for (int i = 0; i < repositoryPos; i++) {
284 url.append(urlsections[i]);
285 if (i < repositoryPos -1) {
286 url.append("/");
287 }
288 }
289
290 this.repositoryPath = url.toString();
291
292 }
293
294 @Override
295 public String getUrlExample() {
296 return HTTP_EXAMPLE_URL;
297 }
298
299 @Override
300 public String getUrlPrefix() {
301 return JcrDriver.HTTP_URL_PREFIX;
302 }
303
304 @Override
305 protected void addUrlPropertyInfo(List<DriverPropertyInfo> results) {
306
307
308
309 if (repositoryPath.indexOf("/") == -1) {
310 setUrl(null);
311 }
312 super.addUrlPropertyInfo(results);
313 }
314
315 }
316
317
318
319 protected class HttpNodeType implements javax.jcr.nodetype.NodeType {
320 private org.modeshape.web.jcr.rest.client.domain.NodeType restnodetype;
321
322 public HttpNodeType(org.modeshape.web.jcr.rest.client.domain.NodeType nodetype) {
323 assert nodetype != null;
324 restnodetype = nodetype;
325 }
326
327 public void setNodeType(org.modeshape.web.jcr.rest.client.domain.NodeType nodetype) {
328 restnodetype = nodetype;
329 }
330
331 public org.modeshape.web.jcr.rest.client.domain.NodeType getNodeType() {
332 return restnodetype;
333 }
334
335 public boolean hasProperties() {
336 return (restnodetype.getProperties().size() > 0 ? true : false);
337 }
338
339 @Override
340 public String getName() {
341 return restnodetype.getName();
342 }
343
344 @Override
345 public String getPrimaryItemName() {
346 return restnodetype.getProperty("jcr:primaryItemName");
347 }
348
349 @Override
350 public boolean isMixin() {
351 return convertBoolean("jcr:isMixin");
352 }
353
354 @Override
355 public boolean isQueryable() {
356 return convertBoolean("jcr:isQueryable");
357 }
358
359
360
361
362
363
364 @Override
365 public boolean canAddChildNode(String arg0) {
366 return false;
367 }
368
369
370
371
372
373
374 @Override
375 public boolean canAddChildNode(String arg0, String arg1) {
376 return false;
377 }
378
379
380
381
382
383
384 @Override
385 public boolean canRemoveItem(String arg0) {
386 return false;
387 }
388
389
390
391
392
393
394 @Override
395 public boolean canRemoveNode(String arg0) {
396 return false;
397 }
398
399
400
401
402
403
404 @Override
405 public boolean canRemoveProperty(String arg0) {
406 return false;
407 }
408
409
410
411
412
413
414 @Override
415 public boolean canSetProperty(String arg0, Value arg1) {
416 return false;
417 }
418
419
420
421
422
423
424 @Override
425 public boolean canSetProperty(String arg0, Value[] arg1) {
426 return false;
427 }
428
429
430
431
432
433
434 @Override
435 public NodeDefinition[] getChildNodeDefinitions() {
436 return null;
437 }
438
439
440
441
442
443
444 @Override
445 public NodeTypeIterator getDeclaredSubtypes() {
446 return null;
447 }
448
449
450
451
452
453
454 @Override
455 public javax.jcr.nodetype.NodeType[] getDeclaredSupertypes() {
456 return null;
457 }
458
459
460
461
462
463
464 @Override
465 public NodeTypeIterator getSubtypes() {
466 return null;
467 }
468
469
470
471
472
473
474 @Override
475 public javax.jcr.nodetype.NodeType[] getSupertypes() {
476 return null;
477 }
478
479
480
481
482
483
484 @Override
485 public boolean isNodeType(String arg0) {
486 String value = restnodetype.getProperty("jcr:nodeTypeName");
487 return (value != null && arg0.equals(value));
488
489 }
490
491
492
493
494
495
496 @Override
497 public NodeDefinition[] getDeclaredChildNodeDefinitions() {
498 return null;
499 }
500
501
502
503
504
505
506 @Override
507 public PropertyDefinition[] getDeclaredPropertyDefinitions() {
508 return null;
509 }
510
511
512
513
514
515
516 @Override
517 public String[] getDeclaredSupertypeNames() {
518
519
520 return null;
521 }
522
523
524
525
526
527
528 @Override
529 public boolean hasOrderableChildNodes() {
530 return convertBoolean("jcr:hasOrderableChildNodes");
531 }
532
533
534
535
536
537
538 @Override
539 public boolean isAbstract() {
540 return convertBoolean("jcr:isAbstract");
541 }
542
543
544
545
546
547
548 @Override
549 public PropertyDefinition[] getPropertyDefinitions() {
550 PropertyDefinition[] defns = null;
551 int cnt = restnodetype.getPropertyDefinitions().size() + restnodetype.getChildNodeDefinitions().size();
552 defns = new PropertyDefinition[cnt];
553 int i = 0;
554 if (restnodetype.getPropertyDefinitions() != null) {
555 for (Iterator<org.modeshape.web.jcr.rest.client.domain.NodeType> it=restnodetype.getPropertyDefinitions().iterator(); it.hasNext();){
556 org.modeshape.web.jcr.rest.client.domain.NodeType nt = it.next();
557 HttpPropertyDefinition propDefn = new HttpPropertyDefinition(nt.getName(), nt.getProperties()) ;
558 defns[i] = propDefn;
559 i++;
560 }
561 }
562
563 if (restnodetype.getChildNodeDefinitions() != null) {
564 for (Iterator<org.modeshape.web.jcr.rest.client.domain.NodeType> it=restnodetype.getChildNodeDefinitions().iterator(); it.hasNext();){
565 org.modeshape.web.jcr.rest.client.domain.NodeType nt = it.next();
566 HttpPropertyDefinition propDefn = new HttpPropertyDefinition(nt.getName(), nt.getProperties()) ;
567 defns[i] = propDefn;
568 i++;
569 }
570 }
571 return defns;
572 }
573
574
575 private boolean convertBoolean(String key ) {
576 String value = restnodetype.getProperty(key);
577 if (value == null || value.equalsIgnoreCase("false")) return false;
578 return true;
579 }
580 }
581
582 protected class HttpPropertyDefinition implements PropertyDefinition {
583 private Properties properties = null;
584 private String name;
585
586 public HttpPropertyDefinition(String name, Properties nodeTypeProperties) {
587 this.properties = nodeTypeProperties;
588 this.name = name;
589 }
590
591
592
593
594
595
596
597 @Override
598 public String[] getAvailableQueryOperators() {
599 return null;
600 }
601
602
603
604
605
606
607 @Override
608 public Value[] getDefaultValues() {
609 return null;
610 }
611
612
613
614
615
616
617 @Override
618 public int getRequiredType() {
619 return 0;
620
621
622 }
623
624
625
626
627
628
629 @Override
630 public String[] getValueConstraints() {
631 return null;
632 }
633
634
635
636
637
638
639 @Override
640 public boolean isFullTextSearchable() {
641 return false;
642 }
643
644
645
646
647
648
649 @Override
650 public boolean isMultiple() {
651 return false;
652 }
653
654
655
656
657
658
659 @Override
660 public boolean isQueryOrderable() {
661 return true;
662
663 }
664
665
666
667
668
669
670 @Override
671 public NodeType getDeclaringNodeType() {
672 return null;
673 }
674
675
676
677
678
679
680 @Override
681 public String getName() {
682 return name;
683 }
684
685
686
687
688
689
690 @Override
691 public int getOnParentVersion() {
692 return 0;
693 }
694
695
696
697
698
699
700 @Override
701 public boolean isAutoCreated() {
702 return convertBoolean("jcr:autoCreated");
703 }
704
705
706
707
708
709
710 @Override
711 public boolean isMandatory() {
712 return convertBoolean("jcr:mandatory");
713 }
714
715
716
717
718
719
720 @Override
721 public boolean isProtected() {
722 return convertBoolean("jcr:protected");
723 }
724
725
726 private boolean convertBoolean(String key ) {
727 String value = properties.getProperty(key);
728 if (value == null || value.equalsIgnoreCase("false")) return false;
729 return true;
730 }
731
732 }
733
734 }