1 package org.tinyjee.maven.dim.spi;
2
3 import org.tinyjee.maven.dim.spi.backport.ServiceLoader;
4
5 import java.io.IOException;
6 import java.io.LineNumberReader;
7 import java.net.URL;
8 import java.util.Iterator;
9 import java.util.Map;
10
11 /**
12 * {@link SnippetSelector} defines an interface that may be implemented and registered via service loading
13 * to add new snippet selection mechanisms.
14 * <p/>
15 * <b>Implementation</b>:<code><pre>
16 * package my.package;
17 * public class MySnippetSelector implements SnippetSelector {
18 * public String[] getExpressionPrefixes() {
19 * return new String[] {"my:"};
20 * }
21 * public boolean canSelectSnippetsWith(String expression, URL contentUrl, Map<String, Object> macroParameters) {
22 * return expression.toLowerCase().startsWith("my:");
23 * }
24 * public Iterator<Integer> selectSnippets(String expression, URL contentUrl, LineNumberReader content,
25 * Map<String, Object> macroParameters) throws IOException {
26 * List<Integer> output = new LinkedList<Integer>();
27 * for (String line = content.readLine(); line != null; line = content.readLine()) {
28 * if (... EXPRESSION MATCHES LINE ...) output.add(content.getLineNumber());
29 * }
30 * return output.iterator();
31 * }
32 * }
33 * </pre></code>
34 * <p/>
35 * <b>Register the implementation using service loading</b>:<ul>
36 * <li>
37 * Create the following file:<code><pre>
38 * META-INF/services/
39 * org.tinyjee.maven.dim.spi.SnippetSelector
40 * </pre></code></li>
41 * <li>Add the fully qualified class name of your implementation to the file "org.tinyjee.maven.dim.spi.SnippetSelector":<code><pre>
42 * my.package.MySnippetSelector
43 * </pre></code></li>
44 * </ul>
45 *
46 * @version 1.1
47 * @since 1.1
48 * @author Juergen_Kellerer, 2011-10-14
49 */
50 public interface SnippetSelector {
51
52 // START SNIPPET: SnippetSelectorParams
53 /**
54 * Is an optional boolean parameter that toggles whether snippet selection is case sensitive.
55 * Whether this parameter is used by selectors is implementation specific. Some selectors may not support to change this value.
56 */
57 String CASE_SENSITIVE = "case-sensitive";
58 /**
59 * Is a boolean parameters that may be used by snippet selectors to expand the included content to additional regions
60 * if matching an element that has belongings in other locations of the same file.
61 * <p/>
62 * E.g. when matching a field, getter or setter a snippet selector may choose to include all 3 code locations if only
63 * one of them was originally matched.
64 */
65 String EXPAND_SNIPPETS = "expand-snippets";
66 // END SNIPPET: SnippetSelectorParams
67
68 /**
69 * Is an iterable over all selectors within the classpath.
70 */
71 Iterable<SnippetSelector> SELECTORS = ServiceLoader.load(SnippetSelector.class);
72
73 /**
74 * Returns all prefixes that are explicitly supported by this snippet selector.
75 * @return all prefixes that are explicitly supported by this snippet selector.
76 */
77 String[] getExpressionPrefixes();
78
79 /**
80 * Returns true if the expression is supported by this snippet selector.
81 *
82 * @param expression a single snippet expression.
83 * @param contentUrl the resolved URL of the content to include (might be 'null' if the source does not provide a Url).
84 * @param macroParameters the parameters used with the macro call.
85 * @return true if the snippet selector supports the given expression.
86 */
87 boolean canSelectSnippetsWith(String expression, URL contentUrl, Map<String, Object> macroParameters);
88
89 /**
90 * Selects snippets in the given content and returns an iterator over selected line numbers.
91 * <p/>
92 * Note: The caller reads the returned iterator fully before closing the content stream.
93 * This way snippet selectors can truly implement streaming selection (in difference to the provided example).
94 *
95 * @param expression a single snippet expression.
96 * @param contentUrl the resolved URL of the content to include (might be 'null' if the source does not provide a Url).
97 * @param content a reader providing the content. Implementations must read content from this reader as the Url
98 * may point to an outdated static source that does not reflect the content to include.
99 * @param macroParameters the parameters used with the macro call.
100 * @return an iterator containing all selected line numbers.
101 * @throws java.io.IOException In case of reading the URL failed.
102 */
103 Iterator<Integer> selectSnippets(final String expression, final URL contentUrl, final LineNumberReader content,
104 final Map<String, Object> macroParameters) throws IOException;
105 }