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