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

Source Code of ch.entwine.weblounge.common.impl.content.AbstractResourceReaderImpl

/*
*  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;

import ch.entwine.weblounge.common.content.Resource;
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.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 abstract class AbstractResourceReaderImpl<S extends ResourceContent, T extends Resource<S>> extends WebloungeContentReader implements ResourceReader<S, T> {

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

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

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

  /** The resource object */
  protected T resource = null;

  /** The root tag */
  protected String rootTag = null;

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

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

  protected enum ParserContext {
    Document, Resource, Head, Body, Content
  };

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

  /**
   * Creates a new resource reader reader that will parse the XML data and store
   * it in the <code>Resource</code> object that is returned by the
   * {@link #read} method.
   *
   * @param rootTag
   *          name of the root tag
   * @throws ParserConfigurationException
   *           if the SAX parser setup failed
   * @throws SAXException
   *           if an error occurs while parsing
   */
  public AbstractResourceReaderImpl(String rootTag)
      throws ParserConfigurationException, SAXException {
    if (rootTag == null)
      throw new IllegalArgumentException("Root tag name must not be null");
    this.rootTag = rootTag.toLowerCase();
    parserRef = new WeakReference<SAXParser>(parserFactory.newSAXParser());
  }

  /**
   * This method is called when a <code>Page</code> object is instantiated.
   *
   * @param is
   *          the xml input stream
   * @param uri
   *          the page uri
   *
   * @throws IOException
   *           if reading the input stream fails
   */
  public T read(InputStream is, Site site) throws SAXException, IOException,
  ParserConfigurationException {
    reset();
    resource = createResource(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 resource;
  }

  /**
   * Creates an empty instance of the resource to read.
   *
   * @param site
   *          the site
   * @return the empty resource
   */
  protected abstract T createResource(Site site);

  /**
   * This method is called to read the head section of a resource.
   *
   * @param is
   *          the xml input stream
   * @param site
   *          the 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 T readHeader(InputStream is, Site site) throws SAXException,
  IOException, ParserConfigurationException {
    if (resource == null) {
      resource = createResource(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 resource;
  }

  /**
   * This method is called to read the body of a resource.
   *
   * @param is
   *          the xml input stream
   * @param site
   *          the 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 T readBody(InputStream is, Site site) throws SAXException,
  IOException, ParserConfigurationException {
    if (resource == null) {
      resource = createResource(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 resource;
  }

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

  /**
   * Resets this parser instance.
   */
  @Override
  public void reset() {
    this.resource = null;
    this.parserContext = ParserContext.Document;
    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) {
    resource.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) {
    resource.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) {
    resource.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) {
    resource.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) {
    resource.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
   */
  @Override
  public void startElement(String uri, String local, String raw,
      Attributes attrs) throws SAXException {

    // read the page url
    if (rootTag.equals(raw)) {
      parserContext = ParserContext.Resource;
      resource.getURI().setType(rootTag);
      resource.getURI().setIdentifier(attrs.getValue("id"));
      if (StringUtils.isNotBlank(attrs.getValue("path")))
        resource.getURI().setPath(attrs.getValue("path"));
      if (StringUtils.isNotBlank(attrs.getValue("version"))) {
        long version = ResourceUtils.getVersion(attrs.getValue("version"));
        resource.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");
        }
      }

    }

    super.startElement(uri, local, raw, attrs);

  }

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

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

      // Promote
      if ("promote".equals(raw)) {
        resource.setPromoted("true".equals(characters.toString()));
      }

      // Type
      else if ("type".equals(raw)) {
        resource.setType(characters.toString());
      }

      // Title
      else if ("title".equals(raw)) {
        Language l = (Language) clipboard.remove("language");
        resource.setTitle(characters.toString(), l);
      }

      // Description
      else if ("description".equals(raw)) {
        Language l = (Language) clipboard.remove("language");
        resource.setDescription(characters.toString(), l);
      }

      // Coverage
      else if ("coverage".equals(raw)) {
        Language l = (Language) clipboard.remove("language");
        resource.setCoverage(characters.toString(), l);
      }

      // Rights
      else if ("rights".equals(raw)) {
        Language l = (Language) clipboard.remove("language");
        resource.setRights(characters.toString(), l);
      }

      // Subject
      else if ("subject".equals(raw)) {
        resource.addSubject(characters.toString());
      }

      // Series
      else if ("series".equals(raw)) {
        resource.addSeries(characters.toString());
      }

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

    }

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

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

    // Have the super implementation handle the unkown
    else {
      super.endElement(uri, local, raw);
    }

  }

  /**
   * The parser encountered problems while parsing. The warning is printed out
   * but the parsing process continues.
   *
   * @param e
   *          information about the warning
   */
  @Override
  public void warning(SAXParseException e) {
    logger.warn("Warning while reading {}: {}", resource, 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
   */
  @Override
  public void error(SAXParseException e) {
    logger.warn("Error while reading {}: {}", resource, 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
   */
  @Override
  public void fatalError(SAXParseException e) {
    logger.warn("Fatal error while reading {}: {}", resource, e.getMessage());
  }

}
TOP

Related Classes of ch.entwine.weblounge.common.impl.content.AbstractResourceReaderImpl

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.