Package org.exist.versioning.svn.xquery

Source Code of org.exist.versioning.svn.xquery.SVNStatus$AddStatusHandler

/*
*  eXist Open Source Native XML Database
*  Copyright (C) 2010 The eXist Project
*  http://exist-db.org
*
*  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 library; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*
*  $Id$
*/
package org.exist.versioning.svn.xquery;

import org.exist.dom.QName;
import org.exist.memtree.MemTreeBuilder;
import org.exist.util.io.Resource;
import org.exist.versioning.svn.wc.ISVNStatusHandler;
import org.exist.versioning.svn.wc.SVNClientManager;
import org.exist.versioning.svn.wc.SVNStatusClient;
import org.exist.versioning.svn.wc.SVNStatusType;
import org.exist.versioning.svn.wc.SVNWCClient;
import org.exist.versioning.svn.wc.SVNWCUtil;
import org.exist.xquery.Cardinality;
import org.exist.xquery.FunctionSignature;
import org.exist.xquery.XPathException;
import org.exist.xquery.XQueryContext;
import org.exist.xquery.value.FunctionReturnSequenceType;
import org.exist.xquery.value.NodeValue;
import org.exist.xquery.value.Sequence;
import org.exist.xquery.value.SequenceType;
import org.exist.xquery.value.Type;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLock;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.wc.SVNRevision;

/**
* Status information on Working Copy items.
*
* @author <a href="mailto:amir.akhmedov@gmail.com">Amir Akhmedov</a>
* @author <a href="mailto:shabanovd@gmail.com">Dmitriy Shabanov</a>
*
*/
public class SVNStatus extends AbstractSVNFunction {

  public final static FunctionSignature signature =
    new FunctionSignature(
      new QName("status", SVNModule.NAMESPACE_URI, SVNModule.PREFIX), "Status information on Working Copy items.",
      new SequenceType[] {
        DB_PATH
            },
            new FunctionReturnSequenceType(Type.ELEMENT, Cardinality.EXACTLY_ONE, ""));

  public SVNStatus(XQueryContext context) {
    super(context, signature);
  }

  @Override
  public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    String uri = args[0].getStringValue();
    SVNRepositoryFactoryImpl.setup();
    SVNClientManager manager = SVNClientManager.newInstance(SVNWCUtil.createDefaultOptions(false), "", "");

    SVNStatusClient statusClient = manager.getStatusClient();
   
    SVNWCClient wcClient = manager.getWCClient();

    MemTreeBuilder builder = context.getDocumentBuilder();
        builder.startDocument();
        builder.startElement(new QName("status", null, null), null);
   
        try {
      statusClient.doStatus(
          new Resource(uri),
          SVNRevision.HEAD,
          SVNDepth.getInfinityOrFilesDepth(true),
          true, true, false, false, 
          new AddStatusHandler(false, builder),
          null);
    } catch (SVNException e1) {
          builder.startElement(new QName("error", null, null), null);
          builder.characters(e1.getMessage());
          builder.endElement();
    }
   
        builder.endElement();
        builder.endDocument();

        return (NodeValue) builder.getDocument().getDocumentElement();
  }
 
    private static class AddStatusHandler implements ISVNStatusHandler {
        private boolean isRemote;

        private final MemTreeBuilder builder;

        public AddStatusHandler(boolean isRemote, MemTreeBuilder builder) {
          this.isRemote = isRemote;
          this.builder = builder;
        }

    @Override
        public void handleStatus(org.exist.versioning.svn.wc.SVNStatus status) throws SVNException {
          boolean isAddedWithHistory = status.isCopied();
         
          /*
           * If SVNStatusClient.doStatus(..) was invoked with  remote = true  the
           * following code finds out whether the current item had  been  changed
           * in the repository  
           */
          String remoteChangeType = " ";

          if(status.getRemotePropertiesStatus() != SVNStatusType.STATUS_NONE ||
             status.getRemoteContentsStatus() != SVNStatusType.STATUS_NONE) {
              /*
               * the local item is out of date
               */
              remoteChangeType = "*";
          }
          /*
           * Now getting the status of properties of an item. SVNStatusType  also
           * contains information on the properties state.
           */
          SVNStatusType propertiesStatus = status.getPropertiesStatus();
          /*
           * Default - properties are normal (unmodified).
           */
          String propertiesChangeType = " ";
          if (propertiesStatus == SVNStatusType.STATUS_MODIFIED) {
              /*
               * Properties were modified.
               */
              propertiesChangeType = "M";
          } else if (propertiesStatus == SVNStatusType.STATUS_CONFLICTED) {
              /*
               * Properties are in conflict with the repository.
               */
              propertiesChangeType = "C";
          }

          /*
           * Whether the item is switched to a different URL (branch).
           */
          boolean isSwitched = status.isSwitched();
          /*
           * If the item is a file it may be locked.
           */
          SVNLock localLock = status.getLocalLock();
          /*
           * If  doStatus()  was  run  with  remote=true  and the item is a file,
           * checks whether a remote lock presents.
           */
          SVNLock remoteLock = status.getRemoteLock();
          String lockLabel = " ";

          if (localLock != null) {
              /*
               * at first suppose the file is locKed
               */
              lockLabel = "K";
              if (remoteLock != null) {
                  /*
                   * if the lock-token of the local lock differs from  the  lock-
                   * token of the remote lock - the lock was sTolen!
                   */
                  if (!remoteLock.getID().equals(localLock.getID())) {
                      lockLabel = "T";
                  }
              } else {
                  if(isRemote){
                    /*
                     * the  local  lock presents but there's  no  lock  in  the
                     * repository - the lock was Broken. This  is  true only if
                       * doStatus() was invoked with remote=true.
                     */
                    lockLabel = "B";
                  }
              }
          } else if (remoteLock != null) {
              /*
               * the file is not locally locked but locked  in  the  repository -
               * the lock token is in some Other working copy.
               */
              lockLabel = "O";
          }

          /*
           * Obtains the number of the revision when the item was last changed.
           */
          long lastChangedRevision = status.getCommittedRevision().getNumber();

          /*
           * status is shown in the manner of the native Subversion command  line
           * client's command "svn status"
           */
//        propertiesChangeType
//            + (isAddedWithHistory ? "+" : " ")
//            + (isSwitched ? "S" : " ")
//            + lockLabel
//            + remoteChangeType


          builder.startElement(ENTRY_ELEMENT, null);
         
          builder.addAttribute(STATUS_ATTRIBUTE, status.getContentsStatus().toString());
          builder.addAttribute(LOCKED_ATTRIBUTE, status.isLocked() ? "true" : "false");
          builder.addAttribute(WORKING_REVISION_ATTRIBUTE, String.valueOf(status.getRevision().getNumber()));
          builder.addAttribute(LAST_CHANGED_REVISION_ATTRIBUTE, lastChangedRevision >= 0 ? String.valueOf(lastChangedRevision) : "?");
          builder.addAttribute(AUTHOR_ATTRIBUTE, status.getAuthor() != null ? status.getAuthor() : "?");
          builder.addAttribute(PATH_ATTRIBUTE, status.getFile().getPath());
         
          builder.endElement();
        }
    }

    private final static QName ENTRY_ELEMENT = new QName("entry", "", "");
    private final static QName STATUS_ATTRIBUTE = new QName("status", "", "");
    private final static QName LOCKED_ATTRIBUTE = new QName("locked", "", "");
    private final static QName WORKING_REVISION_ATTRIBUTE = new QName("working-revision", "", "");
    private final static QName LAST_CHANGED_REVISION_ATTRIBUTE = new QName("last-changed-revision", "", "");
    private final static QName AUTHOR_ATTRIBUTE = new QName("author", "", "");
    private final static QName PATH_ATTRIBUTE = new QName("path", "", "");
}
TOP

Related Classes of org.exist.versioning.svn.xquery.SVNStatus$AddStatusHandler

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.