/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */
/*
 * $Id$
 */
package org.apache.xalan.templates;

import java.util.Hashtable;

import org.apache.xalan.transformer.KeyManager;
import org.apache.xalan.transformer.TransformerImpl;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMIterator;
import org.apache.xml.utils.QName;
import org.apache.xml.utils.XMLString;
import org.apache.xpath.XPathContext;
import org.apache.xpath.axes.UnionPathIterator;
import org.apache.xpath.functions.Function2Args;
import org.apache.xpath.objects.XNodeSet;
import org.apache.xpath.objects.XObject;

/**
 * Execute the Key() function.
 * @xsl.usage advanced
 */
public class FuncKey extends Function2Args
{
    static final long serialVersionUID = 9089293100115347340L;

  /** Dummy value to be used in usedrefs hashtable           */
  static private Boolean ISTRUE = new Boolean(true);

  /**
   * Execute the function.  The function must return
   * a valid object.
   * @param xctxt The current execution context.
   * @return A valid XObject.
   *
   * @throws javax.xml.transform.TransformerException
   */
  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
  {

    // TransformerImpl transformer = (TransformerImpl)xctxt;
    TransformerImpl transformer = (TransformerImpl) xctxt.getOwnerObject();
    XNodeSet nodes = null;
    int context = xctxt.getCurrentNode();
    DTM dtm = xctxt.getDTM(context);
    int docContext = dtm.getDocumentRoot(context);

    if (DTM.NULL == docContext)
    {

      // path.error(context, XPATHErrorResources.ER_CONTEXT_HAS_NO_OWNERDOC); //"context does not have an owner document!");
    }

    String xkeyname = getArg0().execute(xctxt).str();
    QName keyname = new QName(xkeyname, xctxt.getNamespaceContext());
    XObject arg = getArg1().execute(xctxt);
    boolean argIsNodeSetDTM = (XObject.CLASS_NODESET == arg.getType());
    KeyManager kmgr = transformer.getKeyManager();
    
    // Don't bother with nodeset logic if the thing is only one node.
    if(argIsNodeSetDTM)
    {
    	XNodeSet ns = (XNodeSet)arg;
    	ns.setShouldCacheNodes(true);
    	int len = ns.getLength();
    	if(len <= 1)
    		argIsNodeSetDTM = false;
    }

    if (argIsNodeSetDTM)
    {
      Hashtable usedrefs = null;
      DTMIterator ni = arg.iter();
      int pos;
      UnionPathIterator upi = new UnionPathIterator();
      upi.exprSetParent(this);

      while (DTM.NULL != (pos = ni.nextNode()))
      {
        dtm = xctxt.getDTM(pos);
        XMLString ref = dtm.getStringValue(pos);

        if (null == ref)
          continue;

        if (null == usedrefs)
          usedrefs = new Hashtable();

        if (usedrefs.get(ref) != null)
        {
          continue;  // We already have 'em.
        }
        else
        {

          // ISTRUE being used as a dummy value.
          usedrefs.put(ref, ISTRUE);
        }

        XNodeSet nl =
          kmgr.getNodeSetDTMByKey(xctxt, docContext, keyname, ref,
                               xctxt.getNamespaceContext());
                               
        nl.setRoot(xctxt.getCurrentNode(), xctxt);

//        try
//        {
          upi.addIterator(nl);
//        }
//        catch(CloneNotSupportedException cnse)
//        {
//          // will never happen.
//        }
        //mnodeset.addNodesInDocOrder(nl, xctxt); needed??
      }

      int current = xctxt.getCurrentNode();
      upi.setRoot(current, xctxt);

      nodes = new XNodeSet(upi);
    }
    else
    {
      XMLString ref = arg.xstr();
      nodes = kmgr.getNodeSetDTMByKey(xctxt, docContext, keyname,
                                                ref,
                                                xctxt.getNamespaceContext());
      nodes.setRoot(xctxt.getCurrentNode(), xctxt);
    }

    return nodes;
  }
}
