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