Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.felix.feature.impl.FeatureServiceImpl Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.felix.feature.impl;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
import javax.json.JsonNumber;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonReader;
import javax.json.JsonString;
import javax.json.JsonValue;
import javax.json.stream.JsonGenerator;
import javax.json.stream.JsonGeneratorFactory;
import org.apache.felix.cm.json.ConfigurationReader;
import org.apache.felix.cm.json.ConfigurationWriter;
import org.apache.felix.cm.json.Configurations;
import org.osgi.service.feature.BuilderFactory;
import org.osgi.service.feature.Feature;
import org.osgi.service.feature.FeatureArtifact;
import org.osgi.service.feature.FeatureArtifactBuilder;
import org.osgi.service.feature.FeatureBuilder;
import org.osgi.service.feature.FeatureBundle;
import org.osgi.service.feature.FeatureBundleBuilder;
import org.osgi.service.feature.FeatureConfiguration;
import org.osgi.service.feature.FeatureConfigurationBuilder;
import org.osgi.service.feature.FeatureExtension;
import org.osgi.service.feature.FeatureExtensionBuilder;
import org.osgi.service.feature.FeatureService;
import org.osgi.service.feature.ID;
public class FeatureServiceImpl implements FeatureService {
private final BuilderFactoryImpl builderFactory = new BuilderFactoryImpl();
public BuilderFactory getBuilderFactory() {
return builderFactory;
}
@Override
public ID getIDfromMavenCoordinates(String mavenID) {
return IDImpl.fromMavenID(mavenID);
}
@Override
public ID getID(String groupId, String artifactId, String version) {
return new IDImpl(groupId, artifactId, version, null, null);
}
@Override
public ID getID(String groupId, String artifactId, String version, String type) {
if (type == null)
throw new NullPointerException("type must not be null");
return new IDImpl(groupId, artifactId, version, type, null);
}
@Override
public ID getID(String groupId, String artifactId, String version, String type, String classifier) {
if (type == null)
throw new NullPointerException("type must not be null");
if (classifier == null)
throw new NullPointerException("classifier must not be null");
return new IDImpl(groupId, artifactId, version, type, classifier);
}
public Feature readFeature(Reader jsonReader) throws IOException {
JsonObject json = Json.createReader(
Configurations.jsonCommentAwareReader(jsonReader)).readObject();
String id = json.getString("id");
FeatureBuilder builder = builderFactory.newFeatureBuilder(getIDfromMavenCoordinates(id));
builder.setName(json.getString("name", null));
builder.setDescription(json.getString("description", null));
builder.setDocURL(json.getString("docURL", null));
builder.setLicense(json.getString("license", null));
builder.setSCM(json.getString("scm", null));
builder.setVendor(json.getString("vendor", null));
builder.setComplete(json.getBoolean("complete", false));
builder.addVariables(getVariables(json));
builder.addBundles(getBundles(json));
builder.addCategories(getCategories(json));
builder.addConfigurations(getConfigurations(json));
builder.addExtensions(getExtensions(json));
return builder.build();
}
private Map getVariables(JsonObject json) {
Map variables = new LinkedHashMap<>();
JsonObject jo = json.getJsonObject("variables");
if (jo == null)
return Collections.emptyMap();
for (Map.Entry entry : jo.entrySet()) {
Object value;
JsonValue val = entry.getValue();
switch (val.getValueType()) {
case STRING:
value = ((JsonString) val).getString();
break;
case NUMBER:
value = ((JsonNumber) val).bigDecimalValue();
break;
case TRUE:
value = true;
break;
case FALSE:
value = false;
break;
case NULL:
value = null;
break;
default:
throw new IllegalArgumentException("Variables can only contain singular values, not objects or arrays.");
}
variables.put(entry.getKey(), value);
}
return variables;
}
private FeatureBundle[] getBundles(JsonObject json) {
JsonArray ja = json.getJsonArray("bundles");
if (ja == null)
return new FeatureBundle[] {};
List bundles = new ArrayList<>();
for (JsonValue val : ja) {
if (val.getValueType() == JsonValue.ValueType.OBJECT) {
JsonObject jo = val.asJsonObject();
String bid = jo.getString("id");
FeatureBundleBuilder builder = builderFactory.newBundleBuilder(getIDfromMavenCoordinates(bid));
for (Map.Entry entry : jo.entrySet()) {
if (entry.getKey().equals("id"))
continue;
JsonValue value = entry.getValue();
Object v;
switch (value.getValueType()) {
case NUMBER:
v = ((JsonNumber) value).longValueExact();
break;
case STRING:
v = ((JsonString) value).getString();
break;
default:
v = value.toString();
}
builder.addMetadata(entry.getKey(), v);
}
bundles.add(builder.build());
}
}
return bundles.toArray(new FeatureBundle[0]);
}
private String[] getCategories(JsonObject json) {
JsonArray ja = json.getJsonArray("categories");
if (ja == null)
return new String[] {};
List cats = ja.getValuesAs(JsonString::getString);
return cats.toArray(new String[] {});
}
private FeatureConfiguration[] getConfigurations(JsonObject json) throws IOException {
JsonObject jo = json.getJsonObject("configurations");
if (jo == null)
return new FeatureConfiguration[] {};
List configs = new ArrayList<>();
for (Map.Entry entry : jo.entrySet()) {
String p = entry.getKey();
String factoryPid = null;
int idx = p.indexOf('~');
if (idx > 0) {
factoryPid = p.substring(0, idx);
p = p.substring(idx + 1);
}
FeatureConfigurationBuilder builder;
if (factoryPid == null) {
builder = builderFactory.newConfigurationBuilder(p);
} else {
builder = builderFactory.newConfigurationBuilder(factoryPid, p);
}
JsonObject values = entry.getValue().asJsonObject();
ConfigurationReader cr = Configurations.buildReader().build(values);
Hashtable cmap = cr.readConfiguration();
for (Map.Entry cme : cmap.entrySet()) {
builder.addValue(cme.getKey(), cme.getValue());
}
configs.add(builder.build());
}
return configs.toArray(new FeatureConfiguration[] {});
}
private FeatureExtension[] getExtensions(JsonObject json) {
JsonObject jo = json.getJsonObject("extensions");
if (jo == null)
return new FeatureExtension[] {};
List extensions = new ArrayList<>();
for (Map.Entry entry : jo.entrySet()) {
JsonObject exData = entry.getValue().asJsonObject();
FeatureExtension.Type type;
if (exData.containsKey("text")) {
type = FeatureExtension.Type.TEXT;
} else if (exData.containsKey("artifacts")) {
type = FeatureExtension.Type.ARTIFACTS;
} else if (exData.containsKey("json")) {
type = FeatureExtension.Type.JSON;
} else {
throw new IllegalStateException("Invalid extension: " + entry);
}
String k = exData.getString("kind", "optional");
FeatureExtension.Kind kind = FeatureExtension.Kind.valueOf(k.toUpperCase());
FeatureExtensionBuilder builder = builderFactory.newExtensionBuilder(entry.getKey(), type, kind);
switch (type) {
case TEXT:
exData.getJsonArray("text")
.stream()
.filter(jv -> jv.getValueType() == JsonValue.ValueType.STRING)
.map(jv -> ((JsonString) jv).getString())
.forEach(builder::addText);
break;
case ARTIFACTS:
exData.getJsonArray("artifacts")
.stream()
.filter(jv -> jv.getValueType() == JsonValue.ValueType.OBJECT)
.map(jv -> (JsonObject) jv)
.forEach(md -> {
Map v = new HashMap<>(md);
JsonString idVal = (JsonString) v.remove("id");
ID id = getIDfromMavenCoordinates(idVal.getString());
FeatureArtifactBuilder fab = builderFactory.newArtifactBuilder(id);
for (Map.Entry mde : v.entrySet()) {
JsonValue val = mde.getValue();
switch (val.getValueType()) {
case STRING:
fab.addMetadata(mde.getKey(), ((JsonString) val).getString());
break;
case FALSE:
fab.addMetadata(mde.getKey(), false);
break;
case TRUE:
fab.addMetadata(mde.getKey(), true);
break;
case NUMBER:
JsonNumber num = (JsonNumber) val;
if (num.toString().contains(".")) {
fab.addMetadata(mde.getKey(), num.doubleValue());
} else {
fab.addMetadata(mde.getKey(), num.longValue());
}
break;
default:
// do nothing
break;
}
}
builder.addArtifact(fab.build());
});
break;
case JSON:
builder.setJSON(exData.getJsonObject("json").toString());
break;
}
extensions.add(builder.build());
}
return extensions.toArray(new FeatureExtension[] {});
}
public void writeFeature(Feature feature, Writer jsonWriter) throws IOException {
// LinkedHashMap to give it some order, we'd like 'id' and 'name' first.
Map attrs = new LinkedHashMap<>();
attrs.put("id", feature.getID().toString());
feature.getName().ifPresent(n -> attrs.put("name", n));
feature.getDescription().ifPresent(d -> attrs.put("description", d));
feature.getDocURL().ifPresent(d -> attrs.put("docURL", d));
feature.getLicense().ifPresent(l -> attrs.put("license", l));
feature.getSCM().ifPresent(s -> attrs.put("scm", s));
feature.getVendor().ifPresent(v -> attrs.put("vendor", v));
JsonObjectBuilder json = Json.createObjectBuilder(attrs);
JsonObject variables = getVariables(feature);
if (variables != null) {
json.add("variables", variables);
}
JsonArray bundles = getBundles(feature);
if (bundles != null) {
json.add("bundles", bundles);
}
JsonObject configs = getConfigurations(feature);
if (configs != null) {
json.add("configurations", configs);
}
JsonObject extensions = getExtensions(feature);
if (extensions != null) {
json.add("extensions", extensions);
}
JsonObject fo = json.build();
JsonGeneratorFactory gf = Json.createGeneratorFactory(Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true));
try (JsonGenerator gr = gf.createGenerator(jsonWriter)) {
gr.write(fo);
}
}
private JsonObject getVariables(Feature feature) {
Map vars = feature.getVariables();
if (vars == null || vars.size() == 0) {
return null;
}
JsonObjectBuilder jo = Json.createObjectBuilder(vars);
return jo.build();
}
private JsonArray getBundles(Feature feature) {
List bundles = feature.getBundles();
if (bundles == null || bundles.size() == 0)
return null;
JsonArrayBuilder ab = Json.createArrayBuilder();
for (FeatureBundle bundle : bundles) {
Map attrs = new LinkedHashMap<>();
attrs.put("id", bundle.getID().toString());
attrs.putAll(bundle.getMetadata());
ab.add(Json.createObjectBuilder(attrs));
}
return ab.build();
}
private JsonObject getConfigurations(Feature feature) throws IOException {
Map configs = feature.getConfigurations();
if (configs == null || configs.size() == 0)
return null;
JsonObjectBuilder ob = Json.createObjectBuilder();
for (Map.Entry cfg : configs.entrySet()) {
StringWriter sw = new StringWriter();
ConfigurationWriter cw = Configurations.buildWriter().build(sw);
Dictionary dict = Configurations.newConfiguration();
cfg.getValue().getValues().entrySet()
.forEach(e -> dict.put(e.getKey(), e.getValue()));
cw.writeConfiguration(dict);
sw.close();
JsonReader jr = Json.createReader(new StringReader(sw.toString()));
JsonObject jo = jr.readObject();
ob.add(cfg.getKey(), jo);
}
return ob.build();
}
private JsonObject getExtensions(Feature feature) {
Map extensions = feature.getExtensions();
if (extensions == null || extensions.size() == 0)
return null;
JsonObjectBuilder ob = Json.createObjectBuilder();
for (Map.Entry entry : extensions.entrySet()) {
FeatureExtension extVal = entry.getValue();
JsonObjectBuilder vb = Json.createObjectBuilder();
vb.add("kind", extVal.getKind().toString().toLowerCase());
switch (extVal.getType()) {
case TEXT:
vb.add("text", Json.createArrayBuilder(extVal.getText()).build());
break;
case ARTIFACTS:
JsonArrayBuilder arr = Json.createArrayBuilder();
for (FeatureArtifact art : extVal.getArtifacts()) {
Map attrs = new LinkedHashMap<>();
attrs.put("id", art.getID().toString());
attrs.putAll(art.getMetadata());
arr.add(Json.createObjectBuilder(attrs)).build();
}
vb.add("artifacts", arr.build());
break;
case JSON:
vb.add("json", Json.createReader(new StringReader(extVal.getJSON())).readValue());
break;
}
ob.add(entry.getKey(), vb.build());
}
return ob.build();
}
}