X-Git-Url: http://git.argeo.org/?p=lgpl%2Fargeo-commons.git;a=blobdiff_plain;f=org.argeo.init%2Fsrc%2Forg%2Fargeo%2Fapi%2Fa2%2FFsA2Source.java;fp=org.argeo.init%2Fsrc%2Forg%2Fargeo%2Fapi%2Fa2%2FFsA2Source.java;h=e63a6f175c15765ef80ae022465d7adda2cf8e16;hp=0000000000000000000000000000000000000000;hb=b95462873703848193e56fcbe997693630db6121;hpb=55d88fba80cec198a0f11ba7545e19878c51fc5e diff --git a/org.argeo.init/src/org/argeo/api/a2/FsA2Source.java b/org.argeo.init/src/org/argeo/api/a2/FsA2Source.java new file mode 100644 index 000000000..e63a6f175 --- /dev/null +++ b/org.argeo.init/src/org/argeo/api/a2/FsA2Source.java @@ -0,0 +1,173 @@ +package org.argeo.api.a2; + +import java.io.IOException; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.StringJoiner; +import java.util.TreeMap; + +import org.osgi.framework.Version; + +/** A file system {@link AbstractProvisioningSource} in A2 format. */ +public class FsA2Source extends AbstractProvisioningSource implements A2Source { + private final static Logger logger = System.getLogger(FsA2Source.class.getName()); + + private final Path base; + private final Map variantsXOr; + + private final List includes; + private final List excludes; + + public FsA2Source(Path base, Map variantsXOr, boolean usingReference, List includes, + List excludes) { + super(usingReference); + this.base = base; + this.variantsXOr = new HashMap<>(variantsXOr); + this.includes = includes; + this.excludes = excludes; + } + + void load() throws IOException { + SortedMap contributions = new TreeMap<>(); + + DirectoryStream contributionPaths = Files.newDirectoryStream(base); + contributions: for (Path contributionPath : contributionPaths) { + if (Files.isDirectory(contributionPath)) { + String contributionId = contributionPath.getFileName().toString(); + if (A2Contribution.BOOT.equals(contributionId))// skip boot + continue contributions; + if (contributionId.contains(".")) { + A2Contribution contribution = getOrAddContribution(contributionId); + contributions.put(contributionPath, contribution); + } else {// variants + Path variantPath = null; + // is it an explicit variant? + String variant = variantsXOr.get(contributionPath.getFileName().toString()); + if (variant != null) { + variantPath = contributionPath.resolve(variant); + } + + // is there a default variant? + if (variantPath == null) { + Path defaultPath = contributionPath.resolve(A2Contribution.DEFAULT); + if (Files.exists(defaultPath)) { + variantPath = defaultPath; + } + } + + if (variantPath == null) + continue contributions; + + // a variant was found, let's collect its contributions (also common ones in its + // parent) + if (Files.exists(variantPath.getParent())) { + for (Path variantContributionPath : Files.newDirectoryStream(variantPath.getParent())) { + String variantContributionId = variantContributionPath.getFileName().toString(); + if (variantContributionId.contains(".")) { + A2Contribution contribution = getOrAddContribution(variantContributionId); + contributions.put(variantContributionPath, contribution); + } + } + } + if (Files.exists(variantPath)) { + for (Path variantContributionPath : Files.newDirectoryStream(variantPath)) { + String variantContributionId = variantContributionPath.getFileName().toString(); + if (variantContributionId.contains(".")) { + A2Contribution contribution = getOrAddContribution(variantContributionId); + contributions.put(variantContributionPath, contribution); + } + } + } + } + } + } + + contributions: for (Path contributionPath : contributions.keySet()) { + String contributionId = contributionPath.getFileName().toString(); + if (includes != null && !includes.contains(contributionId)) + continue contributions; + if (excludes != null && excludes.contains(contributionId)) + continue contributions; + A2Contribution contribution = getOrAddContribution(contributionId); + DirectoryStream modulePaths = Files.newDirectoryStream(contributionPath); + modules: for (Path modulePath : modulePaths) { + if (!Files.isDirectory(modulePath)) { + // OsgiBootUtils.debug("Registering " + modulePath); + String moduleFileName = modulePath.getFileName().toString(); + int lastDot = moduleFileName.lastIndexOf('.'); + String ext = moduleFileName.substring(lastDot + 1); + if (!"jar".equals(ext)) + continue modules; + Version version; + // TODO optimise? check attributes? + String[] nameVersion = readNameVersionFromModule(modulePath); + String componentName = nameVersion[0]; + String versionStr = nameVersion[1]; + if (versionStr != null) { + version = new Version(versionStr); + } else { + logger.log(Level.TRACE, () -> "Ignore " + modulePath + " since version cannot be found"); + continue modules; + } +// } + A2Component component = contribution.getOrAddComponent(componentName); + A2Module module = component.getOrAddModule(version, modulePath); + logger.log(Level.TRACE, () -> "Registered " + module); + } + } + } + + } + + @Override + public URI getUri() { + URI baseUri = base.toUri(); + try { + if (baseUri.getScheme().equals("file")) { + String queryPart = ""; + if (!getVariantsXOr().isEmpty()) { + StringJoiner sj = new StringJoiner("&"); + for (String key : getVariantsXOr().keySet()) { + sj.add(key + "=" + getVariantsXOr().get(key)); + } + queryPart = sj.toString(); + } + return new URI(isUsingReference() ? SCHEME_A2_REFERENCE : SCHEME_A2, null, base.toString(), queryPart, + null); + } else { + throw new UnsupportedOperationException("Unsupported scheme " + baseUri.getScheme()); + } + } catch (URISyntaxException e) { + throw new IllegalStateException("Cannot build URI from " + baseUri, e); + } + } + + protected Map getVariantsXOr() { + return variantsXOr; + } + +// public static void main(String[] args) { +// if (args.length == 0) +// throw new IllegalArgumentException("Usage: "); +// try { +// Map xOr = new HashMap<>(); +// xOr.put("osgi", "equinox"); +// xOr.put("swt", "rap"); +// FsA2Source context = new FsA2Source(Paths.get(args[0]), xOr); +// context.load(); +// context.asTree(); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } + +}