Class ClientSystemFileCommands


  • public class ClientSystemFileCommands
    extends java.lang.Object
    Implements the simpler lower-level file commands that typically correspond to system commands such as chmod, delete, etc.
    • Field Detail

      • DEFAULT_TMPFILE_PFX

        public static final java.lang.String DEFAULT_TMPFILE_PFX
        See Also:
        Constant Field Values
      • DEFAULT_TMPFILE_SFX

        public static final java.lang.String DEFAULT_TMPFILE_SFX
        See Also:
        Constant Field Values
      • SYSTEM_TMPDIR_PROPS_KEY

        public static final java.lang.String SYSTEM_TMPDIR_PROPS_KEY
        See Also:
        Constant Field Values
      • SYSTEM_TMPDIR_DEFAULT

        public static final java.lang.String SYSTEM_TMPDIR_DEFAULT
        See Also:
        Constant Field Values
      • RECONCILE_HANDLER_SKIP_ADD_KEY

        protected static final java.lang.String RECONCILE_HANDLER_SKIP_ADD_KEY
        See Also:
        Constant Field Values
    • Method Detail

      • openFile

        protected RpcPacketDispatcher.RpcPacketDispatcherResult openFile​(RpcConnection rpcConnection,
                                                                         CommandEnv cmdEnv,
                                                                         java.util.Map<java.lang.String,​java.lang.Object> resultsMap)
                                                                  throws ConnectionException
        Open a client file for writing. We have to process things like NOCLOBBER, and ensure we write to a temp file if a file already exists, etc. Much of the logic here is straight from the C++ API, currently minus the OpenDiff functionality (which will probably be factored out elsewhere).

        We also have to leave the associated file descriptor (or channel equivalent) lying around for the rest of the function sequence to be able to pick up.

        Note that we also now implement the 10.2 sync (etc.) transfer integrity checks; this is actually fairly easy as it can be done on the raw (un-translated) data coming in to the write methods (as opposed to checkFile's version, which has to consider the translated data). We do most of this work in the RpcOutputStream and RpcPerforceFile classes after setting things up here; closeFile does the final round up and delivers the verdict. This all only happens if Server.nonCheckedSyncs is false.

        The temp file created here will be deleted in the subsequent closeFile() method call.

        Parameters:
        rpcConnection - rpcConnection
        cmdEnv - cmdEnv
        resultsMap - resultsMap
        Returns:
        RpcPacketDispatcherResult
        Throws:
        ConnectionException - on error
      • writeFile

        protected RpcPacketDispatcher.RpcPacketDispatcherResult writeFile​(RpcConnection rpcConnection,
                                                                          CommandEnv cmdEnv,
                                                                          java.util.Map<java.lang.String,​java.lang.Object> resultsMap)
                                                                   throws ConnectionException
        Write file contents to the target file. This method assumes that fileOpen has previously been called, and that the state map contains at least one valid file output stream to write bytes to.
        Parameters:
        rpcConnection - rpcConnection
        cmdEnv - cmdEnv
        resultsMap - resultsMap
        Returns:
        RpcPacketDispatcherResult
        Throws:
        ConnectionException - on error
      • writeText

        protected RpcPacketDispatcher.RpcPacketDispatcherResult writeText​(RpcConnection rpcConnection,
                                                                          CommandEnv cmdEnv,
                                                                          java.util.Map<java.lang.String,​java.lang.Object> resultsMap)
                                                                   throws ConnectionException
        Handles the client-OutputText command.

        Basically uses writeBinary (below) with the twist that we currently throw an exception when we see the trans option (which we haven't implemented yet).

        Note that -- like the C++ API -- no line end munging is performed -- we just throw what's coming at us straight back to whoever's catching it...

        Parameters:
        rpcConnection - rpcConnection
        cmdEnv - cmdEnv
        resultsMap - resultsMap
        Returns:
        RpcPacketDispatcherResult
        Throws:
        ConnectionException - on error
      • writeBinary

        protected RpcPacketDispatcher.RpcPacketDispatcherResult writeBinary​(RpcConnection rpcConnection,
                                                                            CommandEnv cmdEnv,
                                                                            java.util.Map<java.lang.String,​java.lang.Object> resultsMap)
                                                                     throws ConnectionException
        A specialised method to handle the client-OutputBinary command.

        Note that this method fakes a handler to keep state around, and assumes that the target (tmp) stream has been passed-in by the higher levels in the cmdEnv state map.

        Parameters:
        rpcConnection - rpcConnection
        cmdEnv - cmdEnv
        resultsMap - resultsMap
        Returns:
        RpcPacketDispatcherResult
        Throws:
        ConnectionException - on error
      • closeFile

        protected RpcPacketDispatcher.RpcPacketDispatcherResult closeFile​(RpcConnection rpcConnection,
                                                                          CommandEnv cmdEnv,
                                                                          java.util.Map<java.lang.String,​java.lang.Object> resultsMap)
                                                                   throws ConnectionException
        Close a file that was opened earlier for writing. Depending on circumstances, this may involve moving a temporary file and / or deleting other files, etc., and stitching up permissions, etc. (we are often not allowed to change a file's executable bits in places like /tmp, etc., so we do it here...).
        Parameters:
        rpcConnection - rpcConnection
        cmdEnv - cmdEnv
        resultsMap - resultsMap
        Returns:
        RpcPacketDispatcherResult
        Throws:
        ConnectionException - on error
      • checkFile

        protected RpcPacketDispatcher.RpcPacketDispatcherResult checkFile​(RpcConnection rpcConnection,
                                                                          CommandEnv cmdEnv,
                                                                          java.util.Map<java.lang.String,​java.lang.Object> resultsMap)
                                                                   throws ConnectionException
        The infamous checkFile omnibus method, used to, well, check files on the Perforce client side. Basically copied and transliterated into Java from the C++ original; not all of it currently makes sense in a Java environment, but this will be fixed (HR).

        Much of the work happens off-stage in the support methods elsewhere.

        What follows is copied from the C++ API:

        This routine, for compatibility purposes, has several modes.

        1. If clientType is set, we know the type and we're checking to see if the file exists and (if digest is set) if the file has the same fingerprint. We return this in "status" with a value of "missing", "exists", or "same". This starts around version 1742.

        2. If clientType is unset, we're looking for the type of the file, and we'll return it in "type". This is sort of overloaded, 'cause it can also get set with pseudo-types like "missing". In this case, we use the "xfiles" protocol check to make sure we don't return something the server doesn't expect.

        
         	- xfiles unset: return text, binary.
         	- xfiles >= 0: also return xtext, xbinary.
         	- xfiles >= 1: also return symlink.
         	- xfiles >= 2; also return resource (mac resource file).
         	- xfiles >= 3; also return ubinary
         	- xfiles >= 4; also return apple
         
        If forceType is set, we'll use that in preference over what we've discovered. We still check the file (to make sure they're not adding a directory, and so they get to right warning if they add an empty file), but we'll just override that back to the (typemap's) forceType.

        We map empty/missing/unreadable into forceType/"text".

        Parameters:
        rpcConnection - rpcConnection
        cmdEnv - cmdEnv
        resultsMap - resultsMap
        Returns:
        RpcPacketDispatcherResult
        Throws:
        ConnectionException - on error
      • getTempOutputStream

        public RpcOutputStream getTempOutputStream​(CommandEnv cmdEnv)
                                            throws ConnectionException
        Return the temp RPC output stream. If it doesn't exist, try to create a new one only if the command is run from a "streamCmd" method or tracking is enabled.
        Parameters:
        cmdEnv - cmdEnv
        Returns:
        RpcOutputStream
        Throws:
        ConnectionException - on error
      • getBufferOutputStream

        public RpcByteBufferOutput getBufferOutputStream​(CommandEnv cmdEnv)
                                                  throws ConnectionException
        Return the temp RPC Byte Buffer output. If it doesn't exist, try to create a new one only if the command is run from a "streamCmd" method or tracking is enabled.
        Parameters:
        cmdEnv - cmdEnv
        Returns:
        RpcByteBufferOutput
        Throws:
        ConnectionException - on error
      • convertFileDataMap

        public java.util.Map<java.lang.String,​java.lang.Object> convertFileDataMap​(java.util.Map<java.lang.String,​java.lang.Object> map,
                                                                                         java.nio.charset.Charset charset,
                                                                                         boolean isUnicodeServer)