Skip to content

Commit

Permalink
Version 1.3.4
Browse files Browse the repository at this point in the history
  • Loading branch information
xdcrafts committed Jan 19, 2017
1 parent d1a39d2 commit d632c26
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 25 deletions.
4 changes: 2 additions & 2 deletions flower-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
<groupId>com.github.xdcrafts</groupId>
<artifactId>flower</artifactId>
<relativePath>..</relativePath>
<version>1.3.3</version>
<version>1.3.4</version>
</parent>

<dependencies>
<dependency>
<groupId>com.github.xdcrafts</groupId>
<artifactId>flower-tools</artifactId>
<version>1.3.3</version>
<version>1.3.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
Expand Down
4 changes: 2 additions & 2 deletions flower-spring/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
<groupId>com.github.xdcrafts</groupId>
<artifactId>flower</artifactId>
<relativePath>..</relativePath>
<version>1.3.3</version>
<version>1.3.4</version>
</parent>

<dependencies>
<dependency>
<groupId>com.github.xdcrafts</groupId>
<artifactId>flower-core</artifactId>
<version>1.3.3</version>
<version>1.3.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public abstract class AbstractActionFactoryBean<T>
extends AbstractNameAwareFactoryBean<T>
implements ApplicationContextAware {

private static final String SPLITTER = "::";
protected static final String DEFAULT_FUNCTION = "apply";
protected static final String SPLITTER = "::";

private ApplicationContext applicationContext;
private DataFunctionExtractor dataFunctionExtractor;
Expand All @@ -55,15 +56,26 @@ public ApplicationContext getApplicationContext() {
return applicationContext;
}

public DataFunctionExtractor getDataFunctionExtractor() {
return dataFunctionExtractor;
}

protected Function<Map, Map> resolveDataFunction(String definition) {
final String[] subjectAndMethod = definition.split(SPLITTER);
if (subjectAndMethod.length != 2) {
throw new IllegalArgumentException(
"Invalid action declaration: <class-or-bean-name>::<method-name> expected."
);
final String subject;
final String method;
if (definition.contains(SPLITTER)) {
final String[] subjectAndMethod = definition.split(SPLITTER);
if (subjectAndMethod.length != 2) {
throw new IllegalArgumentException(
"Invalid action declaration: <class-or-bean-name>::<method-name> expected."
);
}
subject = subjectAndMethod[0];
method = subjectAndMethod[1];
} else {
subject = definition;
method = DEFAULT_FUNCTION;
}
final String subject = subjectAndMethod[0];
final String method = subjectAndMethod[1];
final Object classOrBean;
try {
classOrBean = this.getApplicationContext().containsBean(subject)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ private Action toAction(Object item) {
definedMiddleware
);
} else {
throw new IllegalArgumentException(
"Can not convert " + item + " to Action. "
+ "Action or '<bean-or-class-name>::<method-name>' string expected."
return new DefaultAction(
item.getClass() + "@" + RANDOM.nextInt(),
getDataFunctionExtractor().apply(item, DEFAULT_FUNCTION)
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ protected Action toAction(Object item) {
definedMiddleware
);
} else {
throw new IllegalArgumentException(
"Can not convert " + item + " to Action. "
+ "Action or '<bean-or-class-name>::<method-name>' string expected."
return new DefaultAction(
item.getClass() + "@" + RANDOM.nextInt(),
getDataFunctionExtractor().apply(item, DEFAULT_FUNCTION)
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion flower-tools/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<groupId>com.github.xdcrafts</groupId>
<artifactId>flower</artifactId>
<relativePath>..</relativePath>
<version>1.3.3</version>
<version>1.3.4</version>
</parent>

<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,25 @@ public static <T> Optional<T> cast(final Object o, final Class<T> clazz) {
return Optional.ofNullable(result);
}

private static Class findAssignableAncestor(Class<?> from, Class<?> to) {
return Optional
.<Class>ofNullable(from.getSuperclass())
.filter(to::isAssignableFrom)
.orElse(
Arrays
.stream(from.getInterfaces())
.filter(to::isAssignableFrom)
.findFirst()
.orElse(null)
);
}

/**
* Calculates distance between from and to classes, counting from current.
*/
private static int classDistance(Class<?> from, Class<?> to, int current) {
return to.isAssignableFrom(from)
? to.equals(from) ? current : classDistance(from.getSuperclass(), to, current + 1)
? to.equals(from) ? current : classDistance(findAssignableAncestor(from, to), to, current + 1)
: -1;
}

Expand All @@ -99,24 +112,46 @@ public static int methodDistance(Method from, Method to) {
: -1;
}

/**
* Recursively collects all declared methods of the clazz and it's ancestors.
*/
public static Map<String, List<Method>> getDeclaredMethodsRecursively(Class clazz) {
final Map<String, List<Method>> current = Arrays
.stream(clazz.getDeclaredMethods())
.filter(m -> !m.getName().startsWith("lambda"))
.collect(Collectors.groupingBy(Method::getName));
for (Class interfaceClazz : clazz.getInterfaces()) {
getDeclaredMethodsRecursively(interfaceClazz).forEach(current::putIfAbsent);
}
if (clazz.getSuperclass() != null) {
getDeclaredMethodsRecursively(clazz.getSuperclass()).forEach(current::putIfAbsent);
}
return current;
}

/**
* Finds method with name, throws exception if no method found or there are many of them.
*/
public static Method findMethod(Class clazz, String methodName) {
final List<Method> methods = Arrays.stream(clazz.getDeclaredMethods())
.filter(m -> m.getName().equals(methodName))
.collect(Collectors.toList());
final List<Method> methods = getDeclaredMethodsRecursively(clazz).get(methodName);
if (methods.isEmpty()) {
throw new IllegalArgumentException(clazz.getName() + "::" + methodName + " not found");
}
final List<Method> specificMethods;
if (methods.size() > 1) {
specificMethods
= methods.stream().filter(m -> m.getReturnType() != Object.class).collect(Collectors.toList());
} else {
specificMethods = methods;
}
if (specificMethods.size() != 1) {
throw new IllegalArgumentException(
clazz.getName() + "::" + methodName
+ " more then one method found, can not decide which one to use. "
+ methods
);
}
return methods.get(0);
return specificMethods.get(0);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<groupId>com.github.xdcrafts</groupId>
<artifactId>flower</artifactId>
<packaging>pom</packaging>
<version>1.3.3</version>
<version>1.3.4</version>
<name>${project.groupId}:${project.artifactId}</name>
<description>Data-driven workflows with Java.</description>
<url>https://github.com/xdcrafts/flower</url>
Expand Down

0 comments on commit d632c26

Please sign in to comment.