Package org.fao.geonet.services.metadata

Source Code of org.fao.geonet.services.metadata.Response

//=============================================================================
//===  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.services.metadata;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import jeeves.constants.Jeeves;
import jeeves.server.ServiceConfig;
import jeeves.server.context.ServiceContext;
import jeeves.services.ReadWriteController;

import org.fao.geonet.constants.Geonet;
import org.fao.geonet.constants.Params;
import org.fao.geonet.domain.ISODate;
import org.fao.geonet.domain.Metadata;
import org.fao.geonet.domain.responses.IdResponse;
import org.fao.geonet.exceptions.BadParameterEx;
import org.fao.geonet.kernel.AccessManager;
import org.fao.geonet.kernel.DataManager;
import org.fao.geonet.kernel.SchemaManager;
import org.fao.geonet.kernel.setting.SettingManager;
import org.fao.geonet.lib.Lib;
import org.fao.geonet.repository.MetadataRepository;
import org.fao.geonet.utils.Log;
import org.fao.geonet.utils.Xml;
import org.jdom.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* Process a metadata with an XSL transformation declared for the metadata
* schema. All parameters sent to the service are forwarded to XSL process.
* <br/>
* Parameters are:
* <ul>
* <li>process: the process identifier (aka. file name without extension)</li>
* <li>save: (optional) 1 to save the results (default), 0 to only process and return the processed record</li>
* </ul>
* <br/>
*
* In each xml/schemas/schemaId directory, a process could be added in a
* directory called process. Then the process could be called using the
* following URL :
* http://localhost:8080/geonetwork/srv/en/metadata.processing?process
* =keywords-comma-exploder&url=http://xyz
* <br/>
* <br/>
*
* In that example the process has to be named keywords-comma-exploder.xsl.
*
* To retrieve parameters in XSL process use the following:
* <pre>
* {@code
*     <xsl:param name="url">http://localhost:8080/</xsl:param>
* }
* </pre>
*
*
*  TODO : it could be nice to add an option to return a diff
*  so we could preview the change before applying them.
*
* @author fxprunayre
*/
@Controller("metadata.processing")
@ReadWriteController
public class XslProcessing { //extends NotInReadOnlyModeService {
    private String _appPath;
    private static XslProcessing instance;
   
    public void init(String appPath, ServiceConfig params) throws Exception {
        _appPath = appPath;

        // TODO : here we could register process on startup
        // in order to not to check process each time.
    }
   
    /**
     * To replace static calls
     * @return
     */
    public static XslProcessing get() {
      if(XslProcessing.instance == null) {
        XslProcessing.instance = new XslProcessing();
      }
      return XslProcessing.instance;
    }

    /**
     *
     * @param params
     * @param context
     * @return
     * @throws Exception
     */
    public @ResponseBody Response serviceSpecificExec(@RequestParam(defaultValue= Params.PROCESS) String process,
        @RequestParam(defaultValue=Params.SAVE) Boolean save,
        @RequestParam(defaultValue="") String id,
        @RequestParam(defaultValue="") String uuid,
        HttpServletRequest request)
            throws Exception {       
        XslProcessingReport xslProcessingReport = new XslProcessingReport(process);

        if(id.isEmpty()) {
      id = dataMan.getMetadataId(uuid);
        }
        Element processedMetadata;
        try {
            final String siteURL = context.getBean(SettingManager.class).getSiteURL(context);
            processedMetadata = process(id, process, save, _appPath, xslProcessingReport, false, siteURL, request);
            if (processedMetadata == null) {
                throw new BadParameterEx("Processing failed", "Not found:"
                        + xslProcessingReport.getNotFoundMetadataCount() +
                        ", Not owner:" + xslProcessingReport.getNotEditableMetadataCount() +
                        ", No process found:" + xslProcessingReport.getNoProcessFoundCount() + ".");
            }
        } catch (Exception e) {
            throw e;
        }
        // -- return the processed metadata id
        Response res = new Response(id);
        // and the processed metadata if not saved.
        if (!save) {
            //response.addContent(new Element("record").addContent(processedMetadata));
        }
       
        return res;

    }

    /**
     * Process a metadata record and add information about the processing
     * to one or more sets for reporting.
     *
     * @param id    The metadata identifier corresponding to the metadata record to process
     * @param process  The process name
     * @param appPath  The application path (use to get the process XSL)
     * @param params  The input parameters
     * @param context  The current context
     * @param report
     * @return
     * @throws Exception
     */
    public Element process(String id, String process, boolean save,
                                  String appPath,
                                  XslProcessingReport report, boolean useIndexGroup,
                                  String siteUrl,
                                  HttpServletRequest request) throws Exception {

        report.incrementProcessedRecords();
       
        // When a record is deleted the UUID is in the selection manager
        // and when retrieving id, return null
        if (id == null) {
            report.incrementNullRecords();
            return null;
        }
       
        int iId = Integer.valueOf(id);
        Metadata info = metadataRepository.findOne(id);
       
       
        if (info == null) {
            report.addNotFoundMetadataId(iId);
        } else if (!accessMan.canEdit(context, id)) {
            report.addNotEditableMetadataId(iId);
        } else {

            // -----------------------------------------------------------------------
            // --- check processing exist for current schema
            String schema = info.getDataInfo().getSchemaId();

            String filePath = schemaMan.getSchemaDir(schema) + "/process/" + process + ".xsl";
            File xslProcessing = new File(filePath);
            if (!xslProcessing.exists()) {
                Log.info("org.fao.geonet.services.metadata","  Processing instruction not found for " + schema + " schema. Looking for "+filePath);
                report.addNoProcessFoundMetadataId(iId);
                return null;
            }
           
           
            // --- Process metadata
            Element processedMetadata = null;
            try {
                boolean forEditing = false, withValidationErrors = false, keepXlinkAttributes = true;
              Element md = dataMan.getMetadata(context, id, forEditing, withValidationErrors, keepXlinkAttributes);
 
              Map<String, Object> xslParameter = new HashMap<String, Object>();

              xslParameter.put("guiLang", context.getLanguage());
              xslParameter.put("baseUrl", context.getBaseUrl());
                xslParameter.put("catalogUrl", settingsMan.getSiteURL(context));
                xslParameter.put("nodeId", context.getNodeId());
               
              for (Entry<String, String[]> parameter : request.getParameterMap().entrySet()) {
                String value = parameter.getValue()[0].trim();
                String key = parameter.getKey();
                  // Add extra metadata
                  if (key.equals("extra_metadata_uuid")
                          && !value.equals("")) {
                      String extraMetadataId = dataMan.getMetadataId(value);
                      if (extraMetadataId != null) {
                          Element extraMetadata = dataMan.getMetadata(context,
                                  extraMetadataId, forEditing,
                                  withValidationErrors, keepXlinkAttributes);
                          md.addContent(new Element("extra")
                                  .addContent(extraMetadata));
                          xslParameter.put(key, value);
                      }
                  } else {
                      // Or add parameter
                      xslParameter.put(key, value);
                  }
              }
 
 
              xslParameter.put("siteUrl", siteUrl);
 
              processedMetadata = Xml.transform(md, filePath, xslParameter);
 
              // --- save metadata and return status
              if (save) {
                  Lib.resource.checkEditPrivilege(context, id);
 
                  boolean validate = false;
                  boolean ufo = true;
                  boolean index = false;
                  String language = context.getLanguage();
                  // Always udpate metadata date stamp on metadata processing (minor edit has no effect).
                  boolean updateDateStamp = true;
                  dataMan.updateMetadata(context, id, processedMetadata, validate, ufo, index, language, new ISODate().toString(), updateDateStamp);
                    dataMan.indexMetadata(id, true);
              }
 
              report.addMetadataId(iId);
              // TODO : it could be relevant to list at least
              // if there was any change in the record or not.
              // Using hash on processMd and metadata ?
            } catch (Exception e) {
              report.addMetadataError(iId, e);
              context.error("  Processing failed with error " + e.getMessage());
                e.printStackTrace();
            }
            return processedMetadata;
        }
        return null;
    }
   
    @Autowired
    private DataManager dataMan;
    @Autowired
    private SchemaManager schemaMan;
    @Autowired
    private AccessManager accessMan;
    @Autowired
    private SettingManager settingsMan;
    @Autowired
    private MetadataRepository metadataRepository;
    @Autowired
    private ServiceContext context;
}

class Response  extends IdResponse{

    public Response(String id) {

    }
 
}
TOP

Related Classes of org.fao.geonet.services.metadata.Response

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.