Commit 8452bc02 authored by Björn Richerzhagen's avatar Björn Richerzhagen
Browse files

SiS: Refactored some package names

SiS: Refactored typing in the SiS (added static "SiSTypes"-class)
SiS: Continued the InformationProvider-Interface
SiS: Fixed some generics-related issues
parent d5083ae2
......@@ -61,16 +61,4 @@ public interface SiSComponent extends HostComponent {
*/
public SiSInformationConsumer get();
/**
* When interacting with the {@link SiSInformationConsumer} or the
* {@link SiSInformationProvider}, you need a {@link SiSRequest} object
* specifying your actual desire. Use this {@link SiSRequestCreator} to
* create such a request object. These objects can be re-used (if you, for
* example, create a request object to retrieve the current value once, you
* can just use the same request later on again).
*
* @return
*/
public SiSRequestCreator createRequestFor();
}
......@@ -20,7 +20,8 @@
package de.tudarmstadt.maki.simonstrator.api.component.sis;
import de.tudarmstadt.maki.simonstrator.api.component.sis.types.SiSType;
import de.tudarmstadt.maki.simonstrator.api.component.sis.exception.InformationNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sis.type.SiSType;
/**
* Consumer interface, i.e., interface used to access information from the SiS.
......@@ -50,6 +51,16 @@ public interface SiSInformationConsumer {
public <T> void valueOf(SiSType<T> type, SiSRequest request,
SiSResultCallback<T> callback);
/**
* Create a plain request object
*
* TODO as soon as we (usually, the C-projects) stumble across commonly used
* request configurations, we should add convenience methods here.
*
* @return modifiable request object
*/
public SiSRequest request();
/**
* A result-callback (as method calls are non-blocking!) that is to be
* provided by the requesting component.
......@@ -92,16 +103,4 @@ public interface SiSInformationConsumer {
}
/**
* Thrown, if the information is not available
*
* @author Bjoern Richerzhagen
*
*/
public static class InformationNotAvailableException extends Exception {
private static final long serialVersionUID = 1L;
}
}
......@@ -20,7 +20,8 @@
package de.tudarmstadt.maki.simonstrator.api.component.sis;
import de.tudarmstadt.maki.simonstrator.api.component.sis.types.SiSType;
import de.tudarmstadt.maki.simonstrator.api.component.sis.exception.InformationNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sis.type.SiSType;
/**
* Interface used by the SiS to enable components to provide additional
......@@ -37,18 +38,38 @@ import de.tudarmstadt.maki.simonstrator.api.component.sis.types.SiSType;
public interface SiSInformationProvider {
/**
* Provide local access to a single value (the value is retrieved via the
* callback)
* Provide local access to a value (the value is retrieved via the callback)
* and additional information about the quality of the value.
*
* @param type
* @param dataCallback
* @param informationProperties
* description of the quality of data
* description of the quality of data, can be null
*/
public <T> void localAccessTo(SiSType<T> type,
SiSDataCallback<T> dataCallback,
SiSInformationProperties informationProperties);
/**
* Provide local access to a value (the value is retrieved via the callback)
* without defining the quality of the value.
*
* @param type
* @param dataCallback
*/
public <T> void localAccessTo(SiSType<T> type,
SiSDataCallback<T> dataCallback);
/**
* Creates a new {@link SiSInformationProperties} object allowing the
* provider to specify some QoS properties of the given data source by
* modifying the returned object and passing it to calls on the
* {@link SiSInformationProvider}.
*
* @return
*/
public SiSInformationProperties informationProperties();
/**
* Callback provided by the DataProvider that is then queried for the actual
* data if the SiS needs it. If the source is no longer available, the
......@@ -66,20 +87,7 @@ public interface SiSInformationProvider {
*
* @return
*/
public T getValue() throws InformationSourceUnavailableException;
}
/**
* Stating that the current information source is no longer available to
* provide data.
*
* @author Bjoern Richerzhagen
*
*/
public static class InformationSourceUnavailableException extends Exception {
private static final long serialVersionUID = 1L;
public T getValue() throws InformationNotAvailableException;
}
......
......@@ -20,7 +20,8 @@
package de.tudarmstadt.maki.simonstrator.api.component.sis;
import de.tudarmstadt.maki.simonstrator.api.component.sis.types.SiSType;
import de.tudarmstadt.maki.simonstrator.api.component.sis.exception.InformationNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sis.type.SiSType;
/**
* Logic that is to be implemented as part of the SiS to resolve information.
......@@ -31,15 +32,16 @@ import de.tudarmstadt.maki.simonstrator.api.component.sis.types.SiSType;
public interface SiSInformationResolver {
/**
* Has to return true, if the given request can be resolved locally (either
* by accessing the local storage for past values, or by querying one of the
* registered information providers).
* Returns the local state, if the given request can be resolved locally
* (either by accessing the local storage for past values, or by querying
* one of the registered information providers).
*
* @param request
* the requests object contains QoS parameters related to the
* request (e.g., desired granularity, max timeout)
* @return true, if we can resolve the request locally
* @return local data
*/
public <T> boolean canResolveLocally(SiSType<T> type, SiSRequest request);
public <T> T resolveLocally(SiSType<T> type, SiSRequest request)
throws InformationNotAvailableException;
}
......@@ -20,8 +20,9 @@
package de.tudarmstadt.maki.simonstrator.api.component.sis;
import de.tudarmstadt.maki.simonstrator.api.component.sis.types.SiSType;
import de.tudarmstadt.maki.simonstrator.api.component.sis.types.SiSTypeDerivation;
import de.tudarmstadt.maki.simonstrator.api.component.sis.exception.InformationNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sis.type.SiSType;
import de.tudarmstadt.maki.simonstrator.api.component.sis.type.SiSTypeDerivation;
/**
* Access current data hidden behind a Type. This is currently used for the
......@@ -39,8 +40,11 @@ public interface SiSLocalData {
* Returns the current value of the specified type
*
* @param type
* @param request
* (optional)
* @return
*/
public <T extends Object> T getValue(SiSType<T> type);
public <T extends Object> T getValue(SiSType<T> type, SiSRequest request)
throws InformationNotAvailableException;
}
......@@ -18,7 +18,7 @@
*
*/
package de.tudarmstadt.maki.simonstrator.api.component.sis.types.derivations;
package de.tudarmstadt.maki.simonstrator.api.component.sis.exception;
/**
* A Derivation is not possible
......
......@@ -18,35 +18,16 @@
*
*/
package de.tudarmstadt.maki.simonstrator.api.component.sis;
package de.tudarmstadt.maki.simonstrator.api.component.sis.exception;
/**
* Interface hiding the creation of request-objects in the SiS. Most methods are
* just convenience methods - you can just create the basic request object and
* then use its setters to configure everything accordingly. However, accessing
* only one method to get a fully configured request object sounds good, doesn't
* it?
*
* Using this interface, components retrieve a {@link SiSRequest}-object, that
* they have to use when interacting with the SiS.
* Thrown, if the requested information is not available
*
* @author Bjoern Richerzhagen
*
*/
public interface SiSRequestCreator {
/**
* Create a plain request object
*
* @param type
* @return
*/
public SiSRequest create();
public class InformationNotAvailableException extends Exception {
/*
* TODO as soon as we (usually, the C-projects) stumble accross commonly
* used request configurations, we should add convenience methods here.
*/
private static final long serialVersionUID = 1L;
}
......@@ -18,11 +18,10 @@
*
*/
package de.tudarmstadt.maki.simonstrator.api.component.sis.types;
package de.tudarmstadt.maki.simonstrator.api.component.sis.type;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSLocalData;
import de.tudarmstadt.maki.simonstrator.api.component.sis.types.derivations.DerivationNotPossibleException;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Taxonomy definition for the SiS. Right now, we use a flat identifier space
......@@ -34,24 +33,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.sis.types.derivations.Deri
*/
public final class SiSType<T extends Object> {
/*
* Definition of the global Taxonomy and the supported derivations. New
* types and derivations have to be added here.
*
* TODO: move overlay contact to the API to include derivations as well.
*/
public static final SiSType<NetID[]> NET_CONTACT = new SiSType<>(
"Net/Contact", NetID[].class, null);
public static final SiSType<Integer> OVERLAY_NUMBER_OF_CONTACTS = new SiSType<>(
"Overlay/NumberOfContacts", Integer.class, null);
/*
* Per-Type State
*/
private final SiSTypeDerivation<T> derivation;
private final Set<SiSTypeDerivation<T>> derivations;
private final Class<T> dataType;
......@@ -63,55 +45,51 @@ public final class SiSType<T extends Object> {
* @param dataType
* @param derivation
*/
private SiSType(String name, Class<T> dataType,
SiSTypeDerivation<T> derivation) {
protected SiSType(String name, Class<T> dataType) {
this.name = name;
this.dataType = dataType;
this.derivation = derivation;
this.derivations = new LinkedHashSet<>();
}
/**
* Data type. If this is a collection, this method returns the inner type of
* the collection.
* Enables non-API projects to add their own derivation functions for the
* given SiSType programmatically. Long-term, those Derivations should make
* it into the API package.
*
* @return
* @param derivation
*/
public Class<T> getType() {
return dataType;
public void addDerivation(SiSTypeDerivation<T> derivation) {
derivations.add(derivation);
}
/**
* True, if we can derive the target value from any of the available types
* Data type. If this is a collection, this method returns the inner type of
* the collection.
*
* @param availableTypes
* @return
*/
public boolean canDerive(SiSType<?>... availableTypes) {
return (derivation == null ? false : derivation
.canDerive(availableTypes));
public Class<T> getType() {
return dataType;
}
/**
* "Magic" method deriving the target value <T> from a number of the input
* types (availableTypes). The actual value of the types has to be retrieved
* via the {@link SiSLocalData} interface provided upon method invocation.
* Ideally, this method implements a number of ways to derive the target
* value - sorted by complexity and expected cost for the host. If the
* locally available types are not sufficient to derive a value, an
* exception is to be thrown.
* Determines the "best" derivation for the given available types and
* returns it (or null, if no matching derivation is found...)
*
* FIXME Please note: "best" is currently not defined, we just try one after
* the other in the order they were added until we find a matching one.
* Maybe, one wants to add a weight or utility later-on?
*
* @param data
* access to the actual data values
* @param availableTypes
* try to derive the target value using only these types.
* @return derived value
* @return matching derivation or null
*/
public T deriveValueFrom(SiSLocalData data, SiSType<?>... types)
throws DerivationNotPossibleException {
if (derivation == null) {
throw new DerivationNotPossibleException();
public SiSTypeDerivation<T> canDerive(Set<SiSType<?>> availableTypes) {
for (SiSTypeDerivation<T> derivation : derivations) {
if (derivation.canDerive(availableTypes)) {
return derivation;
}
}
return derivation.derive(data, types);
return null;
}
@Override
......@@ -139,4 +117,9 @@ public final class SiSType<T extends Object> {
return true;
}
@Override
public String toString() {
return "SiSType [name=" + name + "]";
}
}
......@@ -18,10 +18,12 @@
*
*/
package de.tudarmstadt.maki.simonstrator.api.component.sis.types;
package de.tudarmstadt.maki.simonstrator.api.component.sis.type;
import java.util.Set;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSLocalData;
import de.tudarmstadt.maki.simonstrator.api.component.sis.types.derivations.DerivationNotPossibleException;
import de.tudarmstadt.maki.simonstrator.api.component.sis.exception.DerivationNotPossibleException;
/**
......@@ -40,7 +42,7 @@ public interface SiSTypeDerivation<T extends Object> {
* @param availableTypes
* @return
*/
public boolean canDerive(SiSType<?>... availableTypes);
public boolean canDerive(Set<SiSType<?>> availableTypes);
/**
* "Magic" method deriving the target value <T> from a number of the input
......@@ -57,7 +59,7 @@ public interface SiSTypeDerivation<T extends Object> {
* try to derive the target value using only these types.
* @return derived value
*/
public T derive(SiSLocalData data, SiSType<?>... availableTypes)
public T derive(SiSLocalData data, Set<SiSType<?>> availableTypes)
throws DerivationNotPossibleException;
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of Simonstrator.KOM.
*
* Simonstrator.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tudarmstadt.maki.simonstrator.api.component.sis.type;
import java.util.LinkedHashMap;
import java.util.Map;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
/**
* Type registry (e.g., our taxonomy). Dependencies between the flat types are
* defined via {@link SiSTypeDerivation}s that can be added to the individual
* types programmatically. Derivations should become a part of the api
* <strong>iff</strong> their types are also part of the API (e.g.,
* TransitOverlayContact is to specific, but OverlayConteact might at some time
* be added).
*
* @author Bjoern Richerzhagen
*
*/
public final class SiSTypes {
private static final Map<String, SiSType<?>> allTypes = new LinkedHashMap<>();
/*
* Type definitions below.
*/
public static final SiSType<NetID[]> NET_CONTACTS = create(
"NET_CONTACTS", NetID[].class);
public static final SiSType<Integer> OVERLAY_NUMBER_OF_CONTACTS = create(
"OVERLAY_NUMBER_OF_CONTACTS", Integer.class);
/**
*
* @param name
* @param type
* @deprecated Not actually deprecated, just not encouraged. Use this for
* testing new types, but add them to the API once they are
* stable.
*/
@Deprecated
public static <T> void registerType(String name, Class<T> type) {
Monitor.log(
SiSType.class,
Level.WARN,
"Programmatically registered a type %s with name %s at the SiS. "
+ "\n\tThis functionality is for testing only. "
+ "\n\tPlease consider adding your types to the SiS-API later on.",
type, name);
create(name, type);
}
/*
* Static methods to add new types programmatically (for development, as you
* do not need to change the API every time). Long term goal is then to
* include the final versions into the static block above.
*/
/**
* UNSAFE method to retrieve a type that is <strong>not</strong> available
* via the API (e.g., static final members of this class).
*
* @param type
* @param name
* @return
*/
@Deprecated
@SuppressWarnings("unchecked")
public static <T> SiSType<T> getType(String name, Class<T> type) {
return (SiSType<T>) allTypes.get(name);
}
/**
* Internal instantiation of the SiSType
*
* @param name
* @param type
* @return
*/
private static <T> SiSType<T> create(String name, Class<T> type) {
SiSType<T> sisType = new SiSType<T>(name, type);
if (allTypes.containsKey(name)) {
throw new AssertionError("Duplicate type with name " + name + "!");
}
allTypes.put(name, sisType);
return sisType;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment