diff --git a/pom.xml b/pom.xml
index 504c317..7eb0cd3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,6 +84,11 @@
commons-csv
${commons.csv.version}
+
+ com.google.code.gson
+ gson
+ 2.10.1
+
diff --git a/src/main/java/com/evolveum/polygon/connector/csv/CsvConfiguration.java b/src/main/java/com/evolveum/polygon/connector/csv/CsvConfiguration.java
index 5f11dc7..1e38112 100644
--- a/src/main/java/com/evolveum/polygon/connector/csv/CsvConfiguration.java
+++ b/src/main/java/com/evolveum/polygon/connector/csv/CsvConfiguration.java
@@ -197,6 +197,17 @@ public boolean isAuxiliary() {
return config.isAuxiliary();
}
+ @ConfigurationProperty(
+ displayMessageKey = "UI_CSV_GROUP_BY_ENABLED",
+ helpMessageKey = "UI_CSV_GROUP_BY_ENABLED_HELP")
+ public boolean isGroupByEnabled() {
+ return config.isGroupByEnabled();
+ }
+
+ public void setGroupByEnabled(boolean groupByEnabled) {
+ config.setGroupByEnabled(groupByEnabled);
+ }
+
public void setContainer(boolean container) {
config.setContainer(container);
}
diff --git a/src/main/java/com/evolveum/polygon/connector/csv/ObjectClassHandler.java b/src/main/java/com/evolveum/polygon/connector/csv/ObjectClassHandler.java
index 81ee89f..1d23f22 100644
--- a/src/main/java/com/evolveum/polygon/connector/csv/ObjectClassHandler.java
+++ b/src/main/java/com/evolveum/polygon/connector/csv/ObjectClassHandler.java
@@ -4,6 +4,7 @@
import com.evolveum.polygon.connector.csv.util.ConfigurationDetector;
import com.evolveum.polygon.connector.csv.util.StringAccessor;
import com.evolveum.polygon.connector.csv.util.Util;
+import com.google.gson.Gson;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVPrinter;
@@ -47,6 +48,7 @@ private enum Operation {
}
private static final Log LOG = Log.getLog(ObjectClassHandler.class);
+ private static final String ATTR_RAW_JSON = AttributeUtil.createSpecialName("RAW_JSON");
private ObjectClassHandlerConfiguration configuration;
@@ -260,6 +262,17 @@ private List createAttributeInfo(Map columns) {
infos.add(builder.build());
}
+ if (configuration.isGroupByEnabled()) {
+ AttributeInfoBuilder builder = new AttributeInfoBuilder(ATTR_RAW_JSON);
+ builder.setType(String.class);
+ builder.setNativeName(ATTR_RAW_JSON);
+ builder.setCreateable(false);
+ builder.setUpdateable(false);
+ builder.setSubtype(AttributeInfo.Subtypes.STRING_JSON);
+
+ infos.add(builder.build());
+ }
+
return infos;
}
@@ -434,6 +447,11 @@ public void executeQuery(ObjectClass oc, Filter filter, ResultsHandler handler,
CSVFormat csv = Util.createCsvFormatReader(configuration);
try (Reader reader = Util.createReader(configuration)) {
+ boolean shouldContinue = true;
+ List recordGroup = new ArrayList<>();
+ int uidIndex = this.getHeader().get(configuration.getUniqueAttribute()).getIndex();
+ String uid = extractUidFromFilter(filter);
+
CSVParser parser = csv.parse(reader);
Iterator iterator = parser.iterator();
while (iterator.hasNext()) {
@@ -442,13 +460,36 @@ public void executeQuery(ObjectClass oc, Filter filter, ResultsHandler handler,
continue;
}
- ConnectorObject obj = createConnectorObject(record);
+ ConnectorObject obj;
- String uid = extractUidFromFilter(filter);
+ if (configuration.isGroupByEnabled()) {
+ // Record group is empty, so push it then check next record
+ if (recordGroup.isEmpty()) {
+ recordGroup.add(record);
+ continue;
+ }
+ // If the current record has same uid with the current record group, push it then check next record
+ String currentUid = record.get(uidIndex);
+ String currentUidOfRecordGroup = recordGroup.get(0).get(uidIndex);
+ if (uidMatches(currentUid, currentUidOfRecordGroup, configuration.isIgnoreIdentifierCase())) {
+ recordGroup.add(record);
+ continue;
+ }
+
+ obj = createConnectorObject(recordGroup);
+
+ // Reset record group for next
+ recordGroup.clear();
+ recordGroup.add(record);
+
+ } else {
+ obj = createConnectorObject(record);
+ }
if (uid == null) {
if (filter == null || filter.accept(obj)) {
- if (!handler.handle(obj)) {
+ shouldContinue = handler.handle(obj);
+ if (!shouldContinue) {
break;
}
}
@@ -459,10 +500,31 @@ public void executeQuery(ObjectClass oc, Filter filter, ResultsHandler handler,
continue;
}
- if (!handler.handle(obj)) {
+ shouldContinue = handler.handle(obj);
+ if (!shouldContinue) {
break;
}
}
+
+ if (configuration.isGroupByEnabled()) {
+ // Handle remaining record group
+ if (shouldContinue && !recordGroup.isEmpty()) {
+ ConnectorObject obj = createConnectorObject(recordGroup);
+
+ if (uid == null) {
+ if (filter == null || filter.accept(obj)) {
+ handler.handle(obj);
+ }
+ return;
+ }
+
+ if (!uidMatches(uid, obj.getUid().getUidValue(), configuration.isIgnoreIdentifierCase())) {
+ return;
+ }
+
+ handler.handle(obj);
+ }
+ }
} catch (Exception ex) {
handleGenericException(ex, "Error during query execution");
}
@@ -934,7 +996,59 @@ private Map reverseHeaderMap() {
return reversed;
}
+ private ConnectorObject createConnectorObject(List recordGroup) {
+ Map header = reverseHeaderMap();
+ Set multivalueAttrs = StringUtil.isEmpty(configuration.getMultivalueAttributes()) || StringUtil.isEmpty(configuration.getMultivalueDelimiter()) ?
+ Collections.emptySet() : Set.of(configuration.getMultivalueAttributes().split(configuration.getMultivalueDelimiter()));
+
+ // Create base connectorObject using first record
+ ConnectorObjectBuilder builder = createConnectorObjectBuilder(recordGroup.get(0));
+
+ // Create rawJson and append to the connectorObject
+ List