1 package org
.argeo
.api
.a2
;
3 import java
.io
.IOException
;
4 import java
.lang
.System
.Logger
;
5 import java
.lang
.System
.Logger
.Level
;
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
;
14 import java
.util
.SortedMap
;
15 import java
.util
.StringJoiner
;
16 import java
.util
.TreeMap
;
18 import org
.osgi
.framework
.Version
;
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());
24 private final Path base
;
25 private final Map
<String
, String
> variantsXOr
;
27 private final List
<String
> includes
;
28 private final List
<String
> excludes
;
30 public FsA2Source(Path base
, Map
<String
, String
> variantsXOr
, boolean usingReference
, List
<String
> includes
,
31 List
<String
> excludes
) {
32 super(usingReference
);
34 this.variantsXOr
= new HashMap
<>(variantsXOr
);
35 this.includes
= includes
;
36 this.excludes
= excludes
;
39 void load() throws IOException
{
40 SortedMap
<Path
, A2Contribution
> contributions
= new TreeMap
<>();
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
);
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
);
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
;
67 if (variantPath
== null)
68 continue contributions
;
70 // a variant was found, let's collect its contributions (also common ones in its
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
);
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
);
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
))
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
);
118 logger
.log(Level
.TRACE
, () -> "Ignore " + modulePath
+ " since version cannot be found");
122 A2Component component
= contribution
.getOrAddComponent(componentName
);
123 A2Module module
= component
.getOrAddModule(version
, modulePath
);
124 logger
.log(Level
.TRACE
, () -> "Registered " + module
);
132 public URI
getUri() {
133 URI baseUri
= base
.toUri();
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
));
142 queryPart
= sj
.toString();
144 return new URI(isUsingReference() ? SCHEME_A2_REFERENCE
: SCHEME_A2
, null, base
.toString(), queryPart
,
147 throw new UnsupportedOperationException("Unsupported scheme " + baseUri
.getScheme());
149 } catch (URISyntaxException e
) {
150 throw new IllegalStateException("Cannot build URI from " + baseUri
, e
);
154 protected Map
<String
, String
> getVariantsXOr() {
158 // public static void main(String[] args) {
159 // if (args.length == 0)
160 // throw new IllegalArgumentException("Usage: <path to A2 base>");
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);
168 // } catch (Exception e) {
169 // e.printStackTrace();