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