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;
35
36 import static info.magnolia.resourceloader.classpath.service.ClasspathService.ClasspathEntryNotFoundException;
37
38 import info.magnolia.resourceloader.AbstractResourceOrigin;
39 import info.magnolia.resourceloader.ResourceOriginFactory;
40 import info.magnolia.resourceloader.ResourceStub;
41 import info.magnolia.resourceloader.ResourceVisitor;
42 import info.magnolia.resourceloader.classpath.hierarchy.ClasspathDirectory;
43 import info.magnolia.resourceloader.classpath.hierarchy.ClasspathEntry;
44 import info.magnolia.resourceloader.classpath.hierarchy.ClasspathFile;
45 import info.magnolia.resourceloader.classpath.service.ClasspathService;
46 import info.magnolia.resourceloader.classpath.service.MonitoredClasspathService;
47 import info.magnolia.resourceloader.util.VoidFunction;
48
49 import java.io.IOException;
50 import java.io.InputStream;
51 import java.nio.charset.Charset;
52 import java.util.List;
53
54 import com.google.auto.factory.AutoFactory;
55 import com.google.auto.factory.Provided;
56 import com.google.common.base.Function;
57 import com.google.common.collect.Lists;
58
59
60
61
62
63
64
65
66
67 @AutoFactory(implementing = ResourceOriginFactory.class)
68 public class ClasspathResourceOrigin extends AbstractResourceOrigin<ClasspathResource> {
69
70 private final Function<ClasspathEntry, ClasspathResource> getResourceInstance = new Function<ClasspathEntry, ClasspathResource>() {
71 @Override
72 @SuppressWarnings("unchecked")
73 public ClasspathResource<ClasspathEntry> apply(ClasspathEntry input) {
74 return new ClasspathResource(ClasspathResourceOrigin.this, input);
75 }
76 };
77
78 private final ClasspathService classpathService;
79
80 public ClasspathResourceOrigin(String name, @Provided ClasspathService classpathService) {
81 super(name);
82 this.classpathService = classpathService;
83
84 }
85
86 @Override
87 protected boolean isFile(ClasspathResource resource) {
88 return resource.getClasspathEntry() instanceof ClasspathFile;
89 }
90
91 @Override
92 protected boolean isDirectory(ClasspathResource resource) {
93 return resource.getClasspathEntry() instanceof ClasspathDirectory;
94 }
95
96 @Override
97 protected String getPath(ClasspathResource resource) {
98 return resource.getClasspathEntry().getAbsolutePath();
99 }
100
101 @Override
102 protected String getName(ClasspathResource resource) {
103 return resource.getClasspathEntry().getName();
104 }
105
106 @Override
107 protected long getLastModified(ClasspathResource resource) {
108 return resource.getClasspathEntry().getLastModified();
109 }
110
111 @Override
112 protected List<ClasspathResource> listChildren(ClasspathResource resource) {
113 final ClasspathEntry classpathEntry = resource.getClasspathEntry();
114 if (resource.isDirectory()) {
115 final ClasspathDirectory folder = (ClasspathDirectory) classpathEntry;
116 return Lists.transform(folder.getEntries(), getResourceInstance);
117 } else {
118 throw new IllegalArgumentException(String.format("%s is not a directory.", resource.getPath()));
119 }
120 }
121
122 @Override
123 protected ClasspathResource getParent(ClasspathResource resource) {
124 if (getRoot().equals(resource)) {
125 return null;
126 }
127
128 try {
129 return getResourceInstance.apply(classpathService.getParent(resource.getClasspathEntry()));
130 } catch (ClasspathEntryNotFoundException e) {
131 throw new ResourceNotFoundException(this, String.format("Failed to resolve a parent of a resource at [%s]", resource.getPath()));
132 }
133 }
134
135 @Override
136 protected InputStream doOpenStream(ClasspathResource resource) throws IOException {
137 final ClasspathEntry classpathEntry = resource.getClasspathEntry();
138 if (!resource.isFile()) {
139 throw new IllegalArgumentException(String.format("It is not allowed to attempt to obtain an input stream for folder classpath entries (%s)", resource.getPath()));
140 }
141 return ((ClasspathFile) classpathEntry).openStream();
142 }
143
144 @Override
145 protected Charset getCharsetFor(ClasspathResource resource) {
146 return classpathService.getConfiguration().getCharset();
147 }
148
149 @Override
150 public ClasspathResource getRoot() {
151 return getResourceInstance.apply(classpathService.getRoot());
152 }
153
154 @Override
155 public ClasspathResource getByPath(String path) {
156 try {
157 return getResourceInstance.apply(classpathService.getEntryAt(path));
158 } catch (ClasspathEntryNotFoundException e) {
159 throw new ResourceNotFoundException(this, String.format("Failed to resolve a classpath resource at [%s]", path));
160 }
161 }
162
163 @Override
164 public boolean hasPath(String path) {
165 return classpathService.hasEntry(path);
166 }
167
168 @Override
169 public void watchForChanges(final ResourceVisitor visitor) {
170 if (classpathService instanceof MonitoredClasspathService) {
171 ((MonitoredClasspathService) classpathService).registerResourceChangeCallback(new VoidFunction<String>() {
172 @Override
173 public void doWith(String resourcePath) {
174 try {
175 final ClasspathResource resource = getByPath(resourcePath);
176 if (resource.isFile()) {
177 visitor.visitFile(resource);
178 } else {
179 visitor.visitDirectory(resource);
180 }
181 } catch (ResourceNotFoundException e) {
182 visitor.visitFile(ResourceStub.withPath(resourcePath));
183 }
184 }
185 });
186 }
187 }
188 }