Package com.salas.bb.utils.discovery.detector

Source Code of com.salas.bb.utils.discovery.detector.XMLFormatDetector

// BlogBridge -- RSS feed reader, manager, and web based service
// Copyright (C) 2002-2006 by R. Pito Salas
//
// This program 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 of the License, or (at your option) any later version.
//
// This program 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 this program;
// if not, write to the Free Software Foundation, Inc., 59 Temple Place,
// Suite 330, Boston, MA 02111-1307 USA
//
// Contact: R. Pito Salas
// mailto:pitosalas@users.sourceforge.net
// More information: about BlogBridge
// http://www.blogbridge.com
// http://sourceforge.net/projects/blogbridge
//
// $Id: XMLFormatDetector.java,v 1.3 2006/11/28 11:05:27 spyromus Exp $
//

package com.salas.bb.utils.discovery.detector;

import com.salas.bb.utils.net.URLInputStream;

import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
* XML Format Detector.
*/
public class XMLFormatDetector
{
    private static final int STATE_BEGINNING        = 0;
    private static final int STATE_TAG_BEGINNING    = 1;
    private static final int STATE_COMMENT          = 2;
    private static final int STATE_XML_INSTR        = 3;

    private byte[] buf;
    private int bufPos;

    /**
     * Creates detector.
     */
    public XMLFormatDetector()
    {
        buf = new byte[4];
    }

    /**
     * Makes an attempt to read first bytes of the resource to understand its format.
     *
     * @param url url.
     *
     * @return the format or <code>NULL</code>.
     *
     * @throws java.io.IOException in case of I/O error.
     */
    public XMLFormat detect(URL url)
        throws IOException
    {
        return detect(new URLInputStream(url));
    }

    /**
     * Makes an attempt to read first bytes of the resource to understand its format.
     *
     * @param in input stream.
     *
     * @return the format or <code>NULL</code>.
     *
     * @throws java.io.IOException in case of I/O error.
     */
    public XMLFormat detect(InputStream in)
        throws IOException
    {
        int state = STATE_BEGINNING;
        bufPos = 0;
        XMLFormat fmt = null;

        int b;
        boolean finished = false;
        while (!finished && (b = in.read()) != -1)
        {
            switch (state)
            {
                case STATE_BEGINNING:
                    if (isSpace(b)) continue; else
                    if (b == '<') state = STATE_TAG_BEGINNING;
                    break;

                case STATE_TAG_BEGINNING:
                    if (b == '?') state = STATE_XML_INSTR; else
                    if (b == '!')
                    {
                        if (in.read() == '-' && in.read() == '-') state = STATE_COMMENT;
                        else state = STATE_XML_INSTR;
                    } else if ((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')) append(b); else
                    if (b == ':') bufPos = 0; else
                    {
                        fmt = parseFormat();
                        finished = true;
                    }
                    break;

                case STATE_XML_INSTR:
                    if (b == '>') state = STATE_BEGINNING;
                    break;

                case STATE_COMMENT:
                    if (b == '-' && in.read() == '-' && in.read() == '>') state = STATE_BEGINNING;
                    break;

                default:
                    break;
            }
        }

        in.close();

        return fmt;
    }

    /**
     * Returns <code>TRUE</code> if the character is space.
     *
     * @param b character code.
     *
     * @return <code>TRUE</code> if the character is space.
     */
    private static boolean isSpace(int b)
    {
        return ' ' == b || '\n' == b;
    }

    /**
     * Appends a character and increments the pointer.
     *
     * @param b character.
     */
    private void append(int b)
    {
        if (bufPos < buf.length) buf[bufPos++] = (byte)b;
    }

    /**
     * Parses the tag name saved in the buffer and returns the format.
     *
     * @return format or <code>NULL</code> if unknown.
     */
    private XMLFormat parseFormat()
    {
        XMLFormat fmt = null;

        String str = new String(buf, 0, bufPos).toLowerCase();
        if ("rss".equals(str)) fmt = XMLFormat.RSS; else
        if ("rdf".equals(str)) fmt = XMLFormat.RDF; else
        if ("feed".equals(str)) fmt = XMLFormat.ATOM; else
        if ("opml".equals(str)) fmt = XMLFormat.OPML;

        return fmt;
    }

    /**
     * Makes attempt to detect the format, and asks for clarifications if not able.
     *
     * @param url       URL to discover.
     * @param parent    parent frame.
     *
     * @return the format.
     */
    public static XMLFormat detectOrAskFormat(URL url, Component parent)
    {
        XMLFormatDetector detector = new XMLFormatDetector();
        XMLFormat fmt;

        try
        {
            fmt = detector.detect(url);
        } catch (IOException e)
        {
            fmt = chooseFormat(parent);
        }

        return fmt;
    }

    /**
     * Shows the modal dialog with the format selector.
     *
     * @param parent    parent dialog.
     *
     * @return the format.
     */
    public static XMLFormat chooseFormat(Component parent)
    {
        XMLFormat fmt = null;

        String dataFeed = "Data Feed";
        String rl = "Reading List";
        Object[] options = { dataFeed, rl };

        // TODO: Localize
        int res = JOptionPane.showOptionDialog(parent,
            "<html><b>BlogBridge is unable to access the resource.</b>\n\n" +
                "Please suggest the format:", "BlogBridge",
            JOptionPane.OK_OPTION, JOptionPane.INFORMATION_MESSAGE,
            null, options, dataFeed);

        if (res != JOptionPane.CLOSED_OPTION)
        {
            fmt = res == 0 ? XMLFormat.ATOM : XMLFormat.OPML;
        }

        return fmt;
    }
}
TOP

Related Classes of com.salas.bb.utils.discovery.detector.XMLFormatDetector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.