ENTAXY-374 release 1.8.2

This commit is contained in:
2022-08-23 13:40:11 +03:00
parent b68642f81c
commit 1061b96c7e
616 changed files with 60896 additions and 3202 deletions

View File

@ -3,7 +3,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime</groupId>
<artifactId>core</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>artifact-management</artifactId>

View File

@ -22,6 +22,8 @@ package ru.entaxy.platform.core.artifact;
import java.io.File;
import java.util.Map;
import ru.entaxy.platform.core.artifact.capabilities.CapabilityDescriptor;
public interface Artifact {
public static final String ARTIFACT_CATEGORY_UNKNOWN = "unknown";
@ -35,9 +37,6 @@ public interface Artifact {
public static final String DEFAULT_RUNTIME_GROUP_ID = "entaxy.runtime";
public static final String MANIFEST_HEADER_ENTAXY_BUNLDE = "Entaxy-Bundle";
public static final String MANIFEST_HEADER_ENTAXY_RUNTIME = "Entaxy-Runtime";
public String getCategory();
public ArtifactCoordinates getCoordinates();
@ -55,7 +54,13 @@ public interface Artifact {
// capabilities support
@Deprecated(forRemoval = true, since = "1.8.2")
public CapabilityDescriptor provideCapability(String namespace);
@Deprecated(forRemoval = true, since = "1.8.2")
public CapabilityDescriptor requireCapability(String namespace);
public default boolean isManifested() {
return Manifested.class.isAssignableFrom(this.getClass());
}
}

View File

@ -19,7 +19,10 @@
*/
package ru.entaxy.platform.core.artifact;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import org.apache.camel.tooling.model.Strings;
@ -29,14 +32,47 @@ public class ArtifactCoordinates {
public static final ArtifactCoordinates EMPTY = new ArtifactCoordinates();
public static final String DEFAULT_VERSION = "1.0.0";
public static final String SNAPSHOT_QUALIFIER = "SNAPSHOT";
// x.y.z[-qualifier]
public static final String VERSION_POLICY_CLEAR = "";
// x.y.z-timestamp
public static final String VERSION_POLICY_TIMESTAMPED = "timestamped";
// x.y.z-yyMMddHHmmss
public static final String VERSION_POLICY_DATED = "dated";
// x.yyMMdd.HHmmss[-qualifier]
public static final String VERSION_POLICY_DATED_EMBEDDED = "dated-embedded";
protected String groupId;
protected String artifactId;
protected String version = "1.0";
protected String type;
protected String classifier;
protected String versionPolicy = VERSION_POLICY_CLEAR;
protected String versionQualifier = "";
protected String timestamp = "";
protected Calendar calendar = null;
protected boolean isSnapshot = false;
protected Set<String> allowedPolicies = new HashSet<>() {/**
*
*/
private static final long serialVersionUID = 1L;
{
add(VERSION_POLICY_CLEAR);
add(VERSION_POLICY_DATED);
add(VERSION_POLICY_DATED_EMBEDDED);
add(VERSION_POLICY_TIMESTAMPED);
}};
public ArtifactCoordinates groupId(String groupId) {
setGroupId(groupId);
return this;
@ -47,6 +83,12 @@ public class ArtifactCoordinates {
return this;
}
public ArtifactCoordinates versionPolicy(String versionPolicy) {
if (this.allowedPolicies.contains(versionPolicy))
this.versionPolicy = versionPolicy;
return this;
}
public ArtifactCoordinates version(String version) {
this.versionQualifier = "";
setVersion(version);
@ -54,20 +96,95 @@ public class ArtifactCoordinates {
}
public ArtifactCoordinates timestampedVersion(String version) {
version(version);
this.versionQualifier = "-" + Calendar.getInstance().getTimeInMillis();
this.version(version);
this.timestamped();
// versionQualifier = "-" + Calendar.getInstance().getTimeInMillis();
return this;
}
public ArtifactCoordinates timestamp(String timestamp) {
this.timestamp = timestamp;
return this;
}
public ArtifactCoordinates timestamped() {
return qualifier(Calendar.getInstance().getTimeInMillis()+"");
return timestamped(Calendar.getInstance().getTimeInMillis()+"");
}
public ArtifactCoordinates timestamped(String timestamp) {
if (CommonUtils.isValid(timestamp))
return qualifier(timestamp);
else
return timestamped();
if (CommonUtils.isValid(timestamp)) {
this.timestamp = timestamp;
this.versionPolicy(VERSION_POLICY_TIMESTAMPED);
} else {
this.timestamp = "";
this.versionPolicy(VERSION_POLICY_CLEAR);
}
return this;
}
public ArtifactCoordinates datedVersion(String version) {
this.version(version);
this.dated();
// versionQualifier = "-" + Calendar.getInstance().getTimeInMillis();
return this;
}
public ArtifactCoordinates dated() {
this.calendar = Calendar.getInstance();
versionPolicy(VERSION_POLICY_DATED);
return this;
}
public ArtifactCoordinates datedEmbeddedVersion(String version) {
this.version(version);
this.datedEmbedded();
return this;
}
public ArtifactCoordinates datedEmbedded() {
this.calendar = Calendar.getInstance();
versionPolicy(VERSION_POLICY_DATED_EMBEDDED);
return this;
}
protected String getResultQualifier() {
if (isSnapshot)
return "-" + SNAPSHOT_QUALIFIER;
if (CommonUtils.isValid(this.versionQualifier))
return "-" + this.versionQualifier;
return "";
}
protected String calculateFinalVersion() {
if (VERSION_POLICY_TIMESTAMPED.equals(this.versionPolicy)) {
if (!CommonUtils.isValid(this.timestamp))
this.timestamp = Calendar.getInstance().getTimeInMillis() + "";
return this.version + "-" + this.timestamp;
}
if (VERSION_POLICY_DATED.equals(this.versionPolicy)) {
prepareCalendar();
return this.version + "-" + ((new SimpleDateFormat("yyMMddHHmmss")).format(this.calendar.getTime()));
}
if (VERSION_POLICY_DATED_EMBEDDED.equals(this.versionPolicy)) {
prepareCalendar();
return this.version.split("\\.")[0]
+ "."
+ ((new SimpleDateFormat("yyMMdd.HHmmss")).format(this.calendar.getTime()))
+ getResultQualifier();
}
return this.version + this.getResultQualifier();
}
protected void prepareCalendar() {
if (this.calendar == null)
this.calendar = Calendar.getInstance();
if (CommonUtils.isValid(this.timestamp)) {
try {
this.calendar.setTimeInMillis(Long.parseLong(this.timestamp));
} catch (Exception e) {
// NOOP
}
}
}
public ArtifactCoordinates type(String type) {
@ -77,7 +194,7 @@ public class ArtifactCoordinates {
public ArtifactCoordinates qualifier(String qualifier) {
if (CommonUtils.isValid(qualifier))
this.versionQualifier = "-" + qualifier;
this.versionQualifier = qualifier;
else
this.versionQualifier = "";
return this;
@ -112,10 +229,13 @@ public class ArtifactCoordinates {
}
public boolean isSnapshot() {
return !Strings.isNullOrEmpty(this.version)
&& this.version.endsWith("-SNAPSHOT");
return this.isSnapshot || SNAPSHOT_QUALIFIER.equals(this.versionQualifier);
}
public void setSnapshot(boolean isSnapshot) {
this.isSnapshot = isSnapshot;
}
public String getGroupId() {
return groupId;
}
@ -129,18 +249,26 @@ public class ArtifactCoordinates {
this.artifactId = artifactId;
}
public String getVersion() {
return version + versionQualifier;
return this.calculateFinalVersion();
}
public void setVersion(String version) {
if (!CommonUtils.isValid(version))
this.version = "1.0.0";
this.version = DEFAULT_VERSION;
else {
String[] splitted = version.split("\\.");
if (splitted.length == 2)
this.version = version + ".0";
else if ((splitted.length==3) && (!CommonUtils.isValid(splitted[2])))
this.version = version + "0";
else this.version = version;
String[] splittedDefault = DEFAULT_VERSION.split("\\.");
String result = "";
for (int i=0; i<splittedDefault.length; i++) {
if (i != 0)
result += ".";
if ((splitted.length >= i+1) && CommonUtils.isValid(splitted[i]))
result += splitted[i];
else
result += splittedDefault[i];
}
this.version = result;
}
}
public String getType() {
@ -156,9 +284,17 @@ public class ArtifactCoordinates {
this.classifier = classifier;
}
public String getVersionPolicy() {
return versionPolicy;
}
public void setVersionPolicy(String versionPolicy) {
this.versionPolicy(versionPolicy);
}
@Override
public String toString() {
String result = String.format("%s/%s/%s%s", groupId, artifactId, version, versionQualifier);
String result = String.format("%s/%s/%s", getGroupId(), getArtifactId(), getVersion());
if (!Strings.isNullOrEmpty(type)) {
result += "/" + type;
if (!Strings.isNullOrEmpty(classifier))

View File

@ -1,8 +1,8 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* test-producers
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,12 +19,17 @@
*/
package ru.entaxy.platform.core.artifact;
import org.osgi.resource.Capability;
import java.util.Map;
public interface CapabilityDescriptor extends Capability {
public interface ArtifactManifest {
public CapabilityDescriptor namespace(String namespace);
public CapabilityDescriptor attribute(String name, String value);
public CapabilityDescriptor attribute(String name, String value, String type);
public static interface HEADERS {
String ENTAXY_BUNDLE = "Entaxy-Bundle";
String ENTAXY_RUNTIME = "Entaxy-Runtime";
}
public Map<String, String> getCustomAttributes();
}

View File

@ -57,17 +57,17 @@ public class Artifacts {
if (DefaultArtifact.class.isAssignableFrom(instance.getClass()))
return (DefaultArtifact)instance;
} catch (NoSuchMethodException e) {
log.error("Erorr creating artifact", e);
log.error("Error creating artifact", e);
} catch (SecurityException e) {
log.error("Erorr creating artifact", e);
log.error("Error creating artifact", e);
} catch (InstantiationException e) {
log.error("Erorr creating artifact", e);
log.error("Error creating artifact", e);
} catch (IllegalAccessException e) {
log.error("Erorr creating artifact", e);
log.error("Error creating artifact", e);
} catch (IllegalArgumentException e) {
log.error("Erorr creating artifact", e);
log.error("Error creating artifact", e);
} catch (InvocationTargetException e) {
log.error("Erorr creating artifact", e);
log.error("Error creating artifact", e);
}
}
return new DefaultArtifact();

View File

@ -19,23 +19,13 @@
*/
package ru.entaxy.platform.core.artifact;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.Properties;
import java.util.jar.Manifest;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.base.support.xml.CommonXMLUtils;
import ru.entaxy.platform.core.artifact.annotation.ArtifactSupport;
@ -43,10 +33,14 @@ import ru.entaxy.platform.core.artifact.annotation.ArtifactSupport;
, supportedContentClasses = {String.class, Document.class, byte[].class}
, defaultArtifactClassifier = Artifact.ARTIFACT_CATEGORY_BLUEPRINT
, defaultArtifactType = "xml")
public class Blueprint extends DefaultArtifact {
public class Blueprint extends DefaultArtifact implements Manifested {
private final static Logger log = LoggerFactory.getLogger(Blueprint.class);
public static final String ARTIFACT_CATEGORY_BLUEPRINT = "blueprint";
protected BlueprintManifest manifest = null;
@Override
public void setContent(Object content) {
super.setContent(content);
@ -63,8 +57,17 @@ public class Blueprint extends DefaultArtifact {
e.printStackTrace();
}
}
}
}
@Override
public ArtifactManifest getManifest() {
if (this.manifest == null)
this.manifest = new BlueprintManifest(this);
if (this.content instanceof Document)
this.manifest.load((Document)this.content);
return this.manifest;
}
@Override
public void toFile(File destination) {
if (this.content instanceof String)
@ -72,18 +75,17 @@ public class Blueprint extends DefaultArtifact {
else if (this.content instanceof Document) {
Document doc = (Document)this.content;
try {
prepareManifest(doc);
asByteArray();
CommonXMLUtils.saveDocument(doc, destination);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error("Error saving to file", e);
}
}
else if (this.content instanceof byte[]) {
// TODO to be implemented
}
}
}
@Override
public byte[] asByteArray() {
@ -94,91 +96,14 @@ public class Blueprint extends DefaultArtifact {
if (this.content instanceof Document)
try {
Document doc = (Document)this.content;
prepareManifest(doc);
if (!this.manifest.isLoaded())
this.manifest.load(doc);
this.manifest.save(doc);
return CommonXMLUtils.doc2string(doc).getBytes();
} catch (Exception e) {
e.printStackTrace();
log.error("Error getting as byte[]: " + this.getCoordinates().toString(), e);
}
return new byte[] {};
}
protected void prepareManifest(Document doc) {
Manifest m = new Manifest();
m.getMainAttributes().putValue("Manifest-Version", "2");
m.getMainAttributes().putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
m.getMainAttributes().putValue(Constants.BUNDLE_SYMBOLICNAME
, this.coordinates.getGroupId() + "." + this.coordinates.getArtifactId());
m.getMainAttributes().putValue(Constants.BUNDLE_NAME
, this.coordinates.getGroupId() + "." + this.coordinates.getArtifactId());
m.getMainAttributes().putValue(Constants.BUNDLE_VERSION, this.coordinates.getVersion().replaceAll("-", "."));
m.getMainAttributes().putValue(Constants.DYNAMICIMPORT_PACKAGE, "*");
m.getMainAttributes().putValue(Artifact.MANIFEST_HEADER_ENTAXY_BUNLDE, "true");
m.getMainAttributes().putValue(Artifact.MANIFEST_HEADER_ENTAXY_RUNTIME, "true");
NodeList l = doc.getElementsByTagName("manifest");
if (l != null) {
for (int i = 0; i < l.getLength(); i++) {
Element e = (Element) l.item(i);
String text = e.getTextContent();
Properties props = new Properties();
try {
props.load(new ByteArrayInputStream(text.trim().getBytes()));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Enumeration en = props.propertyNames();
while (en.hasMoreElements()) {
String k = (String) en.nextElement();
String v = props.getProperty(k);
m.getMainAttributes().putValue(k, v);
}
e.getParentNode().removeChild(e);
}
}
// add capabilities info
String requiredCapabilities = getRequiredCapabilitiesValue();
String providedCapabilities = getProvidedCapabilitiesValue();
if (CommonUtils.isValid(requiredCapabilities)) {
Object v = m.getMainAttributes().get(Constants.REQUIRE_CAPABILITY);
String value = (v==null?"":v.toString());
if (CommonUtils.isValid(value))
value += "," + requiredCapabilities;
else
value = requiredCapabilities;
m.getMainAttributes().putValue(Constants.REQUIRE_CAPABILITY, value);
}
if (CommonUtils.isValid(providedCapabilities)) {
Object v = m.getMainAttributes().get(Constants.PROVIDE_CAPABILITY);
String value = (v==null?"":v.toString());
if (CommonUtils.isValid(value))
value += "," + providedCapabilities;
else
value = providedCapabilities;
m.getMainAttributes().putValue(Constants.PROVIDE_CAPABILITY, value);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String manifestContent = "";
try {
m.write(bos);
manifestContent = bos.toString(StandardCharsets.ISO_8859_1);
manifestContent = manifestContent.replaceAll("\r", "").replaceAll("\n ", "");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Element manifest = doc.createElementNS("http://karaf.apache.org/xmlns/deployer/blueprint/v1.0.0", "manifest");
manifest.setTextContent(manifestContent);
doc.getDocumentElement().insertBefore(manifest, doc.getDocumentElement().getFirstChild());
// copy manifest data to artifact properties
for (Object key: m.getMainAttributes().keySet()) {
this.properties.put(key.toString(), m.getMainAttributes().get(key));
}
}
}

View File

@ -0,0 +1,143 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed 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.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.jar.Manifest;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class BlueprintManifest implements ArtifactManifest {
private static final Logger log = LoggerFactory.getLogger(BlueprintManifest.class);
protected Artifact artifact;
protected Manifest manifest = new Manifest();
boolean isLoaded = false;
protected Map<String, String> customAttributes = new HashMap<>();
public BlueprintManifest(Artifact artifact) {
super();
this.artifact = artifact;
}
public void load(Document document) {
this.isLoaded = false;
manifest = new Manifest();
manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
manifest.getMainAttributes().putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.getMainAttributes().putValue(Constants.DYNAMICIMPORT_PACKAGE, "*");
manifest.getMainAttributes().putValue(HEADERS.ENTAXY_BUNDLE, "true");
manifest.getMainAttributes().putValue(HEADERS.ENTAXY_RUNTIME, "true");
NodeList l = document.getElementsByTagName("manifest");
if (l != null) {
for (int i = 0; i < l.getLength(); i++) {
Element e = (Element) l.item(i);
String text = e.getTextContent();
Properties props = new Properties();
try {
props.load(new ByteArrayInputStream(text.trim().getBytes()));
} catch (IOException e1) {
log.error("Error loading manifest", e1);
}
Enumeration en = props.propertyNames();
while (en.hasMoreElements()) {
String k = (String) en.nextElement();
String v = props.getProperty(k);
manifest.getMainAttributes().putValue(k, v);
}
e.getParentNode().removeChild(e);
}
}
this.isLoaded = true;
}
protected void appendCustoms(Document document) {
for (Entry<String, String> entry: this.customAttributes.entrySet())
this.manifest.getMainAttributes().putValue(entry.getKey(), entry.getValue());
}
protected void beforeSave(Document document) {
this.manifest.getMainAttributes().putValue(Constants.BUNDLE_SYMBOLICNAME
, this.artifact.getCoordinates().getGroupId() + "." + this.artifact.getCoordinates().getArtifactId());
this.manifest.getMainAttributes().putValue(Constants.BUNDLE_NAME
, this.artifact.getCoordinates().getGroupId() + "." + this.artifact.getCoordinates().getArtifactId());
this.manifest.getMainAttributes().putValue(Constants.BUNDLE_VERSION
, this.artifact.getCoordinates().getVersion().replaceAll("-", "."));
appendCustoms(document);
}
public void save(Document document) {
beforeSave(document);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String manifestContent = "";
try {
this.manifest.write(bos);
manifestContent = bos.toString(StandardCharsets.ISO_8859_1);
manifestContent = manifestContent.replaceAll("\r", "").replaceAll("\n ", "");
} catch (IOException e) {
log.error("Error saving manifest to document", e);
}
// remove old manifests
NodeList l = document.getElementsByTagName("manifest");
if (l != null)
for (int i = 0; i < l.getLength(); i++) {
Element e = (Element) l.item(i);
e.getParentNode().removeChild(e);
}
Element manifest = document.createElementNS("http://karaf.apache.org/xmlns/deployer/blueprint/v1.0.0", "manifest");
manifest.setTextContent(manifestContent);
document.getDocumentElement().insertBefore(manifest
, document.getDocumentElement().getFirstChild());
}
@Override
public Map<String, String> getCustomAttributes() {
return this.customAttributes;
}
public boolean isLoaded() {
return isLoaded;
}
}

View File

@ -31,6 +31,7 @@ import java.util.Map;
import org.apache.camel.tooling.model.Strings;
import ru.entaxy.platform.core.artifact.annotation.ArtifactSupport;
import ru.entaxy.platform.core.artifact.capabilities.CapabilityDescriptor;
import ru.entaxy.platform.core.artifact.impl.CapabilityDescriptorImpl;
public class DefaultArtifact implements Artifact {
@ -92,7 +93,7 @@ public class DefaultArtifact implements Artifact {
}
protected void checkSetContent(Object content) {
// TODO throw exception if content suites none of the supported clssses
// TODO throw exception if content suites none of the supported classes
if (this.supportedContentClasses.contains(content.getClass()))
this.content = content;

View File

@ -0,0 +1,26 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed 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.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact;
public interface Manifested {
public ArtifactManifest getManifest();
}

View File

@ -0,0 +1,60 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* ==========
* Licensed 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.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.capabilities;
import org.osgi.resource.Capability;
import java.util.Map;
public interface CapabilityDescriptor extends Capability {
public static final String HEADER_PROVIDE_CAPABILITY = "Provide-Capability";
public static final String HEADER_REQUIRE_CAPABILITY = "Require-Capability";
public static interface ATTRIBUTE_TYPES {
public static final String STRING = "String";
public static final String VERSION = "Version";
public static final String LONG = "Long";
public static final String DOUBLE = "Double";
public static final String LIST = "List";
public static String TYPED_LIST(String itemType) {
return LIST + "<" + itemType + ">";
}
public static boolean isList(String itemType) {
return (itemType!=null) && (itemType.startsWith(LIST));
}
public static String itemType(String listType) {
if (!isList(listType))
return null;
return listType.substring(listType.indexOf("<"), listType.indexOf(">"));
}
}
public CapabilityDescriptor namespace(String namespace);
public CapabilityDescriptor attributes(Map<String, Object> attributes);
public CapabilityDescriptor attribute(String name, Object value);
public CapabilityDescriptor attribute(String name, Object value, String type);
}

View File

@ -0,0 +1,158 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* ==========
* Licensed 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.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.capabilities;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.osgi.resource.Resource;
import ru.entaxy.platform.base.support.CommonUtils;
public class CapabilityDescriptorImpl implements CapabilityDescriptor {
protected String namespace;
protected Map<String, String> directives = new HashMap<>();
protected Map<String, AttributeDescriptor> attributes = new HashMap<>();
private static class AttributeDescriptor {
String type;
Object value;
public AttributeDescriptor(Object value) {
this(value, CapabilityTypeHelper.getTypeName(value));
}
public AttributeDescriptor(Object value, String type) {
this.type = type;
this.value = value==null?"":value.toString();
}
public String getValueAsString() {
if (value == null)
return null;
if (CapabilityDescriptor.ATTRIBUTE_TYPES.isList(type))
return CapabilityTypeHelper.getListAsString((List<?>)value);
return value.toString();
}
}
public CapabilityDescriptorImpl() {
// TODO Auto-generated constructor stub
}
public CapabilityDescriptorImpl(String namespace) {
this();
namespace(namespace);
}
public String getAttributesAsString() {
return this.attributes.entrySet().stream()
.map(entry->
entry.getKey()
+ (!ATTRIBUTE_TYPES.STRING.equals(entry.getValue().type)?(":" + entry.getValue().type):"")
+ "=" + entry.getValue().getValueAsString())
.collect(Collectors.joining(";"));
}
@Override
public String getNamespace() {
return this.namespace;
}
@Override
public Map<String, String> getDirectives() {
return this.directives;
}
@Override
public Map<String, Object> getAttributes() {
Map<String, Object> result = new HashMap<>();
for (Map.Entry<String, AttributeDescriptor> entry: this.attributes.entrySet())
result.put(entry.getKey(), entry.getValue().value);
return result;
}
@Override
public Resource getResource() {
// not implemented
return null;
}
@Override
public CapabilityDescriptor namespace(String namespace) {
this.namespace = namespace;
return this;
}
@Override
public CapabilityDescriptor attribute(String name, Object value) {
this.attributes.put(name, new AttributeDescriptor(value));
return this;
}
@Override
public CapabilityDescriptor attribute(String name, Object value, String type) {
this.attributes.put(name, new AttributeDescriptor(value, type));
return this;
}
public CapabilityDescriptor parseAttribute(String attributeData) {
String nameType = attributeData.substring(0, attributeData.indexOf("="));
if (!CommonUtils.isValid(nameType))
return this;
String[] nameTypeSplit = nameType.split(":");
String name = nameTypeSplit[0].trim();
String type = (nameTypeSplit.length > 1?nameTypeSplit[1]:CapabilityDescriptor.ATTRIBUTE_TYPES.STRING);
if (!CommonUtils.isValid(type))
type = CapabilityDescriptor.ATTRIBUTE_TYPES.STRING;
type = type.trim();
String value = attributeData.substring(attributeData.indexOf("=")+1);
if (!CommonUtils.isValid(value))
value = "";
value = value.trim();
Object typedValue = CapabilityTypeHelper.getTypedValue(type, value);
this.attribute(name, typedValue, type);
return this;
}
@Override
public CapabilityDescriptor attributes(Map<String, Object> attributes) {
if (attributes == null)
return this;
for (Entry<String, Object> entry: attributes.entrySet()) {
this.attribute(entry.getKey(), entry.getValue());
}
return this;
}
}

View File

@ -0,0 +1,109 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed 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.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.capabilities;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.core.artifact.capabilities.CapabilityDescriptor.ATTRIBUTE_TYPES;
public class CapabilityTypeHelper {
public static String getTypeName(Object object) {
if (object == null)
return ATTRIBUTE_TYPES.STRING;
if (object instanceof List<?>) {
return ATTRIBUTE_TYPES.TYPED_LIST(getListTypeName((List<?>)object));
}
return getScalarTypeName(object);
}
public static String getListTypeName(List<?> list) {
if (list.size() == 0)
return ATTRIBUTE_TYPES.STRING;
else
return getScalarTypeName(list.get(0));
}
public static String getScalarTypeName(Object object) {
if ((object instanceof Integer) || (object instanceof Long))
return ATTRIBUTE_TYPES.LONG;
if (object instanceof Number)
return ATTRIBUTE_TYPES.DOUBLE;
return ATTRIBUTE_TYPES.STRING;
}
public static String getListAsString(List<?> list) {
String result = "\"";
if (list != null)
result += list.stream().map(item->(item==null)?"":item.toString())
.collect(Collectors.joining(","));
return result + "\"";
}
public static Object getTypedValue(String type, String value) {
if (CapabilityDescriptor.ATTRIBUTE_TYPES.STRING.equals(type))
return value;
if (CapabilityDescriptor.ATTRIBUTE_TYPES.VERSION.equals(type))
return value;
if (CapabilityDescriptor.ATTRIBUTE_TYPES.LONG.equals(type))
try {
return Long.parseLong(value);
} catch (Exception e) {
return Long.valueOf(-1);
}
if (CapabilityDescriptor.ATTRIBUTE_TYPES.DOUBLE.equals(type))
try {
return Double.parseDouble(value);
} catch (Exception e) {
return Double.valueOf(-1);
}
if (CapabilityDescriptor.ATTRIBUTE_TYPES.isList(type)) {
String itemType = CapabilityDescriptor.ATTRIBUTE_TYPES.itemType(type);
if (!CommonUtils.isValid(itemType))
return value;
List<Object> result = new ArrayList<>();
String val = value;
if (val.startsWith("\""))
val = val.substring(1);
if (val.endsWith("\""))
val = val.substring(0, val.length()-1);
if (!CommonUtils.isValid(val))
return result;
String[] vals = val.split(",");
for (int i=0; i< vals.length; i++)
if (vals[i] == null)
continue;
else
result.add(getTypedValue(itemType, vals[i]));
return result;
}
return value;
}
}

View File

@ -0,0 +1,136 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed 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.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.capabilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.core.artifact.ArtifactManifest;
public class ManifestCapabilityHelper {
protected ArtifactManifest manifest;
protected Map<String, CapabilityDescriptorImpl> requiredCapabilities = new HashMap<>();
protected Map<String, CapabilityDescriptorImpl> providedCapabilities = new HashMap<>();
public ManifestCapabilityHelper(ArtifactManifest manifest) {
super();
this.manifest = manifest;
this.load();
}
protected void load() {
String existing = this.manifest.getCustomAttributes().get(CapabilityDescriptor.HEADER_PROVIDE_CAPABILITY);
if (CommonUtils.isValid(existing)) {
List<CapabilityDescriptorImpl> list = parse(existing);
for (CapabilityDescriptorImpl c: list)
addProvidedCapability(c);
}
existing = this.manifest.getCustomAttributes().get(CapabilityDescriptor.HEADER_REQUIRE_CAPABILITY);
if (CommonUtils.isValid(existing)) {
List<CapabilityDescriptorImpl> list = parse(existing);
for (CapabilityDescriptorImpl c: list)
addRequiredCapability(c);
}
}
protected void addProvidedCapability(CapabilityDescriptorImpl capabilityDescriptorImpl) {
if (capabilityDescriptorImpl == null)
return;
this.providedCapabilities.put(capabilityDescriptorImpl.getNamespace(), capabilityDescriptorImpl);
}
protected void addRequiredCapability(CapabilityDescriptorImpl capabilityDescriptorImpl) {
if (capabilityDescriptorImpl == null)
return;
this.requiredCapabilities.put(capabilityDescriptorImpl.getNamespace(), capabilityDescriptorImpl);
}
protected List<CapabilityDescriptorImpl> parse(String capabilities) {
List<CapabilityDescriptorImpl> result = new ArrayList<>();
String[] caps = capabilities.split(",");
for (int i=0; i< caps.length; i++)
if (CommonUtils.isValid(caps[i])) {
result.add(parseCapability(caps[i]));
}
return result;
}
protected CapabilityDescriptorImpl parseCapability(String capability) {
String[] parsed = capability.split(";");
CapabilityDescriptorImpl result = new CapabilityDescriptorImpl(parsed[0].trim());
for (int i=1; i<parsed.length; i++) {
result.parseAttribute(parsed[i]);
}
return result;
}
public List<CapabilityDescriptor> getProvidedCapabilities(){
return this.providedCapabilities.values().stream()
.map(c -> (CapabilityDescriptor)c)
.collect(Collectors.toList());
}
public List<CapabilityDescriptor> getRequiredCapabilities(){
return this.requiredCapabilities.values().stream()
.map(c -> (CapabilityDescriptor)c)
.collect(Collectors.toList());
}
public boolean isCapabilityProvided(String namespace) {
return this.providedCapabilities.containsKey(namespace);
}
public boolean isCapabilityRequired(String namespace) {
return this.requiredCapabilities.containsKey(namespace);
}
public CapabilityDescriptor provideCapability(String namespace) {
if (!this.providedCapabilities.containsKey(namespace))
this.providedCapabilities.put(namespace, new CapabilityDescriptorImpl(namespace));
return this.providedCapabilities.get(namespace);
}
public CapabilityDescriptor requireCapability(String namespace) {
if (!this.requiredCapabilities.containsKey(namespace))
this.requiredCapabilities.put(namespace, new CapabilityDescriptorImpl(namespace));
return this.requiredCapabilities.get(namespace);
}
public void save() {
this.manifest.getCustomAttributes().put(CapabilityDescriptor.HEADER_PROVIDE_CAPABILITY,
this.providedCapabilities.values().stream()
.map(
cap -> (
cap.getNamespace()
+ ";"
+ cap.getAttributesAsString()
)
)
.collect(Collectors.joining(","))
);
}
}

View File

@ -24,8 +24,9 @@ import java.util.Map;
import org.osgi.resource.Resource;
import ru.entaxy.platform.core.artifact.CapabilityDescriptor;
import ru.entaxy.platform.core.artifact.capabilities.CapabilityDescriptor;
@Deprecated(forRemoval = true, since = "1.8.2")
public class CapabilityDescriptorImpl implements CapabilityDescriptor {
protected String namespace;
@ -103,16 +104,24 @@ public class CapabilityDescriptorImpl implements CapabilityDescriptor {
return this;
}
@Override
public CapabilityDescriptor attribute(String name, String value) {
this.attributes.put(name, new AttributeDescriptor(value));
return this;
public CapabilityDescriptor attributes(Map<String, Object> attributes) {
// TODO Auto-generated method stub
return null;
}
@Override
public CapabilityDescriptor attribute(String name, String value, String type) {
this.attributes.put(name, new AttributeDescriptor(value, type));
return this;
public CapabilityDescriptor attribute(String name, Object value) {
// TODO Auto-generated method stub
return null;
}
@Override
public CapabilityDescriptor attribute(String name, Object value, String type) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -47,7 +47,7 @@ public abstract class AbstractInstaller<T extends Installer<T>, H extends TypedI
protected String bundleName = null;
protected Map<String, Class<? extends TypedInstallerImpl>> typedInstallerClasses = new HashMap<>();
protected Map<Class<? extends TypedInstallerImpl>, Class<? extends H>> typedHelpeClasses = new HashMap<>();
protected Map<Class<? extends TypedInstallerImpl>, Class<? extends H>> typedHelperClasses = new HashMap<>();
// for BundleInstaller implementation
@ -57,7 +57,7 @@ public abstract class AbstractInstaller<T extends Installer<T>, H extends TypedI
protected AbstractInstaller() {
this.typedInstallerClasses = new HashMap<>();
this.typedHelpeClasses = new HashMap<>();
this.typedHelperClasses = new HashMap<>();
}
protected void doCreateTypedInstaller(Class<? extends TypedInstallerImpl> clazz) {
@ -114,7 +114,7 @@ public abstract class AbstractInstaller<T extends Installer<T>, H extends TypedI
}
protected H createHelper() {
Class<? extends H> clazz = typedHelpeClasses.get(typedInstaller.getClass());
Class<? extends H> clazz = typedHelperClasses.get(typedInstaller.getClass());
if (clazz == null)
return createDefaultHelper();
Constructor<?> constructor;

View File

@ -75,7 +75,7 @@ public class ClusterCommonBundleInstallerHelper extends ClusterTypedInstallerHel
.failed("Can't install/update: CellarBundleMBean not available");
}
// TODO decide if we really need several grouos
// TODO decide if we really need several groups
// now we use only the first one
String groupToInstall = groupsToInstall.get(0);
@ -198,7 +198,7 @@ public class ClusterCommonBundleInstallerHelper extends ClusterTypedInstallerHel
.failed("Can't install/update: CellarBundleMBean not available");
}
// TODO decide if we really need several grouos
// TODO decide if we really need several groups
// now we use only the first one
String groupToInstall = groupsToInstall.get(0);
String bundleId = this.config.getBundleId();

View File

@ -48,11 +48,11 @@ public class DefaultCellarInstaller extends AbstractInstaller<ClusterInstaller,
this.typedInstallerClasses.put(Artifact.ARTIFACT_CATEGORY_BUNDLE, ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BundleInstallerImpl.class);
this.typedInstallerClasses.put(Artifact.ARTIFACT_CATEGORY_JAR, ru.entaxy.platform.core.artifact.installer.builder.typed.impl.JarInstallerImpl.class);
this.typedHelpeClasses.put(ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BlueprintInstallerImpl.class
this.typedHelperClasses.put(ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BlueprintInstallerImpl.class
, ClusterCommonBundleInstallerHelper.class);
this.typedHelpeClasses.put(ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BundleInstallerImpl.class
this.typedHelperClasses.put(ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BundleInstallerImpl.class
, ClusterCommonBundleInstallerHelper.class);
this.typedHelpeClasses.put(ru.entaxy.platform.core.artifact.installer.builder.typed.impl.JarInstallerImpl.class
this.typedHelperClasses.put(ru.entaxy.platform.core.artifact.installer.builder.typed.impl.JarInstallerImpl.class
, ClusterCommonBundleInstallerHelper.class);
initGroups();

View File

@ -38,9 +38,9 @@ public class DefaultLocalInstaller extends AbstractInstaller<LocalInstaller, Loc
this.typedInstallerClasses.put(Artifact.ARTIFACT_CATEGORY_JAR, JarInstallerImpl.class);
this.typedHelpeClasses.put(BlueprintInstallerImpl.class, LocalCommonBundleInstallerHelper.class);
this.typedHelpeClasses.put(BundleInstallerImpl.class, LocalCommonBundleInstallerHelper.class);
this.typedHelpeClasses.put(JarInstallerImpl.class, LocalCommonBundleInstallerHelper.class);
this.typedHelperClasses.put(BlueprintInstallerImpl.class, LocalCommonBundleInstallerHelper.class);
this.typedHelperClasses.put(BundleInstallerImpl.class, LocalCommonBundleInstallerHelper.class);
this.typedHelperClasses.put(JarInstallerImpl.class, LocalCommonBundleInstallerHelper.class);
}
@Override