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.example.sequencer;
25
26 import java.net.URL;
27 import java.util.ArrayList;
28 import java.util.Calendar;
29 import java.util.LinkedList;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Properties;
33 import java.util.TreeMap;
34 import java.util.concurrent.TimeUnit;
35 import javax.jcr.Binary;
36 import javax.jcr.Node;
37 import javax.jcr.NodeIterator;
38 import javax.jcr.PathNotFoundException;
39 import javax.jcr.Property;
40 import javax.jcr.PropertyIterator;
41 import javax.jcr.Repository;
42 import javax.jcr.RepositoryException;
43 import javax.jcr.Session;
44 import javax.jcr.Value;
45 import javax.jcr.ValueFormatException;
46 import org.modeshape.graph.connector.inmemory.InMemoryRepositorySource;
47 import org.modeshape.jcr.JcrConfiguration;
48 import org.modeshape.jcr.JcrEngine;
49 import org.modeshape.jcr.JcrTools;
50 import org.modeshape.jcr.api.SecurityContext;
51 import org.modeshape.jcr.api.SecurityContextCredentials;
52 import org.modeshape.repository.sequencer.SequencingService;
53 import org.modeshape.sequencer.classfile.ClassFileSequencer;
54 import org.modeshape.sequencer.classfile.ClassFileSequencerLexicon;
55
56
57
58
59 public class SequencingClient {
60
61 public static final String DEFAULT_REPOSITORY_NAME = "repo";
62 public static final String DEFAULT_WORKSPACE_NAME = "default";
63 public static final String DEFAULT_USERNAME = "jsmith";
64 public static final char[] DEFAULT_PASSWORD = "secret".toCharArray();
65
66 public static void main( String[] args ) {
67
68
69
70 String repositoryId = "content";
71 String workspaceName = "default";
72 JcrConfiguration config = new JcrConfiguration();
73
74 config.repositorySource("store")
75 .usingClass(InMemoryRepositorySource.class)
76 .setDescription("The repository for our content")
77 .setProperty("defaultWorkspaceName", workspaceName);
78
79 config.repository(repositoryId)
80 .addNodeTypes("sequencing.cnd")
81 .registerNamespace(ClassFileSequencerLexicon.Namespace.PREFIX, ClassFileSequencerLexicon.Namespace.URI)
82 .setSource("store");
83
84 config.sequencer("Image Sequencer")
85 .usingClass("org.modeshape.sequencer.image.ImageMetadataSequencer")
86 .loadedFromClasspath()
87 .setDescription("Sequences image files to extract the characteristics of the image")
88 .sequencingFrom("//(*.(jpg|jpeg|gif|bmp|pcx|png|iff|ras|pbm|pgm|ppm|psd)[*])/jcr:content[@jcr:data]")
89 .andOutputtingTo("/images/$1");
90
91 config.sequencer("MP3 Sequencer")
92 .usingClass("org.modeshape.sequencer.mp3.Mp3MetadataSequencer")
93 .loadedFromClasspath()
94 .setDescription("Sequences mp3 files to extract the id3 tags of the audio file")
95 .sequencingFrom("//(*.mp3[*])/jcr:content[@jcr:data]")
96 .andOutputtingTo("/mp3s/$1");
97
98 config.sequencer("Java Class Sequencer")
99 .usingClass(ClassFileSequencer.class)
100 .setDescription("Sequences Java class files to extract the structure of the classes")
101 .sequencingFrom("//*.class[*]/jcr:content[@jcr:data]")
102 .andOutputtingTo("/classes");
103
104 config.sequencer("Java Sequencer")
105 .usingClass("org.modeshape.sequencer.java.JavaMetadataSequencer")
106 .loadedFromClasspath()
107 .setDescription("Sequences Java files to extract the AST structure of the Java source code")
108 .sequencingFrom("//(*.java[*])/jcr:content[@jcr:data]")
109 .andOutputtingTo("/java/$1");
110
111 config.sequencer("CSV Sequencer")
112 .usingClass("org.modeshape.sequencer.text.DelimitedTextSequencer")
113 .loadedFromClasspath()
114 .setDescription("Sequences CSV files to extract the contents")
115 .sequencingFrom("//(*.csv[*])/jcr:content[@jcr:data]")
116 .andOutputtingTo("/csv/$1");
117
118 config.sequencer("Fixed Width Sequencer")
119 .usingClass("org.modeshape.sequencer.text.FixedWidthTextSequencer")
120 .loadedFromClasspath()
121 .setDescription("Sequences fixed width files to extract the contents")
122 .setProperty("commentMarker", "#")
123 .setProperty("columnStartPositions", new int[] {10, 20, 30, 40})
124 .sequencingFrom("//(*.txt[*])/jcr:content[@jcr:data]")
125 .andOutputtingTo("/txt/$1");
126
127
128 SequencingClient client = new SequencingClient(config, repositoryId, workspaceName);
129 client.setUserInterface(new ConsoleInput(client));
130 }
131
132 private final String repositoryName;
133 private final String workspaceName;
134 private final JcrConfiguration configuration;
135 private JcrEngine engine;
136 private UserInterface userInterface;
137 private Repository repository;
138
139 public SequencingClient( JcrConfiguration config,
140 String repositoryName,
141 String workspaceName ) {
142 this.configuration = config;
143 this.repositoryName = repositoryName != null ? repositoryName : DEFAULT_REPOSITORY_NAME;
144 this.workspaceName = workspaceName != null ? workspaceName : DEFAULT_WORKSPACE_NAME;
145 }
146
147
148
149
150
151
152 public void setUserInterface( UserInterface userInterface ) {
153 this.userInterface = userInterface;
154 }
155
156
157
158
159
160
161 public void startRepository() throws Exception {
162 if (this.repository == null) {
163 try {
164
165 this.engine = this.configuration.build();
166 this.engine.start();
167
168
169 this.repository = this.engine.getRepository(repositoryName);
170
171 } catch (Exception e) {
172 this.repository = null;
173 throw e;
174 }
175 }
176 }
177
178
179
180
181
182
183 public void shutdownRepository() throws Exception {
184 if (this.repository != null) {
185 try {
186 this.engine.shutdown();
187 this.engine.awaitTermination(4, TimeUnit.SECONDS);
188 } finally {
189 this.repository = null;
190 }
191 }
192 }
193
194
195
196
197
198
199 public SequencingService.Statistics getStatistics() {
200 return this.engine.getSequencingService().getStatistics();
201 }
202
203
204
205
206
207
208 public void uploadFile() throws Exception {
209 URL url = this.userInterface.getFileToUpload();
210
211 String filename = url.getPath().replaceAll("([^/]*/)*", "");
212 String nodePath = this.userInterface.getRepositoryPath("/a/b/" + filename);
213 String mimeType = getMimeType(url);
214
215 if (mimeType == null) {
216 System.err.println("Could not determine mime type for file " + url + ". Cancelling upload.");
217 return;
218 }
219
220
221 Session session = createSession();
222 JcrTools tools = new JcrTools();
223 try {
224
225 Node node = tools.findOrCreateNode(session, nodePath, "nt:folder", "nt:file");
226
227
228 Node contentNode = tools.findOrCreateChild(node, "jcr:content", "nt:resource");
229 contentNode.setProperty("jcr:mimeType", mimeType);
230 contentNode.setProperty("jcr:lastModified", Calendar.getInstance());
231 Binary binaryValue = session.getValueFactory().createBinary(url.openStream());
232 contentNode.setProperty("jcr:data", binaryValue);
233
234
235 session.save();
236 } finally {
237 session.logout();
238 }
239 }
240
241
242
243
244
245
246 public void search() throws Exception {
247
248 List<ContentInfo> infos = new ArrayList<ContentInfo>();
249 Session session = createSession();
250 try {
251
252 Node root = session.getRootNode();
253
254 if (root.hasNode("images") || root.hasNode("mp3s")) {
255 Node mediasNode;
256 if (root.hasNode("images")) {
257 mediasNode = root.getNode("images");
258
259 for (NodeIterator iter = mediasNode.getNodes(); iter.hasNext();) {
260 Node mediaNode = iter.nextNode();
261 if (mediaNode.hasNode("image:metadata")) {
262 infos.add(extractMediaInfo("image:metadata", "image", mediaNode));
263 }
264 }
265 }
266 if (root.hasNode("mp3s")) {
267 mediasNode = root.getNode("mp3s");
268
269 for (NodeIterator iter = mediasNode.getNodes(); iter.hasNext();) {
270 Node mediaNode = iter.nextNode();
271 if (mediaNode.hasNode("mp3:metadata")) {
272 infos.add(extractMediaInfo("mp3:metadata", "mp3", mediaNode));
273 }
274 }
275 }
276
277 }
278 if (root.hasNode("zips")) {
279 LinkedList<Node> nodesToVisit = new LinkedList<Node>();
280
281 for (NodeIterator i = root.getNode("zips").getNodes(); i.hasNext();) {
282 nodesToVisit.addLast(i.nextNode());
283 }
284
285 while (!nodesToVisit.isEmpty()) {
286 Node node = nodesToVisit.remove();
287
288 String nodeType = "nt:folder".equals(node.getPrimaryNodeType().getName()) ? "folder" : "file";
289 infos.add(new MediaInfo(node.getPath(), node.getName(), nodeType, new Properties()));
290
291 for (NodeIterator i = node.getNodes(); i.hasNext();) {
292 nodesToVisit.addLast(i.nextNode());
293 }
294
295 }
296 }
297 if (root.hasNode("txt")) {
298 LinkedList<Node> nodesToVisit = new LinkedList<Node>();
299
300 for (NodeIterator i = root.getNode("txt").getNodes(); i.hasNext();) {
301 nodesToVisit.addLast(i.nextNode());
302 }
303
304 while (!nodesToVisit.isEmpty()) {
305 Node node = nodesToVisit.remove();
306 Properties props = new Properties();
307 int rowCount = 0;
308 int colCount = 0;
309
310 for (NodeIterator rowIter = node.getNodes(); rowIter.hasNext();) {
311 Node rowNode = rowIter.nextNode();
312
313 rowCount++;
314 colCount = 0;
315
316 for (NodeIterator colIter = rowNode.getNodes(); colIter.hasNext();) {
317 colIter.nextNode();
318 colCount++;
319 }
320 }
321 props.put("rows", String.valueOf(rowCount));
322 props.put("columns", String.valueOf(colCount));
323
324 infos.add(new ContentInfo(node.getPath(), node.getName(), props));
325 }
326 }
327 if (root.hasNode("csv")) {
328 LinkedList<Node> nodesToVisit = new LinkedList<Node>();
329
330 for (NodeIterator i = root.getNode("csv").getNodes(); i.hasNext();) {
331 nodesToVisit.addLast(i.nextNode());
332 }
333
334 while (!nodesToVisit.isEmpty()) {
335 Node node = nodesToVisit.remove();
336 Properties props = new Properties();
337 int rowCount = 0;
338 int colCount = 0;
339
340 for (NodeIterator rowIter = node.getNodes(); rowIter.hasNext();) {
341 Node rowNode = rowIter.nextNode();
342
343 rowCount++;
344 colCount = 0;
345
346 for (NodeIterator colIter = rowNode.getNodes(); colIter.hasNext();) {
347 colIter.nextNode();
348 colCount++;
349 }
350 }
351 props.put("rows", String.valueOf(rowCount));
352 props.put("columns", String.valueOf(colCount));
353
354 infos.add(new ContentInfo(node.getPath(), node.getName(), props));
355 }
356 }
357
358 if (root.hasNode("classes")) {
359 LinkedList<Node> nodesToVisit = new LinkedList<Node>();
360
361 for (NodeIterator i = root.getNode("classes").getNodes(); i.hasNext();) {
362 nodesToVisit.addLast(i.nextNode());
363 }
364
365 while (!nodesToVisit.isEmpty()) {
366 Node node = nodesToVisit.remove();
367
368 if ("class:class".equals(node.getPrimaryNodeType().getName())) {
369 Properties props = new Properties();
370 props.put("constructors", node.getNode("class:constructors").getNodes().getSize());
371 props.put("methods", node.getNode("class:methods").getNodes().getSize());
372 props.put("fields", node.getNode("class:fields").getNodes().getSize());
373
374 infos.add(new MediaInfo(node.getPath(), node.getName(), "class", props));
375
376 } else {
377 for (NodeIterator i = node.getNodes(); i.hasNext();) {
378 nodesToVisit.addLast(i.nextNode());
379 }
380 }
381
382 }
383 }
384 if (root.hasNode("java")) {
385 Map<String, List<Properties>> tree = new TreeMap<String, List<Properties>>();
386
387 List<Properties> javaElements;
388 if (root.hasNode("java")) {
389 Node javaSourcesNode = root.getNode("java");
390 for (NodeIterator i = javaSourcesNode.getNodes(); i.hasNext();) {
391
392 Node javaSourceNode = i.nextNode();
393
394 if (javaSourceNode.hasNodes()) {
395 Node javaCompilationUnit = javaSourceNode.getNodes().nextNode();
396
397
398 javaElements = new ArrayList<Properties>();
399 try {
400 Node javaPackageDeclarationNode = javaCompilationUnit.getNode("java:package/java:packageDeclaration");
401 javaElements.add(extractJavaInfo(javaPackageDeclarationNode));
402 tree.put("Class package", javaElements);
403 } catch (PathNotFoundException e) {
404
405 }
406
407
408 javaElements = new ArrayList<Properties>();
409 try {
410 for (NodeIterator singleImportIterator = javaCompilationUnit.getNode("java:import/java:importDeclaration/java:singleImport")
411 .getNodes(); singleImportIterator.hasNext();) {
412 Node javasingleTypeImportDeclarationNode = singleImportIterator.nextNode();
413 javaElements.add(extractJavaInfo(javasingleTypeImportDeclarationNode));
414 }
415 tree.put("Class single Imports", javaElements);
416 } catch (PathNotFoundException e) {
417
418 }
419
420 javaElements = new ArrayList<Properties>();
421 try {
422 for (NodeIterator javaImportOnDemandIterator = javaCompilationUnit.getNode("java:import/java:importDeclaration/java:importOnDemand")
423 .getNodes(); javaImportOnDemandIterator.hasNext();) {
424 Node javaImportOnDemandtDeclarationNode = javaImportOnDemandIterator.nextNode();
425 javaElements.add(extractJavaInfo(javaImportOnDemandtDeclarationNode));
426 }
427 tree.put("Class on demand imports", javaElements);
428
429 } catch (PathNotFoundException e) {
430
431 }
432
433 javaElements = new ArrayList<Properties>();
434 Node javaNormalDeclarationClassNode = javaCompilationUnit.getNode("java:unitType/java:classDeclaration/java:normalClass/java:normalClassDeclaration");
435 javaElements.add(extractJavaInfo(javaNormalDeclarationClassNode));
436 tree.put("Class head information", javaElements);
437
438
439 javaElements = new ArrayList<Properties>();
440 for (NodeIterator javaFieldTypeIterator = javaCompilationUnit.getNode("java:unitType/java:classDeclaration/java:normalClass/java:normalClassDeclaration/java:field/java:fieldType")
441 .getNodes(); javaFieldTypeIterator.hasNext();) {
442 Node rootFieldTypeNode = javaFieldTypeIterator.nextNode();
443 if (rootFieldTypeNode.hasNode("java:primitiveType")) {
444 Node javaPrimitiveTypeNode = rootFieldTypeNode.getNode("java:primitiveType");
445 javaElements.add(extractJavaInfo(javaPrimitiveTypeNode));
446
447 }
448
449 if (rootFieldTypeNode.hasNode("java:simpleType")) {
450 Node javaSimpleTypeNode = rootFieldTypeNode.getNode("java:simpleType");
451 javaElements.add(extractJavaInfo(javaSimpleTypeNode));
452 }
453 if (rootFieldTypeNode.hasNode("java:parameterizedType")) {
454 Node javaParameterizedType = rootFieldTypeNode.getNode("java:parameterizedType");
455 javaElements.add(extractJavaInfo(javaParameterizedType));
456 }
457 if (rootFieldTypeNode.hasNode("java:arrayType")) {
458 Node javaArrayType = rootFieldTypeNode.getNode("java:arrayType[2]");
459 javaElements.add(extractJavaInfo(javaArrayType));
460 }
461 }
462 tree.put("Class field members", javaElements);
463
464
465 javaElements = new ArrayList<Properties>();
466 for (NodeIterator javaConstructorIterator = javaCompilationUnit.getNode("java:unitType/java:classDeclaration/java:normalClass/java:normalClassDeclaration/java:constructor")
467 .getNodes(); javaConstructorIterator.hasNext();) {
468 Node javaConstructor = javaConstructorIterator.nextNode();
469 javaElements.add(extractJavaInfo(javaConstructor));
470 }
471 tree.put("Class constructors", javaElements);
472
473
474 javaElements = new ArrayList<Properties>();
475 for (NodeIterator javaMethodIterator = javaCompilationUnit.getNode("java:unitType/java:classDeclaration/java:normalClass/java:normalClassDeclaration/java:method")
476 .getNodes(); javaMethodIterator.hasNext();) {
477 Node javaMethod = javaMethodIterator.nextNode();
478 javaElements.add(extractJavaInfo(javaMethod));
479 }
480 tree.put("Class member functions", javaElements);
481
482 JavaInfo javaInfo = new JavaInfo(javaCompilationUnit.getPath(), javaCompilationUnit.getName(),
483 "java source", tree);
484 infos.add(javaInfo);
485 }
486 }
487 }
488
489 }
490 } finally {
491 session.logout();
492 }
493
494
495 this.userInterface.displaySearchResults(infos);
496 }
497
498 private MediaInfo extractMediaInfo( String metadataNodeName,
499 String mediaType,
500 Node mediaNode ) throws RepositoryException, PathNotFoundException, ValueFormatException {
501 String nodePath = mediaNode.getPath();
502 String nodeName = mediaNode.getName();
503 mediaNode = mediaNode.getNode(metadataNodeName);
504
505
506 Properties props = new Properties();
507 for (PropertyIterator propertyIter = mediaNode.getProperties(); propertyIter.hasNext();) {
508 Property property = propertyIter.nextProperty();
509 String name = property.getName();
510 String stringValue = null;
511 if (property.getDefinition().isMultiple()) {
512 StringBuilder sb = new StringBuilder();
513 boolean first = true;
514 for (Value value : property.getValues()) {
515 if (!first) {
516 sb.append(", ");
517 first = false;
518 }
519 sb.append(value.getString());
520 }
521 stringValue = sb.toString();
522 } else {
523 stringValue = property.getValue().getString();
524 }
525 props.put(name, stringValue);
526 }
527
528 return new MediaInfo(nodePath, nodeName, mediaType, props);
529 }
530
531
532
533
534
535
536
537
538
539
540 private Properties extractJavaInfo( Node node ) throws ValueFormatException, IllegalStateException, RepositoryException {
541 if (node.hasProperties()) {
542 Properties properties = new Properties();
543 for (PropertyIterator propertyIter = node.getProperties(); propertyIter.hasNext();) {
544 Property property = propertyIter.nextProperty();
545 String name = property.getName();
546 String stringValue = property.getValue().getString();
547 properties.put(name, stringValue);
548 }
549 return properties;
550 }
551 return null;
552 }
553
554
555
556
557
558
559
560 protected Session createSession() throws RepositoryException {
561
562
563
564
565
566 SecurityContext securityContext = new MyCustomSecurityContext();
567 SecurityContextCredentials credentials = new SecurityContextCredentials(securityContext);
568 return this.repository.login(credentials, workspaceName);
569 }
570
571 protected String getMimeType( URL file ) {
572 String filename = file.getPath().toLowerCase();
573 if (filename.endsWith(".gif")) return "image/gif";
574 if (filename.endsWith(".png")) return "image/png";
575 if (filename.endsWith(".pict")) return "image/x-pict";
576 if (filename.endsWith(".bmp")) return "image/bmp";
577 if (filename.endsWith(".jpg")) return "image/jpeg";
578 if (filename.endsWith(".jpe")) return "image/jpeg";
579 if (filename.endsWith(".jpeg")) return "image/jpeg";
580 if (filename.endsWith(".ras")) return "image/x-cmu-raster";
581 if (filename.endsWith(".mp3")) return "audio/mpeg";
582 if (filename.endsWith(".jar")) return "application/java-archive";
583 if (filename.endsWith(".java")) return "text/x-java-source";
584 if (filename.endsWith(".csv")) return "text/csv";
585 if (filename.endsWith(".txt")) return "text/plain";
586 if (filename.endsWith(".clazz")) return "application/x-java-class";
587 return null;
588 }
589
590 protected class MyCustomSecurityContext implements SecurityContext {
591
592
593
594
595
596 public String getUserName() {
597 return "Fred";
598 }
599
600
601
602
603
604
605 public boolean hasRole( String roleName ) {
606 return true;
607 }
608
609
610
611
612
613
614 public void logout() {
615
616 }
617 }
618
619 }