1 package com.atlassian.plugin.metadata;
2
3 import com.atlassian.plugin.ModuleDescriptor;
4 import com.atlassian.plugin.Plugin;
5 import com.google.common.collect.ImmutableSet;
6 import org.apache.commons.io.IOUtils;
7 import org.apache.commons.lang3.StringUtils;
8
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.net.URL;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Enumeration;
15 import java.util.List;
16 import java.util.Set;
17
18 import static org.apache.commons.io.IOUtils.readLines;
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 public class ClasspathFilePluginMetadata implements PluginMetadata, RequiredPluginProvider {
35 final static String APPLICATION_PROVIDED_PLUGINS_FILENAME = "application-provided-plugins.txt";
36 final static String APPLICATION_REQUIRED_PLUGINS_FILENAME = "application-required-plugins.txt";
37 final static String APPLICATION_REQUIRED_MODULES_FILENAME = "application-required-modules.txt";
38
39 private final Set<String> providedPluginKeys;
40 private final Set<String> requiredPluginKeys;
41 private final Set<String> requiredModuleKeys;
42 private final ClassLoader classLoader;
43
44 public ClasspathFilePluginMetadata() {
45 this(ClasspathFilePluginMetadata.class.getClassLoader());
46 }
47
48 ClasspathFilePluginMetadata(ClassLoader classLoader) {
49 this.classLoader = classLoader;
50 this.providedPluginKeys = getStringsFromFile(APPLICATION_PROVIDED_PLUGINS_FILENAME);
51 this.requiredPluginKeys = getStringsFromFile(APPLICATION_REQUIRED_PLUGINS_FILENAME);
52 this.requiredModuleKeys = getStringsFromFile(APPLICATION_REQUIRED_MODULES_FILENAME);
53 }
54
55 public boolean applicationProvided(final Plugin plugin) {
56 return providedPluginKeys.contains(plugin.getKey());
57 }
58
59 public boolean required(final Plugin plugin) {
60 return requiredPluginKeys.contains(plugin.getKey());
61 }
62
63 public boolean required(final ModuleDescriptor<?> module) {
64 return requiredModuleKeys.contains(module.getCompleteKey());
65 }
66
67 public Set<String> getRequiredPluginKeys() {
68 return requiredPluginKeys;
69 }
70
71 public Set<String> getRequiredModuleKeys() {
72 return requiredModuleKeys;
73 }
74
75 private Set<String> getStringsFromFile(final String fileName) {
76 final ImmutableSet.Builder<String> stringsFromFiles = ImmutableSet.builder();
77
78 final Collection<InputStream> fileInputStreams = getInputStreamsForFilename(fileName);
79 try {
80 for (InputStream fileInputStream : fileInputStreams) {
81 if (fileInputStream != null) {
82 try {
83 @SuppressWarnings("unchecked")
84 final List<String> lines = readLines(fileInputStream);
85
86
87
88
89 for (String line : lines) {
90 final String processedLine = processedLine(line);
91 if (processedLine != null) {
92 stringsFromFiles.add(processedLine.intern());
93 }
94 }
95 } catch (final IOException e) {
96 throw new RuntimeException(e);
97 }
98 }
99 }
100 } finally {
101 for (InputStream fileInputStream : fileInputStreams) {
102 IOUtils.closeQuietly(fileInputStream);
103 }
104 }
105 return stringsFromFiles.build();
106 }
107
108
109
110
111
112
113
114
115
116 private String processedLine(String rawLine) {
117 if (rawLine == null) {
118 return null;
119 }
120
121 final String trimmedLine = rawLine.trim();
122
123 if (StringUtils.isBlank(trimmedLine)) {
124 return null;
125 }
126
127
128 if (trimmedLine.startsWith("#")) {
129 return null;
130 }
131 return trimmedLine;
132 }
133
134 Collection<InputStream> getInputStreamsForFilename(final String fileName) {
135 final Collection<InputStream> inputStreams = new ArrayList<>();
136 final Class<ClasspathFilePluginMetadata> clazz = ClasspathFilePluginMetadata.class;
137 final String resourceName = clazz.getPackage().getName().replace(".", "/") + "/" + fileName;
138 try {
139 final Enumeration<URL> urlEnumeration = classLoader.getResources(resourceName);
140 while (urlEnumeration.hasMoreElements()) {
141 inputStreams.add(urlEnumeration.nextElement().openStream());
142 }
143 } catch (final IOException e) {
144
145 for (InputStream inputStream : inputStreams) {
146 IOUtils.closeQuietly(inputStream);
147 }
148 throw new RuntimeException(e);
149 }
150 return inputStreams;
151 }
152
153 }