1. /*
  2. * Copyright 1999-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.model.beans;
  17. import java.util.Locale;
  18. import org.apache.commons.jxpath.JXPathBeanInfo;
  19. import org.apache.commons.jxpath.JXPathIntrospector;
  20. import org.apache.commons.jxpath.ri.QName;
  21. import org.apache.commons.jxpath.ri.model.NodePointer;
  22. /**
  23. * A Pointer that points to a JavaBean or a collection. It is either
  24. * the first element of a path or a pointer for a property value.
  25. * Typically there is a BeanPropertyPointer between two BeanPointers
  26. * in the chain.
  27. *
  28. * @author Dmitri Plotnikov
  29. * @version $Revision: 1.13 $ $Date: 2004/02/29 14:17:41 $
  30. */
  31. public class BeanPointer extends PropertyOwnerPointer {
  32. private QName name;
  33. private Object bean;
  34. private JXPathBeanInfo beanInfo;
  35. public BeanPointer(
  36. QName name,
  37. Object bean,
  38. JXPathBeanInfo beanInfo,
  39. Locale locale)
  40. {
  41. super(null, locale);
  42. this.name = name;
  43. this.bean = bean;
  44. this.beanInfo = beanInfo;
  45. }
  46. /**
  47. * @param name is the name given to the first node
  48. */
  49. public BeanPointer(
  50. NodePointer parent,
  51. QName name,
  52. Object bean,
  53. JXPathBeanInfo beanInfo)
  54. {
  55. super(parent);
  56. this.name = name;
  57. this.bean = bean;
  58. this.beanInfo = beanInfo;
  59. }
  60. public PropertyPointer getPropertyPointer() {
  61. return new BeanPropertyPointer(this, beanInfo);
  62. }
  63. public QName getName() {
  64. return name;
  65. }
  66. /**
  67. * Returns the bean itself
  68. */
  69. public Object getBaseValue() {
  70. return bean;
  71. }
  72. /**
  73. * Returns false
  74. */
  75. public boolean isCollection() {
  76. return false;
  77. }
  78. /**
  79. * Returns 1.
  80. */
  81. public int getLength() {
  82. return 1;
  83. }
  84. public boolean isLeaf() {
  85. Object value = getNode();
  86. return value == null
  87. || JXPathIntrospector.getBeanInfo(value.getClass()).isAtomic();
  88. }
  89. public int hashCode() {
  90. return name == null ? 0 : name.hashCode();
  91. }
  92. public boolean equals(Object object) {
  93. if (object == this) {
  94. return true;
  95. }
  96. if (!(object instanceof BeanPointer)) {
  97. return false;
  98. }
  99. BeanPointer other = (BeanPointer) object;
  100. if (parent != other.parent) {
  101. if (parent == null || !parent.equals(other.parent)) {
  102. return false;
  103. }
  104. }
  105. if ((name == null && other.name != null)
  106. || (name != null && !name.equals(other.name))) {
  107. return false;
  108. }
  109. int iThis = (index == WHOLE_COLLECTION ? 0 : index);
  110. int iOther = (other.index == WHOLE_COLLECTION ? 0 : other.index);
  111. if (iThis != iOther) {
  112. return false;
  113. }
  114. if (bean instanceof Number
  115. || bean instanceof String
  116. || bean instanceof Boolean) {
  117. return bean.equals(other.bean);
  118. }
  119. return bean == other.bean;
  120. }
  121. /**
  122. * If the pointer has a parent, then parent's path.
  123. * If the bean is null, "null()".
  124. * If the bean is a primitive value, the value itself.
  125. * Otherwise - an empty string.
  126. */
  127. public String asPath() {
  128. if (parent != null) {
  129. return super.asPath();
  130. }
  131. else if (bean == null) {
  132. return "null()";
  133. }
  134. else if (bean instanceof Number) {
  135. String string = bean.toString();
  136. if (string.endsWith(".0")) {
  137. string = string.substring(0, string.length() - 2);
  138. }
  139. return string;
  140. }
  141. else if (bean instanceof Boolean) {
  142. return ((Boolean) bean).booleanValue() ? "true()" : "false()";
  143. }
  144. else if (bean instanceof String) {
  145. return "'" + bean + "'";
  146. }
  147. return "/";
  148. }
  149. }