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: /**
016: * A node that is created for queries with a non-null result spefied.
017: * This creates necc. metadata from the parsed structure to be used by the application.
018: */
019: public class ResultNode extends Node {
020: public static final int[] EMPTY_INT_ARRAY = new int[0];
021:
022: private boolean distinct;
023: private int containsVarNodes = 0;
024: private int size;
025:
026: public ResultNode(Node child) {
027: childList = child;
028: }
029:
030: public boolean isDistinct() {
031: return distinct;
032: }
033:
034: public void setDistinct(boolean distinct) {
035: this .distinct = distinct;
036: }
037:
038: public String toString() {
039: return super .toString() + " distinct = " + distinct;
040: }
041:
042: /**
043: * Resolve field refs and so on relative to the compiler. This must
044: * recursively resolve any child nodes.
045: */
046: public void resolve(QueryParser comp, ClassMetaData cmd,
047: boolean ordering) {
048: for (Node n = childList; n != null; n = n.next) {
049: n.resolve(comp, cmd, ordering);
050: size++;
051: }
052: }
053:
054: public int getResultSize() {
055: return size;
056: }
057:
058: /**
059: * Abstract method to force all nodes to implement visitor pattern
060: */
061: public Field visit(MemVisitor visitor, Object obj) {
062: return null; //To change body of implemented methods use File | Settings | File Templates.
063: }
064:
065: public boolean processForVarNodes() {
066: if (containsVarNodes == 0) {
067: if (containsVarNodeImp(this )) {
068: containsVarNodes = 1;
069: } else {
070: containsVarNodes = -1;
071: }
072: }
073: return (containsVarNodes == 1);
074: }
075:
076: private boolean containsVarNodeImp(Node n) {
077: if (n == null)
078: return false;
079: if (n instanceof VarNodeIF) {
080: ((VarNodeIF) n).setUsedInProjection(true);
081: return true;
082: }
083: if (n instanceof FieldNavNode) {
084: if (((FieldNavNode) n).var != null) {
085: ((FieldNavNode) n).var.setUsedInProjection(true);
086: return true;
087: }
088: }
089:
090: if (n.childList != null) {
091: if (containsVarNodeImp(n.childList)) {
092: return true;
093: }
094: }
095: for (Node nn = n.next; nn != null; nn = nn.next) {
096: if (containsVarNodeImp(nn))
097: return true;
098: }
099: return false;
100: }
101:
102: public Object accept(NodeVisitor visitor, Object[] results) {
103: return visitor.visitResultNode(this , results);
104: }
105:
106: public Object arrive(NodeVisitor v, Object msg) {
107: return v.arriveResultNode(this, msg);
108: }
109: }
|