Repository: cassandra
Updated Branches:
  refs/heads/trunk 869bdabf4 -> 01d26dd3f


Replace trivial uses of String.replace/replaceAll/split with StringUtils methods

patch by Alexander Shopov; reviewed by Robert Stupp for CASSANDRA-8755


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/01d26dd3
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/01d26dd3
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/01d26dd3

Branch: refs/heads/trunk
Commit: 01d26dd3fc35a6b22a538f75545b0d9b739ee48d
Parents: 869bdab
Author: Alexander Shopov <li...@kambanaria.org>
Authored: Mon Jan 4 22:33:44 2016 +0100
Committer: Robert Stupp <sn...@snazy.de>
Committed: Mon Jan 4 22:33:44 2016 +0100

----------------------------------------------------------------------
 .../org/apache/cassandra/config/CFMetaData.java |  9 ++-
 .../cassandra/config/DatabaseDescriptor.java    |  6 +-
 .../apache/cassandra/cql3/ColumnIdentifier.java |  5 +-
 .../statements/CreateKeyspaceStatement.java     |  5 +-
 .../cql3/statements/CreateTableStatement.java   |  6 +-
 .../cql3/statements/PropertyDefinitions.java    |  5 +-
 .../db/commitlog/CommitLogArchiver.java         | 18 ++++--
 .../db/commitlog/CommitLogReplayer.java         |  2 +-
 .../db/marshal/AbstractCompositeType.java       |  9 ++-
 .../apache/cassandra/db/marshal/TupleType.java  | 18 +++++-
 .../index/internal/CassandraIndex.java          |  7 ++-
 .../metrics/CassandraMetricsRegistry.java       | 16 ++++-
 .../apache/cassandra/schema/IndexMetadata.java  | 11 +++-
 .../cassandra/service/StorageService.java       |  4 +-
 .../cassandra/utils/CassandraVersion.java       |  6 +-
 .../apache/cassandra/config/CFMetaDataTest.java | 20 +++++++
 .../config/DatabaseDescriptorTest.java          | 15 +++++
 .../cassandra/cql3/ColumnIdentifierTest.java    | 19 ++++++
 .../statements/PropertyDefinitionsTest.java     | 61 ++++++++++++++++++++
 .../db/marshal/AbstractCompositeTypeTest.java   | 35 +++++++++++
 .../metrics/CassandraMetricsRegistryTest.java   | 34 +++++++++++
 .../cassandra/schema/IndexMetadataTest.java     | 36 ++++++++++++
 .../cassandra/utils/CassandraVersionTest.java   | 51 +++++++++++++++-
 23 files changed, 363 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/config/CFMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java 
b/src/java/org/apache/cassandra/config/CFMetaData.java
index 128255c..ffa55c3 100644
--- a/src/java/org/apache/cassandra/config/CFMetaData.java
+++ b/src/java/org/apache/cassandra/config/CFMetaData.java
@@ -25,6 +25,7 @@ import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -69,6 +70,8 @@ public final class CFMetaData
         SUPER, COUNTER, DENSE, COMPOUND
     }
 
+    private static final Pattern PATTERN_WORD_CHARS = Pattern.compile("\\w+");
+
     private static final Logger logger = 
LoggerFactory.getLogger(CFMetaData.class);
 
     public static final Serializer serializer = new Serializer();
@@ -830,9 +833,9 @@ public final class CFMetaData
         return columnMetadata.get(name);
     }
 
-    public static boolean isNameValid(String name)
-    {
-        return name != null && !name.isEmpty() && name.length() <= 
Schema.NAME_LENGTH && name.matches("\\w+");
+    public static boolean isNameValid(String name) {
+        return name != null && !name.isEmpty()
+                && name.length() <= Schema.NAME_LENGTH && 
PATTERN_WORD_CHARS.matcher(name).matches();
     }
 
     public CFMetaData validate() throws ConfigurationException

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java 
b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index edcbcf5..3fc0b31 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -54,9 +54,9 @@ import org.apache.cassandra.scheduler.NoScheduler;
 import org.apache.cassandra.security.EncryptionContext;
 import org.apache.cassandra.service.CacheService;
 import org.apache.cassandra.thrift.ThriftServer;
-import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.utils.FBUtilities;
 import org.apache.cassandra.utils.memory.*;
+import org.apache.commons.lang3.StringUtils;
 
 public class DatabaseDescriptor
 {
@@ -927,8 +927,8 @@ public class DatabaseDescriptor
     {
         List<String> tokens = new ArrayList<String>();
         if (tokenString != null)
-            for (String token : tokenString.split(","))
-                tokens.add(token.replaceAll("^\\s+", "").replaceAll("\\s+$", 
""));
+            for (String token : StringUtils.split(tokenString, ','))
+                tokens.add(token.trim());
         return tokens;
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/cql3/ColumnIdentifier.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/ColumnIdentifier.java 
b/src/java/org/apache/cassandra/cql3/ColumnIdentifier.java
index 93734e9..74d0d28 100644
--- a/src/java/org/apache/cassandra/cql3/ColumnIdentifier.java
+++ b/src/java/org/apache/cassandra/cql3/ColumnIdentifier.java
@@ -46,7 +46,8 @@ import org.apache.cassandra.utils.memory.AbstractAllocator;
 public class ColumnIdentifier extends Selectable implements IMeasurableMemory, 
Comparable<ColumnIdentifier>
 {
     private static final Pattern PATTERN_DOUBLE_QUOTE = Pattern.compile("\"", 
Pattern.LITERAL);
-
+    private static final String ESCAPED_DOUBLE_QUOTE = 
Matcher.quoteReplacement("\"\"");
+    
     public final ByteBuffer bytes;
     private final String text;
     /**
@@ -332,6 +333,6 @@ public class ColumnIdentifier extends Selectable implements 
IMeasurableMemory, C
     {
         if (UNQUOTED_IDENTIFIER.matcher(text).matches())
             return text;
-        return '"' + 
PATTERN_DOUBLE_QUOTE.matcher(text).replaceAll(Matcher.quoteReplacement("\"\"")) 
+ '"';
+        return '"' + 
PATTERN_DOUBLE_QUOTE.matcher(text).replaceAll(ESCAPED_DOUBLE_QUOTE) + '"';
     }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java 
b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
index 3eb0ac9..86754b6 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
@@ -17,6 +17,7 @@
  */
 package org.apache.cassandra.cql3.statements;
 
+import java.util.regex.Pattern;
 import org.apache.cassandra.auth.*;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.config.Schema;
@@ -31,6 +32,8 @@ import org.apache.cassandra.transport.Event;
 /** A <code>CREATE KEYSPACE</code> statement parsed from a CQL query. */
 public class CreateKeyspaceStatement extends SchemaAlteringStatement
 {
+    private static final Pattern PATTERN_WORD_CHARS = Pattern.compile("\\w+");
+
     private final String name;
     private final KeyspaceAttributes attrs;
     private final boolean ifNotExists;
@@ -73,7 +76,7 @@ public class CreateKeyspaceStatement extends 
SchemaAlteringStatement
         ThriftValidation.validateKeyspaceNotSystem(name);
 
         // keyspace name
-        if (!name.matches("\\w+"))
+        if (!PATTERN_WORD_CHARS.matcher(name).matches())
             throw new InvalidRequestException(String.format("\"%s\" is not a 
valid keyspace name", name));
         if (name.length() > Schema.NAME_LENGTH)
             throw new InvalidRequestException(String.format("Keyspace names 
shouldn't be more than %s characters long (got \"%s\")", Schema.NAME_LENGTH, 
name));

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java 
b/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
index c19f970..debb200 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
@@ -19,7 +19,7 @@ package org.apache.cassandra.cql3.statements;
 
 import java.nio.ByteBuffer;
 import java.util.*;
-
+import java.util.regex.Pattern;
 import com.google.common.collect.HashMultiset;
 import com.google.common.collect.Multiset;
 import org.apache.commons.lang3.StringUtils;
@@ -41,6 +41,8 @@ import org.apache.cassandra.transport.Event;
 /** A {@code CREATE TABLE} parsed from a CQL query statement. */
 public class CreateTableStatement extends SchemaAlteringStatement
 {
+    private static final Pattern PATTERN_WORD_CHARS = Pattern.compile("\\w+");
+
     private List<AbstractType<?>> keyTypes;
     private List<AbstractType<?>> clusteringTypes;
 
@@ -202,7 +204,7 @@ public class CreateTableStatement extends 
SchemaAlteringStatement
         public ParsedStatement.Prepared prepare(Types udts) throws 
RequestValidationException
         {
             // Column family name
-            if (!columnFamily().matches("\\w+"))
+            if (!PATTERN_WORD_CHARS.matcher(columnFamily()).matches())
                 throw new InvalidRequestException(String.format("\"%s\" is not 
a valid table name (must be alphanumeric character or underscore only: 
[a-zA-Z_0-9]+)", columnFamily()));
             if (columnFamily().length() > Schema.NAME_LENGTH)
                 throw new InvalidRequestException(String.format("Table names 
shouldn't be more than %s characters long (got \"%s\")", Schema.NAME_LENGTH, 
columnFamily()));

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java 
b/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java
index 793285b..590910f 100644
--- a/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java
+++ b/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java
@@ -18,6 +18,7 @@
 package org.apache.cassandra.cql3.statements;
 
 import java.util.*;
+import java.util.regex.Pattern;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -26,6 +27,8 @@ import org.apache.cassandra.exceptions.SyntaxException;
 
 public class PropertyDefinitions
 {
+    private static final Pattern PATTERN_POSITIVE = 
Pattern.compile("(1|true|yes)");
+    
     protected static final Logger logger = 
LoggerFactory.getLogger(PropertyDefinitions.class);
 
     protected final Map<String, Object> properties = new HashMap<String, 
Object>();
@@ -91,7 +94,7 @@ public class PropertyDefinitions
     public Boolean getBoolean(String key, Boolean defaultValue) throws 
SyntaxException
     {
         String value = getSimple(key);
-        return (value == null) ? defaultValue : 
value.toLowerCase().matches("(1|true|yes)");
+        return (value == null) ? defaultValue : 
PATTERN_POSITIVE.matcher(value.toLowerCase()).matches();
     }
 
     // Return a property value, typed as a double

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java 
b/src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java
index 5547d0e..97b26c7 100644
--- a/src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java
+++ b/src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java
@@ -29,6 +29,8 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.TimeZone;
 import java.util.concurrent.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.cassandra.concurrent.JMXEnabledThreadPoolExecutor;
 import org.apache.cassandra.config.DatabaseDescriptor;
@@ -46,6 +48,10 @@ public class CommitLogArchiver
     private static final Logger logger = 
LoggerFactory.getLogger(CommitLogArchiver.class);
     public static final SimpleDateFormat format = new 
SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
     private static final String DELIMITER = ",";
+    private static final Pattern NAME = Pattern.compile("%name");
+    private static final Pattern PATH = Pattern.compile("%path");
+    private static final Pattern FROM = Pattern.compile("%from");
+    private static final Pattern TO = Pattern.compile("%to");
     static
     {
         format.setTimeZone(TimeZone.getTimeZone("GMT"));
@@ -136,8 +142,8 @@ public class CommitLogArchiver
             protected void runMayThrow() throws IOException
             {
                 segment.waitForFinalSync();
-                String command = archiveCommand.replace("%name", 
segment.getName());
-                command = command.replace("%path", segment.getPath());
+                String command = 
NAME.matcher(archiveCommand).replaceAll(Matcher.quoteReplacement(segment.getName()));
+                command = 
PATH.matcher(command).replaceAll(Matcher.quoteReplacement(segment.getPath()));
                 exec(command);
             }
         }));
@@ -158,8 +164,8 @@ public class CommitLogArchiver
         {
             protected void runMayThrow() throws IOException
             {
-                String command = archiveCommand.replace("%name", name);
-                command = command.replace("%path", path);
+                String command = 
NAME.matcher(archiveCommand).replaceAll(Matcher.quoteReplacement(name));
+                command = 
PATH.matcher(command).replaceAll(Matcher.quoteReplacement(path));
                 exec(command);
             }
         }));
@@ -244,8 +250,8 @@ public class CommitLogArchiver
                     continue;
                 }
 
-                String command = restoreCommand.replace("%from", 
fromFile.getPath());
-                command = command.replace("%to", toFile.getPath());
+                String command = 
FROM.matcher(restoreCommand).replaceAll(Matcher.quoteReplacement(fromFile.getPath()));
+                command = 
TO.matcher(command).replaceAll(Matcher.quoteReplacement(toFile.getPath()));
                 try
                 {
                     exec(command);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/db/commitlog/CommitLogReplayer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/commitlog/CommitLogReplayer.java 
b/src/java/org/apache/cassandra/db/commitlog/CommitLogReplayer.java
index 0c71871..e97b36e 100644
--- a/src/java/org/apache/cassandra/db/commitlog/CommitLogReplayer.java
+++ b/src/java/org/apache/cassandra/db/commitlog/CommitLogReplayer.java
@@ -295,7 +295,7 @@ public class CommitLogReplayer
             Multimap<String, String> toReplay = HashMultimap.create();
             for (String rawPair : 
System.getProperty("cassandra.replayList").split(","))
             {
-                String[] pair = rawPair.trim().split("\\.");
+                String[] pair = StringUtils.split(rawPair.trim(), '.');
                 if (pair.length != 2)
                     throw new IllegalArgumentException("Each table to be 
replayed must be fully qualified with keyspace name, e.g., 'system.peers'");
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java 
b/src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java
index ad4050d..130ed7b 100644
--- a/src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java
+++ b/src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java
@@ -21,6 +21,7 @@ import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.regex.Pattern;
 
 import org.apache.cassandra.cql3.Term;
 import org.apache.cassandra.serializers.TypeSerializer;
@@ -107,6 +108,10 @@ public abstract class AbstractCompositeType extends 
AbstractType<ByteBuffer>
         }
         return l.toArray(new ByteBuffer[l.size()]);
     }
+    private static final String COLON = ":";
+    private static final Pattern COLON_PAT = Pattern.compile(COLON);
+    private static final String ESCAPED_COLON = "\\\\:";
+    private static final Pattern ESCAPED_COLON_PAT = 
Pattern.compile(ESCAPED_COLON);
 
 
     /*
@@ -118,7 +123,7 @@ public abstract class AbstractCompositeType extends 
AbstractType<ByteBuffer>
         if (input.isEmpty())
             return input;
 
-        String res = input.replaceAll(":", "\\\\:");
+        String res = COLON_PAT.matcher(input).replaceAll(ESCAPED_COLON);
         char last = res.charAt(res.length() - 1);
         return last == '\\' || last == '!' ? res + '!' : res;
     }
@@ -132,7 +137,7 @@ public abstract class AbstractCompositeType extends 
AbstractType<ByteBuffer>
         if (input.isEmpty())
             return input;
 
-        String res = input.replaceAll("\\\\:", ":");
+        String res = ESCAPED_COLON_PAT.matcher(input).replaceAll(COLON);
         char last = res.charAt(res.length() - 1);
         return last == '!' ? res.substring(0, res.length() - 1) : res;
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/db/marshal/TupleType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/TupleType.java 
b/src/java/org/apache/cassandra/db/marshal/TupleType.java
index 9480229..362388b 100644
--- a/src/java/org/apache/cassandra/db/marshal/TupleType.java
+++ b/src/java/org/apache/cassandra/db/marshal/TupleType.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
+import java.util.regex.Pattern;
 
 import com.google.common.base.Objects;
 
@@ -37,6 +38,15 @@ import org.apache.cassandra.utils.ByteBufferUtil;
  */
 public class TupleType extends AbstractType<ByteBuffer>
 {
+    private static final String COLON = ":";
+    private static final Pattern COLON_PAT = Pattern.compile(COLON);
+    private static final String ESCAPED_COLON = "\\\\:";
+    private static final Pattern ESCAPED_COLON_PAT = 
Pattern.compile(ESCAPED_COLON);
+    private static final String AT = "@";
+    private static final Pattern AT_PAT = Pattern.compile(AT);
+    private static final String ESCAPED_AT = "\\\\@";
+    private static final Pattern ESCAPED_AT_PAT = Pattern.compile(ESCAPED_AT);
+    
     protected final List<AbstractType<?>> types;
 
     public TupleType(List<AbstractType<?>> types)
@@ -215,7 +225,9 @@ public class TupleType extends AbstractType<ByteBuffer>
 
             ByteBuffer field = ByteBufferUtil.readBytes(input, size);
             // We use ':' as delimiter, and @ to represent null, so escape 
them in the generated string
-            sb.append(type.getString(field).replaceAll(":", 
"\\\\:").replaceAll("@", "\\\\@"));
+            String fld = 
COLON_PAT.matcher(type.getString(field)).replaceAll(ESCAPED_COLON);
+            fld = AT_PAT.matcher(fld).replaceAll(ESCAPED_AT);
+            sb.append(fld);
         }
         return sb.toString();
     }
@@ -238,7 +250,9 @@ public class TupleType extends AbstractType<ByteBuffer>
                 continue;
 
             AbstractType<?> type = type(i);
-            fields[i] = type.fromString(fieldString.replaceAll("\\\\:", 
":").replaceAll("\\\\@", "@"));
+            fieldString = 
ESCAPED_COLON_PAT.matcher(fieldString).replaceAll(COLON);
+            fieldString = ESCAPED_AT_PAT.matcher(fieldString).replaceAll(AT);
+            fields[i] = type.fromString(fieldString);
         }
         return buildValue(fields);
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/index/internal/CassandraIndex.java 
b/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
index 4598326..2204a5e 100644
--- a/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
+++ b/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
@@ -725,6 +725,9 @@ public abstract class CassandraIndex implements Index
         return getFunctions(indexMetadata, parseTarget(baseCfs.metadata, 
indexMetadata)).newIndexInstance(baseCfs, indexMetadata);
     }
 
+    private static final Pattern TWO_QUOTES = Pattern.compile("\"\"");
+    private static final String QUOTE = "\"";
+
     // Public because it's also used to convert index metadata into a 
thrift-compatible format
     public static Pair<ColumnDefinition, IndexTarget.Type> 
parseTarget(CFMetaData cfm,
                                                                        
IndexMetadata indexDef)
@@ -754,10 +757,10 @@ public abstract class CassandraIndex implements Index
         //      abc"def -> abc""def.
         // Because the target string is stored in a CQL compatible form, we
         // need to un-escape any such quotes to get the actual column name
-        if (columnName.startsWith("\""))
+        if (columnName.startsWith(QUOTE))
         {
             columnName = 
StringUtils.substring(StringUtils.substring(columnName, 1), 0, -1);
-            columnName = columnName.replaceAll("\"\"", "\"");
+            columnName = TWO_QUOTES.matcher(columnName).replaceAll(QUOTE);
         }
 
         // if it's not a CQL table, we can't assume that the column name is 
utf8, so

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/metrics/CassandraMetricsRegistry.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/metrics/CassandraMetricsRegistry.java 
b/src/java/org/apache/cassandra/metrics/CassandraMetricsRegistry.java
index 1cd3b6c..0d9e6d6 100644
--- a/src/java/org/apache/cassandra/metrics/CassandraMetricsRegistry.java
+++ b/src/java/org/apache/cassandra/metrics/CassandraMetricsRegistry.java
@@ -191,6 +191,18 @@ public class CassandraMetricsRegistry extends 
MetricRegistry
             mBeanServer.unregisterMBean(name.getMBeanName());
         } catch (Exception ignore) {}
     }
+    
+    /**
+     * Strips a single final '$' from input
+     * 
+     * @param s String to strip
+     * @return a string with one less '$' at end
+     */
+    private static String withoutFinalDollar(String s)
+    {
+        int l = s.length();
+        return (l!=0 && '$' == s.charAt(l-1))?s.substring(0,l-1):s;
+    }
 
     public interface MetricMBean
     {
@@ -601,7 +613,7 @@ public class CassandraMetricsRegistry extends MetricRegistry
         public MetricName(Class<?> klass, String name, String scope)
         {
             this(klass.getPackage() == null ? "" : 
klass.getPackage().getName(),
-                    klass.getSimpleName().replaceAll("\\$$", ""),
+                    withoutFinalDollar(klass.getSimpleName()),
                     name,
                     scope);
         }
@@ -811,7 +823,7 @@ public class CassandraMetricsRegistry extends MetricRegistry
         {
             if (type == null || type.isEmpty())
             {
-                type = klass.getSimpleName().replaceAll("\\$$", "");
+                type = withoutFinalDollar(klass.getSimpleName());
             }
             return type;
         }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/schema/IndexMetadata.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/schema/IndexMetadata.java 
b/src/java/org/apache/cassandra/schema/IndexMetadata.java
index ee9179a..59ac1cf 100644
--- a/src/java/org/apache/cassandra/schema/IndexMetadata.java
+++ b/src/java/org/apache/cassandra/schema/IndexMetadata.java
@@ -21,6 +21,7 @@ package org.apache.cassandra.schema;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.util.*;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 import com.google.common.base.Objects;
@@ -46,6 +47,10 @@ import org.apache.cassandra.utils.UUIDSerializer;
 public final class IndexMetadata
 {
     private static final Logger logger = 
LoggerFactory.getLogger(IndexMetadata.class);
+    
+    private static final Pattern PATTERN_NON_WORD_CHAR = 
Pattern.compile("\\W");
+    private static final Pattern PATTERN_WORD_CHARS = Pattern.compile("\\w+");
+
 
     public static final Serializer serializer = new Serializer();
 
@@ -127,15 +132,15 @@ public final class IndexMetadata
 
     public static boolean isNameValid(String name)
     {
-        return name != null && !name.isEmpty() && name.matches("\\w+");
+        return name != null && !name.isEmpty() && 
PATTERN_WORD_CHARS.matcher(name).matches();
     }
 
     public static String getDefaultIndexName(String cfName, String root)
     {
         if (root == null)
-            return (cfName + "_" + "idx").replaceAll("\\W", "");
+            return PATTERN_NON_WORD_CHAR.matcher(cfName + "_" + 
"idx").replaceAll("");
         else
-            return (cfName + "_" + root + "_idx").replaceAll("\\W", "");
+            return PATTERN_NON_WORD_CHAR.matcher(cfName + "_" + root + 
"_idx").replaceAll("");
     }
 
     public void validate()

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/service/StorageService.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageService.java 
b/src/java/org/apache/cassandra/service/StorageService.java
index 069af53..60ede18 100644
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@ -166,7 +166,7 @@ import static java.util.Arrays.asList;
 public class StorageService extends NotificationBroadcasterSupport implements 
IEndpointStateChangeSubscriber, StorageServiceMBean
 {
     private static final Logger logger = 
LoggerFactory.getLogger(StorageService.class);
-
+    
     public static final int RING_DELAY = getRingDelay(); // delay after which 
we assume ring has stablized
 
     private final JMXProgressSupport progressSupport = new 
JMXProgressSupport(this);
@@ -2707,7 +2707,7 @@ public class StorageService extends 
NotificationBroadcasterSupport implements IE
         Map<Keyspace, List<String>> keyspaceColumnfamily = new 
HashMap<Keyspace, List<String>>();
         for (String table : tableList)
         {
-            String splittedString[] = table.split("\\.");
+            String splittedString[] = StringUtils.split(table, '.');
             if (splittedString.length == 2)
             {
                 String keyspaceName = splittedString[0];

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/src/java/org/apache/cassandra/utils/CassandraVersion.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/CassandraVersion.java 
b/src/java/org/apache/cassandra/utils/CassandraVersion.java
index aac7df9..759ca97 100644
--- a/src/java/org/apache/cassandra/utils/CassandraVersion.java
+++ b/src/java/org/apache/cassandra/utils/CassandraVersion.java
@@ -37,6 +37,8 @@ public class CassandraVersion implements 
Comparable<CassandraVersion>
      * this is because 3rd and the last can be identical.
      **/
     private static final String VERSION_REGEXP = 
"(\\d+)\\.(\\d+)(?:\\.(\\w+))?(\\-[.\\w]+)?([.+][.\\w]+)?";
+    private static final Pattern PATTERN_WHITESPACE = Pattern.compile("\\w+");
+
     private static final Pattern pattern = Pattern.compile(VERSION_REGEXP);
     private static final Pattern SNAPSHOT = Pattern.compile("-SNAPSHOT");
 
@@ -83,10 +85,10 @@ public class CassandraVersion implements 
Comparable<CassandraVersion>
     {
         // Drop initial - or +
         str = str.substring(1);
-        String[] parts = str.split("\\.");
+        String[] parts = StringUtils.split(str, '.');
         for (String part : parts)
         {
-            if (!part.matches("\\w+"))
+            if (!PATTERN_WHITESPACE.matcher(part).matches())
                 throw new IllegalArgumentException("Invalid version value: " + 
version);
         }
         return parts;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/test/unit/org/apache/cassandra/config/CFMetaDataTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/config/CFMetaDataTest.java 
b/test/unit/org/apache/cassandra/config/CFMetaDataTest.java
index 9d91df3..188f72f 100644
--- a/test/unit/org/apache/cassandra/config/CFMetaDataTest.java
+++ b/test/unit/org/apache/cassandra/config/CFMetaDataTest.java
@@ -49,6 +49,8 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 public class CFMetaDataTest
 {
@@ -173,4 +175,22 @@ public class CFMetaDataTest
         assertEquals(cfm.params, params);
         assertEquals(new HashSet<>(cfm.allColumns()), columns);
     }
+    
+    @Test
+    public void testIsNameValidPositive()
+    {
+         assertTrue(CFMetaData.isNameValid("abcdefghijklmnopqrstuvwxyz"));
+         assertTrue(CFMetaData.isNameValid("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+         assertTrue(CFMetaData.isNameValid("_01234567890"));
+    }
+    
+    @Test
+    public void testIsNameValidNegative()
+    {
+        assertFalse(CFMetaData.isNameValid(null));
+        assertFalse(CFMetaData.isNameValid(""));
+        assertFalse(CFMetaData.isNameValid(" "));
+        assertFalse(CFMetaData.isNameValid("@"));
+        assertFalse(CFMetaData.isNameValid("!"));
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java 
b/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
index 3a3b6ee..84f0235 100644
--- a/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
+++ b/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
@@ -23,6 +23,8 @@ import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Enumeration;
 
 import org.junit.BeforeClass;
@@ -43,6 +45,8 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
+import static org.junit.Assert.assertTrue;
+
 @RunWith(OrderedJUnit4ClassRunner.class)
 public class DatabaseDescriptorTest
 {
@@ -265,4 +269,15 @@ public class DatabaseDescriptorTest
         DatabaseDescriptor.applyAddressConfig(testConfig);
 
     }
+    
+    @Test
+    public void testTokensFromString()
+    {
+        assertTrue(DatabaseDescriptor.tokensFromString(null).isEmpty());
+        Collection<String> tokens = DatabaseDescriptor.tokensFromString(" a,b 
,c , d, f,g,h");
+        assertEquals(7, tokens.size());
+        assertTrue(tokens.containsAll(Arrays.asList(new String[]{"a", "b", 
"c", "d", "f", "g", "h"})));
+
+        
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/test/unit/org/apache/cassandra/cql3/ColumnIdentifierTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/ColumnIdentifierTest.java 
b/test/unit/org/apache/cassandra/cql3/ColumnIdentifierTest.java
index c287883..158110c 100644
--- a/test/unit/org/apache/cassandra/cql3/ColumnIdentifierTest.java
+++ b/test/unit/org/apache/cassandra/cql3/ColumnIdentifierTest.java
@@ -26,6 +26,7 @@ import org.junit.Test;
 import junit.framework.Assert;
 import org.apache.cassandra.db.marshal.BytesType;
 import org.apache.cassandra.utils.ByteBufferUtil;
+import static org.junit.Assert.assertEquals;
 
 public class ColumnIdentifierTest
 {
@@ -57,5 +58,23 @@ public class ColumnIdentifierTest
     {
         return v < 0 ? -1 : v > 0 ? 1 : 0;
     }
+    
+    @Test
+    public void testMaybeQuote()
+    {
+        String unquotable = "a";
+        assertEquals(unquotable, ColumnIdentifier.maybeQuote(unquotable));
+        unquotable = "z4";
+        assertEquals(unquotable, ColumnIdentifier.maybeQuote(unquotable));
+        unquotable = "m_4_";
+        assertEquals(unquotable, ColumnIdentifier.maybeQuote(unquotable));
+        unquotable = "f__";
+        assertEquals(unquotable, ColumnIdentifier.maybeQuote(unquotable));
+        
+        assertEquals("\"A\"", ColumnIdentifier.maybeQuote("A"));
+        assertEquals("\"4b\"", ColumnIdentifier.maybeQuote("4b"));
+        assertEquals("\"\"\"\"", ColumnIdentifier.maybeQuote("\""));
+        assertEquals("\"\"\"a\"\"b\"\"\"", 
ColumnIdentifier.maybeQuote("\"a\"b\""));
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/test/unit/org/apache/cassandra/cql3/statements/PropertyDefinitionsTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/cql3/statements/PropertyDefinitionsTest.java 
b/test/unit/org/apache/cassandra/cql3/statements/PropertyDefinitionsTest.java
new file mode 100644
index 0000000..417fcdc
--- /dev/null
+++ 
b/test/unit/org/apache/cassandra/cql3/statements/PropertyDefinitionsTest.java
@@ -0,0 +1,61 @@
+package org.apache.cassandra.cql3.statements;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.Before;
+
+import static org.junit.Assert.assertEquals;
+
+public class PropertyDefinitionsTest {
+    
+    PropertyDefinitions pd;
+    
+    @Before
+    public void setUp()
+    {
+        pd = new PropertyDefinitions();
+    }
+    
+    @After
+    public void clear()
+    {
+        pd = null;
+    }
+    
+
+    @Test
+    public void testGetBooleanExistant()
+    {
+        String key = "one";
+        pd.addProperty(key, "1");
+        assertEquals(Boolean.TRUE, pd.getBoolean(key, null));
+        
+        key = "TRUE";
+        pd.addProperty(key, "TrUe");
+        assertEquals(Boolean.TRUE, pd.getBoolean(key, null));
+        
+        key = "YES";
+        pd.addProperty(key, "YeS");
+        assertEquals(Boolean.TRUE, pd.getBoolean(key, null));
+   
+        key = "BAD_ONE";
+        pd.addProperty(key, " 1");
+        assertEquals(Boolean.FALSE, pd.getBoolean(key, null));
+        
+        key = "BAD_TRUE";
+        pd.addProperty(key, "true ");
+        assertEquals(Boolean.FALSE, pd.getBoolean(key, null));
+        
+        key = "BAD_YES";
+        pd.addProperty(key, "ye s");
+        assertEquals(Boolean.FALSE, pd.getBoolean(key, null));
+    }
+    
+    @Test
+    public void testGetBooleanNonexistant()
+    {
+        assertEquals(Boolean.FALSE, pd.getBoolean("nonexistant", 
Boolean.FALSE));
+        assertEquals(Boolean.TRUE, pd.getBoolean("nonexistant", Boolean.TRUE));
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/test/unit/org/apache/cassandra/db/marshal/AbstractCompositeTypeTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/db/marshal/AbstractCompositeTypeTest.java 
b/test/unit/org/apache/cassandra/db/marshal/AbstractCompositeTypeTest.java
new file mode 100644
index 0000000..0e91532
--- /dev/null
+++ b/test/unit/org/apache/cassandra/db/marshal/AbstractCompositeTypeTest.java
@@ -0,0 +1,35 @@
+package org.apache.cassandra.db.marshal;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+public class AbstractCompositeTypeTest
+{
+    
+    @Test
+    public void testEscape()
+    {
+        assertEquals("", AbstractCompositeType.escape(""));
+        assertEquals("Ab!CdXy \\Z123-345", 
AbstractCompositeType.escape("Ab!CdXy \\Z123-345"));
+        assertEquals("Ab!CdXy \\Z123-345!!", 
AbstractCompositeType.escape("Ab!CdXy \\Z123-345!"));
+        assertEquals("Ab!CdXy \\Z123-345\\!", 
AbstractCompositeType.escape("Ab!CdXy \\Z123-345\\"));
+        
+        assertEquals("A\\:b!CdXy \\\\:Z123-345", 
AbstractCompositeType.escape("A:b!CdXy \\:Z123-345"));
+        assertEquals("A\\:b!CdXy \\\\:Z123-345!!", 
AbstractCompositeType.escape("A:b!CdXy \\:Z123-345!"));
+        assertEquals("A\\:b!CdXy \\\\:Z123-345\\!", 
AbstractCompositeType.escape("A:b!CdXy \\:Z123-345\\"));
+        
+    }
+    
+    @Test
+    public void testUnescape()
+    {
+        assertEquals("", AbstractCompositeType.escape(""));
+        assertEquals("Ab!CdXy \\Z123-345", 
AbstractCompositeType.unescape("Ab!CdXy \\Z123-345"));
+        assertEquals("Ab!CdXy \\Z123-345!", 
AbstractCompositeType.unescape("Ab!CdXy \\Z123-345!!"));
+        assertEquals("Ab!CdXy \\Z123-345\\", 
AbstractCompositeType.unescape("Ab!CdXy \\Z123-345\\!"));
+        
+        assertEquals("A:b!CdXy \\:Z123-345", 
AbstractCompositeType.unescape("A\\:b!CdXy \\\\:Z123-345"));
+        assertEquals("A:b!CdXy \\:Z123-345!", 
AbstractCompositeType.unescape("A\\:b!CdXy \\\\:Z123-345!!"));
+        assertEquals("A:b!CdXy \\:Z123-345\\", 
AbstractCompositeType.unescape("A\\:b!CdXy \\\\:Z123-345\\!"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/test/unit/org/apache/cassandra/metrics/CassandraMetricsRegistryTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/metrics/CassandraMetricsRegistryTest.java 
b/test/unit/org/apache/cassandra/metrics/CassandraMetricsRegistryTest.java
new file mode 100644
index 0000000..0258b8c
--- /dev/null
+++ b/test/unit/org/apache/cassandra/metrics/CassandraMetricsRegistryTest.java
@@ -0,0 +1,34 @@
+package org.apache.cassandra.metrics;
+
+import org.junit.Test;
+import org.apache.cassandra.metrics.CassandraMetricsRegistry.MetricName;
+import static org.junit.Assert.*;
+
+
+public class CassandraMetricsRegistryTest
+{
+    // A class with a name ending in '$'
+    private static class StrangeName$
+    {
+    }
+
+    @Test
+    public void testChooseType()
+    {
+        assertEquals("StrangeName", MetricName.chooseType(null, 
StrangeName$.class));
+        assertEquals("StrangeName", MetricName.chooseType("", 
StrangeName$.class));
+        assertEquals("String", MetricName.chooseType(null, String.class));
+        assertEquals("String", MetricName.chooseType("", String.class));
+        
+        assertEquals("a", MetricName.chooseType("a", StrangeName$.class));
+        assertEquals("b", MetricName.chooseType("b", String.class));
+    }
+    
+    @Test
+    public void testMetricName()
+    {
+         MetricName name = new MetricName(StrangeName$.class, "NaMe", "ScOpE");
+         assertEquals("StrangeName", name.getType());
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/test/unit/org/apache/cassandra/schema/IndexMetadataTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/schema/IndexMetadataTest.java 
b/test/unit/org/apache/cassandra/schema/IndexMetadataTest.java
new file mode 100644
index 0000000..901a5aa
--- /dev/null
+++ b/test/unit/org/apache/cassandra/schema/IndexMetadataTest.java
@@ -0,0 +1,36 @@
+package org.apache.cassandra.schema;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class IndexMetadataTest {
+    
+    @Test
+    public void testIsNameValidPositive()
+    {
+        assertTrue(IndexMetadata.isNameValid("abcdefghijklmnopqrstuvwxyz"));
+        assertTrue(IndexMetadata.isNameValid("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+        assertTrue(IndexMetadata.isNameValid("_01234567890"));
+    }
+    
+    @Test
+    public void testIsNameValidNegative()
+    {
+        assertFalse(IndexMetadata.isNameValid(null));
+        assertFalse(IndexMetadata.isNameValid(""));
+        assertFalse(IndexMetadata.isNameValid(" "));
+        assertFalse(IndexMetadata.isNameValid("@"));
+        assertFalse(IndexMetadata.isNameValid("!"));
+    }
+    
+    @Test
+    public void testGetDefaultIndexName()
+    {
+        Assert.assertEquals("aB4__idx", IndexMetadata.getDefaultIndexName("a 
B-4@!_+", null));
+        Assert.assertEquals("34_Ddd_F6_idx", 
IndexMetadata.getDefaultIndexName("34_()Ddd", "#F%6*"));
+        
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/01d26dd3/test/unit/org/apache/cassandra/utils/CassandraVersionTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/utils/CassandraVersionTest.java 
b/test/unit/org/apache/cassandra/utils/CassandraVersionTest.java
index cec668f..73562b7 100644
--- a/test/unit/org/apache/cassandra/utils/CassandraVersionTest.java
+++ b/test/unit/org/apache/cassandra/utils/CassandraVersionTest.java
@@ -17,10 +17,16 @@
  */
 package org.apache.cassandra.utils;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
 import org.junit.Test;
 
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.matchers.JUnitMatchers.containsString;
 
 public class CassandraVersionTest
 {
@@ -153,7 +159,7 @@ public class CassandraVersionTest
         next = new CassandraVersion("3.2");
         assertTrue(prev.compareTo(next) < 0);
     }
-
+    
     private static void assertThrows(String str)
     {
         try
@@ -163,4 +169,47 @@ public class CassandraVersionTest
         }
         catch (IllegalArgumentException e) {}
     }
+    
+    @Test
+    public void testParseIdentifiersPositive() throws Throwable
+    {
+        String[] result = parseIdentifiers("DUMMY", "+a.b.cde.f_g.");
+        String[] expected = {"a", "b", "cde", "f_g"};
+        assertArrayEquals(expected, result);
+    }
+    
+    @Test
+    public void testParseIdentifiersNegative() throws Throwable
+    {
+        String version = "DUMMY";
+        try
+        {
+            parseIdentifiers(version, "+a. .b");
+            
+        }
+        catch (IllegalArgumentException e)
+        {
+            assertThat(e.getMessage(), containsString(version));
+        }
+    }
+    private static String[] parseIdentifiers(String version, String str) 
throws Throwable
+    {
+        String name = "parseIdentifiers";
+        Class[] args = {String.class, String.class};
+        for (Method m: CassandraVersion.class.getDeclaredMethods())
+        {
+            if (name.equals(m.getName()) && 
+                    Arrays.equals(args, m.getParameterTypes()))
+            {
+                m.setAccessible(true);
+                try 
+                {
+                return (String[]) m.invoke(null, version, str); 
+                } catch (InvocationTargetException e){
+                    throw e.getTargetException();
+                }
+            }
+        }
+        throw new NoSuchMethodException(CassandraVersion.class + "." + name + 
Arrays.toString(args));
+    }
 }

Reply via email to