1. /*
  2. * Copyright 2002-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.jxpath.ri.compiler;
  17. import java.util.Collection;
  18. import java.util.HashSet;
  19. import java.util.Iterator;
  20. import org.apache.commons.jxpath.Pointer;
  21. import org.apache.commons.jxpath.ri.EvalContext;
  22. import org.apache.commons.jxpath.ri.InfoSetUtil;
  23. import org.apache.commons.jxpath.ri.axes.InitialContext;
  24. import org.apache.commons.jxpath.ri.axes.SelfContext;
  25. /**
  26. * Common superclass for the implementations of Expression for the operations
  27. * "=" and "!=".
  28. *
  29. * @author Dmitri Plotnikov
  30. * @version $Revision: 1.3 $ $Date: 2004/02/29 14:17:38 $
  31. */
  32. public abstract class CoreOperationCompare extends CoreOperation {
  33. public CoreOperationCompare(Expression arg1, Expression arg2) {
  34. super(new Expression[] { arg1, arg2 });
  35. }
  36. /**
  37. * Compares two values
  38. */
  39. protected boolean equal(
  40. EvalContext context,
  41. Expression left,
  42. Expression right)
  43. {
  44. Object l = left.compute(context);
  45. Object r = right.compute(context);
  46. // System.err.println("COMPARING: " +
  47. // (l == null ? "null" : l.getClass().getName()) + " " +
  48. // (r == null ? "null" : r.getClass().getName()));
  49. if (l instanceof InitialContext || l instanceof SelfContext) {
  50. l = ((EvalContext) l).getSingleNodePointer();
  51. }
  52. if (r instanceof InitialContext || r instanceof SelfContext) {
  53. r = ((EvalContext) r).getSingleNodePointer();
  54. }
  55. if (l instanceof Collection) {
  56. l = ((Collection) l).iterator();
  57. }
  58. if (r instanceof Collection) {
  59. r = ((Collection) r).iterator();
  60. }
  61. if ((l instanceof Iterator) && !(r instanceof Iterator)) {
  62. return contains((Iterator) l, r);
  63. }
  64. else if (!(l instanceof Iterator) && (r instanceof Iterator)) {
  65. return contains((Iterator) r, l);
  66. }
  67. else if (l instanceof Iterator && r instanceof Iterator) {
  68. return findMatch((Iterator) l, (Iterator) r);
  69. }
  70. return equal(l, r);
  71. }
  72. protected boolean contains(Iterator it, Object value) {
  73. while (it.hasNext()) {
  74. Object element = it.next();
  75. if (equal(element, value)) {
  76. return true;
  77. }
  78. }
  79. return false;
  80. }
  81. protected boolean findMatch(Iterator lit, Iterator rit) {
  82. HashSet left = new HashSet();
  83. while (lit.hasNext()) {
  84. left.add(lit.next());
  85. }
  86. while (rit.hasNext()) {
  87. if (contains(left.iterator(), rit.next())) {
  88. return true;
  89. }
  90. }
  91. return false;
  92. }
  93. protected boolean equal(Object l, Object r) {
  94. if (l instanceof Pointer && r instanceof Pointer) {
  95. if (l.equals(r)) {
  96. return true;
  97. }
  98. }
  99. if (l instanceof Pointer) {
  100. l = ((Pointer) l).getValue();
  101. }
  102. if (r instanceof Pointer) {
  103. r = ((Pointer) r).getValue();
  104. }
  105. if (l == r) {
  106. return true;
  107. }
  108. // System.err.println("COMPARING VALUES: " + l + " " + r);
  109. if (l instanceof Boolean || r instanceof Boolean) {
  110. return (InfoSetUtil.booleanValue(l) == InfoSetUtil.booleanValue(r));
  111. }
  112. else if (l instanceof Number || r instanceof Number) {
  113. return (InfoSetUtil.doubleValue(l) == InfoSetUtil.doubleValue(r));
  114. }
  115. else if (l instanceof String || r instanceof String) {
  116. return (
  117. InfoSetUtil.stringValue(l).equals(InfoSetUtil.stringValue(r)));
  118. }
  119. else if (l == null) {
  120. return r == null;
  121. }
  122. return l.equals(r);
  123. }
  124. }