View Javadoc
1   package com.kodexa.client.connectors;
2   
3   import com.kodexa.client.Document;
4   import com.kodexa.client.KodexaException;
5   import lombok.extern.slf4j.Slf4j;
6   
7   import java.io.*;
8   import java.util.HashMap;
9   import java.util.Map;
10  import java.util.regex.Pattern;
11  
12  /**
13   * Implementation of a {@link Connector} for reading from a local
14   * directory
15   */
16  @Slf4j
17  public class FolderConnector implements Connector {
18  
19      private final String path;
20      private final String filter;
21      private final File[] files;
22      private int position;
23  
24      public FolderConnector() {
25          this.path = null;
26          this.filter = null;
27          this.files = new File[]{};
28          this.position = 0;
29      }
30  
31      public FolderConnector(String path, String filter, boolean recursive) {
32          this.path = path;
33          this.filter = filter;
34  
35          try {
36              File f = new File(path);
37              files = f.listFiles(new WildcardMatcher(filter));
38              position = 0;
39          } catch (Exception e) {
40              throw new RuntimeException("Unable to build folder connector", e);
41          }
42      }
43  
44      @Override
45      public boolean hasNext() {
46          return files != null && position + 1 <= files.length;
47      }
48  
49      @Override
50      public Document next() {
51          File file = files[position];
52          position++;
53          log.info("Found file " + file.getAbsolutePath());
54          DocumentDocument">Document document = new Document();
55          document.getMetadata().put("source_path", file.getAbsolutePath());
56          document.getMetadata().put("connector", getName());
57          Map<String, String> options = new HashMap<>();
58          options.put("path", path);
59          options.put("file_filter", filter);
60          document.getMetadata().put("connector_options", options);
61          return document;
62      }
63  
64      @Override
65      public String getName() {
66          return "folder";
67      }
68  
69      @Override
70      public InputStream getSource(Document document) {
71          try {
72              return new FileInputStream(String.valueOf(document.getMetadata().get("source_path")));
73          } catch (FileNotFoundException e) {
74              throw new KodexaException("Unable to find source file", e);
75          }
76      }
77  
78      public static class WildcardMatcher implements FilenameFilter {
79  
80          private final Pattern pattern;
81  
82          /**
83           * Creates a new matcher with the given expression.
84           *
85           * @param expression wildcard expressions
86           */
87          public WildcardMatcher(final String expression) {
88              final String[] parts = expression.split("\\:");
89              final StringBuilder regex = new StringBuilder(expression.length() * 2);
90              boolean next = false;
91              for (final String part : parts) {
92                  if (next) {
93                      regex.append('|');
94                  }
95                  regex.append('(').append(toRegex(part)).append(')');
96                  next = true;
97              }
98              pattern = Pattern.compile(regex.toString());
99          }
100 
101         private static CharSequence toRegex(final String expression) {
102             final StringBuilder regex = new StringBuilder(expression.length() * 2);
103             for (final char c : expression.toCharArray()) {
104                 switch (c) {
105                     case '?':
106                         regex.append(".");
107                         break;
108                     case '*':
109                         regex.append(".*");
110                         break;
111                     default:
112                         regex.append(Pattern.quote(String.valueOf(c)));
113                         break;
114                 }
115             }
116             return regex;
117         }
118 
119         @Override
120         public boolean accept(File dir, String name) {
121             return pattern.matcher(name).matches();
122         }
123     }
124 }