My task is to write a program to store files in object store. One of the subtasks requires to send json or xml format response to the file uploader/downloader as requested by client.
The following rules must be followed:
entry +-------------------------+ v v upload download +-----------+ +--------------+ v v v v succ err succ err +-----+ +-----+ +-----+ v v v v v v json1 xml1 json2 xml2 josn2 xml2
- if user uploads file with success, return json/xml type 1
- if user uploads file with error, return json/xml type 2
- if user downloads file with success, don't change return object
- if user downloads file with error, return json/xml type 2
I've managed to solve the task but I'm not satisfied with the class dependencies and nested if/else
-s I have. I think mixture of abstract factory and strategy are suitable for the issue. Can you give me a hint on how I can deal with the problem?
My code snippet:
public Result upload(HttpServletRequest request) {
UploadRequestParams uploadParams = UploadRequestParams.getObjectFrom(request);
... // create info object
Result res = handleUploadRequest(uploadParams);
Result result = jsonXml(info, res);
return result;
}
private Result jsonXml(RequestInfo info, Result result) {
Serializer ser;
if ("xml".equals(format)) {
ser = new XmlSerializer();
} else {
ser = new JsonSerializer();
}
Result res = ser.serialize(info, result);
return res;
}
@Override
public Result serialize(RequestInfo info, Result result) { // json implementation
GsonBuilder builder = new GsonBuilder();
Gson g = builder.create();
InputStream stream = null;
InfoInterface wrap;
if (info.isUpload()) {
if (result.isValid()) {
wrap = new InfoWrapperImpl1(info, result);
} else {
wrap = new InfoWrapperImpl2(info, result);
}
} else {
wrap = new InfoWrapperImpl1(info, result);
}
String res = g.toJson(wrap);
stream = new ByteArrayInputStream(res.getBytes(StandardCharsets.UTF_8));
Result newRes = Result.getBuilder().setInputStream(stream).setResultCode(result.getResultCode()).build();
return newRes;
}
private class InfoWrapperImpl1 implements InfoInterface {
private String fileName;
private ResultCode code;
public InfoWrapper1(RequestInfo info, Result res) {
this.fileName = info.getUniqueName();
this.code = res.getCode;
}
}
UML class diagram:
EDIT
I rewrote serialize method, but looks like to be bound to the parameters' implementation. Am I right? On the other, I got rid of the ugly nested classes.
@Override
public Result serialize(RequestInfo info, Result result) {
JsonObject body = new JsonObject();
JsonObject resultCode = new JsonObject();
resultCode.addProperty("code", result.getResultCode().getCode());
resultCode.addProperty("value", result.getResultCode().getDescription());
if (info.isUploadRequest() && result.isValid()) {
body.addProperty(fileTag, info.getExtendedName());
body.addProperty("checksum", result.getMySwiftObject().getEtag());
}
body.add(statusTag, resultCode);
String jsonRes = body.toString();
InputStream stream = new ByteArrayInputStream(jsonRes.getBytes(StandardCharsets.UTF_8));
return Result.getBuilder().setInputStream(stream).setResultCode(result.getResultCode()).build();
}