diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/codecs/InstallCodec.java b/src/main/java/org/eclipsefoundation/marketplace/dto/codecs/InstallCodec.java index 0a6d3b706c858f3f2ee08c4241f0589b295c00b7..21099af74389b1c4f20ced2de0b59d5088ebdd57 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/dto/codecs/InstallCodec.java +++ b/src/main/java/org/eclipsefoundation/marketplace/dto/codecs/InstallCodec.java @@ -18,6 +18,7 @@ import org.bson.codecs.CollectibleCodec; import org.bson.codecs.DecoderContext; import org.bson.codecs.EncoderContext; import org.eclipsefoundation.marketplace.dto.Install; +import org.eclipsefoundation.marketplace.helper.JavaVersionHelper; import org.eclipsefoundation.marketplace.namespace.DatabaseFieldNames; import com.mongodb.MongoClient; @@ -45,7 +46,7 @@ public class InstallCodec implements CollectibleCodec<Install> { Document doc = new Document(); doc.put(DatabaseFieldNames.DOCID, value.getId()); - doc.put(DatabaseFieldNames.INSTALL_JAVA_VERSION, value.getJavaVersion()); + doc.put(DatabaseFieldNames.INSTALL_JAVA_VERSION, JavaVersionHelper.convertToDBSafe(value.getJavaVersion())); doc.put(DatabaseFieldNames.INSTALL_VERSION, value.getVersion()); doc.put(DatabaseFieldNames.INSTALL_LISTING_ID, value.getListingId()); doc.put(DatabaseFieldNames.INSTALL_DATE, value.getInstallDate()); @@ -65,7 +66,7 @@ public class InstallCodec implements CollectibleCodec<Install> { Document document = documentCodec.decode(reader, decoderContext); Install out = new Install(); out.setId(document.getString(DatabaseFieldNames.DOCID)); - out.setJavaVersion(document.getString(DatabaseFieldNames.INSTALL_JAVA_VERSION)); + out.setJavaVersion(JavaVersionHelper.convertToDisplayValue(document.getString(DatabaseFieldNames.INSTALL_JAVA_VERSION))); out.setVersion(document.getString(DatabaseFieldNames.INSTALL_VERSION)); out.setListingId(document.getString(DatabaseFieldNames.INSTALL_LISTING_ID)); out.setInstallDate(document.getDate(DatabaseFieldNames.INSTALL_DATE)); diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/converters/ListingVersionConverter.java b/src/main/java/org/eclipsefoundation/marketplace/dto/converters/ListingVersionConverter.java index bdc24152004a328f878170c4851df5dc9452bc36..bf6eb97243a89264d96253c361aa5faeff1e7294 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/dto/converters/ListingVersionConverter.java +++ b/src/main/java/org/eclipsefoundation/marketplace/dto/converters/ListingVersionConverter.java @@ -10,6 +10,7 @@ import java.util.stream.Collectors; import org.bson.Document; import org.eclipsefoundation.marketplace.dto.ListingVersion; +import org.eclipsefoundation.marketplace.helper.JavaVersionHelper; import org.eclipsefoundation.marketplace.namespace.DatabaseFieldNames; /** @@ -28,7 +29,7 @@ public class ListingVersionConverter implements Converter<ListingVersion> { version.setListingId(src.getString(DatabaseFieldNames.LISTING_ID)); version.setEclipseVersions(src.getList("compatible_versions", String.class)); version.setPlatforms(src.getList("platforms", String.class)); - version.setMinJavaVersion(src.getString("min_java_version")); + version.setMinJavaVersion(JavaVersionHelper.convertToDisplayValue(Integer.toString(src.getInteger("min_java_version")))); version.setUpdateSiteUrl(src.getString("update_site_url")); version.setVersion(src.getString("version")); version.setFeatureIds(src.getList(DatabaseFieldNames.FEATURE_IDS, Document.class).stream() @@ -43,7 +44,7 @@ public class ListingVersionConverter implements Converter<ListingVersion> { doc.put(DatabaseFieldNames.LISTING_ID, src.getListingId()); doc.put("compatible_versions", src.getEclipseVersions()); doc.put("platforms", src.getPlatforms()); - doc.put("min_java_version", src.getMinJavaVersion()); + doc.put("min_java_version", Integer.valueOf(JavaVersionHelper.convertToDBSafe(src.getMinJavaVersion()))); doc.put("update_site_url", src.getUpdateSiteUrl()); doc.put("version", src.getVersion()); doc.put(DatabaseFieldNames.FEATURE_IDS, diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/DtoFilter.java b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/DtoFilter.java index c2b2448b1e50769a68c4a777a0d155de2d95fad7..bb5d8e05a9cfa228241336aca7604afb710847f9 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/DtoFilter.java +++ b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/DtoFilter.java @@ -7,13 +7,12 @@ package org.eclipsefoundation.marketplace.dto.filter; import java.util.List; -import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; import org.bson.conversions.Bson; import org.eclipsefoundation.marketplace.model.RequestWrapper; import com.mongodb.client.model.Aggregates; +import com.mongodb.client.model.Filters; /** * Filter interface for usage when querying data. @@ -35,7 +34,7 @@ public interface DtoFilter<T> { /** * Retrieve aggregate filter operations for the current arguments. * - * @param wrap wrapper for the current request + * @param wrap wrapper for the current request * @return list of aggregates for the current request, or empty if there are no * applicable aggregates. */ @@ -58,18 +57,12 @@ public interface DtoFilter<T> { * @return a list of aggregate pipeline operations representing the filters for * the current request. */ - default List<Bson> wrapFiltersToAggregate(RequestWrapper wrap, String nestedPath) { - return getFilters(wrap, nestedPath).stream().map(Aggregates::match).collect(Collectors.toList()); - } - - /** - * - * @param root - * @param fieldName - * @return - */ - default String getPath(String root, String fieldName) { - return StringUtils.isBlank(root) ? fieldName : root + '.' + fieldName; + default Bson wrapFiltersToAggregate(RequestWrapper wrap, String nestedPath) { + List<Bson> filters = getFilters(wrap, nestedPath); + if (!filters.isEmpty()) { + return Aggregates.match(Filters.elemMatch(nestedPath, Filters.and(filters))); + } + return null; } /** diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/ListingFilter.java b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/ListingFilter.java index d773e722dcd49ff73772357fd0865474d2425329..1fc8d175309b924458a05deb3f8863697e6398a7 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/ListingFilter.java +++ b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/ListingFilter.java @@ -81,7 +81,10 @@ public class ListingFilter implements DtoFilter<Listing> { // adds a $lookup aggregate, joining categories on categoryIDS as "categories" aggs.add(Aggregates.lookup(DtoTableNames.LISTING_VERSION.getTableName(), DatabaseFieldNames.DOCID, DatabaseFieldNames.LISTING_ID, DatabaseFieldNames.LISTING_VERSIONS)); - aggs.addAll(listingVersionFilter.wrapFiltersToAggregate(wrap, DatabaseFieldNames.LISTING_VERSIONS)); + Bson filters = listingVersionFilter.wrapFiltersToAggregate(wrap, DatabaseFieldNames.LISTING_VERSIONS); + if (filters != null) { + aggs.add(filters); + } aggs.add(Aggregates.lookup(DtoTableNames.CATEGORY.getTableName(), DatabaseFieldNames.CATEGORY_IDS, DatabaseFieldNames.DOCID, DatabaseFieldNames.LISTING_CATEGORIES)); List<String> marketIds = wrap.getParams(UrlParameterNames.MARKET_IDS); diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/ListingVersionFilter.java b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/ListingVersionFilter.java index dc0560f7b4aabfaa27eb45faa3e70fce70d44c40..ddc414b1ea60595807964bb56ee204594740389e 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/ListingVersionFilter.java +++ b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/ListingVersionFilter.java @@ -13,6 +13,7 @@ import java.util.Optional; import javax.enterprise.context.ApplicationScoped; +import org.apache.commons.lang3.StringUtils; import org.bson.conversions.Bson; import org.eclipsefoundation.marketplace.dto.ListingVersion; import org.eclipsefoundation.marketplace.model.RequestWrapper; @@ -45,21 +46,19 @@ public class ListingVersionFilter implements DtoFilter<ListingVersion> { // solution version - OS filter Optional<String> os = wrap.getFirstParam(UrlParameterNames.OS); if (os.isPresent()) { - filters.add(Filters.eq(getPath(root, "platforms"), os.get())); + filters.add(Filters.eq("platforms", os.get())); } // solution version - eclipse version Optional<String> eclipseVersion = wrap.getFirstParam(UrlParameterNames.ECLIPSE_VERSION); if (eclipseVersion.isPresent()) { - filters.add(Filters.eq(getPath(root, "compatible_versions"), eclipseVersion.get())); + filters.add(Filters.eq("compatible_versions", eclipseVersion.get())); } - // TODO this sorts by naturally by character rather than by actual number (e.g. - // 1.9 is technically greater than 1.10) // solution version - Java version Optional<String> javaVersion = wrap.getFirstParam(UrlParameterNames.JAVA_VERSION); - if (javaVersion.isPresent()) { - filters.add(Filters.gte(getPath(root, "min_java_version"), javaVersion.get())); + if (javaVersion.isPresent() && StringUtils.isNumeric(javaVersion.get())) { + filters.add(Filters.gte("min_java_version", Integer.valueOf(javaVersion.get()))); } - + return filters; } diff --git a/src/main/java/org/eclipsefoundation/marketplace/helper/JavaVersionHelper.java b/src/main/java/org/eclipsefoundation/marketplace/helper/JavaVersionHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..4298f3a0ff81cd9a7d7b18930dc795ad030c7db0 --- /dev/null +++ b/src/main/java/org/eclipsefoundation/marketplace/helper/JavaVersionHelper.java @@ -0,0 +1,75 @@ +/* Copyright (c) 2019 Eclipse Foundation and others. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License 2.0 + * which is available at http://www.eclipse.org/legal/epl-v20.html, + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipsefoundation.marketplace.helper; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.StringUtils; + +/** + * Used to handle the conversion of Java versions to and from storage mediums. + * + * @author Martin Lowe + * + */ +public class JavaVersionHelper { + // checks retrieves both possible major versions in Java-version strings + private static final Pattern MAJOR_VERSION_CHECK = Pattern.compile("^(\\d+)\\.(\\d+)(?:\\.[\\d_]+){0,}"); + + /** + * Converts value to strip out parts of Java version string that cause issues + * with natural number sorting in databases. + * + * @param val the java version string to convert (e.g. 1.7, 10.0.1) + * @return modified and more sortable version string, or null if it doesn't + * match Java version strings + */ + public static final String convertToDBSafe(String val) { + String out = val; + if (StringUtils.isBlank(out)) { + return null; + } + // strip out the major Java version as it isn't useful. + Matcher m = MAJOR_VERSION_CHECK.matcher(out); + if (m.matches()) { + String majorVersion = m.group(1); + // if we have a major version of 1, this indicates old school java and we should + // use the second group as the product version + if ("1".equals(majorVersion)) { + out = m.group(2); + } else { + out = majorVersion; + } + return out; + } + return null; + } + + /** + * Converts the sortable DB value for the Java version to something more in line + * with what is expected by the user. + * + * @param val the sortable stored version string + * @return display value of the sortable Java version + */ + public static final String convertToDisplayValue(String val) { + String out = val; + if (StringUtils.isBlank(out) || !StringUtils.isNumeric(val)) { + return null; + } + // check that the is 5,6,7,8 before adding a "1." in front + if (val.equals("5") || val.equals("6") || val.equals("7") || val.equals("8")) { + // add major version of 1 to string + out = "1." + val; + } + return out; + } + + private JavaVersionHelper() { + } +} diff --git a/src/test/java/org/eclipsefoundation/marketplace/helper/JavaVersionHelperTest.java b/src/test/java/org/eclipsefoundation/marketplace/helper/JavaVersionHelperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b32ae4d25435b072dcbf512d3e8e0007b83a4296 --- /dev/null +++ b/src/test/java/org/eclipsefoundation/marketplace/helper/JavaVersionHelperTest.java @@ -0,0 +1,44 @@ +/* Copyright (c) 2019 Eclipse Foundation and others. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License 2.0 + * which is available at http://www.eclipse.org/legal/epl-v20.html, + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipsefoundation.marketplace.helper; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; + +/** + * Test class for {@linkplain JavaVersionHelper} + * + * @author Martin Lowe + */ +@QuarkusTest +public class JavaVersionHelperTest { + + @Test + public void testConvertToDBSafe() { + Assertions.assertEquals("7", JavaVersionHelper.convertToDBSafe("1.7")); + Assertions.assertEquals("7", JavaVersionHelper.convertToDBSafe("1.7.0_4")); + Assertions.assertEquals("8", JavaVersionHelper.convertToDBSafe("1.8.45")); + Assertions.assertEquals("8", JavaVersionHelper.convertToDBSafe("8.1.45")); + Assertions.assertEquals("11", JavaVersionHelper.convertToDBSafe("11.1.2")); + Assertions.assertEquals(null, JavaVersionHelper.convertToDBSafe("';DROP TABLES;")); + Assertions.assertEquals(null, JavaVersionHelper.convertToDBSafe(" ")); + Assertions.assertEquals(null, JavaVersionHelper.convertToDBSafe(null)); + } + @Test + public void testConvertToDisplayValue() { + Assertions.assertEquals("1.7", JavaVersionHelper.convertToDisplayValue("7")); + Assertions.assertEquals("1.8", JavaVersionHelper.convertToDisplayValue("8")); + Assertions.assertEquals("9", JavaVersionHelper.convertToDisplayValue("9")); + Assertions.assertEquals("11", JavaVersionHelper.convertToDisplayValue("11")); + Assertions.assertEquals(null, JavaVersionHelper.convertToDisplayValue("11.1")); + Assertions.assertEquals(null, JavaVersionHelper.convertToDisplayValue("';DROP TABLES;")); + Assertions.assertEquals(null, JavaVersionHelper.convertToDisplayValue(" ")); + Assertions.assertEquals(null, JavaVersionHelper.convertToDisplayValue(null)); + } +}