Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

564282 API revision: question extensibility #243

Merged
merged 10 commits into from
Jun 16, 2020
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.eclipse.passage.lic.internal.api;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

header


import java.util.Optional;
import java.util.function.Supplier;

public interface FrameworkSupplier extends Supplier<Optional<Framework>> {

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

import java.util.Collection;
import java.util.Map;
import java.util.function.Supplier;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.eclipse.passage.lic.internal.api.registry.Registry;
import org.eclipse.passage.lic.internal.api.registry.Service;
Expand All @@ -23,31 +24,37 @@

/**
* <p>
* {@linkplain Registry} implementation that delegates actual service owning to
* the incoming {@linkplain Supplier}
* {@linkplain Registry} implementation that is filled and managed at runtime
* programmatically.
* </p>
*
* @param <S> type of {@linkplain Service} to spread
* <p>
* Not thread safe (yet)
* </p>
* <p>
* Null free zone.
* </p>
*
* @param <S> type of {@linkplain Service} to keep
*/
@SuppressWarnings("restriction")
public final class BaseRegistry<I extends ServiceId, S extends Service<I>> implements Registry<I, S> {
public abstract class BaseRegistry<I extends ServiceId, S extends Service<I>> implements Registry<I, S> {

private final Supplier<Collection<S>> services;
protected final Map<I, S> services;
eparovyshnaya marked this conversation as resolved.
Show resolved Hide resolved

/**
* Primary constructor
* Convenience constructor
*
* @param init {@linkplain Map} implementation to be used as service storing
* facility
* @param handler error handler
* @param service {@linkplain Collection} list of actual services to be owned by
* the registry
*/
public BaseRegistry(Supplier<Collection<S>> services) {
this.services = services;
public BaseRegistry(Collection<S> service) {
this.services = service.stream().collect(Collectors.toMap(Service::id, Function.identity()));
}

@Override
public boolean hasService(I id) {
return services.get().stream().anyMatch(s -> id.equals(s.id()));
public final boolean hasService(I id) {
return services.containsKey(id);
}

/**
Expand All @@ -60,17 +67,18 @@ public boolean hasService(I id) {
* @throws IllegalStateException if not yet registered service is requested
*/
@Override
public S service(I id) {
return services.get().stream()//
.filter(s -> id.equals(s.id()))//
.findFirst().orElseThrow(() -> new IllegalStateException(String.format(//
BaseMessages.getString("Registry.retrieve_absent_exception"), //$NON-NLS-1$
id)));
public final S service(I id) {
if (!hasService(id)) {
throw new IllegalStateException(String.format(//
BaseMessages.getString("Registry.retrieve_absent_exception"), //$NON-NLS-1$
id));
}
return services.get(id);
}

@Override
public Collection<S> services() {
return services.get();
public final Collection<S> services() {
return services.values();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
package org.eclipse.passage.lic.internal.base.registry;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Collections;
import java.util.Objects;
import java.util.function.Consumer;

Expand All @@ -40,37 +39,23 @@
* @param <S> type of {@linkplain Service} to keep
*/
@SuppressWarnings("restriction")
public final class BaseRuntimeRegistry<I extends ServiceId, S extends Service<I>> implements RuntimeRegistry<I, S> {
public final class BaseRuntimeRegistry<I extends ServiceId, S extends Service<I>> //
extends BaseRegistry<I, S> //
implements RuntimeRegistry<I, S> {

private final Map<I, S> services;
private final Consumer<String> handler;

/**
* Primary constructor
*
* @param init {@linkplain Map} implementation to be used as service storing
* facility
* @param handler error handler
*/
public BaseRuntimeRegistry(Map<I, S> init, Consumer<String> handler) {
this.services = init;
public BaseRuntimeRegistry(Collection<S> services, Consumer<String> handler) {
super(services);
this.handler = handler;
}

/**
* Convenience constructor, uses {@linkplain HashMap} as a storage and prints
* errors into {@linkplain Stsrem.err} stream
*/
public BaseRuntimeRegistry() {
this(new HashMap<>(), System.err::println);
}

public BaseRuntimeRegistry(Map<I, S> init) {
this(init, System.err::println);
public BaseRuntimeRegistry(Consumer<String> handler) {
this(Collections.emptyList(), handler);
}

public BaseRuntimeRegistry(Consumer<String> handler) {
this(new HashMap<>(), handler);
public BaseRuntimeRegistry() {
this(System.err::println);
}

@Override
Expand All @@ -86,35 +71,6 @@ public void unregister(S service) {
services.remove(service.id());
}

@Override
public boolean hasService(I id) {
return services.containsKey(id);
}

/**
* <p>
* Get the previously registered service by it's {@code id}. It's mandatory to
* either be sure the service has been registered or to check
* {@linkplain #hasService(ServiceId)} first.
* </p>
*
* @throws IllegalStateException if not yet registered service is requested
*/
@Override
public S service(I id) {
if (!hasService(id)) {
throw new IllegalStateException(String.format(//
BaseMessages.getString("Registry.retrieve_absent_exception"), //$NON-NLS-1$
id));
}
return services.get(id);
}

@Override
public Collection<S> services() {
return services.values();
}

private void checkOverride(S service) {
if (!hasService(service.id())) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -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.base.registry;
eparovyshnaya marked this conversation as resolved.
Show resolved Hide resolved

import java.util.Collection;

import org.eclipse.passage.lic.internal.api.registry.Service;
import org.eclipse.passage.lic.internal.api.registry.ServiceId;

@SuppressWarnings("restriction")
public final class ReadOnlyRegistry<I extends ServiceId, S extends Service<I>> extends BaseRegistry<I, S> {

public ReadOnlyRegistry(Collection<S> service) {
super(service);
}

}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,28 @@
import java.util.Optional;

import org.eclipse.passage.lic.internal.api.Framework;
import org.eclipse.passage.lic.internal.api.FrameworkSupplier;
import org.eclipse.passage.lic.internal.api.Passage;
import org.eclipse.passage.lic.internal.base.Access;
import org.eclipse.passage.lic.internal.equinox.i18n.EquinoxMessages;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings("restriction")
public final class EquinoxPassage implements Passage {

private final Logger log = LoggerFactory.getLogger(EquinoxPassage.class);

@Override
public boolean canUse(String feature) {
Optional<Framework> framework = new FrameworkSupplier().get();
Optional<FrameworkSupplier> supplier = frameworkSupplier();
if (!supplier.isPresent()) {
return false;
}
Optional<Framework> framework = supplier.get().get();
if (!framework.isPresent()) {
return false;
}
Expand All @@ -36,4 +49,19 @@ public void checkLicense(String feature) {
throw new UnsupportedOperationException();
}

Optional<FrameworkSupplier> frameworkSupplier() {
BundleContext context = FrameworkUtil.getBundle(getClass()).getBundleContext();
try {
return context.getServiceReferences(FrameworkSupplier.class, null).stream() //
.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
.findAny();
} catch (InvalidSyntaxException e) {
log.error(EquinoxMessages.EquinoxPassage_no_framework, e);
return Optional.empty();
}
}

}

This file was deleted.

Loading