/* ImplementationSource.java -- 
   Copyright (C) 2004 Free Software Foundation, Inc..

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */
package gnu.xml.dom;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.DOMImplementationList;
import org.w3c.dom.DOMImplementationSource;

/**
 * Implementation source for GNU JAXP.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
public class ImplementationSource
  implements DOMImplementationSource
{

  private static final String DIGITS = "1234567890";

  /*
   * GNU DOM implementations.
   */
  private static final DOMImplementation[] implementations;

  static
  {
    List acc = new ArrayList();
    acc.add(new gnu.xml.dom.DomImpl());
    try
      {
        Class t = Class.forName("gnu.xml.libxmlj.dom.GnomeDocumentBuilder");
        acc.add(t.newInstance());
      }
    catch (Exception e)
      {
        // libxmlj not available        
      }
    catch (UnsatisfiedLinkError e)
      {
        // libxmlj not available
      }
    implementations = new DOMImplementation[acc.size()];
    acc.toArray(implementations);
  }

  public DOMImplementation getDOMImplementation(String features)
  {
    List available = getImplementations(features);
    if (available.isEmpty())
      {
        return null;
      }
    return (DOMImplementation) available.get(0);
  }

  public DOMImplementationList getDOMImplementationList(String features)
  {
    List available = getImplementations(features);
    return new ImplementationList(available);
  }

  /**
   * Returns a list of the implementations that support the specified
   * features.
   */
  private final List getImplementations(String features)
  {
    List available = new ArrayList(Arrays.asList(implementations));
    for (Iterator i = parseFeatures(features).iterator(); i.hasNext(); )
      {
        String feature = (String) i.next();
        String version = null;
        int si = feature.indexOf(' ');
        if (si != -1)
          {
            version = feature.substring(si + 1);
            feature = feature.substring(0, si);
          }
        for (Iterator j = available.iterator(); j.hasNext(); )
          {
            DOMImplementation impl = (DOMImplementation) j.next();
            if (!impl.hasFeature(feature, version))
              {
                j.remove();
              }
          }
      }
    return available;
  }

  /**
   * Parses the feature list into feature tokens.
   */
  final List parseFeatures(String features)
  {
    List list = new ArrayList();
    int pos = 0, start = 0;
    int len = features.length();
    for (; pos < len; pos++)
      {
        char c = features.charAt(pos);
        if (c == ' ')
          {
            if (pos + 1 < len &&
                DIGITS.indexOf(features.charAt(pos + 1)) == -1)
              {
                list.add(getFeature(features, start, pos));
                start = pos + 1;
              }
          }
      }
    if (pos > start)
      {
        list.add(getFeature(features, start, len));
      }
    return list;
  }

  final String getFeature(String features, int start, int end)
  {
    if (features.length() > 0 && features.charAt(start) == '+')
      {
        return features.substring(start + 1, end);
      }
    return features.substring(start, end);
  }

}
