All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.data.cassandra.core.cql.CqlIdentifier Maven / Gradle / Ivy

There is a newer version: 4.3.2
Show newest version
/*
 * Copyright 2017-2024 the original author or authors.
 *
 * Licensed 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
 *
 *      https://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.springframework.data.cassandra.core.cql;

import java.io.Serializable;
import java.util.regex.Pattern;

import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

/**
 * This encapsulates the logic for CQL quoted and unquoted identifiers.
 * 

* CQL identifiers, when unquoted, are converted to lower case. When quoted, they are returned as-is with no lower * casing and encased in double quotes. To render, use any of the methods {@link #toCql()}, * {@link #toCql(StringBuilder)}, or {@link #toString()}. * * @author John McPeek * @author Matthew T. Adams * @author Mark Paluch * @author John Blum * @see #toCql() * @see #toString() * @deprecated since 3.0, use {@link com.datastax.oss.driver.api.core.CqlIdentifier} instead. */ @Deprecated public final class CqlIdentifier implements Comparable, Serializable { private static final long serialVersionUID = -974441606330912437L; public static final String UNQUOTED_REGEX = "(?i)[a-z][\\w]*"; public static final Pattern UNQUOTED = Pattern.compile(UNQUOTED_REGEX); public static final String QUOTED_REGEX = "(?i)[a-z]([\\w]*(\"\")+[\\w]*)+"; public static final Pattern QUOTED = Pattern.compile(QUOTED_REGEX); private final String identifier; private final String unquoted; private final boolean quoted; /** * Create a new {@link CqlIdentifier} without force-quoting it. It may end up quoted, depending on its value. * * @see #of(CharSequence) */ private CqlIdentifier(CharSequence identifier) { this(identifier, false); } /** * Create a new CQL identifier, optionally force-quoting it. Force-quoting can be used to preserve identifier case. *

    *
  • If the given identifier is a legal quoted identifier or {@code forceQuote} is true, * {@link #isQuoted()} will return {@code true} and the identifier will be quoted when rendered.
  • *
  • If the given identifier is a legal unquoted identifier, {@link #isQuoted()} will return {@code false}, plus the * name will be converted to lower case and rendered as such.
  • *
  • If the given identifier is illegal, an {@link IllegalArgumentException} is thrown.
  • *
* * @see #of(CharSequence, boolean) * @see #quoted(CharSequence) */ private CqlIdentifier(CharSequence identifier, boolean forceQuote) { Assert.notNull(identifier, "Identifier must not be null"); String string = identifier.toString(); Assert.hasText(string, "Identifier must not be empty"); if (forceQuote || requiresQuoting(string)) { this.unquoted = string; this.identifier = "\"" + string + "\""; this.quoted = true; } else if (isUnquotedIdentifier(string)) { this.identifier = this.unquoted = string.toLowerCase(); this.quoted = false; } else { throw new IllegalArgumentException( String.format("given string [%s] is not a valid quoted or unquoted identifier", identifier)); } } /** * Factory method for {@link CqlIdentifier}. Convenient if imported statically. * * @see #CqlIdentifier(CharSequence) * @deprecated since 2.0, use {@link #of(CharSequence)} */ @Deprecated public static CqlIdentifier cqlId(CharSequence identifier) { return new CqlIdentifier(identifier); } /** * Factory method for {@link CqlIdentifier}. Convenient if imported statically. * * @see #CqlIdentifier(CharSequence, boolean) * @deprecated since 2.0, use {@link #of(CharSequence, boolean)} */ @Deprecated public static CqlIdentifier cqlId(CharSequence identifier, boolean forceQuote) { return new CqlIdentifier(identifier, forceQuote); } /** * Factory method for {@link CqlIdentifier}. * * @since 2.0 */ public static CqlIdentifier of(CharSequence identifier) { return new CqlIdentifier(identifier); } /** * Factory method for {@link CqlIdentifier}. * * @since 2.0 */ public static CqlIdentifier of(CharSequence identifier, boolean forceQuote) { return new CqlIdentifier(identifier, forceQuote); } /** * Factory method for a force-quoted {@link CqlIdentifier}. Convenient if imported statically. * * @see #CqlIdentifier(CharSequence, boolean) * @deprecated since 2.0, use {@link #quoted(CharSequence)}. */ @Deprecated public static CqlIdentifier quotedCqlId(CharSequence identifier) { return new CqlIdentifier(identifier, true); } /** * Factory method for a force-quoted {@link CqlIdentifier}. * * @since 2.0. */ public static CqlIdentifier quoted(CharSequence identifier) { return new CqlIdentifier(identifier, true); } /** * Returns {@code true} if the given {@link CharSequence} is a legal unquoted identifier. */ public static boolean isUnquotedIdentifier(CharSequence chars) { return UNQUOTED.matcher(chars).matches() && !ReservedKeyword.isReserved(chars); } /** * Returns {@code true} if the given {@link CharSequence} is an identifier with quotes. */ public static boolean isQuotedIdentifier(CharSequence chars) { return chars != null && chars.length() > 1 && chars.charAt(0) == '"' && chars.charAt(chars.length() - 1) == '"'; } /** * Returns {@code true} if the given {@link CharSequence} requires quoting. * * @since 2.2 */ public static boolean requiresQuoting(CharSequence chars) { return QUOTED.matcher(chars).matches() || ReservedKeyword.isReserved(chars); } /** * Returns the identifier without encasing quotes, regardless of the value of {@link #isQuoted()}. For * example, if {@link #isQuoted()} is {@code true}, then this value will be the same as {@link #toCql()} and * {@link #toString()}. *

* This is needed, for example, to get the correct * {@link com.datastax.oss.driver.api.core.metadata.schema.TableMetadata} from * {@link com.datastax.oss.driver.api.core.metadata.schema.KeyspaceMetadata#getTable(String)}: the given string must * not be quoted. */ public String getUnquoted() { return unquoted; } /** * Renders this identifier appropriately. */ public String toCql() { return identifier; } /** * Appends the rendering of this identifier to the given {@link StringBuilder}, then returns that * {@link StringBuilder}. If {@literal null} is given, a new {@link StringBuilder} is created, appended to, and * returned. */ public StringBuilder toCql(StringBuilder builder) { return builder.append(toCql()); } /** * Whether or not this identifier is quoted. */ public boolean isQuoted() { return quoted; } /** * Unquoted identifiers sort before quoted ones. Otherwise, they compare according to their identifiers. */ @Override @SuppressWarnings("all") public int compareTo(CqlIdentifier identifier) { int comparison = ((Boolean) this.quoted).compareTo(identifier.quoted); return (comparison != 0 ? comparison : this.identifier.compareTo(identifier.identifier)); } /** * Compares this {@link CqlIdentifier} to the given object. Note that if a {@link CharSequence} is given, a new * {@link CqlIdentifier} is created from it and compared, such that a {@link CharSequence} can be effectively equal to * a {@link CqlIdentifier}. * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(@Nullable Object o) { if (this == o) return true; if (!(o instanceof CqlIdentifier)) return false; CqlIdentifier that = (CqlIdentifier) o; if (quoted != that.quoted) return false; return identifier.equals(that.identifier); } @Override public int hashCode() { int result = identifier.hashCode(); result = 31 * result + (quoted ? 1 : 0); return result; } /** * Alias for {@link #toCql()}. */ @Override public String toString() { return toCql(); } /** * Create a Cassandra driver {@link com.datastax.oss.driver.api.core.CqlIdentifier} from this {@link CqlIdentifier}. * * @return the {@link com.datastax.oss.driver.api.core.CqlIdentifier} from this {@link CqlIdentifier}. * @since 3.0 */ public com.datastax.oss.driver.api.core.CqlIdentifier toCqlIdentifier() { return com.datastax.oss.driver.api.core.CqlIdentifier.fromInternal(this.unquoted); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy