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,29 @@
/*******************************************************************************
* 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}
*/
public interface Registry<I extends ServiceId, S extends Service<I>> {

boolean hasService(I id);

S service(I 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<I extends ServiceId, S extends Service<I>> extends Registry<I, S> {

void register(S service);

void unregister(S service);

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

/**
* <p>
* General notion of a {@code service} interface which can potentially have
* multiple implementations that need to be somehow <i>collected and managed
* together</i>.
* </p>
*
* @param <I> sub type of {@linkplain ServiceId}
*/
public interface Service<I extends ServiceId> {

I id();

}
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;

/**
* Implementation is expected to represent <i>data class</i>: with
* {@code hashCode} and {@code equals} overloaded basing on enclosed data.
*/
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,15 @@
/** ****************************************************************************
* 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;
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,136 @@
/*******************************************************************************
* 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<I extends ServiceId, S extends Service<I>> 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;
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(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(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("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<I extends ServiceId, S extends Service<I>> implements Registry<I, S> {
private final List<Registry<I, S>> delegates;

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

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

@Override
public S service(I 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<I, 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,16 @@
/** ****************************************************************************
* 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;
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,14 @@ ConditionMiners_collect_packs_error=Failed to collect packs at %s
ConditionMiners_mine_error_extracting_conditions=Invalid data %s for configuration %s (%s)
ConditionMiners_mine_task_name=Found licensing conditions for configuration: %s (%s)
ConditionMiners.e_mining_failed=Error for configuration: %s (%s)
JointRegistry.retrieve_absent=No service for id %s can be found amoung %d following registries: \n\t%s
LicensingConditions_validation_invalid_from=Valid from starts in the future for condition %s
LicensingConditions_validation_invalid_until=Valid until ends in the past for condition %s
LicensingConditions_validation_no_from=Valid from not specified for condition %s
LicensingConditions_validation_no_until=Valid until not specified for condition %s
PathConditionMiner.e_no_key_keeper_registry=KeyKeeperRegistry is not available
PathConditionMiner.e_no_stream_codec_registry=StreamCodecRegistry is not available
PathConditionMiner.e_not_a_directory=%s is not a directory
RuntimeRegistry.register_override=Service with id %s is going to be overridden: \n\t from %s \n\t to %s
RuntimeRegistry.retrieve_absent_exception=Service required for id %s is absent in the registry.
RuntimeRegistry.unregister_absent=Service to be unregistered (%s) is not yet contained in the registry
2 changes: 1 addition & 1 deletion releng/org.eclipse.passage.parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<eclipse-repo.url>https://repo.eclipse.org/content/repositories/cbi/</eclipse-repo.url>
<cbi-snapshots-repo.url>https://repo.eclipse.org/content/repositories/cbi-snapshots/</cbi-snapshots-repo.url>

<eclipserun-repo>https://download.eclipse.org/eclipse/updates/4.15-I-builds/</eclipserun-repo>
<eclipserun-repo>https://download.eclipse.org/eclipse/updates/4.16-I-builds/</eclipserun-repo>
<released.baseline>https://download.eclipse.org/passage/updates/release/0.7.0/ldc/</released.baseline>
<staging.baseline>https://download.eclipse.org/passage/updates/release/0.7.0/ldc/</staging.baseline>

Expand Down