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}"/>