Skip to content

Commit

Permalink
fix: Backport fix csv duplicate column name [Backport] (#4032)
Browse files Browse the repository at this point in the history
* fix: Fixed CSV import with duplicate column name (#4031)

Signed-off-by: Nicola Timeus <nicola.timeus@eurotech.com>

* chore: updated web bundle and distrib versions

Signed-off-by: Maiero <matteo.maiero@eurotech.com>

Co-authored-by: nicolatimeus <nicola.timeus@eurotech.com>
  • Loading branch information
MMaiero and nicolatimeus committed Jun 24, 2022
1 parent 2b0a8f7 commit ac0ba18
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 29 deletions.
2 changes: 1 addition & 1 deletion kura/distrib/config/kura.build.properties
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ org.eclipse.kura.raspberrypi.sensehat.version=1.1.1
org.eclipse.kura.raspberrypi.sensehat.example.version=1.1.1
org.eclipse.kura.example.wire.math.singleport.provider.version=1.1.1
org.eclipse.kura.example.wire.math.multiport.provider.version=1.1.1
org.eclipse.kura.web2.version=2.1.1
org.eclipse.kura.web2.version=2.1.2
org.eclipse.kura.wire.camel.version=1.1.1
org.eclipse.kura.wire.component.provider.version=1.1.1
org.eclipse.kura.wire.h2db.component.provider.version=2.1.1
Expand Down
2 changes: 1 addition & 1 deletion kura/org.eclipse.kura.web2/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: org.eclipse.kura.web2
Bundle-SymbolicName: org.eclipse.kura.web2;singleton:=true
Bundle-Version: 2.1.2.qualifier
Bundle-Version: 2.1.2
Bundle-Vendor: Eclipse Kura
Bundle-License: Eclipse Public License v2.0
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Expand Down
4 changes: 2 additions & 2 deletions kura/org.eclipse.kura.web2/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</parent>

<artifactId>org.eclipse.kura.web2</artifactId>
<version>2.1.2-SNAPSHOT</version>
<version>2.1.2</version>
<packaging>eclipse-plugin</packaging>

<properties>
Expand All @@ -40,7 +40,7 @@
<dependency>
<groupId>org.eclipse.kura</groupId>
<artifactId>org.eclipse.kura.web2.ext</artifactId>
<version>1.1.2-SNAPSHOT</version>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

Expand Down Expand Up @@ -66,53 +69,110 @@ private void fillLists(List<Tad> metatypes, List<String> properties, String driv
}));
}

private static class ColumnHeaderInfo {

String name;
int totalOccurrenceCount;
int occurrenceIndex;

public ColumnHeaderInfo(String name, int totalOccurrenceCount, int occurrenceIndex) {
this.name = name;
this.totalOccurrenceCount = totalOccurrenceCount;
this.occurrenceIndex = occurrenceIndex;
}
}

private class LineScanner {

private final List<Tad> adsByIndex;
private final List<GwtConfigParameter> defaultValues;

public LineScanner(final List<Tad> fullChannelMetatype, final List<String> columnHeaders) {
public LineScanner(final List<Tad> fullChannelMetatype, final List<String> columnHeaders)
throws ValidationException {
this.adsByIndex = probeAdsByIndex(fullChannelMetatype, columnHeaders);
this.defaultValues = probeDefaultValues(fullChannelMetatype, columnHeaders);
this.defaultValues = probeDefaultValues(fullChannelMetatype, this.adsByIndex);
}

private List<Tad> probeAdsByIndex(final List<Tad> fullChannelMetatype, final List<String> columnHeaders) {
final List<Tad> result = new ArrayList<>();

for (final String h : columnHeaders) {
final Optional<Tad> exactMatch = fullChannelMetatype.stream().filter(p -> h.equals(p.getId()))
.findAny();
private <T> Optional<T> findLast(final Collection<T> collection, final Predicate<T> predicate) {
Optional<T> result = Optional.empty();

if (exactMatch.isPresent()) {
result.add(exactMatch.get());
continue;
for (final T item : collection) {
if (predicate.test(item)) {
result = Optional.of(item);
}
}

final String assetId = "+" + h;
return result;
}

final Optional<Tad> assetParam = fullChannelMetatype.stream().filter(p -> assetId.equals(p.getId()))
.findAny();
private <T> Optional<T> findFirst(final Collection<T> collection, final Predicate<T> predicate) {

if (assetParam.isPresent()) {
result.add(assetParam.get());
} else {
throw new IllegalStateException("Unknown parameter name " + h);
for (final T item : collection) {
if (predicate.test(item)) {
return Optional.of(item);
}
}

return Optional.empty();
}

private List<ColumnHeaderInfo> getColumnHeaderInfo(final List<String> columnHeaders) {
final Map<String, Integer> occurrenceCount = new HashMap<>();
final List<ColumnHeaderInfo> result = new ArrayList<>();

for (final String columnHeader : columnHeaders) {
final int index = occurrenceCount.merge(columnHeader, 0, (o, n) -> o + 1);
result.add(new ColumnHeaderInfo(columnHeader, 0, index));
}

for (final ColumnHeaderInfo info : result) {
info.totalOccurrenceCount = occurrenceCount.get(info.name) + 1;
}

return result;
}

private List<GwtConfigParameter> probeDefaultValues(final List<Tad> fullChannelMetatype,
final List<String> columnHeaders) {
final List<Tad> missing = fullChannelMetatype.stream().filter(c -> {
if (c.getId().startsWith("+")) {
return !columnHeaders.contains(c.getId().substring(1));
private List<Tad> probeAdsByIndex(final List<Tad> fullChannelMetatype, final List<String> columnHeaders)
throws ValidationException {
final List<Tad> result = new ArrayList<>();
final List<ColumnHeaderInfo> headerInfo = getColumnHeaderInfo(columnHeaders);

for (final ColumnHeaderInfo header : headerInfo) {

final Optional<Tad> boundAd;

if (header.totalOccurrenceCount == 1) {
// we have a single column with the given name, try to associate it with the last matching Driver or
// Asset AD
boundAd = findLast(fullChannelMetatype,
ad -> ad.getId().equals(header.name) || ad.getId().equals("+" + header.name));
} else if (header.totalOccurrenceCount == 2 && header.occurrenceIndex == 0) {
// we have two columns with the given name in CSV file, associate the first CSV column with the
// first Asset configuration parameter
boundAd = findFirst(fullChannelMetatype, ad -> ad.getId().equals("+" + header.name));
} else if (header.totalOccurrenceCount == 2 && header.occurrenceIndex == 1) {
// we have two columns with the given name, associate the second CSV column with the last Driver
// configuration parameter
boundAd = findLast(fullChannelMetatype, ad -> ad.getId().equals(header.name));
} else {
return !columnHeaders.contains(c.getId());
throw new ValidationException("CSV contains more than two columns with the same name");
}

}).collect(Collectors.toList());
if (boundAd.isPresent()) {
result.add(boundAd.get());
} else {
throw new ValidationException("Cannot find an AD for column " + header.name);
}
}

return result;
}

private List<GwtConfigParameter> probeDefaultValues(final List<Tad> fullChannelMetatype,
final List<Tad> boundAds) {
final List<Tad> missing = fullChannelMetatype.stream()
.filter(c -> boundAds.stream().noneMatch(b -> b.getId().equals(c.getId())))
.collect(Collectors.toList());

final List<GwtConfigParameter> result = new ArrayList<>();

Expand Down Expand Up @@ -310,6 +370,13 @@ protected class ValidationException extends Exception {

private static final long serialVersionUID = 5954147929480218028L;

public ValidationException() {
}

public ValidationException(final String message) {
super(message);
}

}

private abstract class GwtValue<T> {
Expand Down

0 comments on commit ac0ba18

Please sign in to comment.