/* * Agiato: A simple no frill Cassandra API * Author: Pranab Ghosh * * 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 agiato.cassandra.data; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Primary key meta data * @author pranab * */ public class PrimaryKey { private List<String> prmKeyElements; private int primKeyElementCount; private int rowKeyElementCount = 1; private int numPrimKeyComponentsFound; private int numPrimKeyComponentsSet; /** * @param prmKeyElements */ public PrimaryKey(String... prmKeyElements ) { //primary keys could be anywhere in the traversed tree with only one row key component this.prmKeyElements = Arrays.asList(prmKeyElements); numPrimKeyComponentsSet = prmKeyElements.length; } /** * @param prmKeyElementsnumPrimKeyComponentsFound * @param rowKeyElementCount */ public PrimaryKey(List<String> prmKeyElements, int rowKeyElementCount) { //primary keys could be anywhere in the traversed tree this.prmKeyElements = prmKeyElements; this.rowKeyElementCount = rowKeyElementCount; numPrimKeyComponentsSet = prmKeyElements.size(); } /** * @param primKeyElementCount * @param rowKeyElementCount */ public PrimaryKey( int primKeyElementCount, int rowKeyElementCount) { //primary keys in the head of the traversed tree this.primKeyElementCount = primKeyElementCount; this.rowKeyElementCount = rowKeyElementCount; numPrimKeyComponentsSet = primKeyElementCount; } /** * @param numPrimKeyComponentsSet * @return */ public PrimaryKey withNumPrimKeyComponentsSet(int numPrimKeyComponentsSet) { this.numPrimKeyComponentsSet = numPrimKeyComponentsSet; return this; } /** * @param rowKeyElementCount * @return */ public PrimaryKey withRowKeyElementCount(int rowKeyElementCount) { this.rowKeyElementCount = rowKeyElementCount; return this; } /** * @return */ public List<String> getPrmKeyElements() { return prmKeyElements; } /** * @return */ public int getPrimKeyElementCount() { return primKeyElementCount; } /** * @return */ public int getRowKeyElementCount() { return rowKeyElementCount; } /** * @return */ public int getNumPrimKeyComponentsSet() { return numPrimKeyComponentsSet; } /** * @param rowKeyElementCount */ public void setRowKeyElementCount(int rowKeyElementCount) { this.rowKeyElementCount = rowKeyElementCount; } /** * @return */ public boolean isOnlyRowKeySet() { return numPrimKeyComponentsSet == rowKeyElementCount; } /** * @return */ public boolean isFullySet() { boolean fullySet = true; if (primKeyElementCount > 0) { fullySet= numPrimKeyComponentsSet == primKeyElementCount; } else { fullySet= numPrimKeyComponentsSet == prmKeyElements.size(); } return fullySet; } /** * Rebuild list with prim key elements at head of list * @param traversedPath * @return */ public List<NamedObject> movePrimKeyToHead(List<NamedObject> traversedPath) { List<NamedObject> newTraversedPath = null; numPrimKeyComponentsFound = 0; if (primKeyElementCount > 0) { //primary key components are at the head of the traversed list newTraversedPath = traversedPath; numPrimKeyComponentsFound = primKeyElementCount; } else { List<NamedObject> head = new ArrayList<NamedObject>(prmKeyElements.size()); for (int i = 0; i < prmKeyElements.size(); ++i) { head.add(null); } List<NamedObject> tail = new ArrayList<NamedObject>(); //separate primary key and non primary key fields for (NamedObject obj : traversedPath) { boolean matched = false; for (int i = 0; i < prmKeyElements.size(); ++i) { if (prmKeyElements.get(i).equals(obj.getName())) { head.set(i, obj); matched = true; ++numPrimKeyComponentsFound; break; } } if (!matched) { //non primary key tail.add(obj); } } //check if there is gap in primary key components for (int i = 0; i < head.size(); ++i) { if (null == head.get(i)) { throw new IllegalArgumentException("primary key subset provided is not contiguous"); } } //make sure all row key component elements are provided if (numPrimKeyComponentsFound < rowKeyElementCount) { throw new IllegalArgumentException("primary key does not contain all the row key components" + "numPrimKeyComponentsFound:" + numPrimKeyComponentsFound + " rowKeyElementCount: " +rowKeyElementCount ); } //put them together head.addAll(tail); newTraversedPath = head; primKeyElementCount = prmKeyElements.size(); } return newTraversedPath; } /** * @return */ public boolean allRowKeyComponentsDefined() { return numPrimKeyComponentsFound >= rowKeyElementCount; } /** * @return */ public boolean allPrimKeyComponentsDefined() { return numPrimKeyComponentsFound == primKeyElementCount; } /** * @return */ public int getNumPrimKeyComponentsFound() { return numPrimKeyComponentsFound; } }