X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.osgi.boot%2Fsrc%2Forg%2Fargeo%2Fosgi%2Fboot%2FDistributionBundle.java;h=a336b6446c920f656f2457fbbcd3fe3bd0d86221;hb=25a31ea46e5de6ce0de366fdb999588c6788c540;hp=340472558f15d9125f9537be4dc9e98526287672;hpb=807ccba419e96a18f7af67a66f986ae4c91c03d9;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/DistributionBundle.java b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/DistributionBundle.java index 340472558..a336b6446 100644 --- a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/DistributionBundle.java +++ b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/DistributionBundle.java @@ -1,33 +1,28 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ package org.argeo.osgi.boot; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.SortedMap; import java.util.StringTokenizer; +import java.util.TreeMap; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import java.util.jar.Manifest; import org.osgi.framework.Constants; +import org.osgi.framework.Version; /** * A distribution bundle is a bundle within a maven-like distribution @@ -36,7 +31,6 @@ import org.osgi.framework.Constants; * expected that it is. The root of the repository is computed based on the file * name of the URL and of the content of the index. */ -@SuppressWarnings({ "rawtypes", "unchecked" }) public class DistributionBundle { private final static String INDEX_FILE_NAME = "modularDistribution.csv"; @@ -50,8 +44,9 @@ public class DistributionBundle { private String baseUrl; /** can be null */ private String relativeUrl; + private String localCache; - private List/* */artifacts; + private List artifacts; private String separator = ","; @@ -59,30 +54,78 @@ public class DistributionBundle { this.url = url; } - public DistributionBundle(String baseUrl, String relativeUrl) { + public DistributionBundle(String baseUrl, String relativeUrl, String localCache) { if (baseUrl == null || !baseUrl.endsWith("/")) - throw new OsgiBootException("Base url " + baseUrl - + " badly formatted"); + throw new OsgiBootException("Base url " + baseUrl + " badly formatted"); if (relativeUrl.startsWith("http") || relativeUrl.startsWith("file:")) - throw new OsgiBootException("Relative URL " + relativeUrl - + " badly formatted"); - this.url = baseUrl + relativeUrl; + throw new OsgiBootException("Relative URL " + relativeUrl + " badly formatted"); + this.url = constructUrl(baseUrl, relativeUrl); this.baseUrl = baseUrl; this.relativeUrl = relativeUrl; + this.localCache = localCache; + } + + protected String constructUrl(String baseUrl, String relativeUrl) { + try { + if (relativeUrl.indexOf('*') >= 0) { + if (!baseUrl.startsWith("file:")) + throw new IllegalArgumentException( + "Wildcard support only for file:, badly formatted " + baseUrl + " and " + relativeUrl); + Path basePath = Paths.get(new URI(baseUrl)); + // Path basePath = Paths.get(new URI(baseUrl)); + // int li = relativeUrl.lastIndexOf('/'); + // String relativeDir = relativeUrl.substring(0, li); + // String relativeFile = relativeUrl.substring(li, + // relativeUrl.length()); + String pattern = "glob:" + basePath + '/' + relativeUrl; + PathMatcher pm = basePath.getFileSystem().getPathMatcher(pattern); + SortedMap res = new TreeMap<>(); + checkDir(basePath, pm, res); + if (res.size() == 0) + throw new OsgiBootException("No file matching " + relativeUrl + " found in " + baseUrl); + return res.get(res.firstKey()).toUri().toString(); + } else { + return baseUrl + relativeUrl; + } + } catch (Exception e) { + throw new OsgiBootException("Cannot build URL from " + baseUrl + " and " + relativeUrl, e); + } + } + + private void checkDir(Path dir, PathMatcher pm, SortedMap res) throws IOException { + try (DirectoryStream ds = Files.newDirectoryStream(dir)) { + for (Path path : ds) { + if (Files.isDirectory(path)) + checkDir(path, pm, res); + else if (pm.matches(path)) { + String fileName = path.getFileName().toString(); + fileName = fileName.substring(0, fileName.lastIndexOf('.')); + if (fileName.endsWith("-SNAPSHOT")) + fileName = fileName.substring(0, fileName.lastIndexOf('-')) + ".SNAPSHOT"; + fileName = fileName.substring(fileName.lastIndexOf('-') + 1); + Version version = new Version(fileName); + res.put(version, path); + } + } + } } public void processUrl() { JarInputStream jarIn = null; try { URL u = new URL(url); + + // local cache + URI localUri = new URI(localCache + relativeUrl); + Path localPath = Paths.get(localUri); + if (Files.exists(localPath)) + u = localUri.toURL(); jarIn = new JarInputStream(u.openStream()); // meta data manifest = jarIn.getManifest(); - symbolicName = manifest.getMainAttributes().getValue( - Constants.BUNDLE_SYMBOLICNAME); - version = manifest.getMainAttributes().getValue( - Constants.BUNDLE_VERSION); + symbolicName = manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME); + version = manifest.getMainAttributes().getValue(Constants.BUNDLE_VERSION); JarEntry indexEntry; while ((indexEntry = jarIn.getNextJarEntry()) != null) { @@ -95,8 +138,7 @@ public class DistributionBundle { // list artifacts if (indexEntry == null) - throw new OsgiBootException("No index " + INDEX_FILE_NAME - + " in " + url); + throw new OsgiBootException("No index " + INDEX_FILE_NAME + " in " + url); artifacts = listArtifacts(jarIn); jarIn.closeEntry(); @@ -104,12 +146,10 @@ public class DistributionBundle { // won't work if distribution artifact is not listed for (int i = 0; i < artifacts.size(); i++) { OsgiArtifact osgiArtifact = (OsgiArtifact) artifacts.get(i); - if (osgiArtifact.getSymbolicName().equals(symbolicName) - && osgiArtifact.getVersion().equals(version)) { + if (osgiArtifact.getSymbolicName().equals(symbolicName) && osgiArtifact.getVersion().equals(version)) { String relativeUrl = osgiArtifact.getRelativeUrl(); if (url.endsWith(relativeUrl)) { - baseUrl = url.substring(0, url.length() - - osgiArtifact.getRelativeUrl().length()); + baseUrl = url.substring(0, url.length() - osgiArtifact.getRelativeUrl().length()); break; } } @@ -126,19 +166,20 @@ public class DistributionBundle { } } - protected List/* */listArtifacts(InputStream in) { - List osgiArtifacts = new ArrayList(); + protected List listArtifacts(InputStream in) { + List osgiArtifacts = new ArrayList(); BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(in)); String line = null; - while ((line = reader.readLine()) != null) { + lines: while ((line = reader.readLine()) != null) { StringTokenizer st = new StringTokenizer(line, separator); String moduleName = st.nextToken(); String moduleVersion = st.nextToken(); String relativeUrl = st.nextToken(); - osgiArtifacts.add(new OsgiArtifact(moduleName, moduleVersion, - relativeUrl)); + if (relativeUrl.endsWith(".pom")) + continue lines; + osgiArtifacts.add(new OsgiArtifact(moduleName, moduleVersion, relativeUrl)); } } catch (Exception e) { throw new OsgiBootException("Cannot list artifacts", e); @@ -147,29 +188,41 @@ public class DistributionBundle { } /** Convenience method */ - public static DistributionBundle processUrl(String baseUrl, - String realtiveUrl) { - DistributionBundle distributionBundle = new DistributionBundle(baseUrl, - realtiveUrl); + public static DistributionBundle processUrl(String baseUrl, String relativeUrl, String localCache) { + DistributionBundle distributionBundle = new DistributionBundle(baseUrl, relativeUrl, localCache); distributionBundle.processUrl(); return distributionBundle; } /** - * List full URLs of the bunmdles, based on base URL, usable directly for + * List full URLs of the bundles, based on base URL, usable directly for * download. */ - public List/* */listUrls() { + public List listUrls() { if (baseUrl == null) throw new OsgiBootException("Base URL is not set"); if (artifacts == null) throw new OsgiBootException("Artifact list not initialized"); - List/* */urls = new ArrayList(); + List urls = new ArrayList(); for (int i = 0; i < artifacts.size(); i++) { OsgiArtifact osgiArtifact = (OsgiArtifact) artifacts.get(i); - urls.add(baseUrl + osgiArtifact.getRelativeUrl()); + // local cache + URI localUri; + try { + localUri = new URI(localCache + relativeUrl); + } catch (URISyntaxException e) { + OsgiBootUtils.warn(e.getMessage()); + localUri = null; + } + Version version = new Version(osgiArtifact.getVersion()); + if (localUri != null && Files.exists(Paths.get(localUri)) && version.getQualifier() != null + && version.getQualifier().startsWith("SNAPSHOT")) { + urls.add(localCache + osgiArtifact.getRelativeUrl()); + } else { + urls.add(baseUrl + osgiArtifact.getRelativeUrl()); + } } return urls; } @@ -193,8 +246,7 @@ public class DistributionBundle { private final String version; private final String relativeUrl; - public OsgiArtifact(String symbolicName, String version, - String relativeUrl) { + public OsgiArtifact(String symbolicName, String version, String relativeUrl) { super(); this.symbolicName = symbolicName; this.version = version;