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 info.magnolia.cms.core.HierarchyManager;
37 import info.magnolia.context.Context;
38 import info.magnolia.jcr.util.NodeTypes;
39 import info.magnolia.jcr.util.PropertyUtil;
40 import info.magnolia.module.groovy.support.HierarchyManagerProvider;
41
42 import java.io.IOException;
43 import java.io.InputStream;
44 import java.net.MalformedURLException;
45 import java.net.URL;
46 import java.net.URLConnection;
47 import java.net.URLStreamHandler;
48 import java.util.Calendar;
49
50 import javax.inject.Provider;
51 import javax.jcr.Node;
52 import javax.jcr.RepositoryException;
53 import javax.jcr.Session;
54
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58 import groovy.lang.GroovyResourceLoader;
59
60
61
62
63
64
65
66 class MgnlGroovyResourceLoader implements GroovyResourceLoader {
67
68 private static final Logger log = LoggerFactory.getLogger(MgnlGroovyResourceLoader.class);
69 private static final String PROTOCOL = "magnolia-repository://";
70
71 private final GroovyResourceLoader delegate;
72 private final Provider<Context> provider;
73 private final String workspaceName;
74
75 MgnlGroovyResourceLoader(GroovyResourceLoader delegate, Provider<Context> provider, String workspaceName) {
76 this.delegate = delegate;
77 this.provider = provider;
78 this.workspaceName = workspaceName;
79 }
80
81
82
83
84 @Deprecated
85 MgnlGroovyResourceLoader(GroovyResourceLoader delegate, Context context, String repoName) throws UnsupportedOperationException {
86 throw new UnsupportedOperationException();
87 }
88
89
90
91
92 @Deprecated
93 MgnlGroovyResourceLoader(GroovyResourceLoader delegate, HierarchyManagerProvider hmp, String repoName) throws UnsupportedOperationException {
94 throw new UnsupportedOperationException();
95 }
96
97 @Override
98 public URL loadGroovySource(String name) throws MalformedURLException {
99 final URL url = loadGroovySourceFromRepository(name);
100 if (url == null) {
101 return delegate.loadGroovySource(name);
102 }
103 return url;
104 }
105
106
107
108
109
110 private URL loadGroovySourceFromRepository(String name) throws MalformedURLException {
111 if (name.startsWith("[") || name.contains("$")) {
112
113
114 log.debug("Skipping {}, array or nested class.", name);
115 return null;
116 }
117
118 final String path = "/" + name.replace('.', '/');
119 try {
120 final Session session = provider.get().getJCRSession(workspaceName);
121 if (!session.nodeExists(path)) {
122 return null;
123 }
124 final Node node = session.getNode(path);
125 if (NodeTypes.Deleted.getDeleted(node) == null && PropertyUtil.getBoolean(node, "enabled", false)) {
126 return new URL(null, PROTOCOL + session.getWorkspace().getName() + path, new MagnoliaStreamHandler(session));
127 } else {
128 return null;
129 }
130 } catch (RepositoryException e) {
131 return null;
132 }
133 }
134
135
136
137
138 protected static class MagnoliaStreamHandler extends URLStreamHandler {
139 private final Session session;
140
141
142
143
144 @Deprecated
145 public MagnoliaStreamHandler(HierarchyManager hm) {
146 this(hm.getWorkspace().getSession());
147 }
148
149 public MagnoliaStreamHandler(Session session) {
150 this.session = session;
151 }
152
153 @Override
154 protected URLConnection openConnection(URL u) throws IOException {
155 if (!"magnolia-repository".equals(u.getProtocol())) {
156 throw new IllegalStateException("Unsupported protocol: " + u.getProtocol() + " (only supports \"magnolia-repository\")");
157 }
158 return new MagnoliaURLConnection(u, session);
159 }
160 }
161
162
163
164
165 protected static class MagnoliaURLConnection extends URLConnection {
166 private final Node node;
167
168
169
170
171 @Deprecated
172 public MagnoliaURLConnection(URL u, HierarchyManager hm) throws IOException {
173 this(u, hm.getWorkspace().getSession());
174 }
175
176 public MagnoliaURLConnection(URL u, Session session) throws IOException {
177 super(u);
178
179 final String path = u.getPath();
180
181 try {
182 this.node = session.getNode(path);
183 } catch (RepositoryException e) {
184 throw new IOException("Can't get " + path + " from the " + session.getWorkspace().getName() + " workspace: " + e.getClass().getSimpleName() + ": " + e.getMessage());
185 }
186 }
187
188 @Override
189 public void connect() throws IOException {
190
191
192
193
194
195 }
196
197 @Override
198 public InputStream getInputStream() throws IOException {
199
200
201 try {
202 return node.getProperty("text").getBinary().getStream();
203 } catch (RepositoryException e) {
204 throw new IOException(e);
205 }
206 }
207
208 @Override
209 public long getLastModified() {
210 try {
211 Calendar date = NodeTypes.LastModified.getLastModified(node);
212 return date.getTimeInMillis();
213 } catch (RepositoryException e) {
214 return 0;
215 }
216
217 }
218 }
219 }