/* * Copyright 2015-2023 Amazon Technologies, 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://aws.amazon.com/apache2.0 * * This file 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.amazonaws.services.dynamodbv2.xspec; import java.util.LinkedHashMap; import java.util.Map; /** * An internal class to represent the substitution context for name maps and * value maps. *

* To avoid attribute names that may conflict with the DynamoDB reserved words, * the expressions builder will automatically transform every component of a * document path into the use of an "expression attribute name" (that begins * with "#") as a placeholder. The actual mapping from the * "expression attribute name" to the actual attribute name is automatically * taken care of by the builder in a "name map". Similarly, the actual mapping * from the "expression attribute value" (that begins with ":") to the actual * attribute value is automatically taken care of by the builder in a * "value map". See more information at Using Placeholders for Attribute Names and Values. */ final class SubstitutionContext { private final Map nameToToken = new LinkedHashMap(); private final Map valueToToken = new LinkedHashMap(); /** * Returns the name token for the given name, creating a new token as * necessary. */ String nameTokenFor(String name) { Integer token = nameToToken.get(name); if (token == null) { token = nameToToken.size(); nameToToken.put(name, token); } return "#" + token; } /** * Returns the value token for the given value, creating a new token as * necessary. */ String valueTokenFor(Object value) { Integer token = valueToToken.get(value); if (token == null) { token = valueToToken.size(); valueToToken.put(value, token); } return ":" + token; } Map getNameMap() { if (nameToToken.size() == 0) return null; Map out = new LinkedHashMap(); for (Map.Entry e: nameToToken.entrySet()) { out.put("#" + e.getValue(), e.getKey()); } return out; } Map getValueMap() { if (valueToToken.size() == 0) return null; Map out = new LinkedHashMap(); for (Map.Entry e: valueToToken.entrySet()) { out.put(":" + e.getValue(), e.getKey()); } return out; } // For testing int numNameTokens() { return nameToToken.size(); } // For testing int numValueTokens() { return valueToToken.size(); } // For testing String getNameByToken(int token) { for (Map.Entry e: nameToToken.entrySet()) { if (e.getValue().intValue() == token) return e.getKey(); } return null; } // For testing Object getValueByToken(int token) { for (Map.Entry e: valueToToken.entrySet()) { if (e.getValue().intValue() == token) return e.getKey(); } return null; } @Override public String toString() { return "name-tokens: " + nameToToken.toString() + "\n" + "value-tokens: " + valueToToken.toString(); } }