001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdo.query;
012:
013: import com.versant.core.metadata.ClassMetaData;
014:
015: import com.versant.core.common.BindingSupportImpl;
016:
017: /**
018: * This is a node with exactly two children. It is optimized to take
019: * advantage of this.
020: */
021: public class BinaryNode extends Node {
022:
023: public BinaryNode() {
024: }
025:
026: public BinaryNode(Node left, Node right) {
027: childList = left;
028: if (left != null) {
029: left.next = right;
030: left.parent = this ;
031: }
032: if (right != null) {
033: right.parent = this ;
034: }
035: }
036:
037: public final Node getLeft() {
038: return childList;
039: }
040:
041: public final Node getRight() {
042: return childList.next;
043: }
044:
045: /**
046: * Resolve field refs and so on relative to the compiler. This must
047: * recursively resolve any child nodes.
048: */
049: public void resolve(QueryParser comp, ClassMetaData cmd,
050: boolean ordering) {
051: childList.resolve(comp, cmd, false);
052: childList.next.resolve(comp, cmd, false);
053: }
054:
055: /**
056: * Replace one node with another.
057: */
058: public void replaceChild(Node old, Node nw) {
059: if (childList == old) {
060: nw.next = childList.next;
061: childList = nw;
062: } else if (childList.next == old) {
063: childList.next = nw;
064: nw.next = null;
065: } else {
066: throw BindingSupportImpl.getInstance().internal(
067: "no such Node: " + old);
068: }
069: nw.parent = this ;
070: }
071:
072: /**
073: * Simplify this node tree as much as possible.
074: */
075: public void normalizeImp() {
076: childList.normalizeImp();
077: childList.next.normalizeImp();
078:
079: // swap left and right nodes if a literal or param is on the left
080: if (childList instanceof LiteralNode
081: || childList instanceof ParamNode
082: || childList instanceof ParamNodeProxy) {
083: swapLeftAndRight();
084: }
085: }
086:
087: /**
088: * Swap left and right nodes.
089: */
090: protected void swapLeftAndRight() {
091: Node t = childList;
092: childList = childList.next;
093: childList.next = t;
094: t.next = null;
095: }
096:
097: public Field visit(MemVisitor visitor, Object obj) {
098: return visitor.visitBinaryNode(this , obj);
099: }
100:
101: public Object arrive(NodeVisitor v, Object msg) {
102: return v.arriveBinaryNode(this, msg);
103: }
104: }
|