]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.osgi.boot/newsrc/org/argeo/osgi/boot/DistributionBundle.java
Rename source directories
[lgpl/argeo-commons.git] / org.argeo.osgi.boot / newsrc / org / argeo / osgi / boot / DistributionBundle.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.osgi.boot;
17
18 import java.io.BufferedReader;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.InputStreamReader;
22 import java.net.URL;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.StringTokenizer;
26 import java.util.jar.JarEntry;
27 import java.util.jar.JarInputStream;
28 import java.util.jar.Manifest;
29
30 import org.osgi.framework.Constants;
31
32 /**
33 * A distribution bundle is a bundle within a maven-like distribution
34 * groupId:Bundle-SymbolicName:Bundle-Version which references others OSGi
35 * bundle. It is not required to be OSGi complete also it will generally be
36 * expected that it is. The root of the repository is computed based on the file
37 * name of the URL and of the content of the index.
38 */
39 public class DistributionBundle {
40 private final static String INDEX_FILE_NAME = "modularDistribution.csv";
41
42 private final String url;
43
44 private Manifest manifest;
45 private String symbolicName;
46 private String version;
47
48 /** can be null */
49 private String baseUrl;
50 /** can be null */
51 private String relativeUrl;
52
53 private List/* <OsgiArtifact> */artifacts;
54
55 private String separator = ",";
56
57 public DistributionBundle(String url) {
58 this.url = url;
59 }
60
61 public DistributionBundle(String baseUrl, String relativeUrl) {
62 if (baseUrl == null || !baseUrl.endsWith("/"))
63 throw new OsgiBootException("Base url " + baseUrl
64 + " badly formatted");
65 if (relativeUrl.startsWith("http") || relativeUrl.startsWith("file:"))
66 throw new OsgiBootException("Relative URL " + relativeUrl
67 + " badly formatted");
68 this.url = baseUrl + relativeUrl;
69 this.baseUrl = baseUrl;
70 this.relativeUrl = relativeUrl;
71 }
72
73 public void processUrl() {
74 JarInputStream jarIn = null;
75 try {
76 URL u = new URL(url);
77 jarIn = new JarInputStream(u.openStream());
78
79 // meta data
80 manifest = jarIn.getManifest();
81 symbolicName = manifest.getMainAttributes().getValue(
82 Constants.BUNDLE_SYMBOLICNAME);
83 version = manifest.getMainAttributes().getValue(
84 Constants.BUNDLE_VERSION);
85
86 JarEntry indexEntry;
87 while ((indexEntry = jarIn.getNextJarEntry()) != null) {
88 String entryName = indexEntry.getName();
89 if (entryName.equals(INDEX_FILE_NAME)) {
90 break;
91 }
92 jarIn.closeEntry();
93 }
94
95 // list artifacts
96 if (indexEntry == null)
97 throw new OsgiBootException("No index " + INDEX_FILE_NAME
98 + " in " + url);
99 artifacts = listArtifacts(jarIn);
100 jarIn.closeEntry();
101
102 // find base URL
103 // won't work if distribution artifact is not listed
104 for (int i = 0; i < artifacts.size(); i++) {
105 OsgiArtifact osgiArtifact = (OsgiArtifact) artifacts.get(i);
106 if (osgiArtifact.getSymbolicName().equals(symbolicName)
107 && osgiArtifact.getVersion().equals(version)) {
108 String relativeUrl = osgiArtifact.getRelativeUrl();
109 if (url.endsWith(relativeUrl)) {
110 baseUrl = url.substring(0, url.length()
111 - osgiArtifact.getRelativeUrl().length());
112 break;
113 }
114 }
115 }
116 } catch (Exception e) {
117 throw new OsgiBootException("Cannot list URLs from " + url, e);
118 } finally {
119 if (jarIn != null)
120 try {
121 jarIn.close();
122 } catch (IOException e) {
123 // silent
124 }
125 }
126 }
127
128 protected List/* <OsgiArtifact> */listArtifacts(InputStream in) {
129 List osgiArtifacts = new ArrayList();
130 BufferedReader reader = null;
131 try {
132 reader = new BufferedReader(new InputStreamReader(in));
133 String line = null;
134 while ((line = reader.readLine()) != null) {
135 StringTokenizer st = new StringTokenizer(line, separator);
136 String moduleName = st.nextToken();
137 String moduleVersion = st.nextToken();
138 String relativeUrl = st.nextToken();
139 osgiArtifacts.add(new OsgiArtifact(moduleName, moduleVersion,
140 relativeUrl));
141 }
142 } catch (Exception e) {
143 throw new OsgiBootException("Cannot list artifacts", e);
144 }
145 return osgiArtifacts;
146 }
147
148 /** Convenience method */
149 public static DistributionBundle processUrl(String baseUrl,
150 String realtiveUrl) {
151 DistributionBundle distributionBundle = new DistributionBundle(baseUrl,
152 realtiveUrl);
153 distributionBundle.processUrl();
154 return distributionBundle;
155 }
156
157 /**
158 * List full URLs of the bunmdles, based on base URL, usable directly for
159 * download.
160 */
161 public List/* <String> */listUrls() {
162 if (baseUrl == null)
163 throw new OsgiBootException("Base URL is not set");
164
165 if (artifacts == null)
166 throw new OsgiBootException("Artifact list not initialized");
167
168 List/* <String> */urls = new ArrayList();
169 for (int i = 0; i < artifacts.size(); i++) {
170 OsgiArtifact osgiArtifact = (OsgiArtifact) artifacts.get(i);
171 urls.add(baseUrl + osgiArtifact.getRelativeUrl());
172 }
173 return urls;
174 }
175
176 public void setBaseUrl(String baseUrl) {
177 this.baseUrl = baseUrl;
178 }
179
180 /** Separator used to parse the tabular file */
181 public void setSeparator(String modulesUrlSeparator) {
182 this.separator = modulesUrlSeparator;
183 }
184
185 public String getRelativeUrl() {
186 return relativeUrl;
187 }
188
189 /** One of the listed artifact */
190 protected static class OsgiArtifact {
191 private final String symbolicName;
192 private final String version;
193 private final String relativeUrl;
194
195 public OsgiArtifact(String symbolicName, String version,
196 String relativeUrl) {
197 super();
198 this.symbolicName = symbolicName;
199 this.version = version;
200 this.relativeUrl = relativeUrl;
201 }
202
203 public String getSymbolicName() {
204 return symbolicName;
205 }
206
207 public String getVersion() {
208 return version;
209 }
210
211 public String getRelativeUrl() {
212 return relativeUrl;
213 }
214
215 }
216 }