All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.semanticwb.base.util.parser.html.HTMLParser Maven / Gradle / Ivy

The newest version!
/*
 * SemanticWebBuilder es una plataforma para el desarrollo de portales y aplicaciones de integración,
 * colaboración y conocimiento, que gracias al uso de tecnología semántica puede generar contextos de
 * información alrededor de algún tema de interés o bien integrar información y aplicaciones de diferentes
 * fuentes, donde a la información se le asigna un significado, de forma que pueda ser interpretada y
 * procesada por personas y/o sistemas, es una creación original del Fondo de Información y Documentación
 * para la Industria INFOTEC, cuyo registro se encuentra actualmente en trámite.
 *
 * INFOTEC pone a su disposición la herramienta SemanticWebBuilder a través de su licenciamiento abierto al público ('open source'),
 * en virtud del cual, usted podrá usarlo en las mismas condiciones con que INFOTEC lo ha diseñado y puesto a su disposición;
 * aprender de él; distribuirlo a terceros; acceder a su código fuente y modificarlo, y combinarlo o enlazarlo con otro software,
 * todo ello de conformidad con los términos y condiciones de la LICENCIA ABIERTA AL PÚBLICO que otorga INFOTEC para la utilización
 * del SemanticWebBuilder 4.0.
 *
 * INFOTEC no otorga garantía sobre SemanticWebBuilder, de ninguna especie y naturaleza, ni implícita ni explícita,
 * siendo usted completamente responsable de la utilización que le dé y asumiendo la totalidad de los riesgos que puedan derivar
 * de la misma.
 *
 * Si usted tiene cualquier duda o comentario sobre SemanticWebBuilder, INFOTEC pone a su disposición la siguiente
 * dirección electrónica:
 *  http://www.semanticwebbuilder.org.mx
 */
package org.semanticwb.base.util.parser.html;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.Reader;

import org.semanticwb.SWBUtils;

/**
 * The Class HTMLParser.
 */
public class HTMLParser implements HTMLParserConstants {

	/** The SUMMAR y_ length. */
	public static final int SUMMARY_LENGTH = 200;

	/** The title. */
	StringBuilder title = new StringBuilder(SUMMARY_LENGTH);

	/** The summary. */
	StringBuilder summary = new StringBuilder(SUMMARY_LENGTH * 2);

	/** The length. */
	int length = 0;

	/** The title complete. */
	boolean titleComplete = false;

	/** The in title. */
	boolean inTitle = false;

	/** The in script. */
	boolean inScript = false;

	/** The after tag. */
	boolean afterTag = false;

	/** The after space. */
	boolean afterSpace = false;

	/** The eol. */
	String eol = System.getProperty("line.separator");

	/** The pipe in. */
	PipedReader pipeIn = null;

	/** The pipe out. */
	PipedWriter pipeOut;

	/**
	 * Instantiates a new hTML parser.
	 * 
	 * @param file
	 *            the file
	 * @throws FileNotFoundException
	 *             the file not found exception
	 */
	public HTMLParser(File file) throws FileNotFoundException {
		this(new FileInputStream(file));
	}

	/**
	 * Gets the title.
	 * 
	 * @return the title
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 * @throws InterruptedException
	 *             the interrupted exception
	 */
	public String getTitle() throws IOException, InterruptedException {
		if (pipeIn == null) {
			getReader(); // spawn parsing thread
		}
		while (true) {
			synchronized (this) {
				if (titleComplete || (length > SUMMARY_LENGTH)) {
					break;
				}
				wait(10);
			}
		}
		return title.toString().trim();
	}

	/**
	 * Gets the summary.
	 * 
	 * @return the summary
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 * @throws InterruptedException
	 *             the interrupted exception
	 */
	public String getSummary() throws IOException, InterruptedException {
		if (pipeIn == null) {
			getReader(); // spawn parsing thread
		}
		while (true) {
			synchronized (this) {
				if (summary.length() >= SUMMARY_LENGTH) {
					break;
				}
				wait(10);
			}
		}
		if (summary.length() > SUMMARY_LENGTH) {
			summary.setLength(SUMMARY_LENGTH);
		}

		String sum = summary.toString().trim();
		String tit = getTitle();
		if (sum.startsWith(tit)) {
			return sum.substring(tit.length());
		} else {
			return sum;
		}
	}

	/**
	 * Gets the text.
	 * 
	 * @return the text
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 * @throws InterruptedException
	 *             the interrupted exception
	 */
	public String getText() throws IOException {
		String ret = null;
		ret = SWBUtils.IO.readReader(getReader());
		return ret;
	}

	/**
	 * Gets the reader.
	 * 
	 * @return the reader
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public Reader getReader() throws IOException {
		if (pipeIn == null) {
			pipeIn = new PipedReader();
			pipeOut = new PipedWriter(pipeIn);

			Thread thread = new ParserThread(this);
			thread.start(); // start parsing
		}

		return pipeIn;
	}

	/**
	 * Adds the to summary.
	 * 
	 * @param text
	 *            the text
	 */
	void addToSummary(String text) {
		if (summary.length() < SUMMARY_LENGTH) {
			summary.append(text);
			if (summary.length() >= SUMMARY_LENGTH) {
				synchronized (this) {
					notifyAll();
				}
			}
		}
	}

	/**
	 * Adds the text.
	 * 
	 * @param text
	 *            the text
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	void addText(String text) throws IOException {
		if (inScript) {
			return;
		}
		if (inTitle) {
			title.append(text);
		} else {
			addToSummary(text);
			if (!titleComplete && !title.toString().equals("")) { // finished title
				synchronized (this) {
					titleComplete = true; // tell waiting threads
					notifyAll();
				}
			}
		}

		length += text.length();
		pipeOut.write(text);

		afterSpace = false;
	}

	/**
	 * Adds the space.
	 * 
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	void addSpace() throws IOException {
		if (inScript) {
			return;
		}
		if (!afterSpace) {
			if (inTitle) {
				title.append(" ");
			} else {
				addToSummary(" ");
			}

			String space = afterTag ? eol : " ";
			length += space.length();
			pipeOut.write(space);
			afterSpace = true;
		}
	}

	/**
	 * HTML document.
	 * 
	 * @throws ParseException
	 *             the parse exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public final void HTMLDocument() throws ParseException, IOException {
		Token t;
		label_1: 
		while (true) {
			switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
			case TagName:
			case DeclName:
			case Comment1:
			case Comment2:
			case Word:
			case Entity:
			case Space:
			case Punct:
				break;
			default:
				jj_la1[0] = jj_gen;
				break label_1;
			}
			switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
			case TagName:
				Tag();
				afterTag = true;
				break;
			case DeclName:
				t = Decl();
				afterTag = true;
				break;
			case Comment1:
			case Comment2:
				CommentTag();
				afterTag = true;
				break;
			case Word:
				t = jj_consume_token(Word);
				addText(t.image);
				afterTag = false;
				break;
			case Entity:
				t = jj_consume_token(Entity);
				addText(Entities.decode(t.image));
				afterTag = false;
				break;
			case Punct:
				t = jj_consume_token(Punct);
				addText(t.image);
				afterTag = false;
				break;
			case Space:
				jj_consume_token(Space);
				addSpace();
				afterTag = false;
				break;
			default:
				jj_la1[1] = jj_gen;
				jj_consume_token(-1);
				throw new ParseException();
			}
		}
		jj_consume_token(0);
	}

	/**
	 * Tag.
	 * 
	 * @throws ParseException
	 *             the parse exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public final void Tag() throws ParseException, IOException {
		Token t1, t2;
		boolean inImg = false;
		t1 = jj_consume_token(TagName);
		inTitle = t1.image.equalsIgnoreCase("
		inImg = t1.image.equalsIgnoreCase("
		if (inScript) { // keep track if in