diff --git a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/api/LicensingConfiguration.java b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/api/LicensingConfiguration.java index 094726771..21c9c8f1f 100644 --- a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/api/LicensingConfiguration.java +++ b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/api/LicensingConfiguration.java @@ -13,12 +13,18 @@ package org.eclipse.passage.lic.api; /** - *

Runtime descriptor for the configuration being examined for restrictions.

+ *

+ * Runtime descriptor for the configuration being examined for restrictions. + *

* - *

Represents the pair {id, version} for the running product.

+ *

+ * Represents the pair {id, version} for the running product. + *

* * @since 0.4.0 + * @deprecated use LicensedProduct */ +@Deprecated public interface LicensingConfiguration { /** diff --git a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/api/LicensingException.java b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/api/LicensingException.java index 5ba06e059..f0afa0b04 100644 --- a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/api/LicensingException.java +++ b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/api/LicensingException.java @@ -13,12 +13,19 @@ package org.eclipse.passage.lic.api; /** - *

A checked exception representing a failure.

- *

Licensing exceptions contain a result object describing the cause of the exception.

+ *

+ * A checked exception representing a failure. + *

+ *

+ * Licensing exceptions contain a result object describing the cause of the + * exception. + *

* * @see LicensingResult + * @deprecated use internal version * @since 0.4.0 */ +@Deprecated public class LicensingException extends Exception { private static final long serialVersionUID = 1L; diff --git a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/AccessCycleConfiguration.java b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/AccessCycleConfiguration.java new file mode 100644 index 000000000..44a066319 --- /dev/null +++ b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/AccessCycleConfiguration.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2020 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.internal.api; + +import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditionsRegistry; +import org.eclipse.passage.lic.internal.api.requirements.ResolvedRequirementsRegistry; + +/** + * Supplies all the service that runtime access cycle can count on. + */ +public interface AccessCycleConfiguration { + + ResolvedRequirementsRegistry requirementsRegistry(); + + MinedConditionsRegistry conditionsRegistry(); + +} diff --git a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/Framework.java b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/Framework.java index a8377fa43..8c67c3ed6 100644 --- a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/Framework.java +++ b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/Framework.java @@ -12,9 +12,6 @@ *******************************************************************************/ package org.eclipse.passage.lic.internal.api; -import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditionsRegistry; -import org.eclipse.passage.lic.internal.api.requirements.ResolvedRequirementsRegistry; - /** *

* All the framework-relying constructions are to originate from this point this @@ -37,8 +34,8 @@ */ public interface Framework { - ResolvedRequirementsRegistry requirementsRegistry(); + LicensedProduct product(); - MinedConditionsRegistry conditionsRegistry(); + AccessCycleConfiguration accessCycleConfiguration(); } diff --git a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/LicensedProduct.java b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/LicensedProduct.java new file mode 100644 index 000000000..6b28a3984 --- /dev/null +++ b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/LicensedProduct.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2020 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.internal.api; + +public interface LicensedProduct { + + String identifier(); + + String version(); + +} diff --git a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/LicensingException.java b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/LicensingException.java new file mode 100644 index 000000000..b8d714d7a --- /dev/null +++ b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/LicensingException.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2020 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.internal.api; + +/** + * As licensing runtime is a complicated and infrastructure-dependent, wide + * variety of things can occasionally go south. This general purpose exception + * serves misbehaviors in crucial parts. + */ +public final class LicensingException extends Exception { + + /** + * generated + */ + private static final long serialVersionUID = 7746884069745071894L; + + public LicensingException(String message, Throwable cause) { + super(message, cause); + } + + public LicensingException(String message) { + super(message); + } + +} diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/LicensingConfigurations.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/LicensingConfigurations.java index 750a56aa8..2c1ed03d0 100644 --- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/LicensingConfigurations.java +++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/base/LicensingConfigurations.java @@ -13,15 +13,18 @@ package org.eclipse.passage.lic.base; import java.util.Map; +import java.util.Objects; import org.eclipse.passage.lic.api.LicensingConfiguration; -import org.eclipse.passage.lic.internal.base.BaseLicensingConfiguration; +import org.eclipse.passage.lic.internal.base.BaseLicensedProduct; import org.eclipse.passage.lic.internal.base.NamedData; +import org.eclipse.passage.lic.internal.base.ProductIdentifier; +import org.eclipse.passage.lic.internal.base.ProductVersion; /** * - * @deprecated use {@linkplain NamedData}, {@linkplain ProductInfo} or - * another implementations, {@linkplain BaseLicensingConfiguration} + * @deprecated use {@linkplain NamedData}, {@linkplain ProductInfo} or another + * implementations, {@linkplain BaseLicensedProduct} */ @Deprecated public final class LicensingConfigurations { @@ -32,7 +35,7 @@ public final class LicensingConfigurations { public static final String IDENTIFIER_INVALID = "org.eclipse.passage.lic.api.configuration.invalid"; //$NON-NLS-1$ - public static final LicensingConfiguration INVALID = new BaseLicensingConfiguration(IDENTIFIER_INVALID, + public static final LicensingConfiguration INVALID = new LicConfig(IDENTIFIER_INVALID, LicensingVersions.VERSION_DEFAULT); private LicensingConfigurations() { @@ -40,13 +43,64 @@ private LicensingConfigurations() { } public static LicensingConfiguration create(String product, String version) { - return new BaseLicensingConfiguration(String.valueOf(product), String.valueOf(version)); + return new LicConfig(String.valueOf(product), String.valueOf(version)); } public static LicensingConfiguration create(Map properties) { String product = String.valueOf(properties.get(LICENSING_PRODUCT_IDENTIFIER)); String version = String.valueOf(properties.get(LICENSING_PRODUCT_VERSION)); - return new BaseLicensingConfiguration(product, version); + return new LicConfig(product, version); + } + + private static final class LicConfig implements LicensingConfiguration { + + private final String id; + private final String version; + + private LicConfig(String id, String version) { + this.id = id; + this.version = version; + } + + @Override + public String getProductIdentifier() { + return id; + } + + @Override + public String getProductVersion() { + return version; + } + + @Override + public int hashCode() { + return Objects.hash(id, version); + } + + @Override + public boolean equals(Object obj) { + if (!LicensingConfiguration.class.isInstance(obj)) { + return false; + } + LicensingConfiguration other = (LicensingConfiguration) obj; + if (!Objects.equals(id, other.getProductIdentifier())) { + return false; + } + if (!Objects.equals(version, other.getProductVersion())) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + new NamedData.Writable(new ProductIdentifier(id)).write(output); + output.append(';'); + new NamedData.Writable(new ProductVersion(version)).write(output); + return output.toString(); + } + } } diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/Access.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/Access.java index 52c1150e0..4c8e44e79 100644 --- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/Access.java +++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/Access.java @@ -31,7 +31,8 @@ public Access(Framework framework) { } public boolean canUse(String feature) { - Set requirements = new Requirements(framework.requirementsRegistry().get(), feature).get(); + Set requirements = new Requirements( + framework.accessCycleConfiguration().requirementsRegistry().get(), feature).get(); if (requirements.isEmpty()) { return true; } diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/BaseLicensingConfiguration.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/BaseLicensedProduct.java similarity index 58% rename from bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/BaseLicensingConfiguration.java rename to bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/BaseLicensedProduct.java index 5c725bb49..79166b970 100644 --- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/BaseLicensingConfiguration.java +++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/BaseLicensedProduct.java @@ -14,61 +14,54 @@ import java.util.Objects; -import org.eclipse.passage.lic.api.LicensingConfiguration; +import org.eclipse.passage.lic.internal.api.LicensedProduct; /** - * Default data-driven implementation of {@code LicensingConfiguration}. True - * {@code data-class}. + * Default data-driven implementation of {@code LicensedProduct} represents + * configuration of the running product. True {@code data-class}. * - * @see LicensingConfiguration + * @see LicensedProduct * @see ProductIdentifier * @see ProductVersion */ -public final class BaseLicensingConfiguration implements LicensingConfiguration { +@SuppressWarnings("restriction") +public final class BaseLicensedProduct implements LicensedProduct { private final String identifier; private final String version; - public BaseLicensingConfiguration(String product, String version) { + public BaseLicensedProduct(String product, String version) { + Objects.requireNonNull(product, "BaseLicensedProduct::product"); //$NON-NLS-1$ + Objects.requireNonNull(version, "BaseLicensedProduct::version"); //$NON-NLS-1$ this.identifier = product; this.version = version; } @Override - public String getProductIdentifier() { + public String identifier() { return identifier; } @Override - public String getProductVersion() { + public String version() { return version; } @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((identifier == null) ? 0 : identifier.hashCode()); - result = prime * result + ((version == null) ? 0 : version.hashCode()); - return result; + return Objects.hash(identifier, version); } @Override public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { + if (!LicensedProduct.class.isInstance(obj)) { return false; } - BaseLicensingConfiguration other = (BaseLicensingConfiguration) obj; - if (!Objects.equals(identifier, other.identifier)) { + LicensedProduct other = (LicensedProduct) obj; + if (!Objects.equals(identifier, other.identifier())) { return false; } - if (!Objects.equals(version, other.version)) { + if (!Objects.equals(version, other.version())) { return false; } return true; diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/InvalidLicensingConfiguration.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/InvalidLicensedProduct.java similarity index 63% rename from bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/InvalidLicensingConfiguration.java rename to bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/InvalidLicensedProduct.java index 75cec4671..626334eba 100644 --- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/InvalidLicensingConfiguration.java +++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/InvalidLicensedProduct.java @@ -12,32 +12,33 @@ *******************************************************************************/ package org.eclipse.passage.lic.internal.base; -import org.eclipse.passage.lic.api.LicensingConfiguration; +import org.eclipse.passage.lic.internal.api.LicensedProduct; /** - * {@linkplain LicensingConfiguration} is a key piece of data for an - * {@code access cycle}. For the cases any sabotage is detected this + * {@linkplain LicensedProduct} is a key piece of data for an + * {@code access cycle}. For the cases of any sabotage is detected this * knowingly invalid configuration is used to make an {@code access cycle} * fail. */ -public final class InvalidLicensingConfiguration implements LicensingConfiguration { +@SuppressWarnings("restriction") +public final class InvalidLicensedProduct implements LicensedProduct { - private final BaseLicensingConfiguration delegate; + private final BaseLicensedProduct delegate; - public InvalidLicensingConfiguration() { - delegate = new BaseLicensingConfiguration(// + public InvalidLicensedProduct() { + delegate = new BaseLicensedProduct(// "org.eclipse.passage.lic.api.configuration.invalid", //$NON-NLS-1$ , "0.0.0"); //$NON-NLS-1$ } @Override - public String getProductIdentifier() { - return delegate.getProductIdentifier(); + public String identifier() { + return delegate.identifier(); } @Override - public String getProductVersion() { - return delegate.getProductVersion(); + public String version() { + return delegate.version(); } @Override diff --git a/bundles/org.eclipse.passage.lic.e4.ui/src/org/eclipse/passage/lic/internal/e4/ui/addons/E4LicensingAddon.java b/bundles/org.eclipse.passage.lic.e4.ui/src/org/eclipse/passage/lic/internal/e4/ui/addons/E4LicensingAddon.java index 41aad4e3d..1112a8568 100644 --- a/bundles/org.eclipse.passage.lic.e4.ui/src/org/eclipse/passage/lic/internal/e4/ui/addons/E4LicensingAddon.java +++ b/bundles/org.eclipse.passage.lic.e4.ui/src/org/eclipse/passage/lic/internal/e4/ui/addons/E4LicensingAddon.java @@ -18,27 +18,27 @@ import org.eclipse.e4.ui.di.UIEventTopic; import org.eclipse.e4.ui.workbench.UIEvents; import org.eclipse.equinox.app.IApplicationContext; -import org.eclipse.passage.lic.api.LicensingConfiguration; -import org.eclipse.passage.lic.internal.equinox.ApplicationConfiguration; import org.eclipse.passage.lic.internal.equinox.EquinoxPassage; +import org.eclipse.passage.lic.internal.equinox.LicensedApplicationFromContext; import org.osgi.service.event.Event; @SuppressWarnings("restriction") public final class E4LicensingAddon { - private final IApplicationContext applicationContext; + private final IApplicationContext context; @Inject - public E4LicensingAddon(IApplicationContext applicationContext) { - this.applicationContext = applicationContext; + public E4LicensingAddon(IApplicationContext context) { + this.context = context; } @Inject @Optional - public void applicationStarted( - @SuppressWarnings("unused") @UIEventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event) { - LicensingConfiguration configuration = new ApplicationConfiguration(applicationContext).get(); - new EquinoxPassage().checkLicense(configuration.getProductIdentifier()); + public void applicationStarted(// + @SuppressWarnings("unused") // + @UIEventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) // + Event event) { + new EquinoxPassage().checkLicense(new LicensedApplicationFromContext(context).get().identifier()); } } diff --git a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/equinox/ApplicationConfigurations.java b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/equinox/ApplicationConfigurations.java index c1945a58d..f589176c6 100644 --- a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/equinox/ApplicationConfigurations.java +++ b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/equinox/ApplicationConfigurations.java @@ -18,7 +18,7 @@ import org.eclipse.passage.lic.api.LicensingConfiguration; import org.eclipse.passage.lic.base.LicensingConfigurations; import org.eclipse.passage.lic.base.LicensingVersions; -import org.eclipse.passage.lic.internal.equinox.ApplicationConfiguration; +import org.eclipse.passage.lic.internal.equinox.LicensedApplicationFromContext; import org.eclipse.passage.lic.internal.equinox.i18n.EquinoxMessages; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -79,7 +79,7 @@ public static LicensingConfiguration getLicensingConfiguration() { /** * - * @deprecated use {@linkplain ApplicationConfiguration} + * @deprecated use {@linkplain LicensedApplicationFromContext} */ @Deprecated public static LicensingConfiguration getLicensingConfiguration(IApplicationContext application) { diff --git a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/ApplicationConfiguration.java b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/ApplicationConfiguration.java deleted file mode 100644 index 0f2aa5f7f..000000000 --- a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/ApplicationConfiguration.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020 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.internal.equinox; - -import java.util.function.Supplier; - -import org.eclipse.equinox.app.IApplicationContext; -import org.eclipse.passage.lic.api.LicensingConfiguration; -import org.eclipse.passage.lic.internal.base.BaseLicensingConfiguration; - -@SuppressWarnings("restriction") -public final class ApplicationConfiguration implements Supplier { - - private final IApplicationContext context; - - public ApplicationConfiguration(IApplicationContext context) { - this.context = context; - } - - @Override - public LicensingConfiguration get() { - return new BaseLicensingConfiguration(// - new ApplicationIdentifier(context).get(), // - new ApplicationVersion(context).get()); - } - -} diff --git a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/ApplicationIdentifier.java b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/ApplicationIdentifier.java index c0f1c33a4..92ac6b067 100644 --- a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/ApplicationIdentifier.java +++ b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/ApplicationIdentifier.java @@ -16,7 +16,7 @@ import java.util.function.Supplier; import org.eclipse.equinox.app.IApplicationContext; -import org.eclipse.passage.lic.internal.base.InvalidLicensingConfiguration; +import org.eclipse.passage.lic.internal.base.InvalidLicensedProduct; import org.eclipse.passage.lic.internal.base.ProductIdentifier; @SuppressWarnings("restriction") @@ -33,16 +33,16 @@ public String get() { if (property.isPresent()) { return property.get(); } - String brandingId = context.getBrandingId(); - if (brandingId != null) { - return brandingId; + String brand = context.getBrandingId(); + if (brand != null) { + return brand; } - String applicationId = context.getBrandingApplication(); - if (applicationId != null) { - return applicationId; + String application = context.getBrandingApplication(); + if (application != null) { + return application; } // OK, no more ideas - return new InvalidLicensingConfiguration().getProductIdentifier(); + return new InvalidLicensedProduct().identifier(); } } diff --git a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/ApplicationVersion.java b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/ApplicationVersion.java index 0997749d2..855a97b14 100644 --- a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/ApplicationVersion.java +++ b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/ApplicationVersion.java @@ -16,7 +16,7 @@ import java.util.function.Supplier; import org.eclipse.equinox.app.IApplicationContext; -import org.eclipse.passage.lic.internal.base.InvalidLicensingConfiguration; +import org.eclipse.passage.lic.internal.base.InvalidLicensedProduct; import org.eclipse.passage.lic.internal.base.ProductVersion; import org.osgi.framework.Bundle; import org.osgi.framework.Version; @@ -37,7 +37,7 @@ public String get() { } Bundle bundle = context.getBrandingBundle(); if (bundle == null) { - return new InvalidLicensingConfiguration().getProductVersion(); + return new InvalidLicensedProduct().version(); } return stringify(bundle.getVersion()); } diff --git a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/EquinoxPassage.java b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/EquinoxPassage.java index 77d1f2e81..160523d56 100644 --- a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/EquinoxPassage.java +++ b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/EquinoxPassage.java @@ -56,7 +56,7 @@ Optional frameworkSupplier() { .map(context::getService) // // DI is used only to get rid of overwhelming dependencies here .filter(supplier -> supplier.getClass().getName() - .equals("org.eclipse.passage.seal.internal.demo.DemoFrameworkSupplier")) //$NON-NLS-1$ FIXME + .equals("org.eclipse.passage.seal.internal.demo.DemoFrameworkSupplier")) //$NON-NLS-1$ .findAny(); } catch (InvalidSyntaxException e) { log.error(EquinoxMessages.EquinoxPassage_no_framework, e); diff --git a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/LicensedApplication.java b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/LicensedApplication.java new file mode 100644 index 000000000..214b949c9 --- /dev/null +++ b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/LicensedApplication.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2020 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.internal.equinox; + +import java.util.Optional; + +import org.eclipse.equinox.app.IApplicationContext; +import org.eclipse.passage.lic.internal.api.LicensedProduct; +import org.eclipse.passage.lic.internal.api.LicensingException; +import org.eclipse.passage.lic.internal.equinox.i18n.EquinoxMessages; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +@SuppressWarnings("restriction") +public final class LicensedApplication { + + public LicensedProduct product() throws LicensingException { + BundleContext context = context(); + ServiceReference reference = reference(context); + LicensedProduct product = product(context, reference); + context.ungetService(reference); + return product; + } + + private BundleContext context() throws LicensingException { + Optional context = Optional.ofNullable(FrameworkUtil.getBundle(getClass()).getBundleContext()); + if (!context.isPresent()) { + throw new LicensingException(EquinoxMessages.LicensedApplication_no_bundle_context); + } + return context.get(); + } + + private ServiceReference reference(BundleContext context) throws LicensingException { + Optional> reference = // + Optional.ofNullable(context.getServiceReference(IApplicationContext.class)); + if (!reference.isPresent()) { + throw new LicensingException(EquinoxMessages.LicensedApplication_no_application_context_service_ref); + } + return reference.get(); + } + + private LicensedProduct product(BundleContext context, ServiceReference reference) + throws LicensingException { + Optional service = Optional.ofNullable(context.getService(reference)); + if (!service.isPresent()) { + throw new LicensingException(EquinoxMessages.LicensedApplication_application_context_service_unregistered); + } + return new LicensedApplicationFromContext(service.get()).get(); + } + +} diff --git a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/LicensedApplicationFromContext.java b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/LicensedApplicationFromContext.java new file mode 100644 index 000000000..56e89882c --- /dev/null +++ b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/LicensedApplicationFromContext.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2020 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.internal.equinox; + +import java.util.Optional; +import java.util.function.Supplier; + +import org.eclipse.equinox.app.IApplicationContext; +import org.eclipse.passage.lic.internal.api.LicensedProduct; +import org.eclipse.passage.lic.internal.base.BaseLicensedProduct; + +@SuppressWarnings("restriction") +public final class LicensedApplicationFromContext implements Supplier { + + private final Supplier> context; + + public LicensedApplicationFromContext(IApplicationContext context) { + this.context = () -> Optional.of(context); + } + + @Override + public LicensedProduct get() { + Optional supplied = context.get(); + if (!supplied.isPresent()) { + throw new RuntimeException(); + } + return new BaseLicensedProduct(// + new ApplicationIdentifier(supplied.get()).get(), // + new ApplicationVersion(supplied.get()).get()); + } + +} diff --git a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/i18n/EquinoxMessages.java b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/i18n/EquinoxMessages.java index fffe28432..c2b6d7d78 100644 --- a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/i18n/EquinoxMessages.java +++ b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/i18n/EquinoxMessages.java @@ -42,6 +42,12 @@ public class EquinoxMessages extends NLS { public static String EquinoxRestrictionExecutorRegistry_info_title; public static String EquinoxRestrictionExecutorRegistry_warning_name; public static String EquinoxRestrictionExecutorRegistry_warning_title; + + public static String LicensedApplication_application_context_service_unregistered; + + public static String LicensedApplication_no_application_context_service_ref; + + public static String LicensedApplication_no_bundle_context; public static String RequirementsFromCapability_no_attributes; public static String RequirementsFromCapability_no_feature_id; diff --git a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/i18n/EquinoxMessages.properties b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/i18n/EquinoxMessages.properties index 9dc6eb07d..3af0fd5e0 100644 --- a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/i18n/EquinoxMessages.properties +++ b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/i18n/EquinoxMessages.properties @@ -34,5 +34,8 @@ EquinoxRestrictionExecutorRegistry_info_name=Info EquinoxRestrictionExecutorRegistry_info_title=Inform about functionality restriction without pausing the execution flow EquinoxRestrictionExecutorRegistry_warning_name=Warning EquinoxRestrictionExecutorRegistry_warning_title=Pause the execution flow with warning, but allow to proceed without functionality blocking +LicensedApplication_application_context_service_unregistered=Severe runtime insufficiency error: IApplicationContext service is unregistered or unavailable +LicensedApplication_no_application_context_service_ref=Severe runtime insufficiency error: no service reference for IApplicationContext +LicensedApplication_no_bundle_context=Severe runtime insufficiency error: no bundle context RequirementsFromCapability_no_attributes=Attributes for capability {0} in bundle {1} is required RequirementsFromCapability_no_feature_id=Configuration of a feature identifier in capability {0} of bundle {1} is required diff --git a/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/DemoFramework.java b/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/DemoFramework.java index 935dbc638..d80767e91 100644 --- a/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/DemoFramework.java +++ b/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/DemoFramework.java @@ -12,60 +12,44 @@ *******************************************************************************/ package org.eclipse.passage.seal.internal.demo; -import java.util.Arrays; - +import org.eclipse.passage.lic.internal.api.AccessCycleConfiguration; import org.eclipse.passage.lic.internal.api.Framework; -import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionTransport; -import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionTransportRegistry; -import org.eclipse.passage.lic.internal.api.conditions.mining.ContentType; -import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditions; -import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditionsRegistry; -import org.eclipse.passage.lic.internal.api.registry.Registry; -import org.eclipse.passage.lic.internal.api.registry.StringServiceId; -import org.eclipse.passage.lic.internal.api.requirements.ResolvedRequirements; -import org.eclipse.passage.lic.internal.api.requirements.ResolvedRequirementsRegistry; -import org.eclipse.passage.lic.internal.base.registry.ReadOnlyRegistry; -import org.eclipse.passage.lic.internal.equinox.requirements.BundleRequirements; -import org.eclipse.passage.lic.internal.equinox.requirements.ComponentRequirements; -import org.eclipse.passage.lic.internal.hc.remote.impl.RemoteConditions; -import org.eclipse.passage.lic.internal.json.tobemoved.JsonConditionTransport; +import org.eclipse.passage.lic.internal.api.LicensedProduct; +import org.eclipse.passage.lic.internal.api.LicensingException; +import org.eclipse.passage.lic.internal.base.InvalidLicensedProduct; +import org.eclipse.passage.lic.internal.equinox.LicensedApplication; @SuppressWarnings("restriction") final class DemoFramework implements Framework { - private final Registry requirements; - private final Registry conditions; - private final Registry transports; + private final AccessCycleConfiguration access; + private final LicensedProduct product; + static final Framework demo = new DemoFramework(); private DemoFramework() { - requirements = // - new ReadOnlyRegistry<>(Arrays.asList(// - new BundleRequirements(), // - new ComponentRequirements()) // - ); - conditions = // - new ReadOnlyRegistry<>(Arrays.asList(// - new RemoteConditions(transports())// - )// - ); - transports = new ReadOnlyRegistry<>(Arrays.asList(// - new JsonConditionTransport()// - )); + access = new SealedAccessCycleConfiguration(); + product = productRead(); } - @Override - public ResolvedRequirementsRegistry requirementsRegistry() { - return () -> requirements; + private LicensedProduct productRead() { + LicensedProduct prod; + try { + prod = new LicensedApplication().product(); + } catch (LicensingException e) { + prod = new InvalidLicensedProduct(); + } + return prod; } @Override - public MinedConditionsRegistry conditionsRegistry() { - return () -> conditions; + public LicensedProduct product() { + return product; } - private ConditionTransportRegistry transports() { - return () -> transports; + @Override + public AccessCycleConfiguration accessCycleConfiguration() { + return access; } } diff --git a/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/SealedAccessCycleConfiguration.java b/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/SealedAccessCycleConfiguration.java new file mode 100644 index 000000000..212f606f4 --- /dev/null +++ b/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/SealedAccessCycleConfiguration.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2020 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.seal.internal.demo; + +import java.util.Arrays; + +import org.eclipse.passage.lic.internal.api.AccessCycleConfiguration; +import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionTransport; +import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionTransportRegistry; +import org.eclipse.passage.lic.internal.api.conditions.mining.ContentType; +import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditions; +import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditionsRegistry; +import org.eclipse.passage.lic.internal.api.registry.Registry; +import org.eclipse.passage.lic.internal.api.registry.StringServiceId; +import org.eclipse.passage.lic.internal.api.requirements.ResolvedRequirements; +import org.eclipse.passage.lic.internal.api.requirements.ResolvedRequirementsRegistry; +import org.eclipse.passage.lic.internal.base.registry.ReadOnlyRegistry; +import org.eclipse.passage.lic.internal.equinox.requirements.BundleRequirements; +import org.eclipse.passage.lic.internal.equinox.requirements.ComponentRequirements; +import org.eclipse.passage.lic.internal.hc.remote.impl.RemoteConditions; +import org.eclipse.passage.lic.internal.json.tobemoved.JsonConditionTransport; + +@SuppressWarnings("restriction") +final class SealedAccessCycleConfiguration implements AccessCycleConfiguration { + + private final Registry requirements; + private final Registry conditions; + private final Registry transports; + + SealedAccessCycleConfiguration() { + requirements = // + new ReadOnlyRegistry<>(Arrays.asList(// + new BundleRequirements(), // + new ComponentRequirements()) // + ); + conditions = // + new ReadOnlyRegistry<>(Arrays.asList(// + new RemoteConditions(transports())// + )// + ); + transports = new ReadOnlyRegistry<>(Arrays.asList(// + new JsonConditionTransport()// + )); + } + + @Override + public ResolvedRequirementsRegistry requirementsRegistry() { + return () -> requirements; + } + + @Override + public MinedConditionsRegistry conditionsRegistry() { + return () -> conditions; + } + + private ConditionTransportRegistry transports() { + return () -> transports; + } + +} diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkContractTest.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkContractTest.java index c5bd2a13f..770528e04 100644 --- a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkContractTest.java +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkContractTest.java @@ -18,6 +18,7 @@ import java.util.Optional; import org.eclipse.passage.lic.api.tests.fakes.FakeResolvedRequirements; +import org.eclipse.passage.lic.internal.api.AccessCycleConfiguration; import org.eclipse.passage.lic.internal.api.Framework; import org.eclipse.passage.lic.internal.api.registry.Registry; import org.eclipse.passage.lic.internal.api.registry.StringServiceId; @@ -45,7 +46,7 @@ public final void exists() { @Test public final void canResolveRequirements() { - Registry registry = framework().get().requirementsRegistry().get(); + Registry registry = config().requirementsRegistry().get(); assertNotNull(registry); assertNotNull(registry.services()); assertTrue(registry.services().size() > 0); @@ -53,18 +54,27 @@ public final void canResolveRequirements() { @Test public final void prohibitsRequirementsResolutionExtension() { - assertTrue(readOnly(framework().get().requirementsRegistry().get())); + assertTrue(readOnly(config().requirementsRegistry().get())); } @Test public final void prohibitsInjectionIntoRequirementResolutionServices() { - Registry registry = framework().get().requirementsRegistry().get(); + Registry registry = config().requirementsRegistry().get(); int before = registry.services().size(); registry.services().add(new FakeResolvedRequirements()); assertTrue(before == registry.services().size()); } + @Test + public final void suppliesLicensedProductInformation() { + assertNotNull(framework().get().product()); + } + + private AccessCycleConfiguration config() { + return framework().get().accessCycleConfiguration(); + } + protected abstract Optional framework(); protected abstract boolean readOnly(Registry registry); diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkRequirementResolutionServiceTest.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkRequirementResolutionServiceTest.java index 21902aed5..32a620bee 100644 --- a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkRequirementResolutionServiceTest.java +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkRequirementResolutionServiceTest.java @@ -35,7 +35,7 @@ public abstract class FrameworkRequirementResolutionServiceTest extends ReadOnly @Override protected final Supplier> collection() { - return () -> framework().get().requirementsRegistry().get().services(); + return () -> framework().get().accessCycleConfiguration().requirementsRegistry().get().services(); } @Override diff --git a/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/RequirementsTest.java b/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/RequirementsTest.java index b65862f59..b11274bd4 100644 --- a/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/RequirementsTest.java +++ b/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/RequirementsTest.java @@ -27,7 +27,7 @@ public final class RequirementsTest { @Test public void noResolversMeansNoAccess() { Set requirements = new Requirements(// - new SabotagedFramework().requirementsRegistry().get(), // + new SabotagedFramework().accessCycleConfiguration().requirementsRegistry().get(), // "feature0" //$NON-NLS-1$ ).get(); assertEquals(1, requirements.size()); diff --git a/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/SabotagedFramework.java b/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/SabotagedFramework.java index 6a7ec2ed8..eabeb61b5 100644 --- a/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/SabotagedFramework.java +++ b/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/SabotagedFramework.java @@ -14,7 +14,9 @@ import java.util.ArrayList; +import org.eclipse.passage.lic.internal.api.AccessCycleConfiguration; import org.eclipse.passage.lic.internal.api.Framework; +import org.eclipse.passage.lic.internal.api.LicensedProduct; import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditions; import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditionsRegistry; import org.eclipse.passage.lic.internal.api.registry.Registry; @@ -26,14 +28,31 @@ @SuppressWarnings("restriction") final class SabotagedFramework implements Framework { + private final AccessCycleConfiguration config = new SabotagedAccessCycleConfiguration(); + private final LicensedProduct product = new BaseLicensedProduct("test-product", "1.0.0"); //$NON-NLS-1$//$NON-NLS-2$ + @Override - public ResolvedRequirementsRegistry requirementsRegistry() { - return new NoRequirementResolvers(); + public LicensedProduct product() { + return product; } @Override - public MinedConditionsRegistry conditionsRegistry() { - return new NoConditionMiners(); + public AccessCycleConfiguration accessCycleConfiguration() { + return config; + } + + private static class SabotagedAccessCycleConfiguration implements AccessCycleConfiguration { + + @Override + public ResolvedRequirementsRegistry requirementsRegistry() { + return new NoRequirementResolvers(); + } + + @Override + public MinedConditionsRegistry conditionsRegistry() { + return new NoConditionMiners(); + } + } private static class NoRequirementResolvers implements ResolvedRequirementsRegistry { diff --git a/tests/org.eclipse.passage.seal.demo.tests/src/org/eclipse/passage/seal/demo/tests/DemoFrameworkContentTest.java b/tests/org.eclipse.passage.seal.demo.tests/src/org/eclipse/passage/seal/demo/tests/DemoFrameworkContentTest.java index dcc480a76..62db58566 100644 --- a/tests/org.eclipse.passage.seal.demo.tests/src/org/eclipse/passage/seal/demo/tests/DemoFrameworkContentTest.java +++ b/tests/org.eclipse.passage.seal.demo.tests/src/org/eclipse/passage/seal/demo/tests/DemoFrameworkContentTest.java @@ -33,18 +33,12 @@ @SuppressWarnings("restriction") public final class DemoFrameworkContentTest { + @Test - public void accessible() { + public void supplied() { assertTrue(new DemoFrameworkSupplier().get().isPresent()); } - @Test - public void providesRequrementsRegistry() { - Optional registry = // - Optional.ofNullable(framework().requirementsRegistry()); - assertTrue(registry.isPresent()); - } - @Test public void providesBothEquinoxRequirementServices() { Registry registry = registry(); @@ -59,16 +53,18 @@ private > void assertHasService(// assertEquals(template.getClass(), registry.service(template.id()).getClass()); } + private Registry registry() { + Optional registry = // + Optional.ofNullable(framework().accessCycleConfiguration().requirementsRegistry()); + assumeTrue(registry.isPresent()); + return registry.get().get(); + } + private Framework framework() { Optional framework = new DemoFrameworkSupplier().get(); assumeTrue(framework.isPresent()); return framework.get(); } - private Registry registry() { - Optional registry = // - Optional.ofNullable(framework().requirementsRegistry()); - assumeTrue(registry.isPresent()); - return registry.get().get(); - } + } diff --git a/tests/org.eclipse.passage.seal.demo.tests/src/org/eclipse/passage/seal/demo/tests/DemoFrameworkContractTest.java b/tests/org.eclipse.passage.seal.demo.tests/src/org/eclipse/passage/seal/demo/tests/DemoFrameworkContractTest.java index 5b819878d..a540049d2 100644 --- a/tests/org.eclipse.passage.seal.demo.tests/src/org/eclipse/passage/seal/demo/tests/DemoFrameworkContractTest.java +++ b/tests/org.eclipse.passage.seal.demo.tests/src/org/eclipse/passage/seal/demo/tests/DemoFrameworkContractTest.java @@ -18,6 +18,7 @@ import org.eclipse.passage.lic.api.tests.FrameworkContractTest; import org.eclipse.passage.lic.internal.api.registry.Registry; +import org.eclipse.passage.lic.internal.base.registry.ReadOnlyRegistry; import org.eclipse.passage.seal.internal.demo.DemoFrameworkSupplier; @SuppressWarnings("restriction") @@ -30,7 +31,7 @@ protected Optional framework() { @Override protected boolean readOnly(Registry registry) { - return false; + return ReadOnlyRegistry.class.isInstance(registry); } }