/*
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * 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.
 */

package org.jboss.axis.utils;

import org.jboss.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.Name;

/**
 * DOM2 utilites
 *
 * @author Thomas Diesler (thomas.diesler@jboss.org)
 */
public final class DOM2Utils
{

   private static Logger log = Logger.getLogger(DOM2Utils.class.getName());

   // The DocumentBuilder
   private static DocumentBuilder builder = getDocumentBuilder();

   // Hide the constructor
   private DOM2Utils()
   {
   }

   /**
    * Initialise the the DocumentBuilder
    */
   public static DocumentBuilder getDocumentBuilder()
   {

      if (builder == null)
      {
         try
         {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setValidating(false);
            factory.setNamespaceAware(true);
            builder = factory.newDocumentBuilder();
         }
         catch (ParserConfigurationException e)
         {
            log.error(e);
         }
      }

      return builder;
   }

   /**
    * Create an Element for a given name
    *
    * @param parent optional parent element
    */
   public static Element createElement(Element parent, String localPart)
   {
      Document doc = getOwnerDocument(parent);
      log.debug("createElement {}" + localPart);
      return doc.createElement(localPart);
   }

   /**
    * Create an Element for a given name and prefix
    *
    * @param parent optional parent element
    */
   public static Element createElement(Element parent, String localPart, String prefix)
   {
      Document doc = getOwnerDocument(parent);
      log.debug("createElement {}" + prefix + ":" + localPart);
      return doc.createElement(prefix + ":" + localPart);
   }

   /**
    * Create an Element for a given name, prefix and uri
    *
    * @param parent optional parent element
    */
   public static Element createElement(Element parent, String uri, String prefix, String localPart)
   {
      Document doc = getOwnerDocument(parent);
      if (prefix == null || prefix.length() == 0)
      {
         log.debug("createElement {" + uri + "}" + localPart);
         return doc.createElementNS(uri, localPart);
      }
      else
      {
         log.debug("createElement {" + uri + "}" + prefix + ":" + localPart);
         return doc.createElementNS(uri, prefix + ":" + localPart);
      }
   }

   /**
    * Create an Element for a given Name object
    *
    * @param parent optional parent element
    */
   public static Element createElement(Element parent, Name name)
   {
      return createElement(parent, name.getURI(), name.getPrefix(), name.getLocalName());
   }

   /**
    * Create a org.w3c.dom.Text node
    */
   public static Text createTextNode(String value)
   {
      Document doc = builder.newDocument();
      return doc.createTextNode(value);
   }

   private static Document getOwnerDocument(Node parent)
   {
      Document doc = null;
      if (parent != null)
         doc = parent.getOwnerDocument();
      if (doc == null)
         doc = builder.newDocument();
      return doc;
   }
}