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