diff --git a/bundles/org.eclipse.passage.lic.base/.settings/.api_filters b/bundles/org.eclipse.passage.lic.base/.settings/.api_filters
index 2910bc162..8614956dd 100644
--- a/bundles/org.eclipse.passage.lic.base/.settings/.api_filters
+++ b/bundles/org.eclipse.passage.lic.base/.settings/.api_filters
@@ -8,6 +8,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/access/Cycle.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/access/Cycle.java
index ddc868afd..6ffe1f6cd 100644
--- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/access/Cycle.java
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/access/Cycle.java
@@ -14,7 +14,6 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -23,11 +22,11 @@
import org.eclipse.passage.lic.api.Framework;
import org.eclipse.passage.lic.api.ServiceInvocationResult;
import org.eclipse.passage.lic.api.conditions.ConditionPack;
-import org.eclipse.passage.lic.api.conditions.evaluation.Permission;
import org.eclipse.passage.lic.api.diagnostic.Diagnostic;
import org.eclipse.passage.lic.api.requirements.Requirement;
import org.eclipse.passage.lic.api.restrictions.ExaminationCertificate;
import org.eclipse.passage.lic.base.BaseServiceInvocationResult;
+import org.eclipse.passage.lic.base.access.Permissions.AppliedLicenses;
import org.eclipse.passage.lic.base.diagnostic.BaseDiagnostic;
import org.eclipse.passage.lic.base.diagnostic.SumOfDiagnostics;
@@ -64,7 +63,7 @@ protected Optional feature() {
}
private T examine(Supplier>> requirements, //
- Supplier>> permissions) {
+ Supplier> permissions) {
ServiceInvocationResult> reqs = requirements.get();
if (failed(reqs)) {
return stop();
@@ -74,7 +73,7 @@ private T examine(Supplier>> req
// we just want to avoid heavy operations below
return freeWayOut();
}
- ServiceInvocationResult> perms = permissions.get();
+ ServiceInvocationResult perms = permissions.get();
if (failed(perms)) {
return stop();
}
@@ -141,11 +140,10 @@ private ServiceInvocationResult> conditions() {
filter.conditional()).get());
}
- private ServiceInvocationResult> permissions() {
+ private ServiceInvocationResult permissions() {
ServiceInvocationResult> conditions = conditions();
if (failed(conditions) || empty(conditions)) {
- return new BaseServiceInvocationResult>(conditions.diagnostic(),
- Collections.emptyList());
+ return new BaseServiceInvocationResult(conditions.diagnostic(), new AppliedLicenses());
}
return scan(new Permissions(//
framework.accessCycleConfiguration().permissionEmitters().get(), //
@@ -154,9 +152,11 @@ private ServiceInvocationResult> permissions() {
}
private ServiceInvocationResult restrictions(Collection requirements,
- Collection permissions) {
+ AppliedLicenses permissions) {
return scan(new Restrictions(//
+ framework.product(), //
framework.accessCycleConfiguration().examinators().get(), //
+ framework.accessCycleConfiguration().acceptance(), //
requirements, //
permissions).get());
}
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/access/Permissions.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/access/Permissions.java
index e7d51c22d..788764a59 100644
--- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/access/Permissions.java
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/access/Permissions.java
@@ -18,9 +18,11 @@
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
import org.eclipse.passage.lic.api.LicensedProduct;
import org.eclipse.passage.lic.api.ServiceInvocationResult;
+import org.eclipse.passage.lic.api.agreements.GlobalAgreement;
import org.eclipse.passage.lic.api.conditions.ConditionPack;
import org.eclipse.passage.lic.api.conditions.evaluation.Emission;
import org.eclipse.passage.lic.api.conditions.evaluation.Permission;
@@ -29,13 +31,14 @@
import org.eclipse.passage.lic.api.registry.StringServiceId;
import org.eclipse.passage.lic.base.BaseServiceInvocationResult;
import org.eclipse.passage.lic.base.SumOfCollections;
+import org.eclipse.passage.lic.base.access.Permissions.AppliedLicenses;
/**
* FIXME: Has public visibility only for testing.
*
* @since 2.1
*/
-public final class Permissions implements Supplier>> {
+public final class Permissions implements Supplier> {
private final Registry registry;
private final Collection conditions;
@@ -49,7 +52,17 @@ public Permissions(Registry registry
}
@Override
- public ServiceInvocationResult> get() {
+ public ServiceInvocationResult get() {
+ BaseServiceInvocationResult> permissions = permissions();
+ return new BaseServiceInvocationResult<>(//
+ permissions.diagnostic(), //
+ new AppliedLicenses(//
+ permissions.data().get(), //
+ agreements())//
+ );
+ }
+
+ private BaseServiceInvocationResult> permissions() {
return registry.services().stream() //
.map(service -> service.emit(conditions, product))//
.reduce(new BaseServiceInvocationResult.Sum<>(new SumOfCollections()))//
@@ -70,6 +83,13 @@ private Collection allPermissions(Optional> emi
new SumOfCollections());
}
+ private Collection agreements() {
+ return conditions.stream()//
+ .map(ConditionPack::agreements)//
+ .flatMap(Collection::stream)//
+ .collect(Collectors.toList());
+ }
+
/**
* Here we do not need `ConditionPack` granularity, thus unfold each one to
* amass all the permissions we have.
@@ -85,4 +105,27 @@ public Collection apply(Collection sum, Emission emissio
}
+ public static final class AppliedLicenses {
+
+ private final Collection permissions;
+ private final Collection agreements;
+
+ AppliedLicenses() {
+ this(Collections.emptyList(), Collections.emptyList());
+ }
+
+ AppliedLicenses(Collection permissions, Collection agreements) {
+ this.permissions = permissions;
+ this.agreements = agreements;
+ }
+
+ Collection permissions() {
+ return permissions;
+ }
+
+ Collection agreements() {
+ return agreements;
+ }
+ }
+
}
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/access/Restrictions.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/access/Restrictions.java
index 5ec893de2..11ee9649f 100644
--- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/access/Restrictions.java
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/access/Restrictions.java
@@ -13,18 +13,33 @@
package org.eclipse.passage.lic.base.access;
import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import org.eclipse.passage.lic.api.LicensedProduct;
import org.eclipse.passage.lic.api.ServiceInvocationResult;
-import org.eclipse.passage.lic.api.conditions.evaluation.Permission;
+import org.eclipse.passage.lic.api.agreements.AgreementAcceptanceService;
+import org.eclipse.passage.lic.api.agreements.AgreementState;
+import org.eclipse.passage.lic.api.agreements.AgreementToAccept;
+import org.eclipse.passage.lic.api.agreements.GlobalAgreement;
+import org.eclipse.passage.lic.api.agreements.ResolvedAgreement;
import org.eclipse.passage.lic.api.diagnostic.Trouble;
import org.eclipse.passage.lic.api.registry.Registry;
import org.eclipse.passage.lic.api.registry.StringServiceId;
import org.eclipse.passage.lic.api.requirements.Requirement;
import org.eclipse.passage.lic.api.restrictions.ExaminationCertificate;
import org.eclipse.passage.lic.api.restrictions.PermissionsExaminationService;
+import org.eclipse.passage.lic.api.restrictions.Restriction;
import org.eclipse.passage.lic.base.BaseServiceInvocationResult;
+import org.eclipse.passage.lic.base.access.Permissions.AppliedLicenses;
+import org.eclipse.passage.lic.base.agreements.AgreementAcceptanceDemand;
+import org.eclipse.passage.lic.base.agreements.BaseAgreementToAccept;
+import org.eclipse.passage.lic.base.agreements.MinedAgreement;
+import org.eclipse.passage.lic.base.agreements.UnacceptedAgreementRestriction;
import org.eclipse.passage.lic.base.diagnostic.code.NoServicesOfType;
+import org.eclipse.passage.lic.base.restrictions.BaseExaminationCertificate;
import org.eclipse.passage.lic.internal.base.i18n.AccessCycleMessages;
/**
@@ -33,12 +48,16 @@
public final class Restrictions implements Supplier> {
private final Registry registry;
+ private final AgreementAcceptanceService acceptance;
private final Collection requirements;
- private final Collection permissions;
+ private final AppliedLicenses permissions;
+ private final LicensedProduct product;
- public Restrictions(Registry registry,
- Collection requirements, Collection permissions) {
+ public Restrictions(LicensedProduct product, Registry registry,
+ AgreementAcceptanceService acceptance, Collection requirements, AppliedLicenses permissions) {
+ this.product = product;
this.registry = registry;
+ this.acceptance = acceptance;
this.requirements = requirements;
this.permissions = permissions;
}
@@ -52,11 +71,43 @@ public ServiceInvocationResult get() {
AccessCycleMessages.getString("Restrictions.no_services"))); //$NON-NLS-1$
}
return new BaseServiceInvocationResult(//
- registry.services().stream()//
- .map(service -> service.examine(requirements, permissions)) //
- .reduce(new SumOfCertificates())//
- .get() // guaranteed to exist as there is at least one service
+ new SumOfCertificates().apply(//
+ permissionBasedCertificate(), //
+ agreementsBasedCertificate())//
);
}
+ private ExaminationCertificate permissionBasedCertificate() {
+ return registry.services().stream()//
+ .map(service -> service.examine(requirements, permissions.permissions())) //
+ .reduce(new SumOfCertificates())//
+ .get(); // guaranteed to exist as there is at least one service
+ }
+
+ private ExaminationCertificate agreementsBasedCertificate() {
+ List agreements = permissions.agreements().stream()//
+ .map(this::agreementToAccept)//
+ .collect(Collectors.toList());
+ return new BaseExaminationCertificate(Collections.emptyMap(), restrictions(agreements), agreements);
+ }
+
+ private AgreementToAccept agreementToAccept(GlobalAgreement agreement) {
+ ResolvedAgreement definition = new MinedAgreement(agreement);
+ return new BaseAgreementToAccept(//
+ new AgreementAcceptanceDemand(definition), //
+ definition, //
+ acceptanceState(agreement));
+ }
+
+ private AgreementState acceptanceState(GlobalAgreement agreement) {
+ return acceptance.accepted(agreement.content(), agreement.name());
+ }
+
+ private Collection restrictions(List agreements) {
+ return agreements.stream()//
+ .filter(agreement -> !agreement.acceptance().accepted())//
+ .map(agreement -> new UnacceptedAgreementRestriction(product, agreement).get())//
+ .collect(Collectors.toList());
+ }
+
}
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/agreements/AgreementAcceptanceDemand.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/agreements/AgreementAcceptanceDemand.java
new file mode 100644
index 000000000..765ab5277
--- /dev/null
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/agreements/AgreementAcceptanceDemand.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2021 ArSysOp
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * https://www.eclipse.org/legal/epl-2.0/.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * ArSysOp - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.passage.lic.base.agreements;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.passage.lic.api.agreements.ResolvedAgreement;
+import org.eclipse.passage.lic.api.requirements.Feature;
+import org.eclipse.passage.lic.api.requirements.Requirement;
+import org.eclipse.passage.lic.api.restrictions.RestrictionLevel;
+
+public final class AgreementAcceptanceDemand implements Requirement {
+
+ private final Feature feature;
+ private final List agreement;
+
+ public AgreementAcceptanceDemand(ResolvedAgreement agreement) {
+ this.feature = new GlobalAgreementSupportFeature().get();
+ this.agreement = Collections.singletonList(agreement);
+ }
+
+ @Override
+ public Feature feature() {
+ return feature;
+ }
+
+ @Override
+ public RestrictionLevel restrictionLevel() {
+ return new RestrictionLevel.Fatal();
+ }
+
+ @Override
+ public List agreements() {
+ return agreement;
+ }
+
+ @Override
+ public Object source() {
+ return "a license"; //$NON-NLS-1$
+ }
+
+}
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/agreements/GlobalAgreementSupportFeature.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/agreements/GlobalAgreementSupportFeature.java
new file mode 100644
index 000000000..ba9e79f82
--- /dev/null
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/agreements/GlobalAgreementSupportFeature.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2021 ArSysOp
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * https://www.eclipse.org/legal/epl-2.0/.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * ArSysOp - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.passage.lic.base.agreements;
+
+import java.util.function.Supplier;
+
+import org.eclipse.passage.lic.api.requirements.Feature;
+import org.eclipse.passage.lic.base.requirements.BaseFeature;
+
+public final class GlobalAgreementSupportFeature implements Supplier {
+
+ @Override
+ public Feature get() {
+ return new BaseFeature(//
+ "passage.global-agreement-support.feature", //$NON-NLS-1$
+ "0.0.0", //$NON-NLS-1$
+ "Global Agreements Support", //$NON-NLS-1$
+ "Eclipse Passage Runtime" //$NON-NLS-1$
+ );
+ }
+
+}
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/agreements/MinedAgreement.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/agreements/MinedAgreement.java
new file mode 100644
index 000000000..e423d749a
--- /dev/null
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/agreements/MinedAgreement.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2021 ArSysOp
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * https://www.eclipse.org/legal/epl-2.0/.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * ArSysOp - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.passage.lic.base.agreements;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.passage.lic.api.agreements.GlobalAgreement;
+import org.eclipse.passage.lic.api.agreements.ResolvedAgreement;
+
+public final class MinedAgreement implements ResolvedAgreement {
+ private final GlobalAgreement agreement;
+
+ public MinedAgreement(GlobalAgreement agreement) {
+ this.agreement = agreement;
+ }
+
+ @Override
+ public InputStream content() throws IOException {
+ return new ByteArrayInputStream(agreement.content());
+ }
+
+ @Override
+ public String path() {
+ return agreement.file();
+ }
+
+}
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/agreements/UnacceptedAgreementRestriction.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/agreements/UnacceptedAgreementRestriction.java
new file mode 100644
index 000000000..a73751b60
--- /dev/null
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/agreements/UnacceptedAgreementRestriction.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2021 ArSysOp
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * https://www.eclipse.org/legal/epl-2.0/.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * ArSysOp - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.passage.lic.base.agreements;
+
+import java.util.function.Supplier;
+
+import org.eclipse.passage.lic.api.LicensedProduct;
+import org.eclipse.passage.lic.api.agreements.AgreementToAccept;
+import org.eclipse.passage.lic.api.restrictions.Restriction;
+import org.eclipse.passage.lic.base.diagnostic.code.AgreementNotAccepted;
+import org.eclipse.passage.lic.base.restrictions.BaseRestriction;
+
+public final class UnacceptedAgreementRestriction implements Supplier {
+
+ private final LicensedProduct product;
+ private final AgreementToAccept agreement;
+
+ public UnacceptedAgreementRestriction(LicensedProduct product, AgreementToAccept agreement) {
+ this.product = product;
+ this.agreement = agreement;
+ }
+
+ @Override
+ public Restriction get() {
+ return new BaseRestriction(product, agreement.origin(), new AgreementNotAccepted());
+ }
+
+}
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/restrictions/BasePermissionsExaminationService.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/restrictions/BasePermissionsExaminationService.java
index b2208961d..20630ef00 100644
--- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/restrictions/BasePermissionsExaminationService.java
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/restrictions/BasePermissionsExaminationService.java
@@ -32,7 +32,7 @@
import org.eclipse.passage.lic.api.restrictions.PermissionsExaminationService;
import org.eclipse.passage.lic.api.restrictions.Restriction;
import org.eclipse.passage.lic.base.agreements.AgreementAssessmentService;
-import org.eclipse.passage.lic.base.diagnostic.code.AgreementNotAccepted;
+import org.eclipse.passage.lic.base.agreements.UnacceptedAgreementRestriction;
import org.eclipse.passage.lic.base.diagnostic.code.InsufficientLicenseCoverage;
/**
@@ -126,12 +126,8 @@ private Restriction insufficientLicenseCoverage(Requirement requirement) {
private List unacceptedAgreements(Collection agreements) {
return agreements.stream()// .
.filter(agreement -> !agreement.acceptance().accepted())//
- .map(this::restrictionForUnacceptedAgreement)//
+ .map(agreement -> new UnacceptedAgreementRestriction(product, agreement).get())//
.collect(Collectors.toList());
}
- private Restriction restrictionForUnacceptedAgreement(AgreementToAccept agreement) {
- return new BaseRestriction(product, agreement.origin(), new AgreementNotAccepted());
- }
-
}