View Javadoc
1   package com.atlassian.plugin.main;
2   
3   import com.atlassian.plugin.osgi.container.PackageScannerConfiguration;
4   import com.atlassian.plugin.osgi.container.impl.DefaultPackageScannerConfiguration;
5   
6   import javax.servlet.ServletContext;
7   import java.util.ArrayList;
8   import java.util.Arrays;
9   import java.util.HashMap;
10  import java.util.List;
11  import java.util.Map;
12  
13  import static java.util.Collections.unmodifiableList;
14  import static java.util.Collections.unmodifiableMap;
15  
16  /**
17   * The builder for {@link PackageScannerConfiguration} instances that additionally performs validation and default creation.
18   * For a usage example, see the package javadocs.
19   * <p>
20   * Not thread-safe. Instances of this class should be thread and preferably method local.
21   *
22   * @since 2.2
23   */
24  public class PackageScannerConfigurationBuilder {
25      /**
26       * Static factory for creating a new builder.
27       *
28       * @return a new builder.
29       */
30      public static PackageScannerConfigurationBuilder packageScannerConfiguration() {
31          return new PackageScannerConfigurationBuilder();
32      }
33  
34      private String hostVersion;
35      private final List<String> jarIncludes = new ArrayList<>();
36      private final List<String> jarExcludes = new ArrayList<>();
37      private final List<String> packageIncludes = new ArrayList<>();
38      private final List<String> packageExcludes = new ArrayList<>();
39      private final Map<String, String> packageVersions = new HashMap<>();
40      private ServletContext servletContext;
41  
42      /**
43       * Default constructor. Uses a DefaultPackageScannerConfiguration as the template.
44       */
45      public PackageScannerConfigurationBuilder() {
46          copy(new DefaultPackageScannerConfiguration());
47      }
48  
49      /**
50       * Copy constructor. Use the supplied PackageScannerConfiguration as a template.
51       *
52       * @param packageScannerConfiguration
53       */
54      public PackageScannerConfigurationBuilder(final PackageScannerConfiguration packageScannerConfiguration) {
55          copy(packageScannerConfiguration);
56      }
57  
58      private void copy(final PackageScannerConfiguration config) {
59          hostVersion = config.getCurrentHostVersion();
60          packageIncludes.addAll(config.getPackageIncludes());
61          packageExcludes.addAll(config.getPackageExcludes());
62          jarIncludes.addAll(config.getJarIncludes());
63          jarExcludes.addAll(config.getJarExcludes());
64          packageVersions.putAll(config.getPackageVersions());
65          servletContext = config.getServletContext();
66      }
67  
68      /**
69       * Sets the current host version.
70       *
71       * @param hostVersion the version to set
72       * @return this
73       * @see PackageScannerConfiguration#getCurrentHostVersion()
74       */
75      public PackageScannerConfigurationBuilder hostVersion(final String hostVersion) {
76          this.hostVersion = hostVersion;
77          return this;
78      }
79  
80      /**
81       * Sets the {@link ServletContext} used to lookup jars as some application servers need it to lookup jar files.
82       *
83       * @param servletContext the servlet context
84       * @return this
85       * @see PackageScannerConfiguration#getServletContext()
86       */
87      public PackageScannerConfigurationBuilder servletContext(final ServletContext servletContext) {
88          this.servletContext = servletContext;
89          return this;
90      }
91  
92      /**
93       * Sets a list of package expressions to expose to plugins.
94       *
95       * @param pkgs A list of package expressions, where the '*' character matches any character including subpackages
96       * @return this
97       * @see PackageScannerConfiguration#getPackageIncludes()
98       */
99      public PackageScannerConfigurationBuilder packagesToInclude(final String... pkgs) {
100         packageIncludes.addAll(Arrays.asList(pkgs));
101         return this;
102     }
103 
104     /**
105      * Sets a list of package expressions to hide from plugins.
106      *
107      * @param pkgs A list of package expressions, where the '*' character matches any character including subpackages
108      * @return this
109      * @see PackageScannerConfiguration#getPackageExcludes()
110      */
111     public PackageScannerConfigurationBuilder packagesToExclude(final String... pkgs) {
112         packageExcludes.addAll(Arrays.asList(pkgs));
113         return this;
114     }
115 
116     /**
117      * Sets which packages should be exposed as which versions.
118      *
119      * @param packageToVersion A map of package names to version names. No wildcards allowed, and the version names
120      *                         must match the expected OSGi versioning scheme.
121      * @return this
122      * @see PackageScannerConfiguration#getPackageVersions()
123      */
124     public PackageScannerConfigurationBuilder packagesVersions(final Map<String, String> packageToVersion) {
125         packageVersions.putAll(packageToVersion);
126         return this;
127     }
128 
129     /**
130      * Sets a list of jar expressions to expose to plugins.
131      *
132      * @param jars A list of jars expressions, where the '*' character matches any character
133      * @return this
134      * @see PackageScannerConfiguration#getJarIncludes()
135      */
136     public PackageScannerConfigurationBuilder jarsToInclude(final String... jars) {
137         jarIncludes.addAll(Arrays.asList(jars));
138         return this;
139     }
140 
141     /**
142      * Sets a list of jar expressions to hide from plugins.
143      *
144      * @param jars A list of jars expressions, where the '*' character matches any character
145      * @return this
146      * @see PackageScannerConfiguration#getJarExcludes()
147      */
148     public PackageScannerConfigurationBuilder jarsToExclude(final String... jars) {
149         jarExcludes.addAll(Arrays.asList(jars));
150         return this;
151     }
152 
153     /**
154      * Builds a {@link PackageScannerConfiguration} instance by processing the configuration that
155      * was previously set and setting any defaults where not explicitly specified.
156      *
157      * @return A valid {@link PackageScannerConfiguration} instance to pass to {@link AtlassianPlugins}
158      */
159     public PackageScannerConfiguration build() {
160         return new ImmutablePackageScannerConfiguration(this);
161     }
162 
163     //
164     // inner classes
165     //
166 
167     /**
168      * Immutable and thread-safe implementation of the {@link PackageScannerConfiguration} returned by a
169      * {@link PackageScannerConfigurationBuilder}
170      */
171     private static final class ImmutablePackageScannerConfiguration implements PackageScannerConfiguration {
172         private final String hostVersion;
173         private final List<String> jarIncludes;
174         private final List<String> jarExcludes;
175         private final List<String> packageIncludes;
176         private final List<String> packageExcludes;
177         private final Map<String, String> packageVersions;
178         private final ServletContext servletContext;
179 
180         ImmutablePackageScannerConfiguration(final PackageScannerConfigurationBuilder builder) {
181             hostVersion = builder.hostVersion;
182             jarIncludes = unmodifiableList(new ArrayList<>(builder.jarIncludes));
183             jarExcludes = unmodifiableList(new ArrayList<>(builder.jarExcludes));
184             packageIncludes = unmodifiableList(new ArrayList<>(builder.packageIncludes));
185             packageExcludes = unmodifiableList(new ArrayList<>(builder.packageExcludes));
186             packageVersions = unmodifiableMap(new HashMap<>(builder.packageVersions));
187             servletContext = builder.servletContext;
188         }
189 
190         public List<String> getJarIncludes() {
191             return jarIncludes;
192         }
193 
194         public List<String> getJarExcludes() {
195             return jarExcludes;
196         }
197 
198         public List<String> getPackageIncludes() {
199             return packageIncludes;
200         }
201 
202         public List<String> getPackageExcludes() {
203             return packageExcludes;
204         }
205 
206         public Map<String, String> getPackageVersions() {
207             return packageVersions;
208         }
209 
210         public String getCurrentHostVersion() {
211             return hostVersion;
212         }
213 
214         public ServletContext getServletContext() {
215             return servletContext;
216         }
217     }
218 }