Package xbird.xquery.expr.var

Source Code of xbird.xquery.expr.var.BindingVariable$LetVariable

/*
* @(#)$Id: BindingVariable.java 3619 2008-03-26 07:23:03Z yui $
*
* Copyright 2006-2008 Makoto YUI
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
*     Makoto YUI - initial implementation
*/
package xbird.xquery.expr.var;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import xbird.xquery.XQueryException;
import xbird.xquery.dm.XQEventReceiver;
import xbird.xquery.dm.value.Item;
import xbird.xquery.dm.value.Sequence;
import xbird.xquery.dm.value.sequence.ValueSequence;
import xbird.xquery.expr.XQExpression;
import xbird.xquery.expr.func.FunctionCall.FunctionCallContext;
import xbird.xquery.meta.DynamicContext;
import xbird.xquery.meta.StaticContext;
import xbird.xquery.meta.XQueryContext;
import xbird.xquery.misc.QNameTable.QualifiedName;
import xbird.xquery.optim.RewriteInfo;
import xbird.xquery.parser.XQueryParserVisitor;
import xbird.xquery.type.Type;
import xbird.xquery.type.xs.StringType;
import xbird.xquery.type.xs.UnsignedIntType;

/**
*
* <DIV lang="en"></DIV>
* <DIV lang="ja"></DIV>
*
* @author Makoto YUI (yuin405+xbird@gmail.com)
*/
public abstract class BindingVariable extends Variable {
    private static final long serialVersionUID = 1L;
    private static final Log LOG = LogFactory.getLog(BindingVariable.class);
    public static final int SLOT_UNSET = -1;

    private transient int bindedSlot = SLOT_UNSET;
    private transient boolean _insideRemoteExpr = false;

    public BindingVariable(QualifiedName varName) {
        super(varName);
    }

    public BindingVariable() {//for Externalizable
        super();
    }

    @Override
    public boolean isImmutable() {
        return false;
    }

    public void setInsideRemoteExpr(boolean inside) {
        this._insideRemoteExpr = inside;
    }

    @Override
    public boolean isInsideRemoteExpr() {
        return _insideRemoteExpr;
    }

    public void setSlot(int slot) {
        this.bindedSlot = slot;
    }

    public int getSlot() {
        return bindedSlot;
    }

    @Override
    public XQExpression visit(XQueryParserVisitor visitor, XQueryContext ctxt)
            throws XQueryException {
        return visitor.visit(this, ctxt);
    }

    @Override
    public void setResult(Sequence res) {
        throw new IllegalStateException("allocateResult(Sequence, DynamicContext) method should be used");
    }

    public void allocateResult(Sequence bindingValue, DynamicContext dynEnv) {
        assert (dynEnv != null);
        assert (bindingValue != null);
        if(!(dynEnv instanceof FunctionCallContext)) {
            this._result = bindingValue;
            return;
        }
        FunctionCallContext fctxt = (FunctionCallContext) dynEnv;
        fctxt.storeLocal(this, bindingValue);
    }

    public Sequence loadResult(Sequence<? extends Item> contextSeq, DynamicContext dynEnv)
            throws XQueryException {
        if(!(dynEnv instanceof FunctionCallContext)) {
            if(_result == null) {
                return _value.eval(contextSeq, dynEnv);
            }
            return _result;
        }
        FunctionCallContext fctxt = (FunctionCallContext) dynEnv;
        int slotSize = fctxt.getSlotSize();
        final Sequence res;
        if(bindedSlot >= slotSize) {
            res = _value.eval(contextSeq, dynEnv);
            fctxt.storeLocal(this, res);
        } else if(bindedSlot == SLOT_UNSET) {
            res = _value.eval(contextSeq, dynEnv);
            fctxt.storeLocal(this, res);
        } else {
            res = fctxt.loadLocal(this, bindedSlot);
        }
        return res;
    }

    @Override
    public Sequence<? extends Item> eval(Sequence<? extends Item> contextSeq, DynamicContext dynEnv)
            throws XQueryException {
        final Sequence res = loadResult(contextSeq, dynEnv);
        if(res == null) {
            throw new IllegalStateException("The value of '$" + getName() + "' is not binded");
        }
        return res;
    }

    @Override
    public void evalAsEvents(XQEventReceiver handler, Sequence<? extends Item> contextSeq, DynamicContext dynEnv)
            throws XQueryException {
        final Sequence res = loadResult(contextSeq, dynEnv);
        if(res == null) {
            throw new IllegalStateException("The value of '$" + getName() + "' is not binded");
        }
        handler.emit(res);
    }

    //--------------------------------------------
    // subclasses

    public static final class ForVariable extends BindingVariable {
        private static final long serialVersionUID = -8304070464774579520L;

        public ForVariable(QualifiedName varName) {
            super(varName);
        }

        public ForVariable() {
            super(null);
        }

        @Override
        public boolean isPathIndexAccessable(StaticContext statEnv, RewriteInfo info) {
            if(info.isLookaheadRequired()) {
                return false;
            }
            boolean accessable = _value.isPathIndexAccessable(statEnv, info);
            if(accessable) {
                info.requestLookahead(this);
                return true;
            } else {
                return false;
            }
        }

        @Override
        public String getName() {
            final String name = super.getName();
            return name == null ? Integer.toString(System.identityHashCode(this)) : name;
        }

    }

    public static class LetVariable extends BindingVariable {
        private static final long serialVersionUID = -5649071142501903158L;

        private boolean eagarEval = false;

        public LetVariable(QualifiedName varName) {
            super(varName);
        }

        public void setEagarEvaluated(boolean eager) {
            this.eagarEval = eager;
        }

        public boolean attemptEagarEvaluation() {
            return eagarEval;
        }

        @Override
        public XQExpression staticAnalysis(StaticContext statEnv) throws XQueryException {
            super.staticAnalysis(statEnv);
            if(_referenceCount == 1) {
                return _value;
            }
            return this;
        }

        @Override
        public boolean isPathIndexAccessable(StaticContext statEnv, RewriteInfo info) {
            if(_value == null) {
                throw new IllegalStateException("value is not set.. bug?");
            }
            return _value.isPathIndexAccessable(statEnv, info);
        }
    }

    public static final class AnonymousLetVariable extends LetVariable {
        private static final long serialVersionUID = -1940001402036505359L;

        public AnonymousLetVariable(XQExpression expr) {
            super(null);
            this._value = expr;
            this._type = expr.getType();
        }

        @Override
        public String getName() {
            return Integer.toString(System.identityHashCode(this));
        }
    }

    public static final class LoopInvariantLetVariable extends LetVariable {
        private static final long serialVersionUID = 3284084573759768499L;

        public LoopInvariantLetVariable(XQExpression expr) {
            super(null);
            this._value = expr;
            this._type = expr.getType();
        }

        @Override
        public XQExpression staticAnalysis(StaticContext statEnv) throws XQueryException {
            this._analyzed = true;
            return this;
        }

        @Override
        public Sequence<Item> eval(Sequence<? extends Item> contextSeq, DynamicContext dynEnv)
                throws XQueryException {
            if(_result != null) {
                if(LOG.isTraceEnabled()) {
                    LOG.trace("reuse materialized result $" + getName());
                }
                return _result;
            }
            if(LOG.isDebugEnabled()) {
                LOG.debug("materialized $" + getName() + "=> \n" + _value);
            }
            Sequence<? extends Item> result = _value.eval(contextSeq, dynEnv);
            List<? extends Item> materialized = result.materialize();
            ValueSequence vs = new ValueSequence(materialized, dynEnv);
            this._result = vs;
            return vs;
        }

        @Override
        public String getName() {
            return Integer.toString(System.identityHashCode(this));
        }
    }

    public static final class PositionalVariable extends BindingVariable {
        private static final long serialVersionUID = 831187130699648659L;

        public PositionalVariable(QualifiedName varName) {
            super(varName);
            this._type = UnsignedIntType.UNSIGNED_INT;
        }

        @Override
        public XQExpression staticAnalysis(StaticContext statEnv) throws XQueryException {
            return this;
        }
    }

    public static final class QuantifiedVariable extends BindingVariable {
        private static final long serialVersionUID = 4005880607260478495L;

        public QuantifiedVariable(QualifiedName varName) {
            super(varName);
        }
    }

    public static final class CaseVariable extends BindingVariable {
        private static final long serialVersionUID = -7853855368064456651L;

        public CaseVariable(QualifiedName varName) {
            super(varName);
            this._type = Type.ANY;
        }

        @Override
        public CaseVariable staticAnalysis(StaticContext statEnv) throws XQueryException {
            return this;
        }
    }

    public static final class ParametricVariable extends BindingVariable {
        private static final long serialVersionUID = 4734930446193789472L;

        public ParametricVariable(QualifiedName varName) {
            super(varName);
        }

        @Override
        public XQExpression visit(XQueryParserVisitor visitor, XQueryContext ctxt)
                throws XQueryException {
            return visitor.visit(this, ctxt);
        }
    }

    public static final class ExecHostVariable extends BindingVariable implements Externalizable {
        private static final long serialVersionUID = -970934824142356358L;
        private Sequence _xferedResult = null;

        public ExecHostVariable(QualifiedName varName) {
            super(varName);
            this._type = StringType.STRING;
        }

        public ExecHostVariable() {
            super();
            this._type = StringType.STRING;
        }

        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this._varName = QualifiedName.readFrom(in);
            this._xferedResult = (Sequence) in.readObject();
        }

        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            _varName.writeExternal(out);
            out.writeObject(_xferedResult);
        }

        @Override
        public XQExpression visit(XQueryParserVisitor visitor, XQueryContext ctxt)
                throws XQueryException {
            return super.visit(visitor, ctxt);
        }

        @Override
        public XQExpression staticAnalysis(StaticContext statEnv) throws XQueryException {
            return this;
        }

        @Override
        public boolean isInsideRemoteExpr() {
            return true;
        }

        @Override
        public void allocateResult(Sequence bindingValue, DynamicContext dynEnv) {
            this._xferedResult = bindingValue;
        }

        @Override
        public Sequence loadResult(Sequence<? extends Item> contextSeq, DynamicContext dynEnv)
                throws XQueryException {
            return _xferedResult;
        }
    }

}
TOP

Related Classes of xbird.xquery.expr.var.BindingVariable$LetVariable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
', 'auto'); ga('send', 'pageview');