Package ch.entwine.weblounge.bridge.oaipmh

Source Code of ch.entwine.weblounge.bridge.oaipmh.AbstractWebloungeRecordHandler

package ch.entwine.weblounge.bridge.oaipmh;

import ch.entwine.weblounge.bridge.oaipmh.harvester.ListRecordsResponse;
import ch.entwine.weblounge.bridge.oaipmh.harvester.RecordHandler;
import ch.entwine.weblounge.common.content.Resource;
import ch.entwine.weblounge.common.content.ResourceContent;
import ch.entwine.weblounge.common.content.ResourceSearchResultItem;
import ch.entwine.weblounge.common.content.ResourceURI;
import ch.entwine.weblounge.common.content.SearchQuery;
import ch.entwine.weblounge.common.content.SearchResult;
import ch.entwine.weblounge.common.content.movie.MovieContent;
import ch.entwine.weblounge.common.content.movie.MovieResource;
import ch.entwine.weblounge.common.impl.content.SearchQueryImpl;
import ch.entwine.weblounge.common.impl.content.movie.MovieResourceSearchResultItemImpl;
import ch.entwine.weblounge.common.impl.language.LanguageImpl;
import ch.entwine.weblounge.common.language.Language;
import ch.entwine.weblounge.common.language.UnknownLanguageException;
import ch.entwine.weblounge.common.repository.ContentRepositoryException;
import ch.entwine.weblounge.common.repository.WritableContentRepository;
import ch.entwine.weblounge.common.security.User;
import ch.entwine.weblounge.common.site.Site;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;

import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.ws.rs.core.MediaType;

/**
* Base implementation of a weblounge record handler
*/
public abstract class AbstractWebloungeRecordHandler implements RecordHandler {

  /** Logging facility */
  protected final Logger logger;

  /** the site */
  protected final Site site;

  /** The content repository */
  protected final WritableContentRepository contentRepository;

  /** User for resource creation */
  protected User harvesterUser;

  /** ISO3 language map */
  protected final Map<String, Language> languages = new HashMap<String, Language>();

  /** Presentation track flavor */
  protected final String presentationTrackFlavor;

  /** Presenter track flavor */
  protected final String presenterTrackFlavor;

  /** Dublin core episode flavor */
  protected final String dcEpisodeFlavor;

  /** Dublin core series flavor */
  protected final String dcSeriesFlavor;
 
  /** Elements mimetypes */
  protected final ArrayList<MediaType> mimeTypes = new ArrayList<MediaType>();

  /**
   * Creates a new abstract weblounge record handler
   *
   * @param site
   *          the site
   * @param contentRepository
   *          the content repository
   * @param harvesterUser
   *          the harvester user
   * @param presentationTrackFlavor
   *          the presentation track flavor
   * @param presenterTrackFlavor
   *          the presenter track flavor
   * @param dcEpisodeFlavor
   *          the dublin core episode flavor
   * @param dcSeriesFlavor
   *          the dublin core series flavor
   * @param mimeTypesStr
   *       the string containing the list of mime-types separated by a string
   */
  public AbstractWebloungeRecordHandler(Site site,
      WritableContentRepository contentRepository, User harvesterUser,
      String presentationTrackFlavor, String presenterTrackFlavor,
      String dcEpisodeFlavor, String dcSeriesFlavor, String mimeTypesStr) {
    this.site = site;
    this.contentRepository = contentRepository;
    this.harvesterUser = harvesterUser;
    this.presentationTrackFlavor = presentationTrackFlavor;
    this.presenterTrackFlavor = presenterTrackFlavor;
    this.dcEpisodeFlavor = dcEpisodeFlavor;
    this.dcSeriesFlavor = dcSeriesFlavor;
    for(String str : StringUtils.split(StringUtils.trimToEmpty(mimeTypesStr), ",")) {
      this.mimeTypes.add(MediaType.valueOf(StringUtils.trimToEmpty(str)));
    }
    logger = LoggerFactory.getLogger(getClass());
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.bridge.oaipmh.harvester.RecordHandler#handle(org.w3c.dom.Node)
   */
  public void handle(Node record) {
    String recordIdentifier = ListRecordsResponse.identifierOfRecord(record);
    boolean isDeleted = ListRecordsResponse.statusOfRecord(record);
    String dateString = ListRecordsResponse.dateOfRecord(record);

    Date date;
    try {
      date = OaiPmhUtil.fromUtc(dateString);
    } catch (ParseException e1) {
      logger.debug("Unable to parse date '{}'", dateString);
      return;
    }

    logger.info("Start harvesting resource " + recordIdentifier);

    SearchResult searchResult = searchSource(recordIdentifier);

    if (isDeleted) {
      if (searchResult.getHitCount() != 1) {
        logger.warn("The found element size is wrong!, size: " + searchResult.getHitCount());
        return;
      }
      ResourceSearchResultItem resourceResult = (ResourceSearchResultItem) searchResult.getItems()[0];
      deleteResource(resourceResult.getResourceURI());
      logger.info("Deleted harvestet resource " + recordIdentifier);
    } else {
      if (searchResult.getHitCount() == 1) {
        MovieResourceSearchResultItemImpl movieResultItem = (MovieResourceSearchResultItemImpl) searchResult.getItems()[0];
        MovieResource movieResource = movieResultItem.getMovieResource();

        if (!date.after(movieResource.getPublishFrom()))
          return;
        logger.warn("Update harvested element {}", recordIdentifier);

        Resource<MovieContent> resource = parseResource(record);
        resource.getURI().setIdentifier(movieResource.getIdentifier());
        resource.setPublished(harvesterUser, date, null);
        removeContents(resource);

        MovieContent content = parseResourceContent(record);
        content.setSource(recordIdentifier);
        resource.addContent(content);

        addResource(resource);
        addContent(resource.getURI(), content);
      } else if (searchResult.getHitCount() > 1) {
        logger.error("The repository contains already more than one element of {}", recordIdentifier);
      } else {
        Resource<?> resource = parseResource(record);
        resource.setPublished(harvesterUser, date, null);
        ResourceContent content = parseResourceContent(record);

        if (resource == null || content == null)
          return;

        addResource(resource);
        content.setSource(recordIdentifier);
        addContent(resource.getURI(), content);
        logger.info("Harvesting resource " + recordIdentifier);
      }
    }
  }

  /**
   * Search a page with the resource identifier.
   *
   * @param sourceIdentifier
   *          the record identifier
   * @return the search result
   */
  private SearchResult searchSource(String sourceIdentifier) {
    SearchResult searchResult;
    SearchQuery q = new SearchQueryImpl(site);
    q.withSource(sourceIdentifier);
    try {
      searchResult = contentRepository.find(q);
    } catch (ContentRepositoryException e) {
      logger.error("Error searching for resources with given subject: " + sourceIdentifier);
      throw new RuntimeException(e);
    }
    return searchResult;
  }

  /**
   * Parse the record to a {@link ResourceContent}
   *
   * @return the resource content to add to the repository
   */
  protected abstract MovieContent parseResourceContent(Node record);

  /**
   * Parse the record to a {@link Resource}
   *
   * @return the resource to add to the repository
   */
  protected abstract Resource<MovieContent> parseResource(Node record);

  /**
   * Parse a matterhorn iso3 or two letter language string to a weblounge
   * language.
   *
   * @param languageCode
   *          the matterhorn iso3 or two letter language
   * @return the weblounge language
   * @throws UnknownLanguageException
   *           if language was not found
   */
  protected Language getLanguage(String languageCode)
      throws UnknownLanguageException {
    Language language = languages.get(languageCode);
    if (language != null)
      return language;
    for (Locale locale : Locale.getAvailableLocales()) {
      if (locale.getISO3Language().equals(languageCode) || locale.getLanguage().equals(languageCode)) {
        language = new LanguageImpl(new Locale(locale.getLanguage(), "", ""));
        languages.put(languageCode, language);
        break;
      }
    }
    if (language == null)
      language = site.getDefaultLanguage();
      //throw new UnknownLanguageException(languageCode);
    return language;
  }

  /**
   * Add a resource content to the repository.
   *
   * @param resourceUri
   *          the resource rui
   * @param content
   *          the resource content
   */
  protected void addContent(ResourceURI resourceUri, ResourceContent content) {
    InputStream is = null;
    try {
      contentRepository.putContent(resourceUri, content, null);
    } catch (IllegalStateException e) {
      logger.warn("Illegal state while adding content to resource {}: {}", resourceUri, e.getMessage());
      try {
        contentRepository.delete(resourceUri);
      } catch (Throwable t) {
        logger.error("Error deleting orphan resource {}", resourceUri, t);
      }
      throw new RuntimeException(e);
    } catch (ContentRepositoryException e) {
      logger.warn("Illegal state while adding content to resource {}: {}", resourceUri, e.getMessage());
      try {
        contentRepository.delete(resourceUri);
      } catch (Throwable t) {
        logger.error("Error deleting orphan resource {}", resourceUri, t);
      }
      throw new RuntimeException(e);
    } catch (IOException e) {
      logger.warn("Error reading resource content {} from request", resourceUri);
      try {
        contentRepository.delete(resourceUri);
      } catch (Throwable t) {
        logger.error("Error deleting orphan resource {}", resourceUri, t);
      }
      throw new RuntimeException(e);
    } finally {
      IOUtils.closeQuietly(is);
    }
  }

  /**
   * Remove all contents from the resource and repository
   *
   * @param resource
   *          the resource
   */
  private void removeContents(Resource<?> resource) {
    for (ResourceContent existingContent : resource.contents()) {
      Language language = existingContent.getLanguage();
      resource.removeContent(language);
      try {
        contentRepository.deleteContent(resource.getURI(), resource.getContent(language));
      } catch (IllegalStateException e) {
        logger.warn("Illegal state while deleting the resource {}: {}", resource.getURI(), e.getMessage());
        throw new RuntimeException(e);
      } catch (ContentRepositoryException e) {
        logger.warn("Error deleting the resource {}: {}", resource.getURI(), e.getMessage());
        throw new RuntimeException(e);
      } catch (IOException e) {
        logger.warn("Error writing the resource {}: {}", resource.getURI(), e.getMessage());
        throw new RuntimeException(e);
      }
    }
  }

  /**
   * Add a resource to the repository
   *
   * @param resource
   *          the resource
   */
  protected void addResource(Resource<?> resource) {
    try {
      contentRepository.put(resource, true);
    } catch (IllegalStateException e) {
      logger.warn("Illegal state while adding new resource {}: {}", resource.getURI(), e.getMessage());
      throw new RuntimeException(e);
    } catch (ContentRepositoryException e) {
      logger.warn("Error adding new resource {}: {}", resource.getURI(), e.getMessage());
      throw new RuntimeException(e);
    } catch (IOException e) {
      logger.warn("Error writing new resource {}: {}", resource.getURI(), e.getMessage());
      throw new RuntimeException(e);
    }
  }

  /**
   * Delete a resource from the repository
   *
   * @param resourceUri
   *          the resource uri to delete
   */
  protected void deleteResource(ResourceURI resourceUri) {
    try {
      contentRepository.delete(resourceUri, true);
    } catch (ContentRepositoryException e) {
      logger.warn("Illegal state while deleting resource {}: {}", resourceUri, e.getMessage());
    } catch (IOException e) {
      logger.error("Error deleting resource {}: {}", resourceUri, e.getMessage());
    }
  }

}
TOP

Related Classes of ch.entwine.weblounge.bridge.oaipmh.AbstractWebloungeRecordHandler

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.