/* * Copyright (c) 2013-2017 Cinchapi Inc. * * 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 * * 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 com.cinchapi.concourse.server.storage; import java.util.regex.Pattern; import com.cinchapi.concourse.Link; import com.cinchapi.concourse.thrift.Operator; import com.cinchapi.concourse.thrift.TObject; import com.cinchapi.concourse.util.Convert; import com.cinchapi.concourse.util.Strings; import com.cinchapi.concourse.util.TStrings; /** * {@link Store} based utility functions. * * @author Jeff Nelson */ public final class Stores { /** * Perform any necessary normalization on {@code operator} so that it can be * properly utilized in {@link Store} methods (i.e. convert a utility * operator to a functional one). * * @param operator * @return the normalized Operator */ public static Operator normalizeOperator(Operator operator) { switch (operator) { case LIKE: return Operator.REGEX; case NOT_LIKE: return Operator.NOT_REGEX; case LINKS_TO: return Operator.EQUALS; default: return operator; } } /** * Perform any necessary normalization on the {@code value} based on the * {@code operator}. * * @param operator * @param values * @return the normalized value */ public static TObject normalizeValue(Operator operator, TObject value) { try { switch (operator) { case REGEX: case NOT_REGEX: value = Convert.javaToThrift(((String) Convert .thriftToJava(value)).replaceAll( TStrings.REGEX_PERCENT_SIGN_WITHOUT_ESCAPE_CHAR, ".*") .replaceAll( TStrings.REGEX_PERCENT_SIGN_WITH_ESCAPE_CHAR, "%")); break; case LINKS_TO: value = Convert.javaToThrift(Link.to(((Number) Convert .thriftToJava(value)).longValue())); break; default: // noop: default case added to suppress compiler warning break; } return value; } catch (ClassCastException e) { return value; } } /** * Perform validation on the {@code key} and {@code value} and throw an * exception if necessary. * * @param key * @param value */ public static void validateWriteData(String key, TObject value) { // CON-21 if(key.length() == 0 || !KEY_VALIDATION_REGEX.matcher(key).matches()) { throw new IllegalArgumentException(Strings.joinWithSpace(key, "is not a valid key")); } else if(value.isBlank()) { throw new IllegalArgumentException("Cannot use a blank value"); } } /** * A pre-compiled regex pattern that is used to validate that each key is * non-empty, alphanumeric with no special characters other than underscore * (_). */ private static final Pattern KEY_VALIDATION_REGEX = Pattern .compile("^[a-zA-Z0-9_]+$"); }