diff --git a/bundles/org.eclipse.passage.loc.licenses.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.passage.loc.licenses.core/META-INF/MANIFEST.MF index 0251ddc63..66551d5ab 100644 --- a/bundles/org.eclipse.passage.loc.licenses.core/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.passage.loc.licenses.core/META-INF/MANIFEST.MF @@ -7,19 +7,20 @@ Bundle-Name: %Bundle-Name Bundle-Vendor: %Bundle-Vendor Bundle-Copyright: %Bundle-Copyright Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.osgi.services;bundle-version="0.0.0", +Require-Bundle: org.apache.logging.log4j;bundle-version="2.8.2", org.eclipse.osgi;bundle-version="0.0.0", + org.eclipse.osgi.services;bundle-version="0.0.0", + org.eclipse.passage.lic.base;bundle-version="0.0.0", org.eclipse.passage.lic.email;bundle-version="0.0.0", org.eclipse.passage.lic.emf;bundle-version="0.0.0", org.eclipse.passage.lic.equinox;bundle-version="0.0.0", + org.eclipse.passage.lic.keys.model;bundle-version="0.0.0", org.eclipse.passage.lic.licenses.model;bundle-version="0.0.0";visibility:=reexport, org.eclipse.passage.lic.users.model;bundle-version="0.0.0", + org.eclipse.passage.loc.agreements.core;bundle-version="0.0.0", org.eclipse.passage.loc.api;bundle-version="0.0.0", org.eclipse.passage.loc.products.core;bundle-version="0.0.0", - org.eclipse.passage.loc.users.core;bundle-version="0.0.0", - org.eclipse.passage.lic.base;bundle-version="0.0.0", - org.apache.logging.log4j;bundle-version="2.8.2", - org.eclipse.passage.lic.keys.model;bundle-version="0.0.0" + org.eclipse.passage.loc.users.core;bundle-version="0.0.0" Export-Package: org.eclipse.passage.loc.internal.licenses; x-friends:="org.eclipse.passage.loc.licenses.emfforms, org.eclipse.passage.loc.licenses.ui, diff --git a/bundles/org.eclipse.passage.loc.licenses.core/OSGI-INF/org.eclipse.passage.loc.internal.licenses.core.LicenseOperatorServiceImpl.xml b/bundles/org.eclipse.passage.loc.licenses.core/OSGI-INF/org.eclipse.passage.loc.internal.licenses.core.LicenseOperatorServiceImpl.xml index 563f540a9..5d11f1ff9 100644 --- a/bundles/org.eclipse.passage.loc.licenses.core/OSGI-INF/org.eclipse.passage.loc.internal.licenses.core.LicenseOperatorServiceImpl.xml +++ b/bundles/org.eclipse.passage.loc.licenses.core/OSGI-INF/org.eclipse.passage.loc.internal.licenses.core.LicenseOperatorServiceImpl.xml @@ -3,6 +3,7 @@ + diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/IssuePersonalLicense.java b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/IssuePersonalLicense.java index 8a1f0562f..47b8e55b7 100644 --- a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/IssuePersonalLicense.java +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/IssuePersonalLicense.java @@ -30,7 +30,9 @@ import org.eclipse.passage.lic.base.io.UserHomeProductResidence; import org.eclipse.passage.lic.emf.validation.ErrorMessages; import org.eclipse.passage.lic.internal.licenses.model.AssignGrantIdentifiers; +import org.eclipse.passage.lic.licenses.LicensePlanDescriptor; import org.eclipse.passage.lic.licenses.model.api.PersonalLicensePack; +import org.eclipse.passage.loc.internal.agreements.AgreementRegistry; import org.eclipse.passage.loc.internal.api.IssuedLicense; import org.eclipse.passage.loc.internal.api.OperatorLicenseEvents; import org.eclipse.passage.loc.internal.api.OperatorProductService; @@ -38,6 +40,7 @@ import org.eclipse.passage.loc.internal.licenses.core.i18n.LicensesCoreMessages; import org.eclipse.passage.loc.internal.licenses.core.issue.PersonalLicenseIssuingProtection; import org.eclipse.passage.loc.internal.products.ProductRegistry; +import org.eclipse.passage.loc.licenses.trouble.code.LicenseAgreementsAttachFailed; import org.eclipse.passage.loc.licenses.trouble.code.LicenseIssuingFailed; import org.eclipse.passage.loc.licenses.trouble.code.LicenseValidationFailed; import org.osgi.service.event.EventAdmin; @@ -45,25 +48,33 @@ final class IssuePersonalLicense { private final LicenseRegistry licenses; + private final AgreementRegistry agreements; private final ProductRegistry products; private final OperatorProductService operator; private final EventAdmin events; - IssuePersonalLicense(LicenseRegistry licenses, ProductRegistry products, OperatorProductService operator, - EventAdmin events) { + IssuePersonalLicense(LicenseRegistry licenses, AgreementRegistry agreements, ProductRegistry products, + OperatorProductService operator, EventAdmin events) { this.licenses = licenses; + this.agreements = agreements; this.products = products; this.operator = operator; this.events = events; } ServiceInvocationResult issue(Supplier template) { - PersonalLicensePack license = new Builder(template.get())// - .adjusted()// - .guarded()// - .withSignature()// - .withAgreements()// - .build(); + PersonalLicensePack license; + try { + license = new Builder(template.get())// + .adjusted()// + .guarded()// + .signed()// + .withAgreements()// + .get(); + } catch (LicensingException e) { + return new BaseServiceInvocationResult<>( + new Trouble(new LicenseAgreementsAttachFailed(), e.getMessage(), e)); + } Optional errors = new ErrorMessages().apply(license); if (errors.isPresent()) { return new BaseServiceInvocationResult<>(new Trouble(new LicenseValidationFailed(), errors.get())); @@ -121,7 +132,7 @@ private BaseLicensedProduct product(PersonalLicensePack license) { license.getLicense().getProduct().getVersion()); } - private static final class Builder { + private final class Builder implements Supplier { private final PersonalLicensePack pack; @@ -129,14 +140,13 @@ private static final class Builder { this.pack = EcoreUtil.copy(template); } - Builder withSignature() { + Builder signed() { new LicenseSignature().accept(pack.getLicense()); return this; } - Builder withAgreements() { - - // TODO + Builder withAgreements() throws LicensingException { + new LicenseAgreements(agreements).install(plan(), pack.getLicense()); return this; } @@ -152,8 +162,13 @@ Builder guarded() { return this; } - PersonalLicensePack build() { + @Override + public PersonalLicensePack get() { return pack; } + + private LicensePlanDescriptor plan() { + return licenses.getLicensePlan(pack.getLicense().getPlan()); + } } } diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/LicenseAgreements.java b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/LicenseAgreements.java new file mode 100644 index 000000000..5a597051b --- /dev/null +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/LicenseAgreements.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * 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.loc.internal.licenses.core; + +import java.util.Collection; +import java.util.Optional; + +import org.eclipse.passage.lic.agreements.AgreementDescriptor; +import org.eclipse.passage.lic.api.LicensingException; +import org.eclipse.passage.lic.api.io.Hashes; +import org.eclipse.passage.lic.api.io.HashesRegistry; +import org.eclipse.passage.lic.licenses.LicensePlanDescriptor; +import org.eclipse.passage.lic.licenses.model.api.AgreementData; +import org.eclipse.passage.lic.licenses.model.api.LicenseRequisites; +import org.eclipse.passage.lic.licenses.model.meta.LicensesFactory; +import org.eclipse.passage.loc.internal.agreements.AgreementRegistry; +import org.eclipse.passage.loc.internal.api.workspace.Agreements; +import org.eclipse.passage.loc.internal.equinox.AgreementsService; +import org.eclipse.passage.loc.internal.equinox.OperatorGearAware; +import org.eclipse.passage.loc.internal.licenses.core.i18n.LicensesCoreMessages; + +@SuppressWarnings("restriction") +final class LicenseAgreements { + + private final AgreementRegistry registry; + + LicenseAgreements(AgreementRegistry registry) { + this.registry = registry; + } + + void install(LicensePlanDescriptor plan, LicenseRequisites license) throws LicensingException { + Agreements service = new AgreementsService().get(); // TODO: cashed field + Hashes hashes = hashes();// TODO: cashed field + for (String identifier : plan.getAgreements()) { + installAgreement(license, registry.agreement(identifier), service, hashes); + } + + } + + private void installAgreement(LicenseRequisites license, AgreementDescriptor agreement, Agreements service, + Hashes hashes) throws LicensingException { + if (!service.exists(agreement.getFile())) { + throw new LicensingException(String.format(// + LicensesCoreMessages.LicenseOperatorServiceImpl_failed_to_find_agreement_file, // + service.located(agreement.getFile()).info(), // + agreement.getName())); + } + license.getAgreements().add(data(agreement, service, hashes)); + } + + private AgreementData data(AgreementDescriptor agreement, Agreements service, Hashes hashes) + throws LicensingException { + AgreementData data = LicensesFactory.eINSTANCE.createAgreementData(); + data.setIdentifier(agreement.getIdentifier()); + data.setName(agreement.getName()); + data.setFile(agreement.getFile()); + data.setContentType(agreement.getMime()); + byte[] content = content(agreement, service); + data.setContent(content); + data.setHashAlgo(hashes.id().toString()); + data.setHash(hashes.get(content)); + return data; + } + + private byte[] content(AgreementDescriptor agreement, Agreements service) throws LicensingException { + try { + return service.located(agreement.getFile()).content(); + } catch (Exception e) { + throw new LicensingException(String.format(// + LicensesCoreMessages.LicenseOperatorServiceImpl_failed_to_attach_agreement, // + agreement.getName(), // + service.located(agreement.getFile()).info(), // + e)); + } + } + + private Hashes hashes() throws LicensingException { + Optional service = new OperatorGearAware().withGear(gear -> Optional.of(gear.hashes())); + if (!service.isPresent()) { + throw new LicensingException("There is no HashesRegistry service supplied by Operator Gear"); //$NON-NLS-1$ + } + Collection all = service.get().get().services(); + if (all.isEmpty()) { + throw new LicensingException("There is no Hashes service supplied by Operator Gear"); //$NON-NLS-1$ + } + return all.iterator().next(); + } +} diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/LicenseOperatorServiceImpl.java b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/LicenseOperatorServiceImpl.java index 817b659a4..f355198db 100644 --- a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/LicenseOperatorServiceImpl.java +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/LicenseOperatorServiceImpl.java @@ -23,6 +23,7 @@ import org.eclipse.passage.lic.licenses.model.api.FloatingLicenseAccess; import org.eclipse.passage.lic.licenses.model.api.FloatingLicensePack; import org.eclipse.passage.lic.licenses.model.api.PersonalLicensePack; +import org.eclipse.passage.loc.internal.agreements.AgreementRegistry; import org.eclipse.passage.loc.internal.api.FloatingLicenseRequest; import org.eclipse.passage.loc.internal.api.IssuedFloatingLicense; import org.eclipse.passage.loc.internal.api.IssuedLicense; @@ -44,6 +45,7 @@ public class LicenseOperatorServiceImpl implements OperatorLicenseService { private ProductRegistry products; private UserRegistry users; private LicenseRegistry licenses; + private AgreementRegistry agreements; private OperatorProductService operator; @Reference @@ -90,6 +92,17 @@ public void unbindLicenseRegistry(LicenseRegistry registry) { } } + @Reference + public void bindAgreementRegistry(AgreementRegistry registry) { + this.agreements = registry; + } + + public void unbindAgreementRegistry(AgreementRegistry registry) { + if (Objects.equals(this.agreements, registry)) { + this.agreements = null; + } + } + @Reference public void bindUserRegistry(UserRegistry registry) { this.users = registry; @@ -125,7 +138,7 @@ public ServiceInvocationResult issueLicensePack(PersonalLicenseRe Supplier pack = (template instanceof PersonalLicensePack) // ? () -> PersonalLicensePack.class.cast(template)// : () -> createLicensePack(request); - return new IssuePersonalLicense(licenses, products, operator, events).issue(pack); + return new IssuePersonalLicense(licenses, agreements, products, operator, events).issue(pack); } @Override diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicenseTroubleCodeMessages.java b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicenseTroubleCodeMessages.java index 6fc32d978..ff05d7ef4 100644 --- a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicenseTroubleCodeMessages.java +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicenseTroubleCodeMessages.java @@ -20,6 +20,7 @@ public final class LicenseTroubleCodeMessages extends NLS { public static String LicenseValidationFailed_explanation; public static String LicenseIssuingFailed_explanation; public static String LicenseIssuingIsPartial_explanation; + public static String LicenseAgreementAttachFailed_explanation; static { // initialize resource bundle diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicenseTroubleCodeMessages.properties b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicenseTroubleCodeMessages.properties index 72c6684ad..59d193ea1 100644 --- a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicenseTroubleCodeMessages.properties +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicenseTroubleCodeMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2020 ArSysOp and others +# Copyright (c) 2020, 2021 ArSysOp and others # # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at @@ -13,3 +13,4 @@ LicenseIssuingFailed_explanation=License issuing failed LicenseValidationFailed_explanation=License information contains unavoidable errors LicenseIssuingIsPartial_explanation=License issuing is partially completed +LicenseAgreementAttachFailed_explanation=Failed to attach agreement to license pack diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.java b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.java index 17bc9840f..2559fd559 100644 --- a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.java +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.java @@ -48,6 +48,8 @@ public final class LicensesCoreMessages extends NLS { public static String LicenseOperatorServiceImpl_floating_save_encoded_failed; public static String LicenseOperatorServiceImpl_floating_save_product_key; public static String LicenseOperatorServiceImpl_floating_save_encoded_file_error; + public static String LicenseOperatorServiceImpl_failed_to_find_agreement_file; + public static String LicenseOperatorServiceImpl_failed_to_attach_agreement; static { // initialize resource bundle diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.properties b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.properties index 32b8f0971..8ad104f46 100644 --- a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.properties +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.properties @@ -16,6 +16,8 @@ EmfObjectPersisted_failed=Failed to persist emf object %s to %s LicenseOperatorServiceImpl_error_io=Failed on I/O operation LicenseOperatorServiceImpl_export_error=License Pack export error LicenseOperatorServiceImpl_export_success=License pack exported successfully: \n\n %s \n +LicenseOperatorServiceImpl_failed_to_find_agreement_file=Content file [%s] for agreement [%s] is not found +LicenseOperatorServiceImpl_failed_to_attach_agreement=Failed to attach agreement [%s] with content [%s] to license LicenseOperatorServiceImpl_failed_to_save_decoded=Failed on decoded license file saving LicenseOperatorServiceImpl_status_invalid_licensing_request=Invalid Licensing Request LicenseOperatorServiceImpl_w_no_encoding=License Pack has been exported without encoding: \n\n %s \n diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/licenses/trouble/code/LicenseAgreementsAttachFailed.java b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/licenses/trouble/code/LicenseAgreementsAttachFailed.java new file mode 100644 index 000000000..242818e55 --- /dev/null +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/licenses/trouble/code/LicenseAgreementsAttachFailed.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * 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.loc.licenses.trouble.code; + +import org.eclipse.passage.lic.api.diagnostic.TroubleCode; +import org.eclipse.passage.loc.internal.licenses.core.i18n.LicenseTroubleCodeMessages; + +public final class LicenseAgreementsAttachFailed extends TroubleCode { + + public LicenseAgreementsAttachFailed() { + super(903, LicenseTroubleCodeMessages.LicenseAgreementAttachFailed_explanation); + } + +} diff --git a/bundles/org.eclipse.passage.loc.licenses.emfforms/META-INF/MANIFEST.MF b/bundles/org.eclipse.passage.loc.licenses.emfforms/META-INF/MANIFEST.MF index c42b9ad26..7eaa403f4 100644 --- a/bundles/org.eclipse.passage.loc.licenses.emfforms/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.passage.loc.licenses.emfforms/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Automatic-Module-Name: org.eclipse.passage.loc.licenses.emfforms Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.passage.loc.licenses.emfforms;singleton:=true -Bundle-Version: 0.8.0.qualifier +Bundle-Version: 0.9.0.qualifier Bundle-Name: %Bundle-Name Bundle-Vendor: %Bundle-Vendor Bundle-Copyright: %Bundle-Copyright diff --git a/bundles/org.eclipse.passage.loc.licenses.emfforms/viewmodels/LicensePlan.view b/bundles/org.eclipse.passage.loc.licenses.emfforms/viewmodels/LicensePlan.view index 69c9eade6..f07a4c00a 100644 --- a/bundles/org.eclipse.passage.loc.licenses.emfforms/viewmodels/LicensePlan.view +++ b/bundles/org.eclipse.passage.loc.licenses.emfforms/viewmodels/LicensePlan.view @@ -16,5 +16,10 @@ + + + + + /org.eclipse.passage.lic.licenses.ecore/model/licenses.ecore