| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.tinkerpop.gremlin.structure.io; |
| |
| import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONCompatibility; |
| import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoCompatibility; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.regex.Pattern; |
| import java.util.stream.Collectors; |
| |
| /** |
| * @author Stephen Mallette (http://stephen.genoprime.com) |
| */ |
| public class Compatibilities { |
| |
| public static final Compatibilities GRYO_ONLY = Compatibilities.with(GryoCompatibility.class); |
| |
| public static final Compatibilities UNTYPED_GRAPHSON = Compatibilities.with(GraphSONCompatibility.class) |
| .configuredAs(".*no-types|v1d0"); |
| |
| private final Class<? extends Enum<? extends Compatibility>> compatibility; |
| |
| /** |
| * Initialized to 4.0.0 which is non-existent, but obviously the high-end of whatever would be tested. |
| */ |
| private String releaseVersionBefore = "4.0.0"; |
| |
| /** |
| * Initialized to 3.0.0 which is non-existent, but obviously the low-end of whatever would be tested. |
| */ |
| private String releaseVersionAfter = "3.0.0"; |
| |
| /** |
| * Initialized to 0.0 which is non-existent, but obviously the low-end of whatever would be tested. |
| */ |
| private String ioVersionBefore = "4.0"; |
| |
| /** |
| * Initialized to 3.0 which is non-existent, but obviously the high-end of whatever would be tested. |
| */ |
| private String ioVersionAfter = "0.0"; |
| |
| private String configuredAs = ".*"; |
| |
| private List<Compatibilities> compatibilitiesToJoin = Collections.emptyList(); |
| |
| private Compatibilities(final Class<? extends Enum<? extends Compatibility>> c) { |
| this.compatibility = c; |
| } |
| |
| public static Compatibilities with(final Class<? extends Enum<? extends Compatibility>> c) { |
| return new Compatibilities(c); |
| } |
| |
| /** |
| * Finds {@link Compatibility} instances before (and not inclusive of) the specified version. |
| */ |
| public Compatibilities beforeRelease(final String before) { |
| this.releaseVersionBefore = before; |
| return this; |
| } |
| |
| /** |
| * Finds {@link Compatibility} instances after (and not inclusive of) the specified version. |
| */ |
| public Compatibilities afterRelease(final String after) { |
| this.releaseVersionAfter = after; |
| return this; |
| } |
| |
| /** |
| * Finds {@link Compatibility} instances between (and not inclusive of) the specified versions. |
| */ |
| public Compatibilities betweenReleases(final String start, final String end) { |
| return beforeRelease(end).afterRelease(start); |
| } |
| |
| /** |
| * Finds {@link Compatibility} instances before (and not inclusive of) the specified version. |
| */ |
| public Compatibilities before(final String before) { |
| this.ioVersionBefore = before; |
| return this; |
| } |
| |
| /** |
| * Finds {@link Compatibility} instances after (and not inclusive of) the specified version. |
| */ |
| public Compatibilities after(final String after) { |
| this.ioVersionAfter = after; |
| return this; |
| } |
| |
| /** |
| * Finds {@link Compatibility} instances between (and not inclusive of) the specified versions. |
| */ |
| public Compatibilities between(final String start, final String end) { |
| return before(end).after(start); |
| } |
| |
| public Compatibilities configuredAs(final String regex) { |
| this.configuredAs = regex; |
| return this; |
| } |
| |
| public Compatibilities join(final Compatibilities... compatibilities) { |
| this.compatibilitiesToJoin = Arrays.asList(compatibilities); |
| return this; |
| } |
| |
| public List<Compatibility> match() { |
| final Compatibility[] enumArray = (Compatibility[]) compatibility.getEnumConstants(); |
| final List<Compatibility> enums = Arrays.asList(enumArray); |
| final Pattern pattern = Pattern.compile(configuredAs); |
| |
| final List<Compatibility> thisMatch = enums.stream() |
| .filter(c -> beforeRelease(c, releaseVersionBefore)) |
| .filter(c -> afterRelease(c, releaseVersionAfter)) |
| .filter(c -> beforeIo(c, ioVersionBefore)) |
| .filter(c -> afterIo(c, ioVersionAfter)) |
| .filter(c -> pattern.matcher(c.getConfiguration()).matches()) |
| .collect(Collectors.toList()); |
| final List<Compatibility> matches = new ArrayList<>(thisMatch); |
| compatibilitiesToJoin.forEach(c -> matches.addAll(c.match())); |
| return matches; |
| } |
| |
| public Compatibility[] matchToArray() { |
| final List<Compatibility> list = match(); |
| final Compatibility [] compatibilities = new Compatibility[list.size()]; |
| list.toArray(compatibilities); |
| return compatibilities; |
| } |
| |
| private static boolean afterRelease(final Compatibility version, final String after) { |
| return versionCompare(version.getReleaseVersion(), after) > 0; |
| } |
| |
| private static boolean beforeRelease(final Compatibility version, final String before) { |
| return versionCompare(version.getReleaseVersion(), before) < 0; |
| } |
| |
| private static boolean afterIo(final Compatibility version, final String after) { |
| return versionCompare(version.getVersion(), after) > 0; |
| } |
| |
| private static boolean beforeIo(final Compatibility version, final String before) { |
| return versionCompare(version.getVersion(), before) < 0; |
| } |
| |
| /** |
| * @return The result is a negative integer if v1 is less than v2. |
| * The result is a positive integer if v1 is greater than v2. |
| * The result is zero if the strings are equal. |
| */ |
| private static int versionCompare(final String v1, final String v2) { |
| final String[] vals1 = v1.split("\\."); |
| final String[] vals2 = v2.split("\\."); |
| int i = 0; |
| |
| // set index to first non-equal ordinal or length of shortest version string |
| while (i < vals1.length && i < vals2.length && vals1[i].equals(vals2[i])) { |
| i++; |
| } |
| |
| // compare first non-equal ordinal number |
| if (i < vals1.length && i < vals2.length) { |
| int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i])); |
| return Integer.signum(diff); |
| } |
| |
| // the strings are equal or one string is a substring of the other |
| // e.g. "1.2.3" = "1.2.3" or "1.2.3" < "1.2.3.4" |
| return Integer.signum(vals1.length - vals2.length); |
| } |
| } |