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.module.groovy.support.classes;
35
36 import groovy.lang.GroovyResourceLoader;
37 import info.magnolia.cms.core.Content;
38 import info.magnolia.cms.core.HierarchyManager;
39 import info.magnolia.cms.core.MetaData;
40 import info.magnolia.cms.core.NodeData;
41 import info.magnolia.module.groovy.support.HierarchyManagerProvider;
42
43 import javax.jcr.RepositoryException;
44 import java.io.ByteArrayInputStream;
45 import java.io.IOException;
46 import java.io.InputStream;
47 import java.net.MalformedURLException;
48 import java.net.URL;
49 import java.net.URLConnection;
50 import java.net.URLStreamHandler;
51 import java.util.Calendar;
52
53
54
55
56
57
58
59
60
61
62
63
64 class MgnlGroovyResourceLoader implements GroovyResourceLoader {
65 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MgnlGroovyResourceLoader.class);
66
67 private static final String PROTOCOL = "magnolia-repository://";
68 private final GroovyResourceLoader delegate;
69 private final HierarchyManagerProvider hmp;
70 private final String repoName;
71
72 MgnlGroovyResourceLoader(GroovyResourceLoader delegate, HierarchyManagerProvider hmp, String repoName) {
73 this.delegate = delegate;
74 this.hmp = hmp;
75 this.repoName = repoName;
76 }
77
78 @Override
79 public URL loadGroovySource(String name) throws MalformedURLException {
80 final URL url = loadGroovySourceFromRepository(name);
81 if (url == null) {
82 return delegate.loadGroovySource(name);
83 }
84 return url;
85 }
86
87
88
89
90
91 private URL loadGroovySourceFromRepository(String name) throws MalformedURLException {
92 if (name.startsWith("[") || name.contains("$")) {
93
94
95 log.debug("Skipping {}, array or nested class.", name);
96 return null;
97 }
98
99 final HierarchyManager hm;
100 try {
101 hm = hmp.getHierarchyManager(repoName);
102 } catch (Exception e) {
103 return null;
104 }
105 final String path = "/" + name.replace('.', '/');
106 try {
107 if (hm.isExist(path) && hm.getNodeData(path + "/enabled").getBoolean()) {
108 return new URL(null, PROTOCOL + hm.getName() + path, new MagnoliaStreamHandler(hm));
109 } else {
110 return null;
111 }
112 } catch (RepositoryException e) {
113 return null;
114 }
115 }
116
117
118
119
120
121 protected static class MagnoliaStreamHandler extends URLStreamHandler {
122 private final HierarchyManager hm;
123
124 public MagnoliaStreamHandler(HierarchyManager hm) {
125 this.hm = hm;
126 }
127
128 @Override
129 protected URLConnection openConnection(URL u) throws IOException {
130 if (!"magnolia-repository".equals(u.getProtocol())) {
131 throw new IllegalStateException("Unsupported protocol: " + u.getProtocol() + " (only supports \"magnolia-repository\")");
132 }
133 return new MagnoliaURLConnection(u, hm);
134 }
135 }
136
137
138
139
140
141 protected static class MagnoliaURLConnection extends URLConnection {
142 private final Content node;
143
144 public MagnoliaURLConnection(URL u, HierarchyManager hm) throws IOException {
145 super(u);
146
147 final String path = u.getPath();
148
149 try {
150 this.node = hm.getContent(path);
151 } catch (RepositoryException e) {
152 throw new IOException("Can't get " + path + " from the " + hm.getName() + " repository: " + e.getClass().getSimpleName() + ": " + e.getMessage());
153 }
154 }
155
156 @Override
157 public void connect() throws IOException {
158
159
160
161
162
163 }
164
165 @Override
166 public InputStream getInputStream() throws IOException {
167 final NodeData prop = node.getNodeData("text");
168 if (!prop.isExist()) {
169 throw new IOException(node.getHandle() + " has no 'text' property");
170 }
171
172
173
174 final String sourceStr = prop.getString();
175 return new ByteArrayInputStream(sourceStr.getBytes());
176 }
177
178 @Override
179 public long getLastModified() {
180 final MetaData md = node.getMetaData();
181 final Calendar date = md.getModificationDate();
182 return date.getTimeInMillis();
183 }
184 }
185 }