Repository: incubator-unomi Updated Branches: refs/heads/master a9c88997c -> 510ae898b
UNOMI-25 : Added segments names into export Project: http://git-wip-us.apache.org/repos/asf/incubator-unomi/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-unomi/commit/510ae898 Tree: http://git-wip-us.apache.org/repos/asf/incubator-unomi/tree/510ae898 Diff: http://git-wip-us.apache.org/repos/asf/incubator-unomi/diff/510ae898 Branch: refs/heads/master Commit: 510ae898bfe57e948c7d4c0b0b80f7f561217b5f Parents: a9c8899 Author: Thomas Draier <[email protected]> Authored: Tue Apr 26 18:44:52 2016 +0200 Committer: Thomas Draier <[email protected]> Committed: Tue Apr 26 18:44:52 2016 +0200 ---------------------------------------------------------------------- .../unomi/rest/ProfileServiceEndPoint.java | 29 ++++++--- .../services/services/ProfileServiceImpl.java | 65 +++++++++----------- .../resources/OSGI-INF/blueprint/blueprint.xml | 1 + 3 files changed, 50 insertions(+), 45 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/510ae898/rest/src/main/java/org/apache/unomi/rest/ProfileServiceEndPoint.java ---------------------------------------------------------------------- diff --git a/rest/src/main/java/org/apache/unomi/rest/ProfileServiceEndPoint.java b/rest/src/main/java/org/apache/unomi/rest/ProfileServiceEndPoint.java index 9557595..3241aac 100644 --- a/rest/src/main/java/org/apache/unomi/rest/ProfileServiceEndPoint.java +++ b/rest/src/main/java/org/apache/unomi/rest/ProfileServiceEndPoint.java @@ -118,11 +118,7 @@ public class ProfileServiceEndPoint { @Produces("text/csv") public Response getExportProfiles(@QueryParam("query") String query) { try { - Query queryObject = CustomObjectMapper.getObjectMapper().readValue(query, Query.class); - Response.ResponseBuilder response = Response.ok(profileService.exportProfilesPropertiesToCsv(queryObject)); - response.header("Content-Disposition", - "attachment; filename=Profiles_export_" + new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(new Date()) + ".csv"); - return response.build(); + return exportProfiles(CustomObjectMapper.getObjectMapper().readValue(query, Query.class)); } catch (IOException e) { logger.error(e.getMessage(), e); return Response.serverError().build(); @@ -141,11 +137,7 @@ public class ProfileServiceEndPoint { @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response formExportProfiles(@FormParam("query") String query) { try { - Query queryObject = CustomObjectMapper.getObjectMapper().readValue(query, Query.class); - Response.ResponseBuilder response = Response.ok(profileService.exportProfilesPropertiesToCsv(queryObject)); - response.header("Content-Disposition", - "attachment; filename=Profiles_export_" + new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(new Date()) + ".csv"); - return response.build(); + return exportProfiles(CustomObjectMapper.getObjectMapper().readValue(query, Query.class)); } catch (IOException e) { logger.error(e.getMessage(), e); return Response.serverError().build(); @@ -153,6 +145,23 @@ public class ProfileServiceEndPoint { } /** + * Retrieves an export of profiles matching the specified query as a downloadable file using the comma-separated values (CSV) format. + * + * @param query a String JSON representation of the query the profiles to export should match + * @return a Response object configured to allow caller to download the CSV export file + */ + @POST + @Path("/export") + @Produces("text/csv") + public Response exportProfiles(Query query) { + String toCsv = profileService.exportProfilesPropertiesToCsv(query); + Response.ResponseBuilder response = Response.ok(toCsv); + response.header("Content-Disposition", + "attachment; filename=Profiles_export_" + new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(new Date()) + ".csv"); + return response.build(); + } + + /** * Update all profiles in batch according to the specified {@link BatchUpdate} * * @param update the batch update specification http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/510ae898/services/src/main/java/org/apache/unomi/services/services/ProfileServiceImpl.java ---------------------------------------------------------------------- diff --git a/services/src/main/java/org/apache/unomi/services/services/ProfileServiceImpl.java b/services/src/main/java/org/apache/unomi/services/services/ProfileServiceImpl.java index a25fc44..177cb90 100644 --- a/services/src/main/java/org/apache/unomi/services/services/ProfileServiceImpl.java +++ b/services/src/main/java/org/apache/unomi/services/services/ProfileServiceImpl.java @@ -22,9 +22,11 @@ import org.apache.unomi.api.*; import org.apache.unomi.api.conditions.Condition; import org.apache.unomi.api.conditions.ConditionType; import org.apache.unomi.api.query.Query; +import org.apache.unomi.api.segments.Segment; import org.apache.unomi.api.services.DefinitionsService; import org.apache.unomi.api.services.ProfileService; import org.apache.unomi.api.services.QueryService; +import org.apache.unomi.api.services.SegmentService; import org.apache.unomi.persistence.spi.CustomObjectMapper; import org.apache.unomi.persistence.spi.PersistenceService; import org.apache.unomi.persistence.spi.PropertyHelper; @@ -47,6 +49,8 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList private DefinitionsService definitionsService; + private SegmentService segmentService; + private QueryService queryService; private ActionExecutorDispatcher actionExecutorDispatcher; @@ -79,6 +83,10 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList this.definitionsService = definitionsService; } + public void setSegmentService(SegmentService segmentService) { + this.segmentService = segmentService; + } + public void postConstruct() { logger.debug("postConstruct {" + bundleContext.getBundle() + "}"); @@ -296,9 +304,6 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList return filteredProperties; } - - // TODO: can be improve to use ES mappings directly to read the existing properties - @Override public String exportProfilesPropertiesToCsv(Query query) { StringBuilder sb = new StringBuilder(); Set<PropertyType> profileProperties = getExistingProperties("profileProperties", Profile.ITEM_TYPE); @@ -310,12 +315,9 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList for (int i = 0; i < propertyTypes.length; i++) { PropertyType propertyType = propertyTypes[i]; sb.append(propertyType.getMetadata().getId()); - if (i < propertyTypes.length - 1) { - sb.append(";"); - } else { - sb.append("\n"); - } + sb.append(";"); } + sb.append("segments\n"); // rows for (Profile profile : profiles.getList()) { @@ -328,14 +330,16 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList } else { sb.append(""); } - if (i < propertyTypes.length - 1) { - sb.append(";"); - } else { - sb.append("\n"); - } + sb.append(";"); + } + List<String> segmentNames = new ArrayList<String>(); + for (String segment : profile.getSegments()) { + Segment s = segmentService.getSegmentDefinition(segment); + segmentNames.add(csvEncode(s.getMetadata().getName())); } + sb.append(csvEncode(StringUtils.join(segmentNames, ","))); + sb.append('\n'); } - return sb.toString(); } @@ -343,30 +347,21 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList private void handleExportProperty(StringBuilder sb, Object propertyValue, PropertyType propertyType) { if (propertyValue instanceof Collection && propertyType.isMultivalued()) { Collection propertyValues = (Collection) propertyValue; - if (propertyValues.size() > 0) { - Object[] propertyValuesArray = propertyValues.toArray(); - for (int i = 0; i < propertyValuesArray.length; i++) { - Object o = propertyValuesArray[i]; - if (o instanceof String && i == 0) { - sb.append("\""); - } - sb.append(propertyValue.toString()); - if (o instanceof String && i == propertyValuesArray.length - 1) { - sb.append("\""); - } else { - sb.append(","); - } - } + Collection encodedValues = new ArrayList(propertyValues.size()); + for (Object value : propertyValues) { + encodedValues.add(csvEncode(value.toString())); } + sb.append(csvEncode(StringUtils.join(encodedValues, ","))); } else { - if (propertyValue instanceof String) { - sb.append("\""); - } - sb.append(propertyValue.toString()); - if (propertyValue instanceof String) { - sb.append("\""); - } + sb.append(csvEncode(propertyValue.toString())); + } + } + + private String csvEncode(String input) { + if (StringUtils.containsAny(input, '\n', '"', ',')) { + return "\"" + input.replace("\"","\"\"") + "\""; } + return input; } public PartialList<Profile> findProfilesByPropertyValue(String propertyName, String propertyValue, int offset, int size, String sortBy) { http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/510ae898/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml ---------------------------------------------------------------------- diff --git a/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml index ef28738..edee65f 100644 --- a/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -112,6 +112,7 @@ init-method="postConstruct" destroy-method="preDestroy"> <property name="persistenceService" ref="persistenceService"/> <property name="definitionsService" ref="definitionsServiceImpl"/> + <property name="segmentService" ref="segmentServiceImpl"/> <property name="queryService" ref="queryServiceImpl"/> <property name="bundleContext" ref="blueprintBundleContext"/> <property name="purgeProfileInterval" value="${services.profile.purge.interval}"/>
