Skip to content

Commit c57698b

Browse files
committed
added README
1 parent b6a292d commit c57698b

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

README

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Command4j
2+
3+
### ABOUT
4+
Command4j is a general-purpose command framework for Java (>= 7).
5+
It lets you program custom interceptors (wrappers, filters), and handle cross-cutting concerns.
6+
7+
### USE CASE EXAMPLES
8+
9+
A good example is calling a remote web service. By putting the call itself into a command,
10+
command4j offers a couple of built-in extensions to deal with situations such as:
11+
12+
* logging
13+
* failover/retry
14+
* exception translation
15+
* enforce timeout
16+
17+
18+
### BASE CONCEPTS
19+
20+
##### Command
21+
22+
The command is the code to be executed. It can get an optional argument A and
23+
can return a result R. (If more than one argument must be passed to the command,
24+
an aggregator argument containing the others must be used.)
25+
26+
Commands can be chained: Execute command 1, take the result, feed it to command 2, return (and such).
27+
28+
##### Mode
29+
30+
The mode contains definitions that apply to a whole execution of a command, and is usually
31+
used for executing many commands.
32+
33+
##### CommandExecutor
34+
35+
The executor can execute a command directly. And it can create a CommandExecutorService, which
36+
can run commands concurrently.
37+
38+
##### ModeExtension
39+
40+
Such extensions allow it to wrap the Command. This allows for executing code before, after or
41+
around each command. An example is a logging extension that informs before and after each execution.
42+
43+
44+
45+
### CODE EXAMPLES
46+
47+
##### Command with Timeout
48+
49+
//a command that sleeps 100ms, then returns null.
50+
Command<Void, Void> command = new Command<Void, Void>() {
51+
@Nullable @Override
52+
public Void call(@NotNull Optional<Void> arg, @NotNull ExecutionContext ec) throws Exception {
53+
Thread.sleep(100);
54+
return null;
55+
}
56+
};
57+
//wrap the command with the timeout extension and allow max 500ms:
58+
command = TimeoutExtensions.withTimeout(command, Duration.millis(500));
59+
CommandExecutor executor = new CommandExecutorBuilder().build();
60+
executor.execute(cmd, Mode.create(), null); //works, 100 is less than 500
61+
62+
63+
##### Exception Translation
64+
65+
//a command that throws
66+
Command<Void, Void> command = new Command<Void, Void>() {
67+
@Nullable @Override
68+
public Void call(@NotNull Optional<Void> arg, @NotNull ExecutionContext ec) throws Exception {
69+
throw new UnsupportedOperationException("Nah, can't do!");
70+
}
71+
};
72+
//some exception translator impl
73+
ExceptionTranslator myExceptionTranslator = new ExceptionTranslator() {
74+
@Override
75+
public boolean canTranslate(@NotNull Throwable t) {
76+
return t instanceof UnsupportedOperationException;
77+
}
78+
@NotNull @Override
79+
public Exception translate(@NotNull Throwable t) throws Exception {
80+
throw new MyException("Translated", t);
81+
}
82+
};
83+
//creating an executor that features translation:
84+
CommandExecutor exceptionTranslationExecutor = new CommandExecutorBuilder()
85+
.withExtension(new ExceptionTranslationExtension())
86+
.build();
87+
//enabling my translator in the mode:
88+
Mode mode = Mode.create().with(ExceptionTranslationExtension.TRANSLATOR, myExceptionTranslator);
89+
exceptionTranslationExecutor.command(cmd, mode, null);
90+
91+
92+
##### Using an Executor Service
93+
94+
CommandExecutor commandExecutor = new CommandExecutorBuilder()
95+
//put in my extensions
96+
//.withExtension(...)
97+
.build();
98+
ExecutorService javaExecutor = Executors.newFixedThreadPool(numThreads);
99+
CommandExecutorService executorService = commandExecutor.service(javaExecutor);
100+
Command<Void,Void> command = new Sleep(100);
101+
for (int i=0; i<999; i++) {
102+
ListenableFuture<Optional<Void>> submit = executorService.submit(cmd, mode, null);
103+
}
104+
105+
106+
> For these and more examples see the unit tests.
107+
108+
109+
110+
### DEPENDENCIES
111+
112+
##### Guava (usually the latest version)
113+
For the `Optional` class, and the `ListeningExecutorService`, and probably some more.
114+
115+
##### org.slf4j slf4j-api
116+
For the `Logger` interface.
117+
118+
##### com.intellij annotations
119+
For the `@Nullable` and `@NotNull` annotations
120+
121+
122+
### STATE
123+
124+
Command4j has been in development and use for long time internally at Optimaize, and is now published on GitHub.
125+
The interfaces and classes are well documented, and there is a fair amount of unit tests.
126+
127+
### AUTHORS
128+
129+
Command4j was prototyped and written in large parts by Eike Kettner.

0 commit comments

Comments
 (0)