Having a class like this:
@Transactional
@RestController("check/health")
public class ServerHealthIcons {
/**
* The entitymanager to use, never <code>null</code>.
*/
@PersistenceContext
private final EntityManager entityManager = null;
@GetMapping("bad/{shcid}.png")
public void bad(@PathVariable long shcid, HttpServletRequest request, HttpServletResponse response)
throws IOException {
ServerHealthCheck shc = entityManager.find(ServerHealthCheck.class, shcid);
byte[] iconPng = shc.getBadIconPng();
response.setContentLength(iconPng.length);
response.setContentType("image/png");
ServletOutputStream out = response.getOutputStream();
out.write(iconPng);
out.close();
}
@GetMapping("warn/{shcid}.png")
public void warn(@PathVariable long shcid, HttpServletRequest request, HttpServletResponse response)
throws IOException {
ServerHealthCheck shc = entityManager.find(ServerHealthCheck.class, shcid);
byte[] iconPng = shc.getBadIconPng();
response.setContentLength(iconPng.length);
response.setContentType("image/png");
ServletOutputStream out = response.getOutputStream();
out.write(iconPng);
out.close();
}
@GetMapping("good/{shcid}.png")
public void good(@PathVariable long shcid, HttpServletRequest request, HttpServletResponse response)
throws IOException {
ServerHealthCheck shc = entityManager.find(ServerHealthCheck.class, shcid);
byte[] iconPng = shc.getGoodIconPng();
response.setContentLength(iconPng.length);
response.setContentType("image/png");
ServletOutputStream out = response.getOutputStream();
out.write(iconPng);
out.close();
}
}
We have about 3 times the mostly exact same method body.
The only difference is the initialization of the iconPng-variable. So we have to extract the iconPng initialization first.
This is the Menu:
Unfortunately we can only extract as
- Local variable
- Method
What I miss here is the possibility to extract the variable to a lamda-function.
The extraction should only be available for one input and one output (two input for BiFunction if you like, consumer, supplier respectievly).
This should the extraction create:
This Line:
byte[] iconPng = shc.getBadIconPng();
Should be extracted to this line:
Function<ServerHealthCheck, byte[]> supply = ServerHealthCheck::getBadIconPng;
byte[] iconPng = supply.apply(shc);
As soon as the FR is implemented, it will be an ease to transform the code above to this:
@Transactional
@RestController("check/health")
public class ServerHealthIcons {
/**
* The entitymanager to use, never <code>null</code>.
*/
@PersistenceContext
private final EntityManager entityManager = null;
@GetMapping("bad/{shcid}.png")
public void bad(@PathVariable long shcid, HttpServletRequest request, HttpServletResponse response)
throws IOException {
extracted(shcid, response, ServerHealthCheck::getBadIconPng);
}
@GetMapping("warn/{shcid}.png")
public void warn(@PathVariable long shcid, HttpServletRequest request, HttpServletResponse response)
throws IOException {
extracted(shcid, response, ServerHealthCheck::getWarningIconPng);
}
@GetMapping("good/{shcid}.png")
public void good(@PathVariable long shcid, HttpServletRequest request, HttpServletResponse response)
throws IOException {
extracted(shcid, response, ServerHealthCheck::getGoodIconPng);
}
private void extracted(long shcid, HttpServletResponse response, Function<ServerHealthCheck, byte[]> supply)
throws IOException {
ServerHealthCheck shc = entityManager.find(ServerHealthCheck.class, shcid);
byte[] iconPng = supply.apply(shc);
response.setContentLength(iconPng.length);
response.setContentType("image/png");
ServletOutputStream out = response.getOutputStream();
out.write(iconPng);
out.close();
}
}
Thanks.