Package xbird.xquery.func.seq

Source Code of xbird.xquery.func.seq.IndexOf$IndexOfEmuration

/*
* @(#)$Id: IndexOf.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.func.seq;

import java.io.ObjectStreamException;
import java.text.Collator;
import java.util.Iterator;

import xbird.util.resource.CollationUtils;
import xbird.xquery.XQueryException;
import xbird.xquery.dm.value.*;
import xbird.xquery.dm.value.sequence.ProxySequence;
import xbird.xquery.dm.value.sequence.ValueSequence;
import xbird.xquery.func.BuiltInFunction;
import xbird.xquery.func.FunctionSignature;
import xbird.xquery.meta.DynamicContext;
import xbird.xquery.meta.IFocus;
import xbird.xquery.misc.TypeUtil;
import xbird.xquery.type.*;
import xbird.xquery.type.xs.StringType;

/**
* fn:index-of.
* <DIV lang="en">
* Returns a sequence of positive integers giving the positions
* within the sequence $seqParam of items that are equal to $srchParam.
* <ul>
* <li>fn:index-of($seqParam as xdt:anyAtomicType*, $srchParam as xdt:anyAtomicType) as xs:integer*</li>
* <li>fn:index-of($seqParam as xdt:anyAtomicType*, $srchParam as xdt:anyAtomicType, $collation as xs:string) as xs:integer*</li>
* </ul>
* </DIV>
* <DIV lang="ja"></DIV>
*
* @author Makoto YUI (yuin405+xbird@gmail.com)
* @link http://www.w3.org/TR/xquery-operators/#func-index-of
*/
public final class IndexOf extends BuiltInFunction {
    private static final long serialVersionUID = 1498600419388016663L;
    public static final String SYMBOL = "fn:index-of";

    public IndexOf() {
        super(SYMBOL, TypeRegistry.safeGet("xs:integer*"));
    }

    protected FunctionSignature[] signatures() {
        final FunctionSignature[] s = new FunctionSignature[2];
        final Type anyatom = TypeRegistry.safeGet("xs:anyAtomicType*");
        s[0] = new FunctionSignature(getName(), new Type[] { anyatom, AtomicType.ANY_ATOMIC_TYPE });
        s[1] = new FunctionSignature(getName(), new Type[] { anyatom, AtomicType.ANY_ATOMIC_TYPE,
                StringType.STRING });
        return s;
    }

    /**
     * Note:
     *  The first item in a sequence is at position 1, not position 0.
     *  The result sequence is in ascending numeric order.
     */
    public Sequence eval(Sequence<? extends Item> contextSeq, ValueSequence argv, DynamicContext dynEnv)
            throws XQueryException {
        final Sequence<? extends Item> src = argv.getItem(0).atomize(dynEnv);
        final Item target = argv.getItem(1);
        final AtomicValue searchItem = (AtomicValue) target;
        final Item coll = (argv.size() == 3) ? argv.getItem(2) : null;
        return new IndexOfEmuration(src, searchItem, (coll != null) ? coll.stringValue() : null, dynEnv);
    }

    private static final class IndexOfEmuration extends ProxySequence {
        private static final long serialVersionUID = 3824666835912342600L;

        private final AtomicValue _searchItem;
        private final String _collation;
        /** The collation is used when string comparison is required. */
        private transient Collator _collator = null;
        private String _searchItemStr;

        public IndexOfEmuration(Sequence<? extends Item> src, AtomicValue searchItem, String collation, DynamicContext dynEnv) {
            super(src, dynEnv);
            assert (searchItem != null);
            this._searchItem = searchItem;
            this._collation = collation;
            if(TypeUtil.subtypeOf(searchItem.getType(), StringType.STRING)) {
                this._searchItemStr = searchItem.stringValue();
                if(collation != null) {
                    this._collator = CollationUtils.resolve(collation, dynEnv.getStaticContext());
                }
            }
        }

        public boolean next(IFocus focus) throws XQueryException {
            Iterator<? extends Item> srcItor = focus.getBaseFocus();
            while(srcItor.hasNext()) {
                Item srcItem = srcItor.next();
                assert (srcItem != null);
                if(found(srcItem)) {
                    focus.setContextItem(srcItem);
                    return true;
                }
            }
            return false;
        }

        private boolean found(Item srcItem) {
            final int cmp;
            // TODO when string comparison is required?
            if(_searchItemStr != null && _collator != null) {
                cmp = _collator.compare(srcItem, _searchItemStr);
            } else {
                cmp = srcItem.compareTo(_searchItem);
            }
            return cmp == 0;
        }

        @Override
        public Type getType() {
            return TypeRegistry.safeGet("xs:integer*");
        }

        private Object readResolve() throws ObjectStreamException {
            if(_collator == null && _collation != null) {
                assert (_dynEnv != null);
                this._collator = CollationUtils.resolve(_collation, _dynEnv.getStaticContext());
            }
            return this;
        }

    }

}
TOP

Related Classes of xbird.xquery.func.seq.IndexOf$IndexOfEmuration

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.