1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.resourceloader.classpath.service.impl.base;
35
36 import info.magnolia.resourceloader.classpath.hierarchy.ClasspathDirectory;
37 import info.magnolia.resourceloader.classpath.hierarchy.ClasspathEntry;
38 import info.magnolia.resourceloader.classpath.service.ClasspathServiceConfiguration;
39
40 import java.net.URL;
41 import java.util.Map;
42
43 import org.apache.commons.lang3.StringUtils;
44 import org.reflections.vfs.Vfs;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 import com.google.common.base.Predicate;
49 import com.google.common.collect.Maps;
50
51
52
53
54
55
56
57
58
59
60
61
62
63 public abstract class ClasspathEntriesResolver {
64
65 private final ClasspathFileConstructionStrategy classpathFileConstructionStrategy;
66
67 public ClasspathEntriesResolver(ClasspathFileConstructionStrategy classpathFileConstructionStrategy) {
68 this.classpathFileConstructionStrategy = classpathFileConstructionStrategy;
69 }
70
71
72
73
74
75
76 public abstract Map<String, ClasspathEntry> resolveClasspathEntries(ClasspathServiceConfiguration configuration);
77
78 protected ClasspathFileConstructionStrategy getClasspathFileConstructionStrategy() {
79 return classpathFileConstructionStrategy;
80 }
81
82
83
84
85 public static class ReflectionsVfsBased extends ClasspathEntriesResolver {
86
87 private static final Logger log = LoggerFactory.getLogger(ReflectionsVfsBased.class);
88
89 public ReflectionsVfsBased(ClasspathFileConstructionStrategy classpathFileConstructionStrategy) {
90 super(classpathFileConstructionStrategy);
91 }
92
93 @Override
94 public Map<String, ClasspathEntry> resolveClasspathEntries(ClasspathServiceConfiguration configuration) {
95 final Predicate<String> resourcesFilter = configuration.getResourceFilter();
96 final Iterable<URL> classpathLocations = configuration.getClasspathLocations();
97
98 final Map<String, ClasspathEntry> entries = Maps.newHashMap();
99 ClasspathFileConstructionStrategy strategy = getClasspathFileConstructionStrategy();
100
101 for (final URL url : classpathLocations) {
102 try {
103 for (final Vfs.File file : Vfs.fromURL(url).getFiles()) {
104 if (resourcesFilter.apply(file.getRelativePath())) {
105 final ClasspathEntry resource = strategy.buildFile(file, url);
106 attachAndIndex(resource, entries);
107 }
108 }
109 } catch (Exception e) {
110 log.debug("Failed to populate resources from {} due to: ", url, e);
111 }
112 }
113 return entries;
114 }
115
116
117
118
119
120 protected void attachAndIndex(ClasspathEntry resource, Map<String, ClasspathEntry> entries) {
121 entries.put(resource.getAbsolutePath(), resource);
122
123
124 String parentPath = getParentPath(resource.getAbsolutePath());
125 while (parentPath != null) {
126 ClasspathDirectory parent;
127 if (!entries.containsKey(parentPath)) {
128
129 parent = new ClasspathDirectory(parentPath);
130 parent.getEntries().add(resource);
131 entries.put(parentPath, parent);
132 } else {
133
134 parent = (ClasspathDirectory) entries.get(parentPath);
135 parent.getEntries().add(resource);
136 break;
137 }
138 parentPath = getParentPath(parentPath);
139 resource = parent;
140 }
141 }
142
143 private String getParentPath(String resourcePath) {
144 if ("/".equals(resourcePath)) {
145
146 return null;
147 }
148 String parentPath = StringUtils.substringBeforeLast(resourcePath, "/");
149 return StringUtils.defaultIfEmpty(parentPath, "/");
150 }
151 }
152 }