/**
 * GUI Commands
 * Copyright 2004 Andrew Pietsch
 *
 * 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.
 *
 * $Id: Util.java,v 1.8 2006/02/26 00:59:06 pietschy Exp $
 */

package org.pietschy.command;

import org.jaxen.JaxenException;
import org.jaxen.dom.DOMXPath;
import org.w3c.dom.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

class
Util
{
   static final String _ID_ = "$Id: Util.java,v 1.8 2006/02/26 00:59:06 pietschy Exp $";
   private static HashMap evaluators = new HashMap();

   /**
    * Attempts to retrive the specified attribute from the element.
    *
    * @return the attribute value if it exists, otherwise it returns null.
    */
   public static String
   getAttribute(Element element, String attributeName)
   {
      if (element == null)
         throw new NullPointerException("element is null");

      if (attributeName == null)
         throw new NullPointerException("attributeName is null");

      Attr attribute = element.getAttributeNode(attributeName);
      return (attribute != null) ? attribute.getValue() : null;
   }

   public static String
   getElementId(Element element)
   {
      String id = getAttribute(element, Names.ID_ATTRIBUTE);
      if (id == null || id.trim().length() < 1)
         throw new IllegalArgumentException("Missing ID on element: " + element.getTagName());

      return id;
   }

   public static boolean
   isEmpty(String s)
   {
      return s == null || s.trim().length() < 1;
   }

   public static Node
   getFirstElement(Element element, String name)
   {
      if (element == null)
         throw new NullPointerException("element is null");

      if (name == null)
         throw new NullPointerException("name is null");

      NodeList list = element.getElementsByTagName(name);
      return list != null & list.getLength() > 0 ? list.item(0) : null;
   }

   public static List
   getElementsByName(Element element, String name)
   {
      if (element == null)
         throw new NullPointerException("element is null");

      if (name == null)
         throw new NullPointerException("name is null");

      NodeList nodes = element.getElementsByTagName(name);

      if (nodes == null)
         return Collections.EMPTY_LIST;

      ArrayList list = new ArrayList();
      for (int i = 0; i < nodes.getLength(); i++)
      {
         Node n = nodes.item(i);
         if (n.getNodeType() == Node.ELEMENT_NODE)
            list.add(n);
      }

      return list;
   }

   public static List
   getElements(Node node)
   {
      if (node == null)
         throw new NullPointerException("node is null");

      NodeList nodes = node.getChildNodes();

      if (nodes == null)
         return Collections.EMPTY_LIST;

      ArrayList list = new ArrayList();
      for (int i = 0; i < nodes.getLength(); i++)
      {
         Node n = nodes.item(i);
         if (n.getNodeType() == Node.ELEMENT_NODE)
            list.add(n);
      }
      return list;
   }


   public static Node
   selectSingleNode(Node node, String expression)
   {
      if (node == null)
         throw new NullPointerException("node is null");

      if (expression == null)
         throw new NullPointerException("expression is null");

      try
      {
         return (Node) getEvaluator(expression).selectSingleNode(node);
      }
      catch (JaxenException e)
      {
         throw new RuntimeException("Invalid xpath expression", e);
      }
   }

   public static List
   selectNodes(Node node, String expression)
   {
      if (node == null)
         throw new NullPointerException("node is null");

      if (expression == null)
         throw new NullPointerException("expression is null");

      try
      {
         return getEvaluator(expression).selectNodes(node);
      }
      catch (JaxenException e)
      {
         throw new RuntimeException("Invalid xpath expression", e);
      }
   }

   private static DOMXPath
   getEvaluator(String expression)
   throws JaxenException
   {
      if (expression == null)
         throw new NullPointerException("expression is null");

      DOMXPath evaluator = (DOMXPath) evaluators.get(expression);
      if (evaluator == null)
      {
         evaluator = new DOMXPath(expression);
         evaluators.put(expression, evaluator);
      }

      return evaluator;
   }

   public static String
   getElementText(Element e)
   {
      if (e == null)
         return null;

      StringBuffer buf = new StringBuffer();
      NodeList children = e.getChildNodes();
      for (int i = 0; i < children.getLength(); i++)
      {
         Node node = children.item(i);

         if (node instanceof CDATASection)
         {
            buf.append(((CDATASection) node).getNodeValue());
         }
         else if (node instanceof Text)
         {
            buf.append(((Text) node).getNodeValue());
         }
      }

      return buf.toString();
   }
}
