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