1 package org
.argeo
.slc
.repo
.osgi
;
3 import static org
.argeo
.slc
.ManifestConstants
.SLC_ORIGIN_M2
;
4 import static org
.argeo
.slc
.ManifestConstants
.SLC_ORIGIN_URI
;
6 import java
.io
.IOException
;
8 import java
.nio
.file
.Files
;
9 import java
.nio
.file
.Path
;
10 import java
.nio
.file
.Paths
;
11 import java
.util
.ArrayList
;
12 import java
.util
.HashSet
;
13 import java
.util
.Iterator
;
14 import java
.util
.List
;
17 import java
.util
.SortedSet
;
18 import java
.util
.TreeMap
;
19 import java
.util
.TreeSet
;
21 import org
.argeo
.api
.cms
.CmsLog
;
22 import org
.argeo
.slc
.CategoryNameVersion
;
23 import org
.argeo
.slc
.ManifestConstants
;
24 import org
.argeo
.slc
.ModuleSet
;
25 import org
.argeo
.slc
.NameVersion
;
26 import org
.argeo
.slc
.build
.Distribution
;
27 import org
.argeo
.slc
.execution
.ExecutionFlow
;
28 import org
.argeo
.slc
.repo
.ArgeoOsgiDistribution
;
29 import org
.argeo
.slc
.repo
.ArtifactDistribution
;
30 import org
.argeo
.slc
.repo
.FreeLicense
;
31 import org
.eclipse
.aether
.artifact
.Artifact
;
32 import org
.eclipse
.aether
.artifact
.DefaultArtifact
;
33 import org
.osgi
.framework
.Constants
;
36 * A consistent and versioned OSGi distribution, which can be built and tested.
38 public class ArgeoOsgiDistributionImpl
extends ArtifactDistribution
implements ArgeoOsgiDistribution
{
39 private final static CmsLog log
= CmsLog
.getLog(ArgeoOsgiDistributionImpl
.class);
41 private List
<Object
> modules
= new ArrayList
<Object
>();
43 public ArgeoOsgiDistributionImpl(String coords
) {
48 if (log
.isDebugEnabled())
49 log
.debug(describe());
50 migrateTov2(Paths
.get(System
.getProperty("user.home"), "dev/git/unstable/argeo-tp/migration"));
53 public void destroy() {
57 public String
describe() {
58 SortedSet
<String
> sort
= new TreeSet
<String
>();
59 Iterator
<?
extends NameVersion
> nvIt
= nameVersions();
60 while (nvIt
.hasNext()) {
61 NameVersion nv
= nvIt
.next();
62 String str
= nv
.toString();
63 if (nv
instanceof MavenWrapper
)
64 str
= str
+ "\t(Maven)";
65 else if (nv
instanceof UriWrapper
)
66 str
= str
+ "\t(URI)";
67 else if (nv
instanceof ArchiveWrapperCNV
)
68 str
= str
+ "\t(OSGi from archive)";
69 else if (nv
instanceof BndWrapper
)
70 str
= str
+ "\t(Plain BND from archive)";
72 str
= str
+ "\t(UNKNOWN??)";
76 StringBuffer buf
= new StringBuffer("## DISTRIBUTION " + toString() + " ##\n");
77 for (String str
: sort
) {
78 buf
.append(str
).append('\n');
80 return buf
.toString();
83 public void migrateTov2(Path baseDir
) {
84 Set
<ArchiveWrapper
> archiveWrappers
= new HashSet
<>();
85 Iterator
<?
extends NameVersion
> nvIt
= nameVersions();
86 while (nvIt
.hasNext()) {
87 NameVersion nv
= nvIt
.next();
89 if (nv
instanceof CategoryNameVersion
) {
90 CategoryNameVersion cnv
= (CategoryNameVersion
) nv
;
92 Path categoryBase
= baseDir
.resolve(cnv
.getCategory());
93 Files
.createDirectories(categoryBase
);
94 if (cnv
instanceof BndWrapper
) {
95 BndWrapper bw
= (BndWrapper
) cnv
;
96 Path bndPath
= categoryBase
.resolve(cnv
.getName() + ".bnd");
97 Map
<String
, String
> props
= new TreeMap
<>();
98 for (Map
.Entry
<Object
, Object
> entry
: ((BndWrapper
) cnv
).getBndProperties().entrySet()) {
99 props
.put(entry
.getKey().toString(), entry
.getValue().toString());
101 props
.put(Constants
.BUNDLE_SYMBOLICNAME
, cnv
.getName());
102 props
.put(Constants
.BUNDLE_VERSION
, cnv
.getVersion());
103 if (bw
.getLicense() != null)
104 props
.put(Constants
.BUNDLE_LICENSE
, bw
.getLicense().toString());
106 log
.warn("No license for " + cnv
);
107 if (bw
.getDoNotModify()) {
108 props
.put(ManifestConstants
.SLC_ORIGIN_MANIFEST_NOT_MODIFIED
.toString(), "true");
110 // props.put("SLC-Category", cnv.getCategory());
112 if (cnv
instanceof MavenWrapper
) {
113 MavenWrapper mw
= (MavenWrapper
) cnv
;
114 String sourceCoords
= mw
.getSourceCoords();
115 props
.put(SLC_ORIGIN_M2
.toString(), sourceCoords
);
116 Artifact mavenCnv
= new DefaultArtifact(sourceCoords
);
117 if (mavenCnv
.getArtifactId().equals(cnv
.getName()))
118 props
.remove(Constants
.BUNDLE_SYMBOLICNAME
);
119 if (mavenCnv
.getVersion().equals(cnv
.getVersion()))
120 props
.remove(Constants
.BUNDLE_VERSION
);
121 } else if (cnv
instanceof UriWrapper
) {
122 UriWrapper mw
= (UriWrapper
) cnv
;
123 props
.put(SLC_ORIGIN_URI
.toString(), mw
.getEffectiveUri());
124 if (mw
.getUri() == null && mw
.getBaseUri() != null) {
125 log
.warn("Base URI for " + cnv
);
126 props
.put("SLC-Origin-BaseURI", mw
.getBaseUri());
127 props
.put("SLC-Origin-VersionSeparator", mw
.getVersionSeparator());
130 log
.warn("Unidentified BND wrapper " + cnv
);
134 try (Writer writer
= Files
.newBufferedWriter(bndPath
)) {
135 // writer.write("# " + cnv + "\n");
136 props
: for (String key
: props
.keySet()) {
137 String value
= props
.get(key
);
138 if (Constants
.EXPORT_PACKAGE
.equals(key
) && "*".equals(value
.trim()))
141 writer
.write(key
+ ": " + value
+ '\n');
143 if (log
.isTraceEnabled())
144 log
.trace("Wrote " + bndPath
);
146 } else if (cnv
instanceof ArchiveWrapperCNV
) {
147 ArchiveWrapperCNV onv
= (ArchiveWrapperCNV
) cnv
;
148 ArchiveWrapper aw
= onv
.getBuild();
149 archiveWrappers
.add(aw
);
150 // TODO specify and implement archive wrapper support
152 log
.warn("Unsupported wrapper " + cnv
.getClass() + " for " + cnv
);
156 log
.error("Category required for " + nv
+ ", skipping...");
158 } catch (IOException e
) {
159 log
.error("Could not process " + nv
, e
);
162 if (log
.isDebugEnabled()) {
163 for (ArchiveWrapper aw
: archiveWrappers
) {
164 log
.debug("Archive wrapper " + aw
.getUri() + ":");
165 log
.debug(" includes: " + aw
.getIncludes());
166 log
.debug(" excludes: " + aw
.getExcludes());
167 log
.debug(" beans : " + aw
.getWrappers());
169 String uri
= aw
.getUri();
170 String duName
= null;
171 String category
= null;
172 String oldCategory
= null;
173 if (uri
.startsWith("http://www.eclipse.org/downloads/rt/rap/3.10/e4/rap-e4")) {
174 duName
= "eclipse-rap";
175 category
= "org.argeo.tp.eclipse.rap";
176 oldCategory
= "org.argeo.tp.rap.e4";
177 } else if (uri
.startsWith("http://www.eclipse.org/downloads/equinox/")) {
178 duName
= "eclipse-equinox";
179 category
= "org.argeo.tp.eclipse.equinox";
180 oldCategory
= "org.argeo.tp.equinox";
181 } else if (uri
.startsWith("http://www.eclipse.org/downloads/eclipse/downloads/drops4")) {
182 duName
= "eclipse-rcp";
183 category
= "org.argeo.tp.eclipse.rcp";
184 oldCategory
= "org.argeo.tp.rcp.e4";
187 if (duName
!= null) {
189 Path duDir
= baseDir
.resolve(category
).resolve(duName
);
190 Files
.createDirectories(duDir
);
191 Path bndPath
= duDir
.resolve("common.bnd");
192 Path includesPath
= duDir
.resolve("includes.properties");
194 Map
<String
, String
> props
= new TreeMap
<>();
195 props
.put(ManifestConstants
.SLC_ORIGIN_URI
.toString(), aw
.getUri());
196 props
.put(ManifestConstants
.SLC_ORIGIN_MANIFEST_NOT_MODIFIED
.toString(), "true");
197 props
.put(Constants
.BUNDLE_LICENSE
, FreeLicense
.EPL
.toString());
199 try (Writer bndWriter
= Files
.newBufferedWriter(bndPath
);
200 Writer includesWriter
= Files
.newBufferedWriter(includesPath
);) {
201 // writer.write("# " + cnv + "\n");
202 props
: for (String key
: props
.keySet()) {
203 String value
= props
.get(key
);
204 if (Constants
.EXPORT_PACKAGE
.equals(key
) && "*".equals(value
.trim()))
207 bndWriter
.write(key
+ ": " + value
+ '\n');
210 for (String key
: aw
.getIncludes().keySet()) {
211 String value
= aw
.getIncludes().get(key
);
212 if (value
.equals(oldCategory
))
214 includesWriter
.write(key
+ "=" + value
+ '\n');
216 if (log
.isTraceEnabled())
217 log
.trace("Wrote " + bndPath
);
219 } catch (IOException e
) {
220 log
.error("Could not process " + aw
, e
);
229 public Iterator
<NameVersion
> nameVersions() {
230 List
<NameVersion
> nameVersions
= new ArrayList
<NameVersion
>();
231 for (Object module
: modules
) {
232 // extract runnable from execution flow
233 if (module
instanceof ExecutionFlow
) {
234 for (Iterator
<Runnable
> it
= ((ExecutionFlow
) module
).runnables(); it
.hasNext();) {
235 processModule(nameVersions
, it
.next());
238 processModule(nameVersions
, module
);
241 return nameVersions
.iterator();
244 private void processModule(List
<NameVersion
> nameVersions
, Object module
) {
245 if (module
instanceof ModuleSet
)
246 addNameVersions(nameVersions
, (ModuleSet
) module
);
247 else if (module
instanceof NameVersion
) {
248 NameVersion nv
= (NameVersion
) module
;
249 addNameVersion(nameVersions
, nv
);
251 log
.warn("Ignored " + module
);
254 private void addNameVersions(List
<NameVersion
> nameVersions
, ModuleSet moduleSet
) {
255 Iterator
<?
extends NameVersion
> it
= moduleSet
.nameVersions();
256 while (it
.hasNext()) {
257 NameVersion nv
= it
.next();
258 addNameVersion(nameVersions
, nv
);
262 protected void addNameVersion(List
<NameVersion
> nameVersions
, NameVersion nv
) {
263 if (!nameVersions
.contains(nv
)) {
264 nameVersions
.add(nv
);
268 // Modular distribution interface methods. Not yet used.
269 public Distribution
getModuleDistribution(String moduleName
, String moduleVersion
) {
270 throw new UnsupportedOperationException();
273 public Object
getModulesDescriptor(String descriptorType
) {
274 throw new UnsupportedOperationException();
277 /* DEPENDENCY INJECTION */
278 public void setModules(List
<Object
> modules
) {
279 this.modules
= modules
;