]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.repo/src/org/argeo/slc/repo/osgi/OsgiFactoryImpl.java
92389339eba8817284724865f1e75d49d4a01443
[gpl/argeo-slc.git] / org.argeo.slc.repo / src / org / argeo / slc / repo / osgi / OsgiFactoryImpl.java
1 package org.argeo.slc.repo.osgi;
2
3 import java.io.BufferedInputStream;
4 import java.io.FileNotFoundException;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.net.MalformedURLException;
8 import java.net.URL;
9 import java.net.URLConnection;
10 import java.util.ArrayList;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14
15 import javax.jcr.Node;
16 import javax.jcr.Repository;
17 import javax.jcr.RepositoryException;
18 import javax.jcr.Session;
19
20 import org.apache.commons.io.IOUtils;
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.argeo.jcr.JcrUtils;
24 import org.argeo.slc.SlcConstants;
25 import org.argeo.slc.SlcException;
26 import org.argeo.slc.jcr.SlcNames;
27 import org.argeo.slc.jcr.SlcTypes;
28 import org.argeo.slc.repo.NodeIndexer;
29 import org.argeo.slc.repo.OsgiFactory;
30 import org.argeo.slc.repo.maven.MavenConventionsUtils;
31 import org.eclipse.aether.artifact.Artifact;
32 import org.eclipse.aether.artifact.DefaultArtifact;
33
34 /** Default implementation of {@link OsgiFactory}. */
35 public class OsgiFactoryImpl implements OsgiFactory, SlcNames {
36 private final static Log log = LogFactory.getLog(OsgiFactoryImpl.class);
37
38 private String workspace;
39 private Repository distRepository;
40 private Repository javaRepository;
41
42 private List<NodeIndexer> nodeIndexers = new ArrayList<NodeIndexer>();
43
44 /** key is URI prefix, value list of base URLs */
45 private Map<String, List<String>> mirrors = new HashMap<String, List<String>>();
46
47 private List<String> mavenRepositories = new ArrayList<String>();
48 private String downloadBase = "/download";
49 private String mavenProxyBase = downloadBase + "/maven";
50
51 public void init() {
52 if (workspace == null)
53 throw new SlcException("A workspace must be specified");
54
55 // default Maven repo
56 if (mavenRepositories.size() == 0) {
57 // mavenRepositories
58 // .add("http://search.maven.org/remotecontent?filepath=");
59 mavenRepositories.add("http://repo1.maven.org/maven2");
60 }
61
62 Session javaSession = null;
63 Session distSession = null;
64 try {
65 // TODO rather user a JavaRepoManager that will also implicitely
66 // manage the indexing of newly created nodes.
67 javaSession = JcrUtils.loginOrCreateWorkspace(javaRepository, workspace);
68 distSession = JcrUtils.loginOrCreateWorkspace(distRepository, workspace);
69
70 // Privileges
71 JcrUtils.addPrivilege(javaSession, "/", SlcConstants.ROLE_SLC, "jcr:all");
72 JcrUtils.addPrivilege(distSession, "/", SlcConstants.ROLE_SLC, "jcr:all");
73 } catch (RepositoryException e) {
74 throw new SlcException("Cannot initialize OSGi Factory " + workspace, e);
75 } finally {
76 JcrUtils.logoutQuietly(javaSession);
77 JcrUtils.logoutQuietly(distSession);
78 }
79 }
80
81 public void destroy() {
82
83 }
84
85 public Session openJavaSession() throws RepositoryException {
86 return javaRepository.login(workspace);
87 }
88
89 public Session openDistSession() throws RepositoryException {
90 return distRepository.login(workspace);
91 }
92
93 public void indexNode(Node node) {
94 for (NodeIndexer nodeIndexer : nodeIndexers) {
95 nodeIndexer.index(node);
96 }
97 }
98
99 public Node getMaven(Session distSession, String coords) throws RepositoryException {
100 Artifact artifact = new DefaultArtifact(coords);
101 String path = MavenConventionsUtils.artifactPath(mavenProxyBase, artifact);
102
103 // exists
104 if (distSession.itemExists(path))
105 return distSession.getNode(path);
106
107 for (String mavenRepo : mavenRepositories) {
108 String url = MavenConventionsUtils.artifactUrl(mavenRepo, artifact);
109 try {
110 Node node = loadUrlToPath(url, distSession, path);
111 if (node != null) {
112 // checksums
113 try {
114 loadUrlToPath(url + ".md5", distSession, path + ".md5");
115 } catch (FileNotFoundException e) {
116 // silent
117 }
118 try {
119 loadUrlToPath(url + ".sha1", distSession, path + ".sha1");
120 } catch (FileNotFoundException e) {
121 // silent
122 }
123 return node;
124 }
125 } catch (FileNotFoundException e) {
126 if (log.isDebugEnabled())
127 log.debug("Maven " + coords + " could not be downloaded from " + url);
128 }
129 }
130 throw new SlcException("Could not download Maven " + coords);
131 }
132
133 public Node getDist(Session distSession, String uri) throws RepositoryException {
134 String distPath = downloadBase + '/' + JcrUtils.urlAsPath(uri);
135
136 // already retrieved
137 if (distSession.itemExists(distPath))
138 return distSession.getNode(distPath);
139
140 // find mirror
141 List<String> urlBases = null;
142 String uriPrefix = null;
143 uriPrefixes: for (String uriPref : mirrors.keySet()) {
144 if (uri.startsWith(uriPref)) {
145 if (mirrors.get(uriPref).size() > 0) {
146 urlBases = mirrors.get(uriPref);
147 uriPrefix = uriPref;
148 break uriPrefixes;
149 }
150 }
151 }
152 if (urlBases == null)
153 try {
154 return loadUrlToPath(uri, distSession, distPath);
155 } catch (FileNotFoundException e) {
156 throw new SlcException("Cannot download " + uri, e);
157 }
158
159 // try to download
160 for (String urlBase : urlBases) {
161 String relativePath = uri.substring(uriPrefix.length());
162 String url = urlBase + relativePath;
163 try {
164 return loadUrlToPath(url, distSession, distPath);
165 } catch (FileNotFoundException e) {
166 if (log.isDebugEnabled())
167 log.debug("Cannot download " + url + ", trying another mirror");
168 }
169 }
170
171 throw new SlcException("Could not download " + uri);
172 }
173
174 /** Actually downloads a file to an internal location */
175 protected Node loadUrlToPath(String url, Session distSession, String path)
176 throws RepositoryException, FileNotFoundException {
177 if (log.isDebugEnabled())
178 log.debug("Downloading " + url + "...");
179
180 InputStream in = null;
181 URLConnection conn = null;
182 Node folderNode = JcrUtils.mkfolders(distSession, JcrUtils.parentPath(path));
183 try {
184 URL u = new URL(url);
185 conn = u.openConnection();
186 conn.connect();
187 in = new BufferedInputStream(conn.getInputStream());
188 // byte[] arr = IOUtils.toByteArray(in);
189 // Node fileNode = JcrUtils.copyBytesAsFile(folderNode,
190 // JcrUtils.nodeNameFromPath(path), arr);
191 Node fileNode = JcrUtils.copyStreamAsFile(folderNode, JcrUtils.nodeNameFromPath(path), in);
192 fileNode.addMixin(SlcTypes.SLC_KNOWN_ORIGIN);
193 Node origin = fileNode.addNode(SLC_ORIGIN, SlcTypes.SLC_PROXIED);
194 JcrUtils.urlToAddressProperties(origin, url);
195 distSession.save();
196 return fileNode;
197 } catch (MalformedURLException e) {
198 throw new SlcException("URL " + url + " not valid.", e);
199 } catch (FileNotFoundException e) {
200 throw e;
201 } catch (IOException e) {
202 throw new SlcException("Cannot load " + url + " to " + path, e);
203 } finally {
204 IOUtils.closeQuietly(in);
205 }
206
207 }
208
209 public void setWorkspace(String workspace) {
210 this.workspace = workspace;
211 }
212
213 public void setDistRepository(Repository distRepository) {
214 this.distRepository = distRepository;
215 }
216
217 public void setJavaRepository(Repository javaRepository) {
218 this.javaRepository = javaRepository;
219 }
220
221 public void setNodeIndexers(List<NodeIndexer> nodeIndexers) {
222 this.nodeIndexers = nodeIndexers;
223 }
224
225 public void setMirrors(Map<String, List<String>> mirrors) {
226 this.mirrors = mirrors;
227 }
228
229 public void setMavenRepositories(List<String> mavenRepositories) {
230 this.mavenRepositories = mavenRepositories;
231 }
232
233 public void setMavenProxyBase(String mavenProxyBase) {
234 this.mavenProxyBase = mavenProxyBase;
235 }
236
237 }