Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / iapi / types / WorkHorseForCollatorDatatypes.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/iapi/types/WorkHorseForCollatorDatatypes.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/iapi/types/WorkHorseForCollatorDatatypes.java
new file mode 100644 (file)
index 0000000..05dc1f0
--- /dev/null
@@ -0,0 +1,285 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.iapi.types.WorkHorseForCollatorDatatypes\r
\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.iapi.types;\r
+\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+import org.apache.derby.iapi.types.BooleanDataValue;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import java.text.CollationElementIterator;\r
+import java.text.CollationKey;\r
+import java.text.RuleBasedCollator;\r
+\r
+/**\r
+ * WorkHorseForCollatorDatatypes class holds on to RuleBasedCollator,\r
+ * and the base SQLChar object for the collation sensitive SQLChar,\r
+ * SQLVarchar, SQLLongvarchar and SQLClob. This class uses RuleBasedCollator\r
+ * and SQLChar object in the collation sensitive methods to do the comparison. \r
+ * The reason for encapsulating this here is that the collation version of \r
+ * SQLChar, SQLVarchar, SQLLongvarchar and SQLClob do not all have to duplicate  \r
+ * the code for collation sensitive methods. Instead, they can simply delegate\r
+ * the work to methods defined in this class. \r
+ */\r
+final class WorkHorseForCollatorDatatypes  \r
+{\r
+       /** \r
+        * Use this object for collation on character datatype. This collator\r
+        * object is passed as a parameter to the constructor.\r
+        */\r
+       private RuleBasedCollator collatorForCharacterDatatypes;\r
+       /**\r
+        * collatorForCharacterDatatypes will be used on this SQLChar to determine\r
+        * collationElementsForString. The collationElementsForString is used by\r
+        * the like method to do Collator specific comparison.\r
+        * This SQLChar object is passed as a parameter to the constructor.\r
+        */\r
+       private SQLChar stringData;\r
+       /**\r
+        * Following is the array holding a series of collation elements for the\r
+        * string. It will be used in the like method. This gets initialized when\r
+        * the like method is first invoked. \r
+        */\r
+       private int[]   collationElementsForString;\r
+       /** \r
+        * Number of valid collation elements in the array above. Note that this \r
+        * might be smaller than the actual size of the array above. Gets \r
+        * initialized when the like method is first invoked.\r
+        */\r
+       private int             countOfCollationElements;\r
+\r
+       // For null strings, cKey = null.\r
+       private CollationKey cKey; \r
+\r
+       WorkHorseForCollatorDatatypes(\r
+                       RuleBasedCollator collatorForCharacterDatatypes,\r
+                       SQLChar stringData)\r
+       {\r
+               this.collatorForCharacterDatatypes = collatorForCharacterDatatypes;\r
+               this.stringData = stringData;\r
+       }\r
+       \r
+       /** @see SQLChar#stringCompare(SQLChar, SQLChar) */\r
+       int stringCompare(SQLChar str1, SQLChar str2)\r
+       throws StandardException\r
+       {\r
+               CollationKey ckey1 = str1.getCollationKey();\r
+               CollationKey ckey2 = str2.getCollationKey();\r
+               \r
+               /*\r
+               ** By convention, nulls sort High, and null == null\r
+               */\r
+               if (ckey1 == null || ckey2 == null)\r
+               {\r
+                       if (ckey1 != null)      // str2 == null\r
+                               return -1;\r
+                       if (ckey2 != null)      // this == null\r
+                               return 1;\r
+                       return 0;                       // both == null\r
+               }\r
+\r
+               return ckey1.compareTo(ckey2);\r
+       }\r
+       \r
+       /**\r
+        * This method implements the like function for char (with no escape value).\r
+        * The difference in this method and the same method in SQLChar is that \r
+        * here we use special Collator object to do the comparison rather than\r
+        * using the Collator object associated with the default jvm locale.\r
+        *\r
+        * @param pattern               The pattern to use\r
+        *\r
+        * @return      A SQL boolean value telling whether the first operand is\r
+        *                      like the second operand\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       BooleanDataValue like(DataValueDescriptor pattern)\r
+                                                               throws StandardException\r
+       {\r
+               Boolean likeResult;\r
+\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(\r
+                               pattern instanceof CollationElementsInterface,\r
+                               "Both the operands must be instances of CollationElementsInterface");\r
+               likeResult = Like.like(stringData.getCharArray(), \r
+                               stringData.getLength(), \r
+                               ((SQLChar)pattern).getCharArray(), \r
+                               pattern.getLength(), \r
+                               null, \r
+                               0,\r
+                               collatorForCharacterDatatypes);\r
+\r
+               return SQLBoolean.truthValue(stringData ,\r
+                                                                        pattern,\r
+                                                                        likeResult);\r
+       }\r
+       \r
+       /**\r
+        * This method implements the like function for char with an escape value.\r
+        * \r
+        * @param pattern               The pattern to use\r
+        * \r
+        * @return      A SQL boolean value telling whether the first operand is\r
+        *                      like the second operand\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       BooleanDataValue like(DataValueDescriptor pattern, \r
+                       DataValueDescriptor escape)     throws StandardException\r
+       {\r
+               Boolean likeResult;\r
+\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(\r
+                                                        pattern instanceof CollationElementsInterface &&\r
+                                                        escape instanceof CollationElementsInterface,\r
+                       "All three operands must be instances of CollationElementsInterface");\r
+               \r
+               // ANSI states a null escape yields 'unknown' results \r
+               //\r
+               // This method is only called when we have an escape clause, so this \r
+               // test is valid\r
+\r
+               if (escape.isNull())\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_ESCAPE_IS_NULL);\r
+               }\r
+\r
+               CollationElementsInterface escapeCharacter = (CollationElementsInterface) escape;\r
+\r
+               if (escapeCharacter.getCollationElementsForString() != null && \r
+                               (escapeCharacter.getCountOfCollationElements() != 1))\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_INVALID_ESCAPE_CHARACTER,\r
+                                       new String(escapeCharacter.toString()));\r
+               }\r
+               likeResult = Like.like(stringData.getCharArray(), \r
+                               stringData.getLength(), \r
+                               ((SQLChar)pattern).getCharArray(), \r
+                               pattern.getLength(), \r
+                               ((SQLChar)escape).getCharArray(), \r
+                               escape.getLength(),\r
+                               collatorForCharacterDatatypes);\r
+\r
+               return SQLBoolean.truthValue(stringData,\r
+                                                                pattern,\r
+                                                                likeResult);\r
+       }\r
+\r
+       /**\r
+        * Get the RuleBasedCollator which is getting used for collation sensitive\r
+        * methods. \r
+        */\r
+       RuleBasedCollator getCollatorForCollation()\r
+       {\r
+               return(collatorForCharacterDatatypes);\r
+       }\r
+\r
+       /**\r
+        * This method returns the count of collation elements for SQLChar object.\r
+        * It method will return the correct value only if method   \r
+        * getCollationElementsForString has been called previously on the SQLChar\r
+        * object. \r
+        *\r
+        * @return count of collation elements for this instance of CollatorSQLChar\r
+        */\r
+       int getCountOfCollationElements()\r
+       {\r
+               return countOfCollationElements;\r
+       }\r
+\r
+       /**\r
+        * This method translates the string into a series of collation elements.\r
+        * These elements will get used in the like method.\r
+        * \r
+        * @return an array of collation elements for the string\r
+        * @throws StandardException\r
+        */\r
+       int[] getCollationElementsForString()\r
+               throws StandardException\r
+       {\r
+               if (stringData.isNull())\r
+               {\r
+                       return (int[]) null;\r
+               }\r
+\r
+\r
+\r
+        // Caching of collationElementsForString is not working properly, in \r
+        // order to cache it needs to get invalidated everytime the container\r
+        // type's value is changed - through any interface, eg: readExternal, \r
+        // setValue, ...  To get proper behavior, disabling caching, and will\r
+        // file a performance enhancement to implement correct caching.\r
+        collationElementsForString = null;\r
+        countOfCollationElements   = 0;\r
+\r
+\r
+               if (collationElementsForString != null)\r
+               {\r
+                       return collationElementsForString;\r
+               }\r
+\r
+               // countOfCollationElements should always be 0 when \r
+        // collationElementsForString is null\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (countOfCollationElements != 0)\r
+                       {\r
+                               SanityManager.THROWASSERT(\r
+                                       "countOfCollationElements expected to be 0, not " + \r
+                    countOfCollationElements);\r
+                       }\r
+               }\r
+        \r
+\r
+               collationElementsForString = new int[stringData.getLength()];\r
+\r
+               CollationElementIterator cei = \r
+            collatorForCharacterDatatypes.getCollationElementIterator(\r
+                stringData.getString());\r
+\r
+               int nextInt;\r
+               while ((nextInt = cei.next()) != CollationElementIterator.NULLORDER)\r
+               {\r
+                       /* Believe it or not, a String might have more\r
+                        * collation elements than characters.\r
+                        * So, we handle that case by increasing the int array\r
+                        * by 5 and copying array elements.\r
+                        */\r
+                       if (countOfCollationElements == collationElementsForString.length)\r
+                       {\r
+                               int[] expandedArray = new int[countOfCollationElements + 5];\r
+                               System.arraycopy(collationElementsForString, 0, expandedArray, \r
+                                               0, collationElementsForString.length);\r
+                               collationElementsForString = expandedArray;\r
+                       }\r
+                       collationElementsForString[countOfCollationElements++] = nextInt;\r
+               }\r
+\r
+               return collationElementsForString;\r
+       }\r
+}\r