Skip to content

Commit

Permalink
Merge pull request #170 from eclipse-passage/559091
Browse files Browse the repository at this point in the history
559091 -  generic API for service registry
  • Loading branch information
eparovyshnaya authored Mar 19, 2020
2 parents a73912b + 0239915 commit 971965a
Show file tree
Hide file tree
Showing 12 changed files with 337 additions and 2 deletions.
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();

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

}
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

0 comments on commit 971965a

Please sign in to comment.