Class RpcMessage


  • public class RpcMessage
    extends java.lang.Object
    Definitions and methods for processing, encapsulating, and handling RPC error and info codes on and off the wire.

    The Perforce RPC scheme encodes messages for the client -- warnings, fatal errors, user errors, infomercials, etc., with an integer code (usually codeX in the incoming packet, where X is 0, 1, 2, etc., i.e. there can be multiple codes in one packet) and a corresponding formatted message (keyed with fmtX, where the X corresponds to the code, etc.). The integer code encodes severity and generic levels, at least, and needs to be unpacked carefully before interpretation, especially as it comes across the wire as a string.

    The apparent generic packing for codes looks like this:

    
     ((sev<<28)|(arg<<24)|(gen<<16)|(sub<<10)|cod)
     
    where sev == severity, arg == arg count, gen == generic code, sub == subsystem (client vs. server. etc.), and cod is the actual individual error code.

    The integer code is assumed by all sides of the wire to decode into four bytes. We attempt to make this so....

    • Field Summary

      Fields 
      Modifier and Type Field Description
      static java.lang.String CODE
      CODE - code
      static java.lang.String FMT
      FMT - fmt
      static int NO_GENERIC_CODE_FOUND
      What getGeneric() returns if it can't find a plausible error generic level in a candidate string.
    • Constructor Summary

      Constructors 
      Constructor Description
      RpcMessage​(int subSystem, int code, int severity, int generic, java.lang.String[] fmtStrs, java.lang.String[] argNameStrs, java.lang.String[] argStrs)  
      RpcMessage​(ClientMessage.ClientMessageId id, int severity, int generic, java.lang.String[] argStrs)  
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      java.lang.String[] getArgNameStrs()  
      java.lang.String[] getArgStrs()  
      int getCode()  
      java.lang.String[] getFmtStrs()  
      int getGeneric()  
      static int getGeneric​(java.lang.String codeStr)
      Given a string encoding of a complete error code, return its generic error code value ("generic" being Perforce's rather odd name for the specific error value).
      int getSeverity()  
      static int getSeverity​(java.lang.String codeStr)
      Given a string encoding of a complete error code off the wire, return its severity level, if possible.
      static int getSubsystem​(java.lang.String codeStr)
      Given a string encoding of a complete error code, return its subsystem error code value.
      int getSubSystem()  
      static java.lang.String interpolateArgs​(java.lang.String fmtStr, java.util.Map<java.lang.String,​java.lang.Object> map)
      Try to fill in the %...% bits in a typical server text message.
      java.lang.String makeErrorCodeString()
      Encode the various error code subcodes as a string as seen on the wire.
      void setArgNameStrs​(java.lang.String[] argNameStrs)  
      void setArgStrs​(java.lang.String[] argStrs)  
      void setCode​(int code)  
      void setFmtStrs​(java.lang.String[] fmtStrs)  
      void setGeneric​(int generic)  
      void setSeverity​(int severity)  
      void setSubSystem​(int subSystem)  
      java.util.Map<java.lang.String,​java.lang.Object> toMap()  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • NO_GENERIC_CODE_FOUND

        public static final int NO_GENERIC_CODE_FOUND
        What getGeneric() returns if it can't find a plausible error generic level in a candidate string.
        See Also:
        Constant Field Values
    • Constructor Detail

      • RpcMessage

        public RpcMessage​(int subSystem,
                          int code,
                          int severity,
                          int generic,
                          java.lang.String[] fmtStrs,
                          java.lang.String[] argNameStrs,
                          java.lang.String[] argStrs)
      • RpcMessage

        public RpcMessage​(ClientMessage.ClientMessageId id,
                          int severity,
                          int generic,
                          java.lang.String[] argStrs)
        Parameters:
        id - id
        severity - severity
        generic - generic
        argStrs - argStrs
    • Method Detail

      • interpolateArgs

        public static java.lang.String interpolateArgs​(java.lang.String fmtStr,
                                                       java.util.Map<java.lang.String,​java.lang.Object> map)
        Try to fill in the %...% bits in a typical server text message. Example:
         fmtStr="Access for user '%user%' has not been enabled by 'p4 protect'."
         args[0]="nouser"
         
        Harder example, with alternates:
         [%argc% - no|No] such file(s).
         
        Another difficult example, with a different type of alternate:
        fmtStr=%change% created[ with %workCount% open file(s)][ fixing %jobCount% job(s)]
         
        Typically used in this implementation for error messages coming back from the server, but can have broader uses with untagged server output in general.

        FIXME: this is a rather ad-hoc and not particularly efficient algorithm, which will be replaced by a better implementation when I get more experience with relative efficiencies, etc. -- (HR).

        FIXME: provide a version that works with multiple format strings -- HR.

        Parameters:
        fmtStr - fmtStr
        map - map
        Returns:
        formatted string
      • toMap

        public java.util.Map<java.lang.String,​java.lang.Object> toMap()
        Returns:
        a Map'd version of this error in the format expected by the upper levels of the API.
      • getSeverity

        public static int getSeverity​(java.lang.String codeStr)
        Given a string encoding of a complete error code off the wire, return its severity level, if possible. Will return NONE if it can't decode the string into a suitable level (or if it was null).
        Parameters:
        codeStr - candidate error code
        Returns:
        corresponding MessageSeverityCode level, or MessageSeverityCode.E_EMPTY
      • getGeneric

        public static int getGeneric​(java.lang.String codeStr)
        Given a string encoding of a complete error code, return its generic error code value ("generic" being Perforce's rather odd name for the specific error value). Will return NO_GENERIC_CODE_FOUND if it can't find a suitable value in the passed-in string (or if the string was null).
        Parameters:
        codeStr - candidate error code
        Returns:
        corresponding generic level, or NO_GENERIC_CODE_FOUND
      • getSubsystem

        public static int getSubsystem​(java.lang.String codeStr)
        Given a string encoding of a complete error code, return its subsystem error code value. Will return CLIENT if it can't find a suitable value in the passed-in string (or if the string was null).
        Parameters:
        codeStr - candidate error code
        Returns:
        corresponding subsystem, or CLIENT if none found (FIXME? -- HR)
      • makeErrorCodeString

        public java.lang.String makeErrorCodeString()
        Encode the various error code subcodes as a string as seen on the wire. The general encoding (taken straight from the C++ API) is as follows:
        
         # define ErrorOf( sub, cod, sev, gen, arg ) \
         ((sev<<28)|(arg<<24)|(gen<<16)|(sub<<10)|cod)
         
        Returns:
        error code
      • getSeverity

        public int getSeverity()
      • setSeverity

        public void setSeverity​(int severity)
      • getSubSystem

        public int getSubSystem()
      • setSubSystem

        public void setSubSystem​(int subSystem)
      • getGeneric

        public int getGeneric()
      • setGeneric

        public void setGeneric​(int generic)
      • getCode

        public int getCode()
      • setCode

        public void setCode​(int code)
      • getFmtStrs

        public java.lang.String[] getFmtStrs()
      • setFmtStrs

        public void setFmtStrs​(java.lang.String[] fmtStrs)
      • getArgStrs

        public java.lang.String[] getArgStrs()
      • setArgStrs

        public void setArgStrs​(java.lang.String[] argStrs)
      • getArgNameStrs

        public java.lang.String[] getArgNameStrs()
      • setArgNameStrs

        public void setArgNameStrs​(java.lang.String[] argNameStrs)