Class TypeRegistry
- java.lang.Object
-
- net.ssehub.easy.instantiation.core.model.vilTypes.TypeRegistry
-
public class TypeRegistry extends java.lang.ObjectUsed to register the actual types (also replacements by extensions). Optional type resolvers (ITypeResolver) allow deferred type resolution on other models, e.g., variability models. Type retrieval calls using a class are intended to be used by the implementation (and may prevent creating dynamic types) while the others based on string are intended for resolution of names used in the VIL/VTL.- Author:
- Holger Eichelberger
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private classTypeRegistry.DirectAccessImplements the direct access interface forITypeResolver.
-
Field Summary
Fields Modifier and Type Field Description static TypeRegistryDEFAULTprivate IDirectTypeRegistryAccessdirectAccessprivate java.util.Map<IDatatype,TypeDescriptor<?>>fallbacksprivate java.util.Map<java.lang.String,TypeDescriptor<? extends IVilType>>instantiatorsStores the registered instantiators.static java.lang.Class<?>[]INVISIBLE_BY_DEFAULTThose classes for which the methods shall be invisible by default, in particularjava.lang.Object.private static java.util.Map<java.lang.String,java.util.List<java.lang.reflect.Method>>INVISIBLE_INHERITEDCaches the operations vs.private static EASyLoggerFactory.EASyLoggerLOGGERstatic java.lang.ObjectNULLprivate TypeRegistryparentRegistryprivate java.util.List<ITypeResolver>resolverprivate java.util.Map<java.lang.String,TypeDescriptor<?>>typesStores the registered types.
-
Constructor Summary
Constructors Modifier Constructor Description privateTypeRegistry()Creates the default type registry.TypeRegistry(TypeRegistry parentRegistry)Creates a (local) type registry, which delegates unknown types to theparentRegistry.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private static booleanaddInvisibleInherited(java.lang.reflect.Method method)Adds the givenmethodto the cache of invisible inherited methods.<T> booleanaddTypeAlias(java.lang.String name, TypeDescriptor<T> type)Adds a type alias to this specific type registry.static voidaddTypeMapping(java.lang.String name, TypeDescriptor<? extends IVilType> type)Allows to register internal mapped types, e.g.,TypeDescriptor.voidaddTypeResolver(ITypeResolver resolver)Adds a type resolver as the current resolver of highest precedence.java.lang.Iterable<TypeDescriptor<? extends IVilType>>allInstantiators()Provides access to all instantiators.protected booleanallowFallbacks()Whether fallback datatypes are allowed to be stored on this registry.java.lang.Iterable<TypeDescriptor<?>>allTypes()Provides access to all type descriptors.static TypeDescriptor<?>anyType()Returns the type descriptor for the built-in type 'any'.static TypeDescriptor<?>booleanType()Returns the type descriptor for the built-in type 'Boolean'.private static voidcacheInheritedAnnotations(java.lang.Class<?> cls)Caches the inherited annotations and avoids repeated class analysis.TypeDescriptor<?>[]convert(java.lang.Class<?> param)Converts a class into a set of type descriptors.TypeDescriptor<?>[]convert(java.lang.Class<?>... params)Converts a set of classes into type descriptors.private static <T extends IVilType>
ReflectionTypeDescriptor<T>createTypeDescriptor(java.lang.Class<T> type)Creates a type descriptor consideringIActualValueProvider.static booleanequals(IMetaType t1, IMetaType t2)Returns whether two types are equal including base type considerations.TypeDescriptor<?>findType(java.lang.Class<?> cls)Finds the type descriptor for a given class.TypeDescriptor<?>findType(java.lang.Class<?> cls, boolean addIfMissing)Finds the type descriptor for a given class.private TypeDescriptor<?>findType(java.lang.String name)Searches for a type calledname, first in this registry, then in parent registries if given.booleanforRuntime()Returns whether this registry provides types for runtime variability instantiation.static TypeDescriptor<? extends Collection<?>>getCollectionType(TypeDescriptor<?>... parameter)Returns the VIL type for a collection with the given type parameters.TypeDescriptor<? extends IVilType>getInstantiator(java.lang.String name)Returns the registered instantiator type descriptor for the givennamealso inparentRegistry.static TypeDescriptor<? extends PseudoIterator<?>>getIteratorType(TypeDescriptor<?>... parameter)Returns the VIL type for a map with the given type parameters.protected TypeDescriptor<?>getMappedType(java.lang.Class<?> cls, java.lang.Class<?>[] generics, IntHolder pos)Returns mapped types provided by this registry and the descriptors created by this registry.static TypeDescriptor<? extends Map<?,?>>getMapType(TypeDescriptor<?>... parameter)Returns the VIL type for a map with the given type parameters.TypeRegistrygetParentRegistry()Returns the parent registry.static TypeDescriptor<? extends ResolvableOperationType>getRuleType(TypeDescriptor<?>... parameter)Returns the VIL type for a rule type with the given type parameters.static TypeDescriptor<? extends Sequence<?>>getSequenceType(TypeDescriptor<?>... parameter)Returns the VIL type for a sequence with the given type parameters.static TypeDescriptor<? extends Set<?>>getSetType(TypeDescriptor<?>... parameter)Returns the VIL type for a set with the given type parameters.TypeDescriptor<?>getType(java.lang.Class<?> cls)Converts a class into a type descriptor.TypeDescriptor<?>getType(java.lang.String name)Returns the registered type descriptor for the givennamealso inparentRegistry.TypeDescriptor<?>getType(java.lang.String name, boolean addIfMissing)Returns the registered type descriptor for the givennamealso inparentRegistry.TypeDescriptor<?>getType(IDatatype type)Returns the registered type descriptor for the giventype.TypeDescriptor<?>getTypeOrFallback(IDatatype type)Returns the registered type descriptor for the giventypeor tries an explicitly registered fallback, e.g., for unknown types in models without advices.(package private) static booleanhasInheritedInvisibleAnnotation(java.lang.String signature, java.lang.Class<?> cls)Returns whether a certain method given by its signature (seeOperationDescriptor.getSignature()has an inherited invisible annotation.booleanhasType(java.lang.String name)Returns whether this type registry knows a type of the given name.booleanhasTypeResolver(java.lang.Class<? extends ITypeResolver> cls)Returns whether this registry has a type resolver of the given type.static TypeDescriptor<?>integerType()Returns the type descriptor for the built-in type 'Integer'.static booleanisInternalType(java.lang.Class<?> cls)Returns whetherclsis considered as an internal type including implementation types such as the collections.TypeDescriptor<?>obtainTypeDescriptor(java.lang.Object obj)Obtains the type descriptor of an object.static TypeDescriptor<?>realType()Returns the type descriptor for the built-in type 'Real'.<T extends IVilType>
TypeDescriptor<T>register(java.lang.Class<T> type)Internal default registration function with error handling.protected voidregister(java.lang.String key, TypeDescriptor<?> desc)Registers an individual type and emits an information message on the logger.private <T extends IVilType>
voidregister(TypeDescriptor<T> desc, java.lang.Class<T> metaProvider)Registers an individual type via its name and emits an information message on the logger.booleanregisterCompoundType(CompoundTypeDescriptor type)Registers a compound type, but only if a type of this name has not been registered so far.private <T extends IVilType>
voidregisterEquivalentClasses(java.lang.Class<T> type, TypeDescriptor<T> desc)Registers equivalent classes fromClassMeta.equiv().voidregisterFallbackType(IDatatype type, TypeDescriptor<?> descriptor)Registers a fallback type.<T extends IVilType>
TypeDescriptor<T>registerType(java.lang.Class<T> type)Registers a type.voidremoveTypeResolver(ITypeResolver resolver)Renoves a type resolver.static TypeDescriptor<?>resolvableOperationType()Returns the type descriptor for the built-in operation references (a kind of function pointer to evaluate functions generically).private TypeDescriptor<?>resolve(java.lang.String name, boolean addIfMissing)Resolves the given typenamevia the resolvers.TypeDescriptor<?>[]resolveGenerics(IDatatype type)Resolves IVML type generics.static TypeDescriptor<?>stringType()Returns the type descriptor for the built-in type String.private static voidtestInstantiatorType(TypeDescriptor<? extends IVilType> type, Instantiator inst)Some basic semantic tests for instantiators.static java.lang.StringtoName(IMetaType type)Returns the VIL name oftype.java.lang.Iterable<TypeDescriptor<?>>typesByNamePrefix(java.lang.String prefix)Provides access to all type descriptors with names starting with the givenprefix.static TypeDescriptor<?>typeType()Returns the type descriptor for the built-in type 'Type'.static TypeDescriptor<?>versionType()Returns the type descriptor for the built-in type 'Version'.static TypeDescriptor<?>voidType()Returns the type descriptor for the built-in type 'void'.
-
-
-
Field Detail
-
NULL
public static final java.lang.Object NULL
-
INVISIBLE_BY_DEFAULT
public static final java.lang.Class<?>[] INVISIBLE_BY_DEFAULT
Those classes for which the methods shall be invisible by default, in particularjava.lang.Object. (public also for testing)
-
DEFAULT
public static final TypeRegistry DEFAULT
-
LOGGER
private static final EASyLoggerFactory.EASyLogger LOGGER
-
INVISIBLE_INHERITED
private static final java.util.Map<java.lang.String,java.util.List<java.lang.reflect.Method>> INVISIBLE_INHERITED
Caches the operations vs. inheriting invisible methods.
-
types
private java.util.Map<java.lang.String,TypeDescriptor<?>> types
Stores the registered types.
-
instantiators
private java.util.Map<java.lang.String,TypeDescriptor<? extends IVilType>> instantiators
Stores the registered instantiators.
-
fallbacks
private java.util.Map<IDatatype,TypeDescriptor<?>> fallbacks
-
parentRegistry
private TypeRegistry parentRegistry
-
resolver
private java.util.List<ITypeResolver> resolver
-
directAccess
private IDirectTypeRegistryAccess directAccess
-
-
Constructor Detail
-
TypeRegistry
private TypeRegistry()
Creates the default type registry.
-
TypeRegistry
public TypeRegistry(TypeRegistry parentRegistry)
Creates a (local) type registry, which delegates unknown types to theparentRegistry.- Parameters:
parentRegistry- the parent registry, if nullDEFAULTis used
-
-
Method Detail
-
getParentRegistry
public TypeRegistry getParentRegistry()
Returns the parent registry.- Returns:
- the parent registry (may be null in case of the root registry)
-
addTypeResolver
public void addTypeResolver(ITypeResolver resolver)
Adds a type resolver as the current resolver of highest precedence.- Parameters:
resolver- the resolver to be added (may be null, but is ignored then)
-
registerCompoundType
public boolean registerCompoundType(CompoundTypeDescriptor type)
Registers a compound type, but only if a type of this name has not been registered so far.- Parameters:
type- the type to register- Returns:
trueif registered/successful,falseelse
-
hasTypeResolver
public boolean hasTypeResolver(java.lang.Class<? extends ITypeResolver> cls)
Returns whether this registry has a type resolver of the given type.- Parameters:
cls- the type to match, may be null to match all- Returns:
trueif there is a resolver,falseelse
-
removeTypeResolver
public void removeTypeResolver(ITypeResolver resolver)
Renoves a type resolver.- Parameters:
resolver- the resolver to be added (may be null, but is ignored then)
-
addInvisibleInherited
private static boolean addInvisibleInherited(java.lang.reflect.Method method)
Adds the givenmethodto the cache of invisible inherited methods. Already existing registrations will not be changed.- Parameters:
method- the method to be added.- Returns:
trueifmethodwas registered before,falseelse
-
registerType
public <T extends IVilType> TypeDescriptor<T> registerType(java.lang.Class<T> type) throws VilException
Registers a type. Please note that overriding a default artifact requires the same simple class name as the one to be overridden and that the new artifact type subclasses the existing one.- Type Parameters:
T- the actual type- Parameters:
type- the Java class of the VIL type to be registered- Returns:
- the registered descriptor
- Throws:
VilException- in case thattypecannot be registered for some reason
-
createTypeDescriptor
private static <T extends IVilType> ReflectionTypeDescriptor<T> createTypeDescriptor(java.lang.Class<T> type) throws VilException
Creates a type descriptor consideringIActualValueProvider.- Type Parameters:
T- the VIL type- Parameters:
type- the type the descriptor shall be created for- Returns:
- the descriptor
- Throws:
VilException- in case that creating the descriptor fails
-
testInstantiatorType
private static void testInstantiatorType(TypeDescriptor<? extends IVilType> type, Instantiator inst) throws VilException
Some basic semantic tests for instantiators.- Parameters:
type- the type to be testedinst- the instatiator annotation- Throws:
VilException- in case of failing tests
-
register
private <T extends IVilType> void register(TypeDescriptor<T> desc, java.lang.Class<T> metaProvider)
Registers an individual type via its name and emits an information message on the logger.- Type Parameters:
T- the actual VIL type- Parameters:
desc- the type descriptor being registeredmetaProvider- the class holding the @Meta annotation for registering equivalent classes (may be null)- See Also:
registerEquivalentClasses(Class, TypeDescriptor)
-
register
protected void register(java.lang.String key, TypeDescriptor<?> desc)Registers an individual type and emits an information message on the logger.- Parameters:
key- the type name to register fordesc- the type descriptor being registered
-
registerEquivalentClasses
private <T extends IVilType> void registerEquivalentClasses(java.lang.Class<T> type, TypeDescriptor<T> desc)
Registers equivalent classes fromClassMeta.equiv().- Type Parameters:
T- the actual VIL type- Parameters:
type- the type being registereddesc- the already created descriptor fortype
-
cacheInheritedAnnotations
private static void cacheInheritedAnnotations(java.lang.Class<?> cls)
Caches the inherited annotations and avoids repeated class analysis. [performance]- Parameters:
cls- the class to be cached
-
hasInheritedInvisibleAnnotation
static boolean hasInheritedInvisibleAnnotation(java.lang.String signature, java.lang.Class<?> cls)Returns whether a certain method given by its signature (seeOperationDescriptor.getSignature()has an inherited invisible annotation. Helper method for subsequent class analysis.- Parameters:
signature- the signature of the method to be queried forcls- the declaring class of the method- Returns:
trueif it has an inheritedInvisibleannotation,falseelse
-
register
public <T extends IVilType> TypeDescriptor<T> register(java.lang.Class<T> type)
Internal default registration function with error handling.- Type Parameters:
T- the actual implementing type- Parameters:
type- the type class to be registered- Returns:
- the corresponding type descriptor (may be null)
-
allTypes
public java.lang.Iterable<TypeDescriptor<?>> allTypes()
Provides access to all type descriptors.- Returns:
- all type descriptors (without a specific sequence)
-
allInstantiators
public java.lang.Iterable<TypeDescriptor<? extends IVilType>> allInstantiators()
Provides access to all instantiators.- Returns:
- all instantiators (without a specific sequence)
-
typesByNamePrefix
public java.lang.Iterable<TypeDescriptor<?>> typesByNamePrefix(java.lang.String prefix)
Provides access to all type descriptors with names starting with the givenprefix.- Parameters:
prefix- the prefix to look for- Returns:
- the type descriptors matching the prefix (without a specific sequence)
-
getTypeOrFallback
public TypeDescriptor<?> getTypeOrFallback(IDatatype type)
Returns the registered type descriptor for the giventypeor tries an explicitly registered fallback, e.g., for unknown types in models without advices.- Parameters:
type- the type to look for- Returns:
- the type or null if none was registered
- See Also:
getType(IDatatype)
-
allowFallbacks
protected boolean allowFallbacks()
Whether fallback datatypes are allowed to be stored on this registry.- Returns:
truefor allowed,falseelse
-
registerFallbackType
public void registerFallbackType(IDatatype type, TypeDescriptor<?> descriptor)
Registers a fallback type.- Parameters:
type- the IVML datatype to register the fallbackdescriptorfordescriptor- the fallback descriptor
-
getType
public TypeDescriptor<?> getType(IDatatype type)
Returns the registered type descriptor for the giventype.- Parameters:
type- the type to look for- Returns:
- the type or null if none was registered
-
resolveGenerics
public TypeDescriptor<?>[] resolveGenerics(IDatatype type)
Resolves IVML type generics.- Parameters:
type- the type to resolve the generics fro- Returns:
- the generics, null if there are no generics or the generics are not resolvable
- See Also:
getType(IDatatype)
-
getType
public TypeDescriptor<?> getType(java.lang.String name)
Returns the registered type descriptor for the givennamealso inparentRegistry.- Parameters:
name- the name to look for- Returns:
- the type descriptor or null if no one is registered for
name
-
getType
public TypeDescriptor<?> getType(java.lang.String name, boolean addIfMissing)
Returns the registered type descriptor for the givennamealso inparentRegistry.- Parameters:
name- the name to look foraddIfMissing- allow to dynamically add the type if it is missing through a type resolver (this shall be prevented for internal types!)- Returns:
- the type descriptor or null if no one is registered for
name
-
findType
private TypeDescriptor<?> findType(java.lang.String name)
Searches for a type calledname, first in this registry, then in parent registries if given.- Parameters:
name- the name of the type- Returns:
- the found type, null if not found
-
hasType
public boolean hasType(java.lang.String name)
Returns whether this type registry knows a type of the given name.- Parameters:
name- the name to search for- Returns:
trueif the type withnameis known,falseelse
-
resolve
private TypeDescriptor<?> resolve(java.lang.String name, boolean addIfMissing)
Resolves the given typenamevia the resolvers.- Parameters:
name- the name to look foraddIfMissing- allow to dynamically add the type if it is missing through a type resolver (this shall be prevented for internal types!)- Returns:
- the resolved type, null if none
-
getMapType
public static final TypeDescriptor<? extends Map<?,?>> getMapType(TypeDescriptor<?>... parameter) throws VilException
Returns the VIL type for a map with the given type parameters.- Parameters:
parameter- the type parameter- Returns:
- the type
- Throws:
VilException- in case that the derivation of the type fails
-
getIteratorType
public static final TypeDescriptor<? extends PseudoIterator<?>> getIteratorType(TypeDescriptor<?>... parameter) throws VilException
Returns the VIL type for a map with the given type parameters.- Parameters:
parameter- the type parameter- Returns:
- the type
- Throws:
VilException- in case that the derivation of the type fails
-
getCollectionType
public static final TypeDescriptor<? extends Collection<?>> getCollectionType(TypeDescriptor<?>... parameter) throws VilException
Returns the VIL type for a collection with the given type parameters.- Parameters:
parameter- the type parameter- Returns:
- the type
- Throws:
VilException- in case that the derivation of the type fails
-
getSetType
public static final TypeDescriptor<? extends Set<?>> getSetType(TypeDescriptor<?>... parameter) throws VilException
Returns the VIL type for a set with the given type parameters.- Parameters:
parameter- the type parameter- Returns:
- the type
- Throws:
VilException- in case that the derivation of the type fails
-
getSequenceType
public static final TypeDescriptor<? extends Sequence<?>> getSequenceType(TypeDescriptor<?>... parameter) throws VilException
Returns the VIL type for a sequence with the given type parameters.- Parameters:
parameter- the type parameter- Returns:
- the type
- Throws:
VilException- in case that the derivation of the type fails
-
getRuleType
public static final TypeDescriptor<? extends ResolvableOperationType> getRuleType(TypeDescriptor<?>... parameter) throws VilException
Returns the VIL type for a rule type with the given type parameters.- Parameters:
parameter- the type parameter- Returns:
- the type
- Throws:
VilException- in case that the derivation of the type fails
-
getInstantiator
public TypeDescriptor<? extends IVilType> getInstantiator(java.lang.String name)
Returns the registered instantiator type descriptor for the givennamealso inparentRegistry.- Parameters:
name- the name to look for- Returns:
- the type descriptor or null if no one is registered for
name
-
resolvableOperationType
public static final TypeDescriptor<?> resolvableOperationType()
Returns the type descriptor for the built-in operation references (a kind of function pointer to evaluate functions generically).- Returns:
- the type descriptor
-
stringType
public static final TypeDescriptor<?> stringType()
Returns the type descriptor for the built-in type String.- Returns:
- the type descriptor
-
booleanType
public static final TypeDescriptor<?> booleanType()
Returns the type descriptor for the built-in type 'Boolean'.- Returns:
- the type descriptor
-
versionType
public static final TypeDescriptor<?> versionType()
Returns the type descriptor for the built-in type 'Version'.- Returns:
- the type descriptor
-
anyType
public static final TypeDescriptor<?> anyType()
Returns the type descriptor for the built-in type 'any'.- Returns:
- the type descriptor
-
voidType
public static final TypeDescriptor<?> voidType()
Returns the type descriptor for the built-in type 'void'.- Returns:
- the type descriptor
-
typeType
public static final TypeDescriptor<?> typeType()
Returns the type descriptor for the built-in type 'Type'.- Returns:
- the type descriptor
-
integerType
public static final TypeDescriptor<?> integerType()
Returns the type descriptor for the built-in type 'Integer'.- Returns:
- the type descriptor
-
realType
public static final TypeDescriptor<?> realType()
Returns the type descriptor for the built-in type 'Real'.- Returns:
- the type descriptor
-
getType
public TypeDescriptor<?> getType(java.lang.Class<?> cls)
Converts a class into a type descriptor.- Parameters:
cls- the classes to be converted- Returns:
- the corresponding type descriptor or null
-
isInternalType
public static boolean isInternalType(java.lang.Class<?> cls)
Returns whetherclsis considered as an internal type including implementation types such as the collections.- Parameters:
cls- the class to be considered- Returns:
true
-
findType
public TypeDescriptor<?> findType(java.lang.Class<?> cls)
Finds the type descriptor for a given class.- Parameters:
cls- the classes to be converted- Returns:
- the corresponding type descriptor or null
-
findType
public TypeDescriptor<?> findType(java.lang.Class<?> cls, boolean addIfMissing)
Finds the type descriptor for a given class.- Parameters:
cls- the classes to be convertedaddIfMissing- allow to dynamically add the type if it is missing through a type resolver (this shall be prevented for internal types!)- Returns:
- the corresponding type descriptor or null
-
convert
public TypeDescriptor<?>[] convert(java.lang.Class<?> param)
Converts a class into a set of type descriptors.- Parameters:
param- the class to be converted- Returns:
- the resulting type descriptors,
nullifparamsis null or empty. If a type descriptor cannot be found,TypeDescriptor#VOIDis used instead.
-
convert
public TypeDescriptor<?>[] convert(java.lang.Class<?>... params)
Converts a set of classes into type descriptors.- Parameters:
params- the classes to be converted- Returns:
- the resulting type descriptors,
nullifparamsis null or empty. If a type descriptor cannot be found,TypeDescriptor#VOIDis used instead.
-
forRuntime
public boolean forRuntime()
Returns whether this registry provides types for runtime variability instantiation. This is the case if this or at least one of the parent type registries indicates runtime type support.- Returns:
trueif this registry or one of its parent registries provides runtime types,falseelse
-
equals
public static final boolean equals(IMetaType t1, IMetaType t2)
Returns whether two types are equal including base type considerations.- Parameters:
t1- the first type to be comparedt2- the second type to be compared- Returns:
trueift1andt2are equal,falseelse
-
toName
public static java.lang.String toName(IMetaType type)
Returns the VIL name oftype.- Parameters:
type- the type to return the name for- Returns:
- the VIL name (if possible), the name else
-
addTypeMapping
public static void addTypeMapping(java.lang.String name, TypeDescriptor<? extends IVilType> type)Allows to register internal mapped types, e.g.,TypeDescriptor.- Parameters:
name- the name of the typetype- the actual type
-
getMappedType
protected TypeDescriptor<?> getMappedType(java.lang.Class<?> cls, java.lang.Class<?>[] generics, IntHolder pos)
Returns mapped types provided by this registry and the descriptors created by this registry. This can be used to map Java collections into and from VIL.- Parameters:
cls- the class to be turned into a typegenerics- the generics to be applied to the type (may be null)pos- the modifiable position withingenerics, change only to indicate state of processing ofgenerics- Returns:
- the type descriptor or null if none is provided
-
obtainTypeDescriptor
public TypeDescriptor<?> obtainTypeDescriptor(java.lang.Object obj)
Obtains the type descriptor of an object.- Parameters:
obj- the object the descriptor shall be returned for- Returns:
- the descriptor
-
addTypeAlias
public <T> boolean addTypeAlias(java.lang.String name, TypeDescriptor<T> type) throws VilExceptionAdds a type alias to this specific type registry.- Type Parameters:
T- the specific VilType or Artifact- Parameters:
name- the name of the type aliastype- the type to be aliased- Returns:
trueif successful,falseelse- Throws:
java.lang.IllegalArgumentException- in case that name is null or empty,typeis null or this function shall be applied onDEFAULTVilException- if creating the type fails
-
-