Package org.fao.geonet.guiservices.versioning

Source Code of org.fao.geonet.guiservices.versioning.Get

package org.fao.geonet.guiservices.versioning;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import jeeves.interfaces.Service;
import jeeves.server.ServiceConfig;
import jeeves.server.context.ServiceContext;

import org.apache.commons.lang.time.DateFormatUtils;
import org.fao.geonet.GeonetContext;
import org.fao.geonet.Util;
import org.fao.geonet.constants.Geonet;
import org.fao.geonet.exceptions.BadParameterEx;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;

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

/**
* Parses and returns the contents of the local SVN repository.
*/
public class Get implements Service {
    private static final String DATE = "date";
    private static final String USERNAME = "user";
    private static final String IP = "ip";
    private static final String ACTION = "action";
    private static final String SUBJECT = "subject";
    private static final String ID = "id";
    private static final String TITLE = "title";
    private static final String ASC = "ASC";
    private static final String DESC = "DESC";
    //--------------------------------------------------------------------------
    //---
    //--- Init
    //---
    //--------------------------------------------------------------------------

    public void init(final String appPath, final ServiceConfig params) throws Exception {
    }

    //--------------------------------------------------------------------------
    //---
    //--- API
    //---
    //--------------------------------------------------------------------------

    /**
     * Parses the contents of the local SVN repository and returns an xml
     * Element with the relevant data about what kind of changes were made per metadata.
     *
     * @param params POST request parameters. Will accept (type, name): boolean 'refresh', integer 'start', integer 'limit',
     *               text 'sort', text 'dir'. <br>
     *               - refresh - if a search for new changes will be attempted <br>
     *               - start - the start position of the first entry element to be returned from the sorted collection of entries <br>
     *               - limit - how many entries to return <br>
     *               - sort - by which field to sort. The fields names are date, user, ip, action, subject, id, title <br>
     *               - dir - in which direction to sort. The values can be ASC or DESC <br>
     *               If no parameters are given, defaults to refresh: true, start: 0, limit: 30, sort: date, dir: DESC.
     *
     * @param context the context for service excecution is needed to get the path of the repository
     *
     * @return {@link org.jdom.Element} that contains relevant info about the metadata
     *         {@code <date>} is the NB! server-local NB! date when the change was done
     *         {@code <user>} name of the user in geonetwork who triggered the change
     *         {@code <ip>} The IP address, from where the change was triggered
     *         {@code <action>} can be either Added, Modified or Deleted
     *         {@code <subject>} can be either All, Metadata, Owner, Privileges, Categories or Status.
     *         {@code <id>} the geonetwork-local id (not the global id) of the metadata involved
     *         {@code <title>} the title of the the metadata involved right after the change occurred
     *         An example of two entries:
     *         <pre>
     *         {@code   <logentries>
     *          <totalcount>2</totalcount>
     *          <entry>
     *            <date>08-11-2013 09:22:42</date>
     *            <user>admin</user>
     *            <ip>65.222.202.53</ip>
     *            <action>Modified</action>
     *            <subject>Metadata</subject>
     *            <id>22</id>
     *            <title>notModifiedTitle</title>
     *          </entry>
     *          <entry>
     *            <date>08-11-2013 09:22:36</date>
     *            <user>admin</user>
     *            <ip>65.222.202.53</ip>
     *            <action>Modified</action>
     *            <subject>Metadata</subject>
     *            <id>22</id>
     *            <title>modifiedTitle</title>
     *          </entry>
     *         </logentries>
     *         }
     *         </pre>
     *
     * @throws java.io.IOException when cannot acquire metadata file from repository
     * @throws jeeves.exceptions.BadParameterEx in case of badly formed parameter
     * @throws org.jdom.JDOMException when parsing file into jdom.Document or running xpath on the document fails.
     * @throws org.tmatesoft.svn.core.SVNException when a failure occurs while connecting to repository
     */
    public final Element exec(final Element params, final ServiceContext context) throws BadParameterEx, SVNException, IOException, JDOMException {
        MetadataActionListSingleton singleton = MetadataActionListSingleton.getInstance();
        boolean refresh = Util.getParam(params, "refresh", true);
        if (refresh) {
            GeonetContext gc = (GeonetContext) context
                    .getHandlerContext(Geonet.CONTEXT_NAME);
            String repoPath = gc.getBean(ServiceConfig.class).getMandatoryValue(
                    Geonet.Config.SUBVERSION_PATH);
            SVNURL svnurl = SVNURL.fromFile(new File(repoPath));
            SVNRepository repository = SVNRepositoryFactory.create(svnurl);
            MyLogEntryHandler logEntryHandler = new MyLogEntryHandler();
            List<MetadataAction> oldList = singleton.getMetadataActions();
            Long startRevision = 0L;

            // get the startRevision if we already have some MetadataActions in the list.
            if (oldList != null) {
                startRevision = oldList.get(oldList.size() - 1).getRevision() + 1;
            }

            // is there something to get from repository?
            if (startRevision <= repository.getLatestRevision()) {
                repository.log(new String[]{""}, startRevision, -1, true, true, logEntryHandler);
            }

            List<MetadataAction> newList = logEntryHandler.getMetadataActionList();
            // This method takes a lot of time.
            // That is why using the singleton and getting only the new logs from repository
            addTitles(newList, repoPath);

            if (oldList == null) {
                // since existingList was empty, add only new list, even if it is empty.
                singleton.setMetadataActions(newList);

            } else if (newList.size() > 0) {

                // since oldList and the newList is not empty,
                // add new members to oldList and set it back to singleton.
                oldList.addAll(newList);
                singleton.setMetadataActions(oldList);
            }
        }
        List<MetadataAction> list = new ArrayList<MetadataAction>(singleton.getMetadataActions());
        sort(list, params);
        return xml(list, params);
    }

    private Element xml(final List<MetadataAction> list, final Element params) throws BadParameterEx {
        Element root = new Element("logentries");
        Document doc = new Document(root);
        doc.setRootElement(root);
        Element totalCount = new Element("totalcount").setText(String.valueOf(list.size()));
        doc.getRootElement().addContent(totalCount);
        for (MetadataAction metadataAction : getSmallerList(list, params)) {
            Element entry = new Element("entry");
            entry.addContent(new Element(DATE).setText(DateFormatUtils.format(metadataAction.getDate(), "dd-MM-yyyy HH:mm:ss")));
            entry.addContent(new Element(USERNAME).setText(metadataAction.getUsername()));
            entry.addContent(new Element(IP).setText(metadataAction.getIp()));
            entry.addContent(new Element(ACTION).setText(metadataAction.translatedAction()));
            entry.addContent(new Element(SUBJECT).setText(metadataAction.translatedSubject()));
            entry.addContent(new Element(ID).setText(String.valueOf(metadataAction.getId())));
            entry.addContent(new Element(TITLE).setText(metadataAction.getTitle()));
            doc.getRootElement().addContent(entry);
        }
        return doc.detachRootElement();
    }

    private List<MetadataAction> getSmallerList(final List<MetadataAction> list, final Element params) throws BadParameterEx {
        int startPos = Util.getParam(params, "start", 0);
        int limit = Util.getParam(params, "limit", 30);
        int toIndex = startPos + limit;
        if (toIndex > list.size()) {
            toIndex = list.size();
        }
        if (startPos < 0 || toIndex == 0) {
            return list;
        } else {
            return list.subList(startPos, toIndex);
        }
    }

    private void sort(final List<MetadataAction> list, final Element params) {
        String field = Util.getParam(params, "sort", DATE);
        String direction = Util.getParam(params, "dir", DESC);
        if (direction.compareTo(ASC) == 0) {
            if (field.equals(DATE)) {
                Collections.sort(list, MetadataAction.DATE_COMPARATOR_ASC);
            } else if (field.equals(USERNAME)) {
                Collections.sort(list, MetadataAction.USERNAME_COMPARATOR_ASC);
            } else if (field.equals(IP)) {
                Collections.sort(list, MetadataAction.IP_COMPARATOR_ASC);
            } else if (field.equals(ACTION)) {
                Collections.sort(list, MetadataAction.ACTION_COMPARATOR_ASC);
            } else if (field.equals(SUBJECT)) {
                Collections.sort(list, MetadataAction.SUBJECT_COMPARATOR_ASC);
            } else if (field.equals(ID)) {
                Collections.sort(list, MetadataAction.ID_COMPARATOR_ASC);
            } else if (field.equals(TITLE)) {
                Collections.sort(list, MetadataAction.TITLE_COMPARATOR_ASC);
            }
        } else if (direction.compareTo(DESC) == 0) {
            if (field.equals(DATE)) {
                Collections.sort(list, MetadataAction.DATE_COMPARATOR_DESC);
            } else if (field.equals(USERNAME)) {
                Collections.sort(list, MetadataAction.USERNAME_COMPARATOR_DESC);
            } else if (field.equals(IP)) {
                Collections.sort(list, MetadataAction.IP_COMPARATOR_DESC);
            } else if (field.equals(ACTION)) {
                Collections.sort(list, MetadataAction.ACTION_COMPARATOR_DESC);
            } else if (field.equals(SUBJECT)) {
                Collections.sort(list, MetadataAction.SUBJECT_COMPARATOR_DESC);
            } else if (field.equals(ID)) {
                Collections.sort(list, MetadataAction.ID_COMPARATOR_DESC);
            } else if (field.equals(TITLE)) {
                Collections.sort(list, MetadataAction.TITLE_COMPARATOR_DESC);
            }
        }
    }

    void addTitles(final List<MetadataAction> metadataActions, final String localRepoLocation) throws JDOMException, IOException, SVNException {
        final SVNURL svnurl = SVNURL.fromFile(new File(localRepoLocation));
        final SVNRepository repository = SVNRepositoryFactory.create(svnurl);
        for (MetadataAction metadataAction : metadataActions) {
            final String path = metadataAction.getId() + "/metadata.xml";
            OutputStream out = new ByteArrayOutputStream();
            Long revision = metadataAction.getRevision();
            Long revisionToFetch = revision;
            if (metadataAction.getAction() == 'D') {
                revisionToFetch = revision - 1;
            }
            repository.getFile(path, revisionToFetch, null, out);
            out.close();
            metadataAction.setTitle(getTitle(out));
        }
    }

    private String getTitle(final OutputStream out) throws JDOMException, IOException {
        final String xml = out.toString();
        final byte[] xmlBytes = xml.getBytes(Charset.forName("UTF-8"));
        InputStream is = new ByteArrayInputStream(xmlBytes);
        InputStreamReader isr = new InputStreamReader(is, "UTF-8");
        SAXBuilder sb = new SAXBuilder();
        Document doc;
        doc = sb.build(isr);
        Element element = doc.getRootElement();
        XPath xpath = XPath.newInstance("gmd:identificationInfo/*/gmd:citation/gmd:CI_Citation/gmd:title/gco:CharacterString");
        return xpath.valueOf(element);
    }
}
TOP

Related Classes of org.fao.geonet.guiservices.versioning.Get

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.