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

559091 - generic API for service registry #170

Merged
merged 8 commits into from
Mar 19, 2020
1 change: 1 addition & 0 deletions bundles/org.eclipse.passage.lic.api/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Export-Package: org.eclipse.passage.lic.api,
org.eclipse.passage.lic.api.access,
org.eclipse.passage.lic.api.conditions,
org.eclipse.passage.lic.api.inspector,
org.eclipse.passage.lic.api.internal.registry;x-internal:=true,
org.eclipse.passage.lic.api.io,
org.eclipse.passage.lic.api.requirements,
org.eclipse.passage.lic.api.restrictions
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*******************************************************************************
* 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.api.internal.registry;

/**
*
* @since 0.7
*/
public interface Configuration {
eparovyshnaya marked this conversation as resolved.
Show resolved Hide resolved

public static final class Empty implements Configuration {
ruspl-afed marked this conversation as resolved.
Show resolved Hide resolved

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*******************************************************************************
* 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.api.internal.registry;

import java.util.Collection;

/**
*
* @param <S> sub type of {@linkplain Service}
* @since 0.7
*/
public interface Registry<S extends Service<?>> {

boolean hasService(ServiceId id);

S service(ServiceId id);

Collection<S> services();
ruspl-afed marked this conversation as resolved.
Show resolved Hide resolved

}
Original file line number Diff line number Diff line change
@@ -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.api.internal.registry;

public interface RuntimeRegistry<S extends Service<?>> extends Registry<S> {

void register(S service);

void unregister(S service);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*******************************************************************************
* 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.api.internal.registry;

/**
*
* @param <C> sub type of {@linkplain Configuration}
* @since 0.7
*/
public interface Service<C extends Configuration> {
eparovyshnaya marked this conversation as resolved.
Show resolved Hide resolved

ServiceId id();

C configuration();
eparovyshnaya marked this conversation as resolved.
Show resolved Hide resolved

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*******************************************************************************
* 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.api.internal.registry;

/**
* Implementation is expected to represent <i>data class</i>: with
* {@code hashCode} and {@code equals} overloaded basing on enclosed data.
*
* @since 0.7
*/
public interface ServiceId {
eparovyshnaya marked this conversation as resolved.
Show resolved Hide resolved

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/** ****************************************************************************
* 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
*******************************************************************************/
/**
*
* @since 0.7
*/
package org.eclipse.passage.lic.api.internal.registry;
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public interface KeyKeeper {
*
* @param configuration general licensing configuration of a running product
* @return the stream to read the key
* @throws IOException in case of any file system operation misbehaviour
* @throws IOException in case of any file system operation misbehavior
* @since 0.4.0
*/
InputStream openKeyStream(LicensingConfiguration configuration) throws IOException;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*******************************************************************************
* 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.base.internal.registry;

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

import org.eclipse.passage.lic.api.internal.registry.Registry;
import org.eclipse.passage.lic.api.internal.registry.RuntimeRegistry;
import org.eclipse.passage.lic.api.internal.registry.Service;
import org.eclipse.passage.lic.api.internal.registry.ServiceId;
import org.eclipse.passage.lic.internal.base.i18n.BaseMessages;

/**
*
* <p>
* {@linkplain Registry} implementation that is filled and managed at runtime
* programmatically.
* </p>
*
* <p>
* Not thread safe (yet)
* </p>
* <p>
* Null free zone.
* </p>
*
* @param <S> type of {@linkplain Service} to keep
*/
@SuppressWarnings("restriction")
public final class BaseRuntimeRegistry<S extends Service<?>> implements RuntimeRegistry<S> {

private final Map<ServiceId, 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
* @since 0.6
*/
public BaseRuntimeRegistry(Map<ServiceId, S> init, Consumer<String> handler) {
this.services = init;
this.handler = handler;
}

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

public BaseRuntimeRegistry(Map<ServiceId, S> init) {
this(init, System.err::println);
}

public BaseRuntimeRegistry(Consumer<String> handler) {
this(new HashMap<>(), handler);
}

@Override
public void register(S service) {
Objects.requireNonNull(service);
checkOverride(service);
services.put(service.id(), service);
}

@Override
public void unregister(S service) {
checkAbsent(service);
services.remove(service.id());
}

@Override
public boolean hasService(ServiceId 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
* @since 0.6
*/
@Override
public S service(ServiceId id) {
if (!hasService(id)) {
throw new IllegalStateException(String.format(//
BaseMessages.getString("RuntimeRegistry.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;
}
handler.accept(String.format(//
BaseMessages.getString("RuntimeRegistry.register_override"), //$NON-NLS-1$
service.id(), service(service.id()), service));
}

private void checkAbsent(S service) {
if (hasService(service.id())) {
return;
}
handler.accept(String.format(//
BaseMessages.getString("RuntimeRegistry.unregister_absent"), //$NON-NLS-1$
service));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*******************************************************************************
* 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.base.internal.registry;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import org.eclipse.passage.lic.api.internal.registry.Registry;
import org.eclipse.passage.lic.api.internal.registry.Service;
import org.eclipse.passage.lic.api.internal.registry.ServiceId;
import org.eclipse.passage.lic.internal.base.i18n.BaseMessages;

@SuppressWarnings("restriction")
public final class JointRegistry<S extends Service<?>> implements Registry<S> {
private final List<Registry<S>> delegates;

public JointRegistry(List<Registry<S>> delegates) {
this.delegates = delegates;
}

@Override
public boolean hasService(ServiceId id) {
return delegates.stream().anyMatch(delegate -> delegate.hasService(id));
}

@Override
public S service(ServiceId id) {
return delegates.stream()//
.filter(delgate -> delgate.hasService(id))//
.map(delgate -> delgate.service(id)) //
.findAny() //
.orElseThrow(() -> new IllegalStateException(notFoundMessage(id)));
}

@Override
public Collection<S> services() {
return delegates.stream()//
.map(Registry<S>::services) //
.flatMap(Collection<S>::stream) //
.collect(Collectors.toList());
}

private String notFoundMessage(ServiceId id) {
return String.format(//
BaseMessages.getString("JointRegistry.retrieve_absent"), //$NON-NLS-1$
id, //
delegates.size(), //
delegates.stream()//
.map(Object::toString)//
.collect(Collectors.joining("\n\t"))); //$NON-NLS-1$
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/** ****************************************************************************
* 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
*******************************************************************************/

/**
* @since 0.6
*/
package org.eclipse.passage.lic.base.internal.registry;
Loading