import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
import org.w3c.dom.*;

public class XindiceServlet extends HttpServlet {

    // HTTP GETに対応するメソッド
    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

        // XMLで返します
        response.setContentType("text/xml; charset=UTF-8");

        PrintWriter out = response.getWriter();

        try {
            // 検索した結果をXMLで出力します
            String xpath = "//action";
            serialize(out, xpath);
        }
        catch (Exception e) {
            throw new ServletException(e);
        } 
        finally {
            out.close();
        }
    }

    // 検索した結果をDOMで受け取ってoutにシリアライズします
    public void serialize(Writer out, String xpath) throws Exception {
        org.apache.xml.serialize.OutputFormat format = new 
org.apache.xml.serialize.OutputFormat("XML", "UTF-8", false);
        format.setPreserveSpace(true);
        org.apache.xml.serialize.XMLSerializer serializer = new 
org.apache.xml.serialize.XMLSerializer(out, format);
        serializer.serialize(searchWithXindice(xpath));
    }

    // XindiceからXPathを使って検索します
    private Document searchWithXindice(String xpath) throws Exception {
        Collection col = null;

        // 検索結果をまとめる要素<result>を作成する
        javax.xml.parsers.DocumentBuilderFactory docBuilderFactory = 
javax.xml.parsers.DocumentBuilderFactory.newInstance();
        docBuilderFactory.setNamespaceAware(true);
        Document resultDocument = 
docBuilderFactory.newDocumentBuilder().newDocument();
        // 次の設定はXindiceから取得したDOMオブジェクトをXercesでimportする
ためには必要
        
((org.apache.xerces.dom.DocumentImpl)resultDocument).setErrorChecking(false);
        Element resultElement = resultDocument.createElement("result");
        resultDocument.appendChild(resultElement);

        try {
            // 1. Database実装クラスの登録
            String driver = "org.apache.xindice.client.xmldb.DatabaseImpl";
            Class c = Class.forName(driver);
            Database database = (Database) c.newInstance();
            DatabaseManager.registerDatabase(database);

            // 2. コレクションの取得
            col = DatabaseManager.getCollection("xmldb:xindice:///db/sampledb");

            // 3. XPathQueryServiceの取得
            XPathQueryService service =
                (XPathQueryService) col.getService("XPathQueryService", "1.0");

            // 5. XPathで検索
            ResourceSet resultSet = service.query(xpath);

            // 6. ResourceSetから検索結果を取り出す
            ResourceIterator results = resultSet.getIterator();
            while (results.hasMoreResources()) {
                Resource res = results.nextResource();
                if (res.getResourceType().equals("XMLResource")) {
                    org.xmldb.api.modules.XMLResource xmlres = 
(org.xmldb.api.modules.XMLResource)res;
                    org.w3c.dom.Node node = xmlres.getContentAsDOM();
                    
resultElement.appendChild(resultDocument.importNode(node.getFirstChild(), true));
                }
            }
        }
        catch (XMLDBException e) {
            throw new ServletException(e);
        }
        finally {
           if (col != null) {
              // 7. コレクションのクローズ
              col.close();
           }
        }

        return resultDocument;
    }

}

