blob: 1e09fccd7ccc842b212b16269dc942c8db1091ca [file] [log] [blame]
Richard S. Hall85bafab2009-07-13 13:25:46 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20package org.cauldron.bld.core.internal.model.eclipse;
21
22import java.io.File;
23import java.io.FileOutputStream;
24import java.io.IOException;
25import java.io.InputStream;
26import java.io.InterruptedIOException;
27import java.io.OutputStream;
28import java.net.HttpURLConnection;
29import java.net.URI;
30import java.net.URL;
31import java.net.URLConnection;
32import java.util.HashSet;
33import java.util.Set;
34
35import org.cauldron.bld.core.BldCore;
36import org.cauldron.sigil.model.AbstractCompoundModelElement;
37import org.cauldron.sigil.model.eclipse.IDownloadJar;
38import org.cauldron.sigil.model.eclipse.ISCAComposite;
39import org.cauldron.sigil.model.eclipse.ISigilBundle;
40import org.cauldron.sigil.model.osgi.IBundleModelElement;
41import org.cauldron.sigil.model.osgi.IPackageExport;
42import org.cauldron.sigil.model.osgi.IPackageImport;
43import org.eclipse.core.runtime.IPath;
44import org.eclipse.core.runtime.IProgressMonitor;
45import org.eclipse.core.runtime.SubMonitor;
46import org.osgi.framework.Version;
47
48/**
49 * @author dave
50 *
51 */
52public class SigilBundle extends AbstractCompoundModelElement implements ISigilBundle {
53
54 private static final long serialVersionUID = 1L;
55
56 private IBundleModelElement bundle;
57 private IDownloadJar download;
58 private Set<IPath> sourcePaths;
59 private Set<IPath> libraryPaths;
60 private Set<ISCAComposite> composites;
61 private Set<String> classpath;
62 private Set<String> packages;
63 private Set<String> dlPackages;
64 private IPath location;
65
66 private IPath sourcePathLocation;
67 private IPath licencePathLocation;
68 private IPath sourceRootPath;
69 private String bundleHost;
70
71 public SigilBundle() {
72 super( "Sigil Bundle" );
73 sourcePaths = new HashSet<IPath>();
74 libraryPaths = new HashSet<IPath>();
75 composites = new HashSet<ISCAComposite>();
76 classpath = new HashSet<String>();
77 packages = new HashSet<String>();
78 dlPackages = new HashSet<String>();
79 }
80
81 public void synchronize(IProgressMonitor monitor) throws IOException {
82 SubMonitor progress = SubMonitor.convert(monitor, 100);
83 progress.subTask("Synchronizing " + bundle.getSymbolicName() + " binary" );
84 sync(location, bundle.getUpdateLocation(), progress.newChild(45));
85
86 try {
87 progress.subTask("Synchronizing " + bundle.getSymbolicName() + " source" );
88 sync(sourcePathLocation, bundle.getSourceLocation(), progress.newChild(45));
89 } catch (IOException e) {
90 BldCore.error( "Failed to download source for " + bundle.getSymbolicName() + " " + bundle.getVersion(), e.getCause() );
91 }
92
93 try {
94 progress.subTask("Synchronizing " + bundle.getSymbolicName() + " licence" );
95 sync(licencePathLocation, bundle.getLicenseURI(), progress.newChild(10));
96 } catch (IOException e) {
97 BldCore.error( "Failed to download licence for " + bundle.getSymbolicName() + " " + bundle.getVersion(), e.getCause() );
98 }
99 }
100
101 public boolean isSynchronized() {
102 return location == null || location.toFile().exists();
103 }
104
105 private static void sync(IPath local, URI remote, IProgressMonitor monitor) throws IOException {
106 try {
107 if ( local != null && !local.toFile().exists() ) {
108 if ( remote != null ) {
109 URL url = remote.toURL();
110 URLConnection connection = url.openConnection();
111 int contentLength = connection.getContentLength();
112
113 monitor.beginTask("Downloading from " + url.getHost(), contentLength);
114
115 InputStream in = null;
116 OutputStream out = null;
117 try {
118 URLConnection conn = url.openConnection();
119 if ( conn instanceof HttpURLConnection ) {
120 HttpURLConnection http = (HttpURLConnection) conn;
121 http.setConnectTimeout(10000);
122 http.setReadTimeout(5000);
123 }
124 in = conn.getInputStream();
125 File f = local.toFile();
126 f.getParentFile().mkdirs();
127 out = new FileOutputStream( f );
128 stream( in, out, monitor );
129 }
130 finally {
131 if ( in != null ) {
132 in.close();
133 }
134 if ( out != null ) {
135 out.close();
136 }
137 monitor.done();
138 }
139 }
140 }
141 }
142 catch (IOException e) {
143 local.toFile().delete();
144 throw e;
145 }
146 }
147
148 private static void stream(InputStream in, OutputStream out, IProgressMonitor monitor) throws IOException {
149 byte[] b = new byte[1024];
150 for ( ;; ) {
151 if ( monitor.isCanceled() ) {
152 throw new InterruptedIOException( "User canceled download" );
153 }
154 int r = in.read( b );
155 if ( r == -1 ) break;
156 out.write(b, 0, r);
157 monitor.worked(r);
158 }
159
160 out.flush();
161 }
162
163 public IBundleModelElement getBundleInfo() {
164 return bundle;
165 }
166
167 public void setBundleInfo(IBundleModelElement bundle) {
168 if ( bundle == null ) {
169 if (this.bundle != null) {
170 this.bundle.setParent(null);
171 }
172 }
173 else {
174 bundle.setParent(this);
175 }
176 this.bundle = bundle;
177 }
178
179 public IDownloadJar getDownloadJar() {
180 return download;
181 }
182
183 public void setDownloadJar(IDownloadJar download) {
184 this.download = download;
185 }
186
187 public void addLibraryPath( IPath path ) {
188 libraryPaths.add( path );
189 }
190
191 public void removeLibraryPath( IPath path ) {
192 libraryPaths.remove( path );
193 }
194
195 public Set<IPath> getLibraryPaths() {
196 return libraryPaths;
197 }
198
199 public void addSourcePath( IPath path ) {
200 sourcePaths.add( path );
201 }
202
203 public void removeSourcePath( IPath path ) {
204 sourcePaths.remove( path );
205 }
206
207 public Set<IPath> getSourcePaths() {
208 return sourcePaths;
209 }
210
211 public void clearSourcePaths() {
212 sourcePaths.clear();
213 }
214
215 public void addComposite(ISCAComposite composite) {
216 composites.add( composite );
217 composite.setParent(this);
218 }
219
220 public Set<ISCAComposite> getComposites() {
221 return composites;
222 }
223
224 public void removeComposite(ISCAComposite composite) {
225 if ( composites.remove( composite ) ) {
226 composite.setParent(null);
227 }
228 }
229 public void addClasspathEntry(String encodedClasspath) {
230 classpath.add( encodedClasspath.trim() );
231 }
232
233 public Set<String> getClasspathEntrys() {
234 return classpath;
235 }
236
237 public void removeClasspathEntry(String encodedClasspath) {
238 classpath.remove(encodedClasspath.trim());
239 }
240
241 public IPath getLocation() {
242 return location;
243 }
244
245 public void setLocation(IPath location) {
246 this.location = location;
247 }
248
249 public IPath getSourcePathLocation() {
250 return sourcePathLocation;
251 }
252 public IPath getSourceRootPath() {
253 return sourceRootPath;
254 }
255 public void setSourcePathLocation(IPath location) {
256 this.sourcePathLocation = location;
257 }
258 public void setSourceRootPath(IPath location) {
259 this.sourceRootPath = location;
260 }
261
262 @Override
263 public String toString() {
264 return "SigilBundle[" + (getBundleInfo() == null ? null : (getBundleInfo().getSymbolicName() + ":" + getBundleInfo().getVersion())) + "]";
265 }
266
267 @Override
268 public boolean equals(Object obj) {
269 if ( obj == null ) return false;
270 if ( obj == this ) return true;
271
272 if ( obj instanceof SigilBundle) {
273 return obj.toString().equals( toString() );
274 }
275
276 return false;
277 }
278 @Override
279 public int hashCode() {
280 return 31 * toString().hashCode();
281 }
282
283 public IPath getLicencePathLocation() {
284 return licencePathLocation;
285 }
286
287 public void setLicencePathLocation(IPath licencePathLocation) {
288 this.licencePathLocation = licencePathLocation;
289 }
290
291 public String getFragmentHost() {
292 return bundleHost;
293 }
294
295 public void setFragmentHost(String symbolicName) {
296 this.bundleHost = symbolicName;
297 }
298
299 public String getElementName() {
300 return bundle.getSymbolicName();
301 }
302
303 public Version getVersion() {
304 return bundle.getVersion();
305 }
306
307 public void setVersion(Version version) {
308 this.bundle.setVersion(version);
309 }
310
311 public String getSymbolicName() {
312 return bundle.getSymbolicName();
313 }
314
315 public Set<String> getPackages() {
316 return packages;
317 }
318
319 public void addPackage(String pkg) {
320 packages.add(pkg);
321 }
322
323 public boolean removePackage(String pkg) {
324 return packages.remove(pkg);
325 }
326
327 public Set<String> getDownloadPackages() {
328 return dlPackages;
329 }
330
331 public void addDownloadPackage(String pkg) {
332 dlPackages.add(pkg);
333 }
334
335 public boolean removeDownloadPackage(String pkg) {
336 return dlPackages.remove(pkg);
337 }
338
339 public IPackageExport findExport(String packageName) {
340 for ( IPackageExport e : bundle.getExports() ) {
341 if ( packageName.equals( e.getPackageName() ) ) {
342 return e;
343 }
344 }
345 return null;
346 }
347
348 public IPackageImport findImport(String packageName) {
349 for ( IPackageImport i : bundle.getImports() ) {
350 if ( packageName.equals( i.getPackageName() ) ) {
351 return i;
352 }
353 }
354 return null;
355 }
356}