Package ch.entwine.weblounge.common.impl.content.page

Source Code of ch.entwine.weblounge.common.impl.content.page.PageReader

/*
*  Weblounge: Web Content Management System
*  Copyright (c) 2003 - 2011 The Weblounge Team
*  http://entwinemedia.com/weblounge
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public License
*  along with this program; if not, write to the Free Software Foundation
*  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package ch.entwine.weblounge.common.impl.content.page;

import ch.entwine.weblounge.common.content.ResourceContent;
import ch.entwine.weblounge.common.content.ResourceReader;
import ch.entwine.weblounge.common.content.ResourceUtils;
import ch.entwine.weblounge.common.content.page.Page;
import ch.entwine.weblounge.common.content.page.PageletURI;
import ch.entwine.weblounge.common.impl.content.WebloungeContentReader;
import ch.entwine.weblounge.common.impl.language.LanguageUtils;
import ch.entwine.weblounge.common.language.Language;
import ch.entwine.weblounge.common.security.Authority;
import ch.entwine.weblounge.common.security.Permission;
import ch.entwine.weblounge.common.security.User;
import ch.entwine.weblounge.common.site.Site;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.Date;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

/**
* Utility class used to parse page data.
*/
public class PageReader extends WebloungeContentReader implements ResourceReader<ResourceContent, Page> {

  /** Logging facility */
  private static final Logger logger = LoggerFactory.getLogger(PageReader.class);

  /** Parser factory */
  private static final SAXParserFactory parserFactory = SAXParserFactory.newInstance();

  /** The SAX parser */
  private WeakReference<SAXParser> parserRef = null;

  /** The page object */
  private PageImpl page = null;

  /** Reader used to process pagelet data */
  private PageletReader pageletReader = null;

  /** The composer name */
  private String composer = null;

  /** The pagelet position within the composer */
  private int position = 0;

  /** Flag to indicate whether the page header should be read */
  private boolean readHeader = true;

  /** Flag to indicate whether the page body should be read */
  private boolean readBody = true;

  private enum ParserContext {
    Document, Page, Head, Body, Pagelet
  };

  /** The parser context */
  private ParserContext parserContext = ParserContext.Document;

  /**
   * Creates a new page data reader that will parse the XML data and store it in
   * the <code>Page</code> object that is returned by the {@link #read()} method.
   *
   * @throws ParserConfigurationException
   *           if the SAX parser setup failed
   * @throws SAXException
   *           if an error occurs while parsing
   */
  public PageReader() throws ParserConfigurationException, SAXException {
    parserRef = new WeakReference<SAXParser>(parserFactory.newSAXParser());
    pageletReader = new PageletReader();
  }

  /**
   * This method is called when a <code>Page</code> object is instantiated.
   *
   * @param is
   *          the xml input stream
   * @param site
   *          the page's site
   *
   * @throws IOException
   *           if reading the input stream fails
   */
  public PageImpl read(InputStream is, Site site) throws SAXException,
      IOException, ParserConfigurationException {
    reset();
    page = new PageImpl(new PageURIImpl(site, "/"));
    readHeader = true;
    readBody = true;
    SAXParser parser = parserRef.get();
    if (parser == null) {
      parser = parserFactory.newSAXParser();
      parserRef = new WeakReference<SAXParser>(parser);
    }
    parser.parse(is, this);
    return page;
  }

  /**
   * This method is called when a <code>Page</code> object is instantiated.
   *
   * @param is
   *          the xml input stream
   * @param site
   *          the page's site
   * @throws ParserConfigurationException
   *           if the SAX parser setup failed
   * @throws IOException
   *           if reading the input stream fails
   * @throws SAXException
   *           if an error occurs while parsing
   */
  public PageImpl readHeader(InputStream is, Site site)
      throws SAXException, IOException, ParserConfigurationException {
    if (page == null) {
      page = new PageImpl(new PageURIImpl(site, "/"));
    }
    readHeader = true;
    readBody = false;
    SAXParser parser = parserRef.get();
    if (parser == null) {
      parser = parserFactory.newSAXParser();
      parserRef = new WeakReference<SAXParser>(parser);
    }
    parser.parse(is, this);
    return page;
  }

  /**
   * This method is called when a <code>Page</code> object is instantiated.
   *
   * @param is
   *          the xml input stream
   * @param site
   *          the page's site
   * @throws ParserConfigurationException
   *           if the SAX parser setup failed
   * @throws IOException
   *           if reading the input stream fails
   * @throws SAXException
   *           if an error occurs while parsing
   */
  public PageImpl readBody(InputStream is, Site site)
      throws SAXException, IOException, ParserConfigurationException {
    if (page == null) {
      page = new PageImpl(new PageURIImpl(site, "/"));
    }
    readHeader = false;
    readBody = true;
    SAXParser parser = parserRef.get();
    if (parser == null) {
      parser = parserFactory.newSAXParser();
      parserRef = new WeakReference<SAXParser>(parser);
    }
    parser.parse(is, this);
    return page;
  }

  /**
   * Sets the page that needs to be further enriched with content from an xml
   * document.
   *
   * @param page
   *          the page
   */
  public void init(PageImpl page) {
    this.page = page;
  }

  /**
   * Resets this parser instance.
   */
  public void reset() {
    super.reset();
    this.page = null;
    this.composer = null;
    this.parserContext = ParserContext.Document;
    this.position = 0;
    this.pageletReader.reset();
    SAXParser parser = parserRef.get();
    if (parser != null)
      parser.reset();
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.impl.content.WebloungeContentReader#setOwner(ch.entwine.weblounge.common.security.User)
   */
  @Override
  protected void setOwner(User owner) {
    if (parserContext.equals(ParserContext.Pagelet))
      pageletReader.setOwner(owner);
    else
      page.setOwner(owner);
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.impl.content.WebloungeContentReader#allow(ch.entwine.weblounge.common.security.Permission,
   *      ch.entwine.weblounge.common.security.Authority)
   */
  @Override
  protected void allow(Permission permission, Authority authority) {
    if (parserContext.equals(ParserContext.Pagelet))
      pageletReader.allow(permission, authority);
    else
      page.allow(permission, authority);
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.impl.content.WebloungeContentReader#setCreated(ch.entwine.weblounge.common.security.User,
   *      java.util.Date)
   */
  @Override
  protected void setCreated(User user, Date date) {
    if (parserContext.equals(ParserContext.Pagelet))
      pageletReader.setCreated(user, date);
    else
      page.setCreated(user, date);
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.impl.content.WebloungeContentReader#setModified(ch.entwine.weblounge.common.security.User,
   *      java.util.Date)
   */
  @Override
  protected void setModified(User modifier, Date date) {
    if (parserContext.equals(ParserContext.Pagelet))
      pageletReader.setModified(modifier, date);
    else
      page.setModified(modifier, date);
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.impl.content.WebloungeContentReader#setPublished(ch.entwine.weblounge.common.security.User,
   *      java.util.Date, java.util.Date)
   */
  @Override
  protected void setPublished(User publisher, Date startDate, Date endDate) {
    if (parserContext.equals(ParserContext.Pagelet))
      pageletReader.setPublished(publisher, startDate, endDate);
    else
      page.setPublished(publisher, startDate, endDate);
  }

  /**
   * The parser found the start of an element. Information about this element as
   * well as the attached attributes are passed to this method.
   *
   * @param uri
   *          information about the namespace
   * @param local
   *          the local name of the element
   * @param raw
   *          the raw name of the element
   * @param attrs
   *          the element's attributes
   */
  public void startElement(String uri, String local, String raw,
      Attributes attrs) throws SAXException {

    // read the page url
    if ("page".equals(raw)) {
      parserContext = ParserContext.Page;
      page.getURI().setIdentifier(attrs.getValue("id"));
      if (StringUtils.isNotBlank(attrs.getValue("path")))
        page.getURI().setPath(attrs.getValue("path"));
      if (StringUtils.isNotBlank(attrs.getValue("version"))) {
        long version = ResourceUtils.getVersion(attrs.getValue("version"));
        page.getURI().setVersion(version);
      }
    }

    // in the header
    else if ("head".equals(raw)) {
      parserContext = ParserContext.Head;
    }

    // in the body
    else if ("body".equals(raw)) {
      parserContext = ParserContext.Body;
    }

    if (readHeader) {

      // title, subject and the like
      if ("title".equals(raw) || "subject".equals(raw) || "description".equals(raw) || "coverage".equals(raw) || "rights".equals(raw)) {
        String language = attrs.getValue("language");
        if (language != null) {
          Language l = LanguageUtils.getLanguage(language);
          clipboard.put("language", l);
        } else {
          clipboard.remove("language");
        }
      }

    }

    if (readBody) {

      // composer
      if ("composer".equals(raw)) {
        composer = attrs.getValue("id");
        position = 0;
      }

      // pagelet
      else if ("pagelet".equals(raw)) {
        parserContext = ParserContext.Pagelet;
        PageletURI l = new PageletURIImpl(page.getURI(), composer, position);
        pageletReader.setPageletLocation(l);
      }

    }

    // Forward to pagelet reader if the context matches
    if (parserContext.equals(ParserContext.Pagelet)) {
      if (readBody)
        pageletReader.startElement(uri, local, raw, attrs);
    } else {
      super.startElement(uri, local, raw, attrs);
    }

  }

  /**
   * @see org.xml.sax.ContentHandler#endElement(java.lang.String,
   *      java.lang.String, java.lang.String)
   */
  public void endElement(String uri, String local, String raw)
      throws SAXException {

    if (readBody && parserContext == ParserContext.Pagelet) {

      // Pagelet
      if ("pagelet".equals(raw)) {
        page.addPagelet(pageletReader.getPagelet(), composer, position);
        position++;
        parserContext = ParserContext.Body;
      }

    }

    if (readHeader && parserContext.equals(ParserContext.Head)) {

      // Template
      if ("template".equals(raw)) {
        page.template = getCharacters();
      }

      // Layout
      else if ("layout".equals(raw)) {
        page.layout = getCharacters();
      }

      // Stationary
      else if ("stationary".equals(raw)) {
        page.setStationary("true".equals(getCharacters()));
      }

      // Indexed
      else if ("index".equals(raw)) {
        page.setIndexed("true".equals(getCharacters()));
      }

      // Promote
      else if ("promote".equals(raw)) {
        page.setPromoted("true".equals(getCharacters()));
      }

      // Type
      else if ("type".equals(raw)) {
        page.setType(getCharacters());
      }

      // Title
      else if ("title".equals(raw)) {
        Language l = (Language) clipboard.get("language");
        page.setTitle(getCharacters(), l);
      }

      // Description
      else if ("description".equals(raw)) {
        Language l = (Language) clipboard.get("language");
        page.setDescription(getCharacters(), l);
      }

      // Coverage
      else if ("coverage".equals(raw)) {
        Language l = (Language) clipboard.get("language");
        page.setCoverage(getCharacters(), l);
      }

      // Rights
      else if ("rights".equals(raw)) {
        Language l = (Language) clipboard.get("language");
        page.setRights(getCharacters(), l);
      }

      // Subject
      else if ("subject".equals(raw)) {
        page.addSubject(getCharacters());
      }

      // Pagelock
      else if ("locked".equals(raw)) {
        User user = (User) clipboard.get("user");
        if (user != null)
          page.lock(user);
      }

    }

    // Head
    if ("head".equals(raw)) {
      parserContext = ParserContext.Page;
    }

    // Body
    else if ("body".equals(raw)) {
      parserContext = ParserContext.Page;
    }

    // Forward to pagelet reader if the context matches
    if (parserContext.equals(ParserContext.Pagelet)) {
      if (readBody)
        pageletReader.endElement(uri, local, raw);
    } else {
      super.endElement(uri, local, raw);
    }

  }

  /**
   * @see org.xml.sax.ContentHandler#characters(char[], int, int)
   */
  public void characters(char[] chars, int start, int end) throws SAXException {
    if (parserContext.equals(ParserContext.Pagelet)) {
      if (readBody)
        pageletReader.characters(chars, start, end);
    } else {
      super.characters(chars, start, end);
    }
  }

  /**
   * The parser encountered problems while parsing. The warning is printed out
   * but the parsing process continues.
   *
   * @param e
   *          information about the warning
   */
  public void warning(SAXParseException e) {
    logger.warn("Warning while reading {}: {}", page, e.getMessage());
  }

  /**
   * The parser encountered problems while parsing. The error is printed out and
   * the parsing process is stopped.
   *
   * @param e
   *          information about the error
   */
  public void error(SAXParseException e) {
    logger.warn("Error while reading {}: {}", page, e.getMessage());
  }

  /**
   * The parser encountered problems while parsing. The fatal error is printed
   * out and the parsing process is stopped.
   *
   * @param e
   *          information about the error
   */
  public void fatalError(SAXParseException e) {
    logger.warn("Fatal error while reading {}: {}", page, e.getMessage());
  }

}
TOP

Related Classes of ch.entwine.weblounge.common.impl.content.page.PageReader

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.