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