]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.init/src/org/argeo/api/a2/FsA2Source.java
Clarify ACR API
[lgpl/argeo-commons.git] / org.argeo.init / src / org / argeo / api / a2 / FsA2Source.java
1 package org.argeo.api.a2;
2
3 import java.io.IOException;
4 import java.lang.System.Logger;
5 import java.lang.System.Logger.Level;
6 import java.net.URI;
7 import java.net.URISyntaxException;
8 import java.nio.file.DirectoryStream;
9 import java.nio.file.Files;
10 import java.nio.file.Path;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.SortedMap;
15 import java.util.StringJoiner;
16 import java.util.TreeMap;
17
18 import org.osgi.framework.Version;
19
20 /** A file system {@link AbstractProvisioningSource} in A2 format. */
21 public class FsA2Source extends AbstractProvisioningSource implements A2Source {
22 private final static Logger logger = System.getLogger(FsA2Source.class.getName());
23
24 private final Path base;
25 private final Map<String, String> variantsXOr;
26
27 private final List<String> includes;
28 private final List<String> excludes;
29
30 public FsA2Source(Path base, Map<String, String> variantsXOr, boolean usingReference, List<String> includes,
31 List<String> excludes) {
32 super(usingReference);
33 this.base = base;
34 this.variantsXOr = new HashMap<>(variantsXOr);
35 this.includes = includes;
36 this.excludes = excludes;
37 }
38
39 void load() throws IOException {
40 SortedMap<Path, A2Contribution> contributions = new TreeMap<>();
41
42 DirectoryStream<Path> contributionPaths = Files.newDirectoryStream(base);
43 contributions: for (Path contributionPath : contributionPaths) {
44 if (Files.isDirectory(contributionPath)) {
45 String contributionId = contributionPath.getFileName().toString();
46 if (A2Contribution.BOOT.equals(contributionId))// skip boot
47 continue contributions;
48 if (contributionId.contains(".")) {
49 A2Contribution contribution = getOrAddContribution(contributionId);
50 contributions.put(contributionPath, contribution);
51 } else {// variants
52 Path variantPath = null;
53 // is it an explicit variant?
54 String variant = variantsXOr.get(contributionPath.getFileName().toString());
55 if (variant != null) {
56 variantPath = contributionPath.resolve(variant);
57 }
58
59 // is there a default variant?
60 if (variantPath == null) {
61 Path defaultPath = contributionPath.resolve(A2Contribution.DEFAULT);
62 if (Files.exists(defaultPath)) {
63 variantPath = defaultPath;
64 }
65 }
66
67 if (variantPath == null)
68 continue contributions;
69
70 // a variant was found, let's collect its contributions (also common ones in its
71 // parent)
72 if (Files.exists(variantPath.getParent())) {
73 for (Path variantContributionPath : Files.newDirectoryStream(variantPath.getParent())) {
74 String variantContributionId = variantContributionPath.getFileName().toString();
75 if (variantContributionId.contains(".")) {
76 A2Contribution contribution = getOrAddContribution(variantContributionId);
77 contributions.put(variantContributionPath, contribution);
78 }
79 }
80 }
81 if (Files.exists(variantPath)) {
82 for (Path variantContributionPath : Files.newDirectoryStream(variantPath)) {
83 String variantContributionId = variantContributionPath.getFileName().toString();
84 if (variantContributionId.contains(".")) {
85 A2Contribution contribution = getOrAddContribution(variantContributionId);
86 contributions.put(variantContributionPath, contribution);
87 }
88 }
89 }
90 }
91 }
92 }
93
94 contributions: for (Path contributionPath : contributions.keySet()) {
95 String contributionId = contributionPath.getFileName().toString();
96 if (includes != null && !includes.contains(contributionId))
97 continue contributions;
98 if (excludes != null && excludes.contains(contributionId))
99 continue contributions;
100 A2Contribution contribution = getOrAddContribution(contributionId);
101 DirectoryStream<Path> modulePaths = Files.newDirectoryStream(contributionPath);
102 modules: for (Path modulePath : modulePaths) {
103 if (!Files.isDirectory(modulePath)) {
104 // OsgiBootUtils.debug("Registering " + modulePath);
105 String moduleFileName = modulePath.getFileName().toString();
106 int lastDot = moduleFileName.lastIndexOf('.');
107 String ext = moduleFileName.substring(lastDot + 1);
108 if (!"jar".equals(ext))
109 continue modules;
110 Version version;
111 // TODO optimise? check attributes?
112 String[] nameVersion = readNameVersionFromModule(modulePath);
113 String componentName = nameVersion[0];
114 String versionStr = nameVersion[1];
115 if (versionStr != null) {
116 version = new Version(versionStr);
117 } else {
118 logger.log(Level.TRACE, () -> "Ignore " + modulePath + " since version cannot be found");
119 continue modules;
120 }
121 // }
122 A2Component component = contribution.getOrAddComponent(componentName);
123 A2Module module = component.getOrAddModule(version, modulePath);
124 logger.log(Level.TRACE, () -> "Registered " + module);
125 }
126 }
127 }
128
129 }
130
131 @Override
132 public URI getUri() {
133 URI baseUri = base.toUri();
134 try {
135 if (baseUri.getScheme().equals("file")) {
136 String queryPart = "";
137 if (!getVariantsXOr().isEmpty()) {
138 StringJoiner sj = new StringJoiner("&");
139 for (String key : getVariantsXOr().keySet()) {
140 sj.add(key + "=" + getVariantsXOr().get(key));
141 }
142 queryPart = sj.toString();
143 }
144 return new URI(isUsingReference() ? SCHEME_A2_REFERENCE : SCHEME_A2, null, base.toString(), queryPart,
145 null);
146 } else {
147 throw new UnsupportedOperationException("Unsupported scheme " + baseUri.getScheme());
148 }
149 } catch (URISyntaxException e) {
150 throw new IllegalStateException("Cannot build URI from " + baseUri, e);
151 }
152 }
153
154 protected Map<String, String> getVariantsXOr() {
155 return variantsXOr;
156 }
157
158 // public static void main(String[] args) {
159 // if (args.length == 0)
160 // throw new IllegalArgumentException("Usage: <path to A2 base>");
161 // try {
162 // Map<String, String> xOr = new HashMap<>();
163 // xOr.put("osgi", "equinox");
164 // xOr.put("swt", "rap");
165 // FsA2Source context = new FsA2Source(Paths.get(args[0]), xOr);
166 // context.load();
167 // context.asTree();
168 // } catch (Exception e) {
169 // e.printStackTrace();
170 // }
171 // }
172
173 }