diff --git a/src/main/java/io/ebean/DRawSqlColumnsParser.java b/src/main/java/io/ebean/DRawSqlColumnsParser.java index 3848d4131..4439585fe 100644 --- a/src/main/java/io/ebean/DRawSqlColumnsParser.java +++ b/src/main/java/io/ebean/DRawSqlColumnsParser.java @@ -2,6 +2,7 @@ package io.ebean; import io.ebean.RawSql.ColumnMapping; +import java.util.regex.Pattern; import javax.persistence.PersistenceException; import java.util.ArrayList; @@ -10,6 +11,8 @@ import java.util.ArrayList; */ final class DRawSqlColumnsParser { + private static final Pattern COLINFO_SPLIT = Pattern.compile("\\s(?=[^\\)]*(?:\\(|$))"); + private final int end; private final String sqlSelect; @@ -44,7 +47,7 @@ final class DRawSqlColumnsParser { String colInfo = sqlSelect.substring(start, pos++); colInfo = colInfo.trim(); - String[] split = colInfo.split("\\s(?=[^\\)]*(?:\\(|$))"); + String[] split = COLINFO_SPLIT.split(colInfo); if (split.length > 1) { ArrayList tmp = new ArrayList<>(split.length); for (String aSplit : split) { diff --git a/src/main/java/io/ebean/config/AbstractNamingConvention.java b/src/main/java/io/ebean/config/AbstractNamingConvention.java index 6c2ca3f46..b435d2e46 100644 --- a/src/main/java/io/ebean/config/AbstractNamingConvention.java +++ b/src/main/java/io/ebean/config/AbstractNamingConvention.java @@ -2,6 +2,8 @@ package io.ebean.config; import io.ebean.config.dbplatform.DatabasePlatform; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.persistence.DiscriminatorValue; import javax.persistence.Inheritance; import javax.persistence.Table; @@ -14,16 +16,15 @@ import java.lang.annotation.Annotation; */ public abstract class AbstractNamingConvention implements NamingConvention { + private static final Pattern TABLE_REPLACE = Pattern.compile("{table}", Pattern.LITERAL); + + private static final Pattern COLUMN_REPLACE = Pattern.compile("{column}", Pattern.LITERAL); + /** * The Constant DEFAULT_SEQ_FORMAT. */ public static final String DEFAULT_SEQ_FORMAT = "{table}_seq"; - /** - * Sequence Format that includes the Primary Key column - */ - public static final String TABLE_PKCOLUMN_SEQ_FORMAT = "{table}_{column}_seq"; - /** * The catalog. */ @@ -83,11 +84,11 @@ public abstract class AbstractNamingConvention implements NamingConvention { @Override public String getSequenceName(String tableName, String pkColumn) { - String s = sequenceFormat.replace("{table}", tableName); + String s = TABLE_REPLACE.matcher(sequenceFormat).replaceAll(Matcher.quoteReplacement(tableName)); if (pkColumn == null) { pkColumn = ""; } - return s.replace("{column}", pkColumn); + return COLUMN_REPLACE.matcher(s).replaceAll(Matcher.quoteReplacement(pkColumn)); } /** diff --git a/src/main/java/io/ebean/config/PropertyMapLoader.java b/src/main/java/io/ebean/config/PropertyMapLoader.java index 52c232527..7444de7fe 100644 --- a/src/main/java/io/ebean/config/PropertyMapLoader.java +++ b/src/main/java/io/ebean/config/PropertyMapLoader.java @@ -1,5 +1,7 @@ package io.ebean.config; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,6 +20,8 @@ final class PropertyMapLoader { private static final Logger logger = LoggerFactory.getLogger(PropertyMapLoader.class); + private static final Pattern OTHER_PROPS_REPLACE = Pattern.compile("\\", Pattern.LITERAL); + /** * Load the test-ebean.properties. */ @@ -109,7 +113,7 @@ final class PropertyMapLoader { otherProps = p.remove("load.properties.override"); } if (otherProps != null) { - otherProps = otherProps.replace("\\", "/"); + otherProps = OTHER_PROPS_REPLACE.matcher(otherProps).replaceAll(Matcher.quoteReplacement("/")); InputStream is = findInputStream(otherProps); if (is != null) { logger.debug("loading properties from {}", otherProps); diff --git a/src/main/java/io/ebean/config/ServerConfig.java b/src/main/java/io/ebean/config/ServerConfig.java index 3ed209411..1504f3463 100644 --- a/src/main/java/io/ebean/config/ServerConfig.java +++ b/src/main/java/io/ebean/config/ServerConfig.java @@ -27,6 +27,7 @@ import io.ebean.event.changelog.ChangeLogRegister; import io.ebean.event.readaudit.ReadAuditLogger; import io.ebean.event.readaudit.ReadAuditPrepare; import io.ebean.meta.MetaInfoManager; +import java.util.regex.Pattern; import org.avaje.datasource.DataSourceConfig; import javax.sql.DataSource; @@ -75,6 +76,8 @@ import java.util.ServiceLoader; */ public class ServerConfig { + private static final Pattern NAMES_SPLIT = Pattern.compile("[ ,;]"); + /** * The EbeanServer name. */ @@ -2633,7 +2636,7 @@ public class ServerConfig { List> classes = new ArrayList<>(); - String[] split = classNames.split("[ ,;]"); + String[] split = NAMES_SPLIT.split(classNames); for (String aSplit : split) { String cn = aSplit.trim(); if (!cn.isEmpty() && !"class".equalsIgnoreCase(cn)) { @@ -2654,7 +2657,7 @@ public class ServerConfig { if (searchPackages != null) { - String[] entries = searchPackages.split("[ ,;]"); + String[] entries = NAMES_SPLIT.split(searchPackages); for (String entry : entries) { hitList.add(entry.trim()); } diff --git a/src/main/java/io/ebean/config/dbplatform/DbIdentity.java b/src/main/java/io/ebean/config/dbplatform/DbIdentity.java index 2b53acb20..9102a6ecb 100644 --- a/src/main/java/io/ebean/config/dbplatform/DbIdentity.java +++ b/src/main/java/io/ebean/config/dbplatform/DbIdentity.java @@ -1,12 +1,16 @@ package io.ebean.config.dbplatform; import io.ebean.dbmigration.migration.IdentityType; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Defines the identity/sequence behaviour for the database. */ public class DbIdentity { + private static final Pattern TABLE_REPLACE = Pattern.compile("{table}", Pattern.LITERAL); + /** * Set if this DB supports sequences. Note some DB's support both Sequences * and Identity. @@ -50,7 +54,8 @@ public class DbIdentity { if (selectLastInsertedIdTemplate == null) { return null; } - return selectLastInsertedIdTemplate.replace("{table}", table); + + return TABLE_REPLACE.matcher(selectLastInsertedIdTemplate).replaceAll(Matcher.quoteReplacement(table)); } /** diff --git a/src/main/java/io/ebean/config/dbplatform/sqlserver/SqlServerPlatform.java b/src/main/java/io/ebean/config/dbplatform/sqlserver/SqlServerPlatform.java index c874a429e..3ef2a2e0b 100644 --- a/src/main/java/io/ebean/config/dbplatform/sqlserver/SqlServerPlatform.java +++ b/src/main/java/io/ebean/config/dbplatform/sqlserver/SqlServerPlatform.java @@ -2,9 +2,12 @@ package io.ebean.config.dbplatform.sqlserver; import io.ebean.PersistBatch; import io.ebean.Platform; -import io.ebean.config.dbplatform.*; +import io.ebean.config.dbplatform.DatabasePlatform; +import io.ebean.config.dbplatform.DbPlatformType; +import io.ebean.config.dbplatform.DbType; +import io.ebean.config.dbplatform.IdType; +import io.ebean.config.dbplatform.SqlErrorCodes; import io.ebean.dbmigration.ddlgeneration.platform.SqlServerDdl; - import java.sql.Types; /** diff --git a/src/main/java/io/ebean/dbmigration/model/MigrationVersion.java b/src/main/java/io/ebean/dbmigration/model/MigrationVersion.java index 6cad47b2a..1a3206f26 100644 --- a/src/main/java/io/ebean/dbmigration/model/MigrationVersion.java +++ b/src/main/java/io/ebean/dbmigration/model/MigrationVersion.java @@ -1,12 +1,15 @@ package io.ebean.dbmigration.model; import java.util.Arrays; +import java.util.regex.Pattern; /** * The version of a migration used so that migrations are processed in order. */ public class MigrationVersion implements Comparable { + private static final Pattern SECTION_SPLITTER = Pattern.compile("[\\.-]"); + private static final int[] REPEAT_ORDERING = {Integer.MAX_VALUE}; private static final boolean[] REPEAT_UNDERSCORES = {false}; @@ -169,7 +172,7 @@ public class MigrationVersion implements Comparable { value = value.replace('_', '.'); - String[] sections = value.split("[\\.-]"); + String[] sections = SECTION_SPLITTER.split(value); if ("r".equalsIgnoreCase(sections[0])) { // a "repeatable" version (does not have a version number) diff --git a/src/main/java/io/ebeaninternal/extraddl/model/ExtraDdlXmlReader.java b/src/main/java/io/ebeaninternal/extraddl/model/ExtraDdlXmlReader.java index 51ef82590..5cc7611de 100644 --- a/src/main/java/io/ebeaninternal/extraddl/model/ExtraDdlXmlReader.java +++ b/src/main/java/io/ebeaninternal/extraddl/model/ExtraDdlXmlReader.java @@ -1,5 +1,6 @@ package io.ebeaninternal.extraddl.model; +import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,6 +16,8 @@ public class ExtraDdlXmlReader { private static final Logger logger = LoggerFactory.getLogger(ExtraDdlXmlReader.class); + private static final Pattern PLATFORM_REGEX_SPLIT = Pattern.compile("[,;]"); + /** * Return the combined extra DDL that should be run given the platform name. */ @@ -44,7 +47,8 @@ public class ExtraDdlXmlReader { if (platforms == null || platforms.trim().isEmpty()) { return true; } - String[] names = platforms.split("[,;]"); + + String[] names = PLATFORM_REGEX_SPLIT.split(platforms); for (String name : names) { if (name.trim().toLowerCase().contains(platformName)) { return true; diff --git a/src/main/java/io/ebeaninternal/server/core/bootup/ManifestReader.java b/src/main/java/io/ebeaninternal/server/core/bootup/ManifestReader.java index 25dc60dab..58970c9cd 100644 --- a/src/main/java/io/ebeaninternal/server/core/bootup/ManifestReader.java +++ b/src/main/java/io/ebeaninternal/server/core/bootup/ManifestReader.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.core.bootup; +import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,6 +22,8 @@ class ManifestReader { private final Set packageSet = new HashSet<>(); + private static final Pattern PACKAGE_DELIMITER = Pattern.compile("[,; ]"); + /** * Read the packages from ebean.mf manifest files found as resources. */ @@ -73,7 +76,7 @@ class ManifestReader { * Collect each individual package splitting by delimiters. */ private void add(String packages) { - String[] split = packages.split("[,; ]"); + String[] split = PACKAGE_DELIMITER.split(packages); for (String aSplit : split) { String pkg = aSplit.trim(); if (!pkg.isEmpty()) { diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeAlias.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeAlias.java index 31fc7fab3..95cf4a671 100644 --- a/src/main/java/io/ebeaninternal/server/query/SqlTreeAlias.java +++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeAlias.java @@ -3,6 +3,8 @@ package io.ebeaninternal.server.query; import io.ebeaninternal.server.deploy.BeanDescriptor; import io.ebeaninternal.server.el.ElPropertyDeploy; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.persistence.PersistenceException; import java.util.HashMap; import java.util.HashSet; @@ -15,6 +17,8 @@ import java.util.TreeSet; */ class SqlTreeAlias { + private static final Pattern TABLE_ALIAS_REPLACE = Pattern.compile("${}", Pattern.LITERAL); + private int counter; private int manyWhereCounter; @@ -178,9 +182,9 @@ class SqlTreeAlias { private String parseRootAlias(String clause) { if (rootTableAlias == null) { - return clause.replace("${}", ""); + return TABLE_ALIAS_REPLACE.matcher(clause).replaceAll(""); } else { - return clause.replace("${}", rootTableAlias + "."); + return TABLE_ALIAS_REPLACE.matcher(clause).replaceAll(Matcher.quoteReplacement(rootTableAlias + ".")); } } diff --git a/src/main/java/io/ebeaninternal/server/querydefn/OrmUpdateProperties.java b/src/main/java/io/ebeaninternal/server/querydefn/OrmUpdateProperties.java index 8c7980882..3b2b913e0 100644 --- a/src/main/java/io/ebeaninternal/server/querydefn/OrmUpdateProperties.java +++ b/src/main/java/io/ebeaninternal/server/querydefn/OrmUpdateProperties.java @@ -9,6 +9,7 @@ import java.sql.SQLException; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; +import java.util.regex.Pattern; /** * Set properties for a UpdateQuery. @@ -19,6 +20,8 @@ public class OrmUpdateProperties { private static final NoneValue NONE_VALUE = new NoneValue(); + private static final Pattern TABLE_ALIAS_REPLACE = Pattern.compile("${}", Pattern.LITERAL); + /** * Bind value used in the set clause for update query. * It may/may not have bind values etc. @@ -188,8 +191,9 @@ public class OrmUpdateProperties { if (setCount++ > 0) { sb.append(", "); } + // translate to db columns and remove table alias placeholders - sb.append(deployParser.parse(property).replace("${}", "")); + sb.append(TABLE_ALIAS_REPLACE.matcher(deployParser.parse(property)).replaceAll("")); sb.append(entry.getValue().bindClause()); } return sb.toString(); diff --git a/src/main/java/io/ebeaninternal/server/type/ConvertInetAddresses.java b/src/main/java/io/ebeaninternal/server/type/ConvertInetAddresses.java index 02d03f91f..cf028c81a 100644 --- a/src/main/java/io/ebeaninternal/server/type/ConvertInetAddresses.java +++ b/src/main/java/io/ebeaninternal/server/type/ConvertInetAddresses.java @@ -21,6 +21,8 @@ import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Rob Bygrave: This is a copy of the google guava InetAddresses class @@ -115,6 +117,10 @@ public final class ConvertInetAddresses { private static final int IPV4_PART_COUNT = 4; private static final int IPV6_PART_COUNT = 8; + public static final String DOUBLE_COLON = "::"; + + private static final Pattern IPSTRING_REPLACE = Pattern.compile(DOUBLE_COLON, Pattern.LITERAL); + private ConvertInetAddresses() { } @@ -186,7 +192,7 @@ public final class ConvertInetAddresses { // handle IPv6 forms of IPv4 addresses if (ipString.toUpperCase(Locale.US).startsWith("::FFFF:")) { ipString = ipString.substring(7); - } else if (ipString.startsWith("::")) { + } else if (ipString.startsWith(DOUBLE_COLON)) { ipString = ipString.substring(2); isIpv6 = true; } @@ -260,13 +266,14 @@ public final class ConvertInetAddresses { // Fill in any omitted colons private static String padIpString(String ipString) { - if (ipString.contains("::")) { + if (ipString.contains(DOUBLE_COLON)) { int count = numberOfColons(ipString); - StringBuilder buffer = new StringBuilder("::"); + StringBuilder buffer = new StringBuilder(DOUBLE_COLON); for (int i = 0; i + count < 7; i++) { buffer.append(":"); } - ipString = ipString.replace("::", buffer); + + ipString = IPSTRING_REPLACE.matcher(ipString).replaceAll(Matcher.quoteReplacement(buffer.toString())); } return ipString; }