You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by dr...@apache.org on 2016/04/26 18:45:00 UTC
incubator-unomi git commit: UNOMI-25 : Added segments names into
export
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 <dr...@apache.org>
Authored: Tue Apr 26 18:44:52 2016 +0200
Committer: Thomas Draier <dr...@apache.org>
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}"/>