remove ususage of jackson for json serialization or deserialization. Ensure that additional data set info is always passed back in array format.

This commit is contained in:
Keith Woodlock
2012-07-23 01:21:09 +01:00
parent 31433c2e72
commit ec18277080
8 changed files with 31 additions and 445 deletions
+2 -1
View File
@@ -49,7 +49,8 @@ configurations {
providedCompile
compile
runtime
all*.exclude group: 'commons-logging' // this is where we exclude
all*.exclude group: 'commons-logging'
all*.exclude group: 'org.codehaus.jackson'
}
dependencies {
@@ -9,9 +9,9 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.mifosng.platform.api.data.AuthenticatedUserData;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.user.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -32,11 +32,14 @@ public class AuthenticationApiResource {
@Qualifier("customAuthenticationProvider")
@Autowired
private DaoAuthenticationProvider customAuthenticationProvider;
@Autowired
private ApiDataConversionService apiDataConversionService;
@POST
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response authenticate(@QueryParam("username") final String username, @QueryParam("password") final String password) {
public String authenticate(@QueryParam("username") final String username, @QueryParam("password") final String password) {
Authentication authentication = new UsernamePasswordAuthenticationToken(username, password);
Authentication authenticationCheck = customAuthenticationProvider.authenticate(authentication);
@@ -56,9 +59,8 @@ public class AuthenticationApiResource {
authenticatedUserData.setUserId(principal.getId());
byte[] base64EncodedAuthenticationKey = Base64.encode(username + ":" + password);
authenticatedUserData.setBase64EncodedAuthenticationKey(new String(base64EncodedAuthenticationKey));
}
return Response.ok().entity(authenticatedUserData).build();
return this.apiDataConversionService.convertAuthenticatedUserDataToJson(false, authenticatedUserData);
}
}
@@ -1,46 +0,0 @@
package org.mifosng.platform.api.errorhandling;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import org.codehaus.jackson.map.exc.UnrecognizedPropertyException;
import org.mifosng.platform.api.data.ApiGlobalErrorResponse;
import org.mifosng.platform.api.data.ApiParameterError;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
* An {@link ExceptionMapper} to map {@link UnrecognizedPropertyException} thrown by platform into a HTTP API friendly format.
*
* The {@link UnrecognizedPropertyException} is typically thrown when a parameter is passed during and post or put that is not expected.
*/
@Provider
@Component
@Scope("singleton")
public class UnrecognizedPropertyExceptionMapper implements ExceptionMapper<UnrecognizedPropertyException> {
@Override
public Response toResponse(UnrecognizedPropertyException exception) {
String parameterName = exception.getUnrecognizedPropertyName();
StringBuilder validationErrorCode = new StringBuilder("error.msg.parameter.unsupported");
StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(parameterName).append(" is not supported.");
ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), parameterName, parameterName);
List<ApiParameterError> errors = new ArrayList<ApiParameterError>();
errors.add(error);
ApiGlobalErrorResponse invalidParameterError = ApiGlobalErrorResponse.badClientRequest(
"validation.msg.validation.errors.exist",
"Validation errors exist.", errors);
return Response.status(Status.BAD_REQUEST).entity(invalidParameterError).type(MediaType.APPLICATION_JSON).build();
}
}
@@ -9,7 +9,6 @@ import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import org.codehaus.jackson.map.exc.UnrecognizedPropertyException;
import org.mifosng.platform.api.data.ApiGlobalErrorResponse;
import org.mifosng.platform.api.data.ApiParameterError;
import org.mifosng.platform.exceptions.UnrecognizedQueryParamException;
@@ -17,9 +16,9 @@ import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
* An {@link ExceptionMapper} to map {@link UnrecognizedPropertyException} thrown by platform into a HTTP API friendly format.
* An {@link ExceptionMapper} to map {@link UnrecognizedQueryParamException} thrown by platform into a HTTP API friendly format.
*
* The {@link UnrecognizedPropertyException} is typically thrown when a parameter is passed during and post or put that is not expected.
* The {@link UnrecognizedQueryParamException} is typically thrown when a parameter is passed during and post or put that is not expected.
*/
@Provider
@Component
@@ -17,6 +17,7 @@ import org.mifosng.platform.api.commands.SubmitLoanApplicationCommand;
import org.mifosng.platform.api.commands.UserCommand;
import org.mifosng.platform.api.data.AdditionalFieldsSetData;
import org.mifosng.platform.api.data.AppUserData;
import org.mifosng.platform.api.data.AuthenticatedUserData;
import org.mifosng.platform.api.data.ClientData;
import org.mifosng.platform.api.data.ClientLoanAccountSummaryCollectionData;
import org.mifosng.platform.api.data.ConfigurationData;
@@ -63,6 +64,8 @@ public interface ApiDataConversionService {
String convertAdditionalFieldsSetDataToJson(boolean prettyPrint, AdditionalFieldsSetData... additionalFields);
String convertGenericResultsetDataToJson(boolean prettyPrint, GenericResultsetData result);
String convertAuthenticatedUserDataToJson(boolean prettyPrint, AuthenticatedUserData authenticatedUserData);
//
FundCommand convertJsonToFundCommand(Long resourceIdentifier, String json);
@@ -34,6 +34,7 @@ import org.mifosng.platform.api.commands.UserCommand;
import org.mifosng.platform.api.data.AdditionalFieldsSetData;
import org.mifosng.platform.api.data.ApiParameterError;
import org.mifosng.platform.api.data.AppUserData;
import org.mifosng.platform.api.data.AuthenticatedUserData;
import org.mifosng.platform.api.data.ClientData;
import org.mifosng.platform.api.data.ClientLoanAccountSummaryCollectionData;
import org.mifosng.platform.api.data.ConfigurationData;
@@ -72,6 +73,20 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
public ApiDataConversionServiceImpl() {
gsonConverter = new Gson();
}
@Override
public String convertAuthenticatedUserDataToJson(final boolean prettyPrint, final AuthenticatedUserData authenticatedUserData) {
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(LocalDate.class, new JodaLocalDateAdapter());
builder.registerTypeAdapter(DateTime.class, new JodaDateTimeAdapter());
if (prettyPrint) {
builder.setPrettyPrinting();
}
Gson gsonDeserializer = builder.create();
return gsonDeserializer.toJson(authenticatedUserData);
}
@Override
public String convertGenericResultsetDataToJson(final boolean prettyPrint, final GenericResultsetData result) {
@@ -97,14 +112,8 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
}
Gson gsonDeserializer = builder.create();
String json = "";
if (additionalFields != null && additionalFields.length == 1) {
json = gsonDeserializer.toJson(additionalFields[0]);
} else {
json = gsonDeserializer.toJson(additionalFields);
}
return json;
// even if only a single result, its passed back as an array.
return gsonDeserializer.toJson(additionalFields);
}
@Override
@@ -1,19 +0,0 @@
package org.mifosng.platform.api.infrastructure;
import javax.ws.rs.core.MultivaluedMap;
/**
* Removed in favour of using google gson within {@link ApiDataConversionService}.
*/
@Deprecated
public interface ApiJSONFormattingService {
String convertRequest(Object dataObject, String filterName,
String allowedFieldList, String selectedFields,
MultivaluedMap<String, String> queryParams);
String convertRequest(Object dataObject, String filterName,
String allowedFieldList, String selectedFields,
String associationFields, MultivaluedMap<String, String> queryParams);
}
@@ -1,363 +0,0 @@
package org.mifosng.platform.api.infrastructure;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
import javax.ws.rs.core.MultivaluedMap;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;
import org.codehaus.jackson.map.ser.FilterProvider;
import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter;
import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider;
import org.mifosng.platform.exceptions.PlatformInternalServerException;
/**
*
*/
@Deprecated
public class ApiJSONFormattingServiceImpl implements ApiJSONFormattingService {
@Override
public String convertRequest(Object dataObject, String filterName,
String allowedFieldList, String selectedFields,
MultivaluedMap<String, String> queryParams) {
String associationFields = "";
return convertRequestCommon(dataObject, filterName, allowedFieldList,
selectedFields, associationFields, queryParams);
}
@Override
public String convertRequest(Object dataObject, String filterName,
String allowedFieldList, String selectedFields,
String associationFields, MultivaluedMap<String, String> queryParams) {
return convertRequestCommon(dataObject, filterName, allowedFieldList,
selectedFields, associationFields, queryParams);
}
private String convertRequestCommon(Object dataObject, String filterName,
String allowedFieldList, String selectedFields,
String associationFields, MultivaluedMap<String, String> queryParams) {
// filterType E means Exclude : has the effect of returning all fields
// in the dataObject but can only be used if selectedFields is "" and
// there is no fields query parameter
// filterType I means Include : used when a specific list of fields is
// to be returned.
String filterType = "E";
String fieldList = "";
String fields = queryParams.getFirst("fields");
if (isPassed(fields) || (!(selectedFields.equals("")))) {
filterType = "I";
if (isPassed(fields)) {
if (selectedFields.equals(""))
fieldList = fields;
else {
Set<String> paramFieldsSet = createSetFromString(fields);
Set<String> selectedFieldsSet = createSetFromString(selectedFields);
fieldList = createIncludedInStringList(paramFieldsSet,
selectedFieldsSet);
}
} else {
fieldList = selectedFields;
}
}
fieldList = updateListForTemplate(fieldList, allowedFieldList,
queryParams.getFirst("template"), filterType);
fieldList = updateListForAssociations(fieldList, associationFields,
queryParams.getFirst("associations"), filterType);
return convertDataObjectJSON(dataObject, filterName, filterType,
fieldList, isTrue(queryParams.getFirst("pretty")));
}
private String updateListForTemplate(String fieldList,
String allowedFieldList, String param, String filterType) {
if (isTrue(param)) {
if (filterType.equals("I")) {
return fieldList + "," + allowedFieldList;
}
return fieldList;
}
// No template query param provided
if (filterType.equals("E")) {
fieldList = allowedFieldList; // exclude
}
return fieldList;
}
private String updateListForAssociations(String fieldList,
String associationFields, String param, String filterType) {
if (isPassed(param)) {
// logger.info("is associations");
if (param.equalsIgnoreCase("ALL")) {
// logger.info("is ALL");
if (filterType.equals("I")) {
// logger.info("is Include");
return fieldList + "," + associationFields;
}
// logger.info("is Exclude");
return fieldList;
}
// logger.info("Not ALL");
Set<String> fullAssociationsSet = createSetFromString(associationFields);
Set<String> paramAssociationsSet = createSetFromString(param);
if (filterType.equals("I")) {
String selectedAssociationFields = createIncludedInStringList(
paramAssociationsSet, fullAssociationsSet);
// logger.info("is Include - selected fields are :"
// + selectedAssociationFields);
return fieldList + "," + selectedAssociationFields;
}
String unSelectedAssociationFields = createNotIncludedInStringList(
fullAssociationsSet, paramAssociationsSet);
// logger.info("is Exclude - unselected fields are :"
// + unSelectedAssociationFields);
if (fieldList.equals("")) {
return unSelectedAssociationFields;
}
return fieldList + "," + unSelectedAssociationFields;
}
// No association parameter provided
// If Exclude - then add the list of associationFields to the original
// fieldList
// If filter is Include just return the original fieldList value
if (filterType.equals("E")) {
if (fieldList.equals("")) {
return associationFields;
}
return fieldList + "," + associationFields;
}
return fieldList;
}
private String convertDataObjectJSON(Object dataObject, String filterName,
String filterType, String fields, boolean prettyOutput) {
try {
FilterProvider filters = buildFilter(filterName, filterType, fields);
ObjectWriter jsonWriter = null;
if (prettyOutput) {
jsonWriter = new ObjectMapper()
.writerWithDefaultPrettyPrinter();
} else {
jsonWriter = new ObjectMapper().writer();
}
return jsonWriter.withFilters(filters).writeValueAsString(
dataObject);
} catch (JsonGenerationException e) {
throw new PlatformInternalServerException(
"error.msg.platform.json.generation",
"An error occured whilst generating response from the platform server.",
e.getMessage(), e.getStackTrace());
} catch (JsonMappingException e) {
throw new PlatformInternalServerException(
"error.msg.platform.json.generation",
"An error occured whilst generating response from the platform server.",
e.getMessage(), e.getStackTrace());
} catch (IOException e) {
throw new PlatformInternalServerException(
"error.msg.platform.json.generation",
"An error occured whilst generating response from the platform server.",
e.getMessage(), e.getStackTrace());
}
}
private FilterProvider buildFilter(String filterName, String filterType,
String fields) {
FilterProvider filters = null;
Set<String> filterFields = new HashSet<String>();
StringTokenizer st = new StringTokenizer(fields, ",");
while (st.hasMoreTokens()) {
filterFields.add(st.nextToken().trim());
}
if (filterName.equals("loanFilter")) {
Set<String> loanRepaymentFields = new HashSet<String>();
if (filterType.equals("I")) {
return new SimpleFilterProvider().addFilter(
filterName,
SimpleBeanPropertyFilter
.filterOutAllExcept(filterFields)).addFilter(
"loanRepaymentFilter",
SimpleBeanPropertyFilter
.serializeAllExcept(loanRepaymentFields));
}
return new SimpleFilterProvider().addFilter(filterName,
SimpleBeanPropertyFilter.serializeAllExcept(filterFields))
.addFilter(
"loanRepaymentFilter",
SimpleBeanPropertyFilter
.serializeAllExcept(loanRepaymentFields));
}
if ((filterName.equals("loanRepaymentFilter"))
|| (filterName.equals("myFilter"))
|| (filterName.equals("permissionFilter"))) {
if (filterType.equals("I")) {
return new SimpleFilterProvider().addFilter(filterName,
SimpleBeanPropertyFilter
.filterOutAllExcept(filterFields));
}
return new SimpleFilterProvider().addFilter(filterName,
SimpleBeanPropertyFilter.serializeAllExcept(filterFields));
}
if (filterName.equals("roleFilter")) {
Set<String> permissionFields = new HashSet<String>();
if (filterType.equals("I")) {
return new SimpleFilterProvider().addFilter(
filterName,
SimpleBeanPropertyFilter
.filterOutAllExcept(filterFields)).addFilter(
"permissionFilter",
SimpleBeanPropertyFilter
.serializeAllExcept(permissionFields));
}
return new SimpleFilterProvider().addFilter(filterName,
SimpleBeanPropertyFilter.serializeAllExcept(filterFields))
.addFilter(
"permissionFilter",
SimpleBeanPropertyFilter
.serializeAllExcept(permissionFields));
}
if (filterName.equals("userFilter")) {
Set<String> roleFields = new HashSet<String>();
Set<String> permissionFields = new HashSet<String>();
if (filterType.equals("I")) {
return new SimpleFilterProvider()
.addFilter(
filterName,
SimpleBeanPropertyFilter
.filterOutAllExcept(filterFields))
.addFilter(
"roleFilter",
SimpleBeanPropertyFilter
.serializeAllExcept(roleFields))
.addFilter(
"permissionFilter",
SimpleBeanPropertyFilter
.serializeAllExcept(permissionFields));
}
return new SimpleFilterProvider()
.addFilter(
filterName,
SimpleBeanPropertyFilter
.serializeAllExcept(filterFields))
.addFilter(
"roleFilter",
SimpleBeanPropertyFilter
.serializeAllExcept(roleFields))
.addFilter(
"permissionFilter",
SimpleBeanPropertyFilter
.serializeAllExcept(permissionFields));
}
return filters;
}
private Set<String> createSetFromString(String string) {
Set<String> set = new HashSet<String>();
StringTokenizer st = new StringTokenizer(string, ",");
while (st.hasMoreTokens()) {
set.add(st.nextToken().trim());
}
return set;
}
private String createIncludedInStringList(Set<String> candidates,
Set<String> matchAgainst) {
String stringList = "";
Boolean first = true;
for (String candidate : candidates) {
if (matchAgainst.contains(candidate)) {
if (first) {
stringList = candidate;
first = false;
} else {
stringList += "," + candidate;
}
}
}
return stringList;
}
private String createNotIncludedInStringList(Set<String> candidates,
Set<String> matchAgainst) {
String stringList = "";
Boolean first = true;
for (String candidate : candidates) {
if (!(matchAgainst.contains(candidate))) {
if (first) {
stringList = candidate;
first = false;
} else {
stringList += "," + candidate;
}
}
}
return stringList;
}
private Boolean isTrue(String param) {
if (param != null && param.equalsIgnoreCase("true"))
return true;
return false;
}
private Boolean isPassed(String param) {
if (param == null || param.equals(""))
return false;
return true;
}
}