ing
This commit is contained in:
parent
e7c032b720
commit
97029b672d
9
src/ts/@loafer/pouches/PouchMetadataElement.ts
Normal file
9
src/ts/@loafer/pouches/PouchMetadataElement.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
export interface PouchMetadataElement {
|
||||||
|
/**
|
||||||
|
* Return the configuration source {@code Object} for this metadata element
|
||||||
|
* (may be {@code null}).
|
||||||
|
*/
|
||||||
|
getSource(): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PouchMetadataElement;
|
|
@ -0,0 +1,578 @@
|
||||||
|
import {
|
||||||
|
ClassType,
|
||||||
|
PropertyType,
|
||||||
|
} from '@loafer/core/constants/types';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Assert,
|
||||||
|
} from '@loafer/core/util';
|
||||||
|
|
||||||
|
import {
|
||||||
|
PouchMetadataElement,
|
||||||
|
} from '@loafer/pouches';
|
||||||
|
|
||||||
|
import {
|
||||||
|
HierarchicalPouchFactory,
|
||||||
|
PouchFactory,
|
||||||
|
} from '@loafer/pouches/factory';
|
||||||
|
|
||||||
|
import {
|
||||||
|
PouchDefinition,
|
||||||
|
PouchExpressionResolver,
|
||||||
|
SingletonPouchRegistry,
|
||||||
|
} from '@loafer/pouches/factory/config';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class ConstructorArgumentValues {
|
||||||
|
private readonly indexedArgumentValues: Map<number, ValueHolder> = new Map();
|
||||||
|
private readonly genericArgumentValues: ValueHolder[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deep copy constructor.
|
||||||
|
* @param original the ConstructorArgumentValues to copy
|
||||||
|
*/
|
||||||
|
public constructor(original?: ConstructorArgumentValues) {
|
||||||
|
this.addArgumentValues(original);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy all given argument values into this object, using separate holder
|
||||||
|
* instances to keep the values independent from the original object.
|
||||||
|
* <p>Note: Identical ValueHolder instances will only be registered once,
|
||||||
|
* to allow for merging and re-merging of argument value definitions. Distinct
|
||||||
|
* ValueHolder instances carrying the same content are of course allowed.
|
||||||
|
*/
|
||||||
|
public addArgumentValues(other: ConstructorArgumentValues): void {
|
||||||
|
if (other != null) {
|
||||||
|
other.indexedArgumentValues.forEach((valueHolder, key, map) => {
|
||||||
|
this.addOrMergeIndexedArgumentValue(key, valueHolder.copy());
|
||||||
|
});
|
||||||
|
other.genericArgumentValues.filter((valueHolder, index, array) => {
|
||||||
|
return -1 === this.genericArgumentValues.indexOf(valueHolder);
|
||||||
|
}).forEach((valueHolder, index, array) => {
|
||||||
|
this.addOrMergeGenericArgumentValue(valueHolder.copy());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an argument value for the given index in the constructor argument list.
|
||||||
|
* @param index the index in the constructor argument list
|
||||||
|
* @param newValue the argument value in the form of a ValueHolder
|
||||||
|
*/
|
||||||
|
public addIndexedArgumentValue(index: number, value: ValueHolder): void;
|
||||||
|
/**
|
||||||
|
* Add an argument value for the given index in the constructor argument list.
|
||||||
|
* @param index the index in the constructor argument list
|
||||||
|
* @param value the argument value
|
||||||
|
* @param type the type of the constructor argument
|
||||||
|
*/
|
||||||
|
public addIndexedArgumentValue(index: number, value: any, type?: ClassType): void {
|
||||||
|
Assert.isTrue(index >= 0, 'Index must not be negative');
|
||||||
|
|
||||||
|
let newValue: ValueHolder;
|
||||||
|
if (!(value instanceof ValueHolder)) {
|
||||||
|
newValue = new ValueHolder(value, type);
|
||||||
|
}
|
||||||
|
Assert.notNull(newValue, 'ValueHolder must not be null');
|
||||||
|
this.addOrMergeIndexedArgumentValue(index, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an argument value for the given index in the constructor argument list,
|
||||||
|
* merging the new value (typically a collection) with the current value
|
||||||
|
* if demanded: see {@link org.springframework.beans.Mergeable}.
|
||||||
|
* @param key the index in the constructor argument list
|
||||||
|
* @param newValue the argument value in the form of a ValueHolder
|
||||||
|
*/
|
||||||
|
private addOrMergeIndexedArgumentValue(key: number, newValue: ValueHolder): void {
|
||||||
|
let currentValue: ValueHolder = this.indexedArgumentValues.get(key);
|
||||||
|
if (currentValue !== undefined && newValue.getValue() instanceof Mergeable) {
|
||||||
|
let mergeable: Mergeable = <Mergeable>newValue.getValue();
|
||||||
|
if (mergeable.isMergeEnabled()) {
|
||||||
|
newValue.setValue(mergeable.merge(currentValue.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.indexedArgumentValues.set(key, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether an argument value has been registered for the given index.
|
||||||
|
* @param index the index in the constructor argument list
|
||||||
|
*/
|
||||||
|
public hasIndexedArgumentValue(index: number): boolean {
|
||||||
|
return this.indexedArgumentValues.has(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get argument value for the given index in the constructor argument list.
|
||||||
|
* @param index the index in the constructor argument list
|
||||||
|
* @param requiredType the type to match (can be {@code null} to match
|
||||||
|
* untyped values only)
|
||||||
|
* @return the ValueHolder for the argument, or {@code null} if none set
|
||||||
|
*/
|
||||||
|
public getIndexedArgumentValue(index: number, requiredType: ClassType): ValueHolder {
|
||||||
|
return getIndexedArgumentValue(index, requiredType, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get argument value for the given index in the constructor argument list.
|
||||||
|
* @param index the index in the constructor argument list
|
||||||
|
* @param requiredType the type to match (can be {@code null} to match
|
||||||
|
* untyped values only)
|
||||||
|
* @param requiredName the type to match (can be {@code null} to match
|
||||||
|
* unnamed values only, or empty String to match any name)
|
||||||
|
* @return the ValueHolder for the argument, or {@code null} if none set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public getIndexedArgumentValue(index: number, requiredType: ClassType, requiredName: PropertyType): ValueHolder {
|
||||||
|
Assert.isTrue(index >= 0, "Index must not be negative");
|
||||||
|
ValueHolder valueHolder = this.indexedArgumentValues.get(index);
|
||||||
|
if (valueHolder != null &&
|
||||||
|
(valueHolder.getType() == null ||
|
||||||
|
(requiredType != null && ClassUtils.matchesTypeName(requiredType, valueHolder.getType()))) &&
|
||||||
|
(valueHolder.getName() == null || "".equals(requiredName) ||
|
||||||
|
(requiredName != null && requiredName.equals(valueHolder.getName())))) {
|
||||||
|
return valueHolder;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the map of indexed argument values.
|
||||||
|
* @return unmodifiable Map with Integer index as key and ValueHolder as value
|
||||||
|
* @see ValueHolder
|
||||||
|
*/
|
||||||
|
public Map<Integer, ValueHolder> getIndexedArgumentValues() {
|
||||||
|
return Collections.unmodifiableMap(this.indexedArgumentValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a generic argument value to be matched by type.
|
||||||
|
* <p>Note: A single generic argument value will just be used once,
|
||||||
|
* rather than matched multiple times.
|
||||||
|
* @param value the argument value
|
||||||
|
*/
|
||||||
|
public void addGenericArgumentValue(Object value) {
|
||||||
|
this.genericArgumentValues.add(new ValueHolder(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a generic argument value to be matched by type.
|
||||||
|
* <p>Note: A single generic argument value will just be used once,
|
||||||
|
* rather than matched multiple times.
|
||||||
|
* @param value the argument value
|
||||||
|
* @param type the type of the constructor argument
|
||||||
|
*/
|
||||||
|
public void addGenericArgumentValue(Object value, String type) {
|
||||||
|
this.genericArgumentValues.add(new ValueHolder(value, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a generic argument value to be matched by type or name (if available).
|
||||||
|
* <p>Note: A single generic argument value will just be used once,
|
||||||
|
* rather than matched multiple times.
|
||||||
|
* @param newValue the argument value in the form of a ValueHolder
|
||||||
|
* <p>Note: Identical ValueHolder instances will only be registered once,
|
||||||
|
* to allow for merging and re-merging of argument value definitions. Distinct
|
||||||
|
* ValueHolder instances carrying the same content are of course allowed.
|
||||||
|
*/
|
||||||
|
public void addGenericArgumentValue(ValueHolder newValue) {
|
||||||
|
Assert.notNull(newValue, "ValueHolder must not be null");
|
||||||
|
if (!this.genericArgumentValues.contains(newValue)) {
|
||||||
|
addOrMergeGenericArgumentValue(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a generic argument value, merging the new value (typically a collection)
|
||||||
|
* with the current value if demanded: see {@link org.springframework.beans.Mergeable}.
|
||||||
|
* @param newValue the argument value in the form of a ValueHolder
|
||||||
|
*/
|
||||||
|
private void addOrMergeGenericArgumentValue(ValueHolder newValue) {
|
||||||
|
if (newValue.getName() != null) {
|
||||||
|
for (Iterator<ValueHolder> it = this.genericArgumentValues.iterator(); it.hasNext();) {
|
||||||
|
ValueHolder currentValue = it.next();
|
||||||
|
if (newValue.getName().equals(currentValue.getName())) {
|
||||||
|
if (newValue.getValue() instanceof Mergeable) {
|
||||||
|
Mergeable mergeable = (Mergeable) newValue.getValue();
|
||||||
|
if (mergeable.isMergeEnabled()) {
|
||||||
|
newValue.setValue(mergeable.merge(currentValue.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.genericArgumentValues.add(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look for a generic argument value that matches the given type.
|
||||||
|
* @param requiredType the type to match
|
||||||
|
* @return the ValueHolder for the argument, or {@code null} if none set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public ValueHolder getGenericArgumentValue(Class<?> requiredType) {
|
||||||
|
return getGenericArgumentValue(requiredType, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look for a generic argument value that matches the given type.
|
||||||
|
* @param requiredType the type to match
|
||||||
|
* @param requiredName the name to match
|
||||||
|
* @return the ValueHolder for the argument, or {@code null} if none set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public ValueHolder getGenericArgumentValue(Class<?> requiredType, String requiredName) {
|
||||||
|
return getGenericArgumentValue(requiredType, requiredName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look for the next generic argument value that matches the given type,
|
||||||
|
* ignoring argument values that have already been used in the current
|
||||||
|
* resolution process.
|
||||||
|
* @param requiredType the type to match (can be {@code null} to find
|
||||||
|
* an arbitrary next generic argument value)
|
||||||
|
* @param requiredName the name to match (can be {@code null} to not
|
||||||
|
* match argument values by name, or empty String to match any name)
|
||||||
|
* @param usedValueHolders a Set of ValueHolder objects that have already been used
|
||||||
|
* in the current resolution process and should therefore not be returned again
|
||||||
|
* @return the ValueHolder for the argument, or {@code null} if none found
|
||||||
|
*/
|
||||||
|
|
||||||
|
public ValueHolder getGenericArgumentValue( Class<?> requiredType, String requiredName, Set<ValueHolder> usedValueHolders) {
|
||||||
|
for (ValueHolder valueHolder : this.genericArgumentValues) {
|
||||||
|
if (usedValueHolders != null && usedValueHolders.contains(valueHolder)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (valueHolder.getName() != null && !"".equals(requiredName) &&
|
||||||
|
(requiredName == null || !valueHolder.getName().equals(requiredName))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (valueHolder.getType() != null &&
|
||||||
|
(requiredType == null || !ClassUtils.matchesTypeName(requiredType, valueHolder.getType()))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (requiredType != null && valueHolder.getType() == null && valueHolder.getName() == null &&
|
||||||
|
!ClassUtils.isAssignableValue(requiredType, valueHolder.getValue())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return valueHolder;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the list of generic argument values.
|
||||||
|
* @return unmodifiable List of ValueHolders
|
||||||
|
* @see ValueHolder
|
||||||
|
*/
|
||||||
|
public List<ValueHolder> getGenericArgumentValues() {
|
||||||
|
return Collections.unmodifiableList(this.genericArgumentValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look for an argument value that either corresponds to the given index
|
||||||
|
* in the constructor argument list or generically matches by type.
|
||||||
|
* @param index the index in the constructor argument list
|
||||||
|
* @param requiredType the parameter type to match
|
||||||
|
* @return the ValueHolder for the argument, or {@code null} if none set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public ValueHolder getArgumentValue(index: number, Class<?> requiredType) {
|
||||||
|
return getArgumentValue(index, requiredType, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look for an argument value that either corresponds to the given index
|
||||||
|
* in the constructor argument list or generically matches by type.
|
||||||
|
* @param index the index in the constructor argument list
|
||||||
|
* @param requiredType the parameter type to match
|
||||||
|
* @param requiredName the parameter name to match
|
||||||
|
* @return the ValueHolder for the argument, or {@code null} if none set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public ValueHolder getArgumentValue(index: number, Class<?> requiredType, String requiredName) {
|
||||||
|
return getArgumentValue(index, requiredType, requiredName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look for an argument value that either corresponds to the given index
|
||||||
|
* in the constructor argument list or generically matches by type.
|
||||||
|
* @param index the index in the constructor argument list
|
||||||
|
* @param requiredType the parameter type to match (can be {@code null}
|
||||||
|
* to find an untyped argument value)
|
||||||
|
* @param requiredName the parameter name to match (can be {@code null}
|
||||||
|
* to find an unnamed argument value, or empty String to match any name)
|
||||||
|
* @param usedValueHolders a Set of ValueHolder objects that have already
|
||||||
|
* been used in the current resolution process and should therefore not
|
||||||
|
* be returned again (allowing to return the next generic argument match
|
||||||
|
* in case of multiple generic argument values of the same type)
|
||||||
|
* @return the ValueHolder for the argument, or {@code null} if none set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public ValueHolder getArgumentValue(index: number, Class<?> requiredType, String requiredName, Set<ValueHolder> usedValueHolders) {
|
||||||
|
Assert.isTrue(index >= 0, "Index must not be negative");
|
||||||
|
ValueHolder valueHolder = getIndexedArgumentValue(index, requiredType, requiredName);
|
||||||
|
if (valueHolder == null) {
|
||||||
|
valueHolder = getGenericArgumentValue(requiredType, requiredName, usedValueHolders);
|
||||||
|
}
|
||||||
|
return valueHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of argument values held in this instance,
|
||||||
|
* counting both indexed and generic argument values.
|
||||||
|
*/
|
||||||
|
public int getArgumentCount() {
|
||||||
|
return (this.indexedArgumentValues.size() + this.genericArgumentValues.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return if this holder does not contain any argument values,
|
||||||
|
* neither indexed ones nor generic ones.
|
||||||
|
*/
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return (this.indexedArgumentValues.isEmpty() && this.genericArgumentValues.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear this holder, removing all argument values.
|
||||||
|
*/
|
||||||
|
public void clear() {
|
||||||
|
this.indexedArgumentValues.clear();
|
||||||
|
this.genericArgumentValues.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (this == other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(other instanceof ConstructorArgumentValues)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ConstructorArgumentValues that = (ConstructorArgumentValues) other;
|
||||||
|
if (this.genericArgumentValues.size() != that.genericArgumentValues.size() ||
|
||||||
|
this.indexedArgumentValues.size() != that.indexedArgumentValues.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Iterator<ValueHolder> it1 = this.genericArgumentValues.iterator();
|
||||||
|
Iterator<ValueHolder> it2 = that.genericArgumentValues.iterator();
|
||||||
|
while (it1.hasNext() && it2.hasNext()) {
|
||||||
|
ValueHolder vh1 = it1.next();
|
||||||
|
ValueHolder vh2 = it2.next();
|
||||||
|
if (!vh1.contentEquals(vh2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Map.Entry<Integer, ValueHolder> entry : this.indexedArgumentValues.entrySet()) {
|
||||||
|
ValueHolder vh1 = entry.getValue();
|
||||||
|
ValueHolder vh2 = that.indexedArgumentValues.get(entry.getKey());
|
||||||
|
if (!vh1.contentEquals(vh2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int; hashCode() {
|
||||||
|
int hashCode = 7;
|
||||||
|
for (ValueHolder valueHolder : this.genericArgumentValues) {
|
||||||
|
hashCode = 31 * hashCode + valueHolder.contentHashCode();
|
||||||
|
}
|
||||||
|
hashCode = 29 * hashCode;
|
||||||
|
for (Map.Entry<Integer, ValueHolder> entry : this.indexedArgumentValues.entrySet()) {
|
||||||
|
hashCode = 31 * hashCode + (entry.getValue().contentHashCode() ^ entry.getKey().hashCode());
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holder for a constructor argument value, with an optional type
|
||||||
|
* attribute indicating the target type of the actual constructor argument.
|
||||||
|
*/
|
||||||
|
export class ValueHolder implements PouchMetadataElement {
|
||||||
|
|
||||||
|
|
||||||
|
private Object value;
|
||||||
|
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
|
||||||
|
private Object source;
|
||||||
|
|
||||||
|
private boolean converted = false;
|
||||||
|
|
||||||
|
|
||||||
|
private Object convertedValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ValueHolder for the given value.
|
||||||
|
* @param value the argument value
|
||||||
|
*/
|
||||||
|
public ValueHolder( Object value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ValueHolder for the given value and type.
|
||||||
|
* @param value the argument value
|
||||||
|
* @param type the type of the constructor argument
|
||||||
|
*/
|
||||||
|
public ValueHolder( Object value, String type) {
|
||||||
|
this.value = value;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ValueHolder for the given value, type and name.
|
||||||
|
* @param value the argument value
|
||||||
|
* @param type the type of the constructor argument
|
||||||
|
* @param name the name of the constructor argument
|
||||||
|
*/
|
||||||
|
public ValueHolder( Object value, String type, String name) {
|
||||||
|
this.value = value;
|
||||||
|
this.type = type;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value for the constructor argument.
|
||||||
|
* @see PropertyPlaceholderConfigurer
|
||||||
|
*/
|
||||||
|
public void setValue(; Object value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value for the constructor argument.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Object; getValue(); {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the type of the constructor argument.
|
||||||
|
*/
|
||||||
|
public void setType(; String; type;) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the type of the constructor argument.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String; getType(); {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the name of the constructor argument.
|
||||||
|
*/
|
||||||
|
public void setName(; String; name; ) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of the constructor argument.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String; getName(); {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the configuration source {@code Object} for this metadata element.
|
||||||
|
* <p>The exact type of the object will depend on the configuration mechanism used.
|
||||||
|
*/
|
||||||
|
public void setSource(; Object; source; ) {
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
|
||||||
|
public Object; getSource(); {
|
||||||
|
return this.source;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether this holder contains a converted value already ({@code true}),
|
||||||
|
* or whether the value still needs to be converted ({@code false}).
|
||||||
|
*/
|
||||||
|
public synchronized; boolean; isConverted(); {
|
||||||
|
return this.converted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the converted value of the constructor argument,
|
||||||
|
* after processed type conversion.
|
||||||
|
*/
|
||||||
|
public synchronized; void setConvertedValue(; Object; value; ) {
|
||||||
|
this.converted = (value != null);
|
||||||
|
this.convertedValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the converted value of the constructor argument,
|
||||||
|
* after processed type conversion.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public synchronized; Object; getConvertedValue(); {
|
||||||
|
return this.convertedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the content of this ValueHolder is equal
|
||||||
|
* to the content of the given other ValueHolder.
|
||||||
|
* <p>Note that ValueHolder does not implement {@code equals}
|
||||||
|
* directly, to allow for multiple ValueHolder instances with the
|
||||||
|
* same content to reside in the same Set.
|
||||||
|
*/
|
||||||
|
private boolean; contentEquals(ValueHolder other); {
|
||||||
|
return (this === other ||
|
||||||
|
(ObjectUtils.nullSafeEquals(this.value, other.value) && ObjectUtils.nullSafeEquals(this.type, other.type)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the hash code of the content of this ValueHolder.
|
||||||
|
* <p>Note that ValueHolder does not implement {@code hashCode}
|
||||||
|
* directly, to allow for multiple ValueHolder instances with the
|
||||||
|
* same content to reside in the same Set.
|
||||||
|
*/
|
||||||
|
private int; contentHashCode(); {
|
||||||
|
return ObjectUtils.nullSafeHashCode(this.value) * 29 + ObjectUtils.nullSafeHashCode(this.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a copy of this ValueHolder: that is, an independent
|
||||||
|
* ValueHolder instance with the same contents.
|
||||||
|
*/
|
||||||
|
public ValueHolder; copy(); {
|
||||||
|
ValueHolder; copy = new ValueHolder(this.value, this.type, this.name);
|
||||||
|
copy.setSource(this.source);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default ConstructorArgumentValues;
|
|
@ -8,15 +8,122 @@ import {
|
||||||
} from '@loafer/pouches/constants/types';
|
} from '@loafer/pouches/constants/types';
|
||||||
|
|
||||||
interface PouchDefinition {
|
interface PouchDefinition {
|
||||||
readonly Clazz: ClassType;
|
|
||||||
Scope: PouchScope;
|
/**
|
||||||
Qualifier: PropertyType;
|
* The name of the parent definition of this pouch definition, if any.
|
||||||
readonly PostConstruct: Set<string>;
|
*/
|
||||||
readonly PreDestroy: Set<string>;
|
ParentName: PropertyType;
|
||||||
addPostConstruct(postConstruct: string): void;
|
/**
|
||||||
addPreDestroy(preDestroy: string): void;
|
* The current pouch class name of this pouch definition.
|
||||||
isSingleton(): boolean;
|
* <p>Note that this does not have to be the actual class name used at runtime, in
|
||||||
isTransient(): boolean;
|
* case of a child definition overriding/inheriting the class name from its parent.
|
||||||
|
* Also, this may just be the class that a factory method is called on, or it may
|
||||||
|
* even be empty in case of a factory pouch reference that a method is called on.
|
||||||
|
* Hence, do <i>not</i> consider this to be the definitive pouch type at runtime but
|
||||||
|
* rather only use it for parsing purposes at the individual pouch definition level.
|
||||||
|
* @see #getParentName()
|
||||||
|
* @see #getFactoryPouchName()
|
||||||
|
* @see #getFactoryMethodName()
|
||||||
|
*/
|
||||||
|
PouchClassName: string;
|
||||||
|
/**
|
||||||
|
* Override the target scope of this pouch, specifying a new scope name.
|
||||||
|
* @see #SCOPE_SINGLETON
|
||||||
|
* @see #SCOPE_PROTOTYPE
|
||||||
|
*/
|
||||||
|
Scope: string;
|
||||||
|
/**
|
||||||
|
* Whether this pouch should be lazily initialized.
|
||||||
|
* <p>If {@code false}, the pouch will get instantiated on startup by pouch
|
||||||
|
* factories that perform eager initialization of singletons.
|
||||||
|
*/
|
||||||
|
LazyInit: boolean;
|
||||||
|
/**
|
||||||
|
* The names of the pouchs that this pouch depends on being initialized.
|
||||||
|
* The pouch factory will guarantee that these pouchs get initialized first.
|
||||||
|
*/
|
||||||
|
DependsOn: PropertyType[];
|
||||||
|
/**
|
||||||
|
* Whether this pouch is a candidate for getting autowired into some other pouch.
|
||||||
|
* <p>Note that this flag is designed to only affect type-based autowiring.
|
||||||
|
* It does not affect explicit references by name, which will get resolved even
|
||||||
|
* if the specified pouch is not marked as an autowire candidate. As a consequence,
|
||||||
|
* autowiring by name will nevertheless inject a pouch if the name matches.
|
||||||
|
*/
|
||||||
|
AutowireCandidate: boolean;
|
||||||
|
/**
|
||||||
|
* Whether this pouch is a primary autowire candidate.
|
||||||
|
* <p>If this value is {@code true} for exactly one pouch among multiple
|
||||||
|
* matching candidates, it will serve as a tie-breaker.
|
||||||
|
*/
|
||||||
|
Primary: boolean;
|
||||||
|
/**
|
||||||
|
* Specify the factory pouch to use, if any.
|
||||||
|
* This the name of the pouch to call the specified factory method on.
|
||||||
|
* @see #setFactoryMethodName
|
||||||
|
*/
|
||||||
|
FactoryPouchName: PropertyType;
|
||||||
|
/**
|
||||||
|
* Specify a factory method, if any. This method will be invoked with
|
||||||
|
* constructor arguments, or with no arguments if none are specified.
|
||||||
|
* The method will be invoked on the specified factory pouch, if any,
|
||||||
|
* or otherwise as a static method on the local pouch class.
|
||||||
|
* @see #setFactoryPouchName
|
||||||
|
* @see #setPouchClassName
|
||||||
|
*/
|
||||||
|
FactoryMethodName: PropertyType;
|
||||||
|
/**
|
||||||
|
* Return the constructor argument values for this pouch.
|
||||||
|
* <p>The returned instance can be modified during pouch factory post-processing.
|
||||||
|
* @return the ConstructorArgumentValues object (never {@code null})
|
||||||
|
*/
|
||||||
|
getConstructorArgumentValues(): ConstructorArgumentValues;
|
||||||
|
/**
|
||||||
|
* Return the property values to be applied to a new instance of the pouch.
|
||||||
|
* <p>The returned instance can be modified during pouch factory post-processing.
|
||||||
|
* @return the MutablePropertyValues object (never {@code null})
|
||||||
|
*/
|
||||||
|
getPropertyValues(): MutablePropertyValues;
|
||||||
|
/**
|
||||||
|
* Return whether this a <b>Singleton</b>, with a single, shared instance
|
||||||
|
* returned on all calls.
|
||||||
|
* @see #SCOPE_SINGLETON
|
||||||
|
*/
|
||||||
|
isSingleton(): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether this a <b>Prototype</b>, with an independent instance
|
||||||
|
* returned for each call.
|
||||||
|
* @see #SCOPE_PROTOTYPE
|
||||||
|
*/
|
||||||
|
isPrototype(): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether this pouch is "abstract", that is, not meant to be instantiated.
|
||||||
|
*/
|
||||||
|
isAbstract(): boolean;
|
||||||
|
|
||||||
|
// Read-only attributes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a human-readable description of this pouch definition.
|
||||||
|
*/
|
||||||
|
getDescription(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a description of the resource that this pouch definition
|
||||||
|
* came from (for the purpose of showing context in case of errors).
|
||||||
|
*/
|
||||||
|
getResourceDescription(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the originating PouchDefinition, or {@code null} if none.
|
||||||
|
* Allows for retrieving the decorated pouch definition, if any.
|
||||||
|
* <p>Note that this method returns the immediate originator. Iterate through the
|
||||||
|
* originator chain to find the original PouchDefinition as defined by the user.
|
||||||
|
*/
|
||||||
|
getOriginatingPouchDefinition(): PouchDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PouchDefinition;
|
export default PouchDefinition;
|
||||||
|
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
export * from './PouchesException';
|
export * from './PouchesException';
|
||||||
|
export * from './PouchMetadataElement';
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user