Package org.fao.geonet.kernel.harvest.harvester.geonet20

Source Code of org.fao.geonet.kernel.harvest.harvester.geonet20.Aligner

//=============================================================================
//===  Copyright (C) 2001-2007 Food and Agriculture Organization of the
//===  United Nations (FAO-UN), United Nations World Food Programme (WFP)
//===  and United Nations Environment Programme (UNEP)
//===
//===  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
//===
//===  Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,
//===  Rome - Italy. email: geonetwork@osgeo.org
//==============================================================================

package org.fao.geonet.kernel.harvest.harvester.geonet20;

import jeeves.server.context.ServiceContext;
import org.fao.geonet.Logger;
import org.fao.geonet.constants.Edit;
import org.fao.geonet.constants.Geonet;
import org.fao.geonet.domain.ISODate;
import org.fao.geonet.domain.MetadataCategory;
import org.fao.geonet.domain.MetadataType;
import org.fao.geonet.kernel.DataManager;
import org.fao.geonet.kernel.harvest.harvester.CategoryMapper;
import org.fao.geonet.kernel.harvest.harvester.HarvestResult;
import org.fao.geonet.kernel.harvest.harvester.UUIDMapper;
import org.fao.geonet.repository.MetadataRepository;
import org.fao.geonet.utils.XmlRequest;
import org.jdom.Element;

import java.util.Collection;
import java.util.List;

//=============================================================================

public class Aligner
{
  //--------------------------------------------------------------------------
  //---
  //--- Constructor
  //---
  //--------------------------------------------------------------------------

  public Aligner(Logger log, XmlRequest req, GeonetParams params, DataManager dm,
                   ServiceContext sc, CategoryMapper cm)
  {
    this.log        = log;
    this.req        = req;
    this.params     = params;
    this.dataMan    = dm;
    this.context    = sc;
    this.localCateg = cm;
    }

  //--------------------------------------------------------------------------
  //---
  //--- Alignment method
  //---
  //--------------------------------------------------------------------------

  public HarvestResult align(Element result, String siteId) throws Exception
  {
    log.info("Start of alignment for site-id="+ siteId);

    this.result = new HarvestResult();
    this.result.siteId = siteId;

    @SuppressWarnings("unchecked")
        List<Element> mdList = result.getChildren("metadata");

    //-----------------------------------------------------------------------
    //--- retrieve local uuids for given site-id

    localUuids = new UUIDMapper(context.getBean(MetadataRepository.class), siteId);

        //-----------------------------------------------------------------------
        //--- remove old metadata

        for (String uuid : localUuids.getUUIDs())
      if (!exists(mdList, uuid))
      {
                String id = localUuids.getID(uuid);

                if(log.isDebugEnabled()) log.debug("  - Removing old metadata with id="+ id);
                dataMan.deleteMetadata(context, id);

                dataMan.flush();
        this.result.locallyRemoved++;
      }

    //-----------------------------------------------------------------------
    //--- insert/update new metadata

        for (Element aMdList : mdList) {
            Element info = aMdList.getChild("info", Edit.NAMESPACE);

            String remoteId = info.getChildText("id");
            String remoteUuid = info.getChildText("uuid");
            String schema = info.getChildText("schema");
            String changeDate = info.getChildText("changeDate");

            this.result.totalMetadata++;

            if(log.isDebugEnabled()) log.debug("Obtained remote id=" + remoteId + ", changeDate=" + changeDate);

            if (!dataMan.existsSchema(schema)) {
                if(log.isDebugEnabled()) log.debug("  - Skipping unsupported schema : " + schema);
                this.result.schemaSkipped++;
            } else {
                String id = dataMan.getMetadataId(remoteUuid);

                if (id == null) {
                    id = addMetadata(info);
                } else {
                    updateMetadata(siteId, info, id);
                }

                dataMan.flush();



                //--- maybe the metadata was unretrievable

                if (id != null) {
                    dataMan.indexMetadata(id, false);
                }
            }
        }

    log.info("End of alignment for site-id="+ siteId);

    return this.result;
  }

  //--------------------------------------------------------------------------
  //---
  //--- Private methods : addMetadata
  //---
  //--------------------------------------------------------------------------

  private String addMetadata(Element info) throws Exception
  {
    String remoteId   = info.getChildText("id");
    String remoteUuid = info.getChildText("uuid");
    String schema     = info.getChildText("schema");
    String createDate = info.getChildText("createDate");
    String changeDate = info.getChildText("changeDate");

        if(log.isDebugEnabled()) log.debug("  - Adding metadata with remote id="+ remoteId);

    Element md = getRemoteMetadata(req, remoteId);

    if (md == null)
    {
      log.warning("  - Cannot get metadata (possibly bad XML) with remote id="+ remoteId);
      return null;
    }

        //
        //  insert metadata
        //
        String group = null, isTemplate = null, docType = null, title = null, category = null;
        boolean ufo = false, indexImmediate = false;
        String id = dataMan.insertMetadata(context, schema, md, params.uuid, Integer.parseInt(params.ownerId), group, remoteUuid,
                         isTemplate, docType, category, createDate, changeDate, ufo, indexImmediate);


    int iId = Integer.parseInt(id);

    dataMan.setTemplate(iId, MetadataType.METADATA, null);
    dataMan.setHarvested(iId, params.uuid);

    result.addedMetadata++;

    @SuppressWarnings("unchecked")
        List<Element> categories = info.getChildren("category");
        addCategories(id, categories);

        addPrivileges(id);

    return id;
  }

  //--------------------------------------------------------------------------
  //--- Categories
  //--------------------------------------------------------------------------

  private void addCategories(String id, List<Element> categ) throws Exception
  {
        for (Element aCateg : categ) {
            String catName = aCateg.getText();
            String catId = localCateg.getID(catName);

            if (catId != null) {
                //--- remote category exists locally

                if(log.isDebugEnabled()) log.debug("    - Setting category : " + catName);
                dataMan.setCategory(context, id, catId);
            }
        }
  }

  //--------------------------------------------------------------------------
  //--- Privileges
  //--------------------------------------------------------------------------

  private void addPrivileges(String id) throws Exception
  {
    //--- set view privilege for both groups 'intranet' and 'all'
    dataMan.setOperation(context, id, "0", "0");
    dataMan.setOperation(context, id, "1", "0");
  }

  //--------------------------------------------------------------------------
  //---
  //--- Private methods : updateMetadata
  //---
  //--------------------------------------------------------------------------

  private void updateMetadata(String siteId, Element info, String id) throws Exception
  {
    String remoteId  = info.getChildText("id");
    String remoteUuid= info.getChildText("uuid");
    String changeDate= info.getChildText("changeDate");

    if (localUuids.getID(remoteUuid) == null)
    {
      log.error("  - Warning! The remote uuid '"+ remoteUuid +"' does not belong to site '"+ siteId+"'");
      log.error("     - The site id of this metadata has been changed.");
      log.error("     - The metadata update will be skipped.");

      result.uuidSkipped++;
    }
    else
    {
      updateMetadata(id, remoteId, remoteUuid, changeDate);
      updateCategories(id, info);
    }
  }

  //--------------------------------------------------------------------------

  private void updateMetadata(String id, String remoteId, String remoteUuid, String changeDate) throws Exception
  {
    String date = localUuids.getChangeDate(remoteUuid);

    if (!updateCondition(date, changeDate)) {
            if(log.isDebugEnabled()) log.debug("  - XML not changed to local metadata with id="+ id);
      result.unchangedMetadata++;
    } else {
            if(log.isDebugEnabled()) log.debug("  - Updating local metadata with id="+ id);

      Element md = getRemoteMetadata(req, remoteId);

      if (md == null) {
        log.warning("  - Cannot get metadata (possibly bad XML) with remote id="+ remoteId);
            } else {
                //
                // update metadata
                //
                boolean validate = false;
                boolean ufo = false;
                boolean index = false;
                String language = context.getLanguage();
                dataMan.updateMetadata(context, id, md, validate, ufo, index, language, changeDate, false);

        result.updatedMetadata++;
      }
    }
  }

  //--------------------------------------------------------------------------

  private void updateCategories(String id, Element info) throws Exception
  {
    @SuppressWarnings("unchecked")
        List<Element> catList = info.getChildren("category");

    //--- remove old categories

    @SuppressWarnings("unchecked")
        Collection<MetadataCategory> locCateg = dataMan.getCategories(id);

        for (MetadataCategory el : locCateg) {
            int catId = el.getId();
            String catName = el.getName();

            if (!existsCategory(catList, catName)) {
                if(log.isDebugEnabled()) {
                    log.debug("  - Unsetting category : " + catName);
                }
                dataMan.unsetCategory(context, id, catId);
            }
        }

    //--- add new categories

        for (Element categ : catList) {
            String catName = categ.getAttributeValue("name");
            String catId = localCateg.getID(catName);

            if (catId != null) {
                //--- it is not necessary to query the db. Anyway...
                if (!dataMan.isCategorySet(id, Integer.valueOf(catId))) {
                    if (log.isDebugEnabled()) {
                        log.debug("  - Setting category : " + catName);
                    }
                    dataMan.setCategory(context, id, catId);
                }
            }
        }
  }

  //--------------------------------------------------------------------------

  private boolean existsCategory(List<Element> catList, String name)
  {
        for (Object aCatList : catList) {
            Element categ = (Element) aCatList;
            String catName = categ.getText();

            if (catName.equals(name)) {
                return true;
            }
        }

    return false;
  }

  //--------------------------------------------------------------------------
  //---
  //--- Private methods
  //---
  //--------------------------------------------------------------------------

    /**
     * Retrieves remote metadata. If validation is requested and the metadata does not validate, returns null.
     *
     * @param req
     * @param id
     * @return
     * @throws Exception
     */
  private Element getRemoteMetadata(XmlRequest req, String id) throws Exception
  {
    req.setAddress(params.getServletPath() +"/srv/en/"+ Geonet.Service.XML_METADATA_GET);
    req.clearParams();
    req.addParam("id", id);

    try
    {
      Element md   = req.execute();
      Element info = md.getChild("info", Edit.NAMESPACE);

      if (info != null)
        info.detach();

            // validate it here if requested
            if (params.validate) {
                if(!dataMan.validate(md))  {
                    log.info("Ignoring invalid metadata");
                    result.doesNotValidate++;
                    return null;
                }
            }
      return md;
    }
    catch(Exception e)
    {
      log.warning("Cannot retrieve remote metadata with id:"+id);
      log.warning(" (C) Error is : "+e.getMessage());

      return null;
    }
  }

  //--------------------------------------------------------------------------
  /** Return true if the sourceId is present in the remote site */

  private boolean exists(List<Element> mdList, String uuid)
  {
        for (Element aMdList : mdList) {
            Element elInfo = aMdList.getChild("info", Edit.NAMESPACE);

            if (uuid.equals(elInfo.getChildText("uuid"))) {
                return true;
            }
        }

    return false;
  }

  //--------------------------------------------------------------------------

  private boolean updateCondition(String localDate, String remoteDate)
  {
    ISODate local = new ISODate(localDate);
    ISODate remote= new ISODate(remoteDate);

    //--- accept if remote date is greater than local date

    return (remote.timeDifferenceInSeconds(local) > 0);
  }

  //--------------------------------------------------------------------------
  //---
  //--- Variables
  //---
  //--------------------------------------------------------------------------

  private Logger         log;
  private XmlRequest     req;
  private GeonetParams   params;
  private DataManager    dataMan;
  private ServiceContext context;
  private CategoryMapper localCateg;
    private UUIDMapper     localUuids;
  private HarvestResult result;
}
TOP

Related Classes of org.fao.geonet.kernel.harvest.harvester.geonet20.Aligner

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.