-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reimplemented Wirings using a fresh and simpler approach of a Wiring …
…composed of a PropertySourceChain and a FactoryChain Wirings now support qualifiers and scopes Wirings now report much more detail when they fail to construct instances
- Loading branch information
Showing
38 changed files
with
2,100 additions
and
1,728 deletions.
There are no files selected for viewing
20 changes: 0 additions & 20 deletions
20
core/src/main/java/foundation/stack/datamill/configuration/BooleanValue.java
This file was deleted.
Oops, something went wrong.
18 changes: 18 additions & 0 deletions
18
core/src/main/java/foundation/stack/datamill/configuration/Factory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package foundation.stack.datamill.configuration; | ||
|
||
import rx.functions.Func2; | ||
|
||
/** | ||
* A factory for constructing objects of particular types. Use {@link FactoryChains} to create factories and compose | ||
* them together into chains. Note that the contract of a factory is to return a fully constructed instance of the | ||
* requested type (it can use the provided {@link Wiring} to construct the instance, or return null if the factory | ||
* cannot construct an instance. | ||
* | ||
* @author Ravi Chodavarapu (rchodava@gmail.com) | ||
*/ | ||
@FunctionalInterface | ||
public interface Factory<T, R extends T> extends Func2<Wiring, Class<? extends T>, R> { | ||
static Factory<?, ?> wrap(TypeLessFactory<?> factory) { | ||
return (w, c) -> factory.call(w); | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
core/src/main/java/foundation/stack/datamill/configuration/FactoryChain.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package foundation.stack.datamill.configuration; | ||
|
||
/** | ||
* @author Ravi Chodavarapu (rchodava@gmail.com) | ||
*/ | ||
public interface FactoryChain extends QualifyingFactory<Object, Object> { | ||
/** | ||
* Add a factory which will be used to attempt construction of instances for all types. | ||
*/ | ||
<T, R extends T> FactoryChain thenForAny(Factory<T, R> factory); | ||
|
||
/** | ||
* Add a factory which will be used to attempt construction of instances of concrete classes. | ||
*/ | ||
FactoryChain thenForAnyConcreteClass(); | ||
|
||
/** | ||
* Add a factory for a type, and it's super-classes and interfaces. Note that this factory will be invoked if the | ||
* type requested is exactly the specified type, or one of it's super-classes or interfaces. | ||
*/ | ||
<T, R extends T> FactoryChain thenForSuperOf(Class<T> type, Factory<T, R> factory); | ||
|
||
/** | ||
* Add a factory for a specific type. Note that this factory is only invoked if the type being constructed matches | ||
* the exact type specified. | ||
* | ||
* @param type Exact type for which the specified factory will be used. | ||
*/ | ||
<T, R extends T> FactoryChain thenForType(Class<T> type, Factory<T, R> factory); | ||
|
||
/** | ||
* @see #thenForAny(Factory) | ||
*/ | ||
<R> FactoryChain thenForAny(TypeLessFactory<R> factory); | ||
|
||
/** | ||
* @see #thenForSuperOf(Class, Factory) | ||
*/ | ||
<T, R extends T> FactoryChain thenForSuperOf(Class<T> type, TypeLessFactory<R> factory); | ||
|
||
/** | ||
* @see #thenForType(Class, Factory) | ||
*/ | ||
<T, R extends T> FactoryChain thenForType(Class<T> type, TypeLessFactory<R> factory); | ||
|
||
/** | ||
* Add a qualifying factory which will be used to attempt construction of instances for all types. | ||
* | ||
* @see #thenForAny(Factory) | ||
*/ | ||
<T, R extends T> FactoryChain thenForAny(QualifyingFactory<T, R> factory); | ||
|
||
/** | ||
* Add a qualifying factory for a type, and it's super-classes and interfaces. | ||
* | ||
* @see #thenForSuperOf(Class, Factory) | ||
*/ | ||
<T, R extends T> FactoryChain thenForSuperOf(Class<T> type, QualifyingFactory<T, R> factory); | ||
|
||
/** | ||
* Add a qualifying factory for a specific type. | ||
* | ||
* @see #thenForType(Class, Factory) | ||
*/ | ||
<T, R extends T> FactoryChain thenForType(Class<T> type, QualifyingFactory<T, R> factory); | ||
} |
79 changes: 79 additions & 0 deletions
79
core/src/main/java/foundation/stack/datamill/configuration/FactoryChains.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package foundation.stack.datamill.configuration; | ||
|
||
import foundation.stack.datamill.configuration.impl.ConcreteClassFactory; | ||
import foundation.stack.datamill.configuration.impl.FactoryChainImpl; | ||
|
||
/** | ||
* @author Ravi Chodavarapu (rchodava@gmail.com) | ||
*/ | ||
public class FactoryChains { | ||
/** | ||
* @see FactoryChain#thenForAnyConcreteClass() | ||
*/ | ||
public static FactoryChain forAnyConcreteClass() { | ||
return forAny(ConcreteClassFactory.instance()); | ||
} | ||
|
||
/** | ||
* @see FactoryChain#thenForAny(Factory) | ||
*/ | ||
public static <T, R extends T> FactoryChain forAny(Factory<T, R> factory) { | ||
return new FactoryChainImpl(FactoryChainImpl.tautology(), factory); | ||
} | ||
|
||
/** | ||
* @see FactoryChain#thenForSuperOf(Class, Factory) | ||
*/ | ||
public static <T, R extends T> FactoryChain forSuperOf(Class<T> type, Factory<T, R> factory) { | ||
return new FactoryChainImpl(FactoryChainImpl.isSuperOf(type), factory); | ||
} | ||
|
||
/** | ||
* @see FactoryChain#thenForType(Class, Factory) | ||
*/ | ||
public static <T, R extends T> FactoryChain forType(Class<T> type, Factory<T, R> factory) { | ||
return new FactoryChainImpl(FactoryChainImpl.isExactType(type), factory); | ||
} | ||
|
||
/** | ||
* @see FactoryChain#thenForAny(QualifyingFactory) | ||
*/ | ||
public static <T, R extends T> FactoryChain forAny(QualifyingFactory<T, R> factory) { | ||
return new FactoryChainImpl(FactoryChainImpl.tautology(), factory); | ||
} | ||
|
||
/** | ||
* @see FactoryChain#thenForSuperOf(Class, QualifyingFactory) | ||
*/ | ||
public static <T, R extends T> FactoryChain forSuperOf(Class<T> type, QualifyingFactory<T, R> factory) { | ||
return new FactoryChainImpl(FactoryChainImpl.isSuperOf(type), factory); | ||
} | ||
|
||
/** | ||
* @see FactoryChain#thenForType(Class, QualifyingFactory) | ||
*/ | ||
public static <T, R extends T> FactoryChain forType(Class<T> type, QualifyingFactory<T, R> factory) { | ||
return new FactoryChainImpl(FactoryChainImpl.isExactType(type), factory); | ||
} | ||
|
||
/** | ||
* @see FactoryChain#thenForAny(TypeLessFactory) | ||
*/ | ||
public static <R> FactoryChain forAny(TypeLessFactory<R> factory) { | ||
return new FactoryChainImpl(FactoryChainImpl.tautology(), factory); | ||
} | ||
|
||
/** | ||
* @see FactoryChain#thenForSuperOf(Class, TypeLessFactory) | ||
*/ | ||
public static <T, R extends T> FactoryChain forSuperOf(Class<T> type, TypeLessFactory<R> factory) { | ||
return new FactoryChainImpl(FactoryChainImpl.isSuperOf(type), factory); | ||
} | ||
|
||
/** | ||
* @see FactoryChain#thenForType(Class, TypeLessFactory) | ||
*/ | ||
public static <T, R extends T> FactoryChain forType(Class<T> type, TypeLessFactory<R> factory) { | ||
return new FactoryChainImpl(FactoryChainImpl.isExactType(type), factory); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 0 additions & 20 deletions
20
core/src/main/java/foundation/stack/datamill/configuration/IntegerValue.java
This file was deleted.
Oops, something went wrong.
10 changes: 0 additions & 10 deletions
10
core/src/main/java/foundation/stack/datamill/configuration/Module.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
core/src/main/java/foundation/stack/datamill/configuration/PropertyNameTransformers.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package foundation.stack.datamill.configuration; | ||
|
||
import com.google.common.base.CaseFormat; | ||
import rx.functions.Func1; | ||
|
||
/** | ||
* Some common property name transformers that are useful when creating {@link PropertySources}. | ||
*/ | ||
public class PropertyNameTransformers { /** | ||
* Transforms from lower-camel case to upper-underscore case, for example: propertyName -> PROPERTY_NAME. | ||
*/ | ||
public static final Func1<String, String> LOWER_CAMEL_TO_UPPER_UNDERSCORE = | ||
name -> CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, name); | ||
|
||
/** | ||
* Same as calling {@link #leaf(char)} with '/'. | ||
*/ | ||
public static final Func1<String, String> LEAF = leaf('/'); | ||
|
||
/** | ||
* <p> | ||
* Returns a transformation function that applies the first function, and then the second function on the result | ||
* of the first. So compose(LEAF, LOWER_CAMEL_TO_UPPER_UNDERSCORE) will return a function that transforms: | ||
* </p> | ||
* <p> | ||
* category/propertyName -> PROPERTY_NAME | ||
* </p> | ||
*/ | ||
public static final Func1<String, String> compose(Func1<String, String> a, Func1<String, String> b) { | ||
return name -> b.call(a.call(name)); | ||
} | ||
|
||
/** | ||
* <p> | ||
* Returns a transformation function that returns the leaf name of a name separated by the specified separator | ||
* character. For example: | ||
* </p> | ||
* <p> | ||
* leaf('/') returns a function which transforms: category/propertyName -> propertyName | ||
* leaf(':') returns a function which transforms: category:propertyName -> propertyName | ||
* </p> | ||
*/ | ||
public static final Func1<String, String> leaf(char separator) { | ||
return name -> { | ||
if (name != null) { | ||
int leafSeparator = name.lastIndexOf('/'); | ||
if (leafSeparator > 0) { | ||
return name.substring(leafSeparator + 1); | ||
} | ||
} | ||
|
||
return name; | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.