com.perforce.p4java.impl.mapbased.rpc.msg
Class RpcMessage

java.lang.Object
  extended by com.perforce.p4java.impl.mapbased.rpc.msg.RpcMessage

public class RpcMessage
extends 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
static String CODE
          CODE - code
static 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
RpcMessage(ClientMessage.ClientMessageId id, int severity, int generic, String[] argStrs)
           
RpcMessage(int subSystem, int code, int severity, int generic, String[] fmtStrs, String[] argNameStrs, String[] argStrs)
           
 
Method Summary
 String[] getArgNameStrs()
           
 String[] getArgStrs()
           
 int getCode()
           
 String[] getFmtStrs()
           
 int getGeneric()
           
static int getGeneric(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(String codeStr)
          Given a string encoding of a complete error code off the wire, return its severity level, if possible.
 int getSubSystem()
           
static int getSubsystem(String codeStr)
          Given a string encoding of a complete error code, return its subsystem error code value.
static String interpolateArgs(String fmtStr, Map<String,Object> map)
          Try to fill in the %...% bits in a typical server text message.
 String makeErrorCodeString()
          Encode the various error code subcodes as a string as seen on the wire.
 void setArgNameStrs(String[] argNameStrs)
           
 void setArgStrs(String[] argStrs)
           
 void setCode(int code)
           
 void setFmtStrs(String[] fmtStrs)
           
 void setGeneric(int generic)
           
 void setSeverity(int severity)
           
 void setSubSystem(int subSystem)
           
 Map<String,Object> toMap()
          Return a Map'd version of this error in the format expected by the upper levels of the API.
 
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

CODE

public static final String CODE
CODE - code

See Also:
Constant Field Values

FMT

public static final String FMT
FMT - fmt

See Also:
Constant Field Values
Constructor Detail

RpcMessage

public RpcMessage(int subSystem,
                  int code,
                  int severity,
                  int generic,
                  String[] fmtStrs,
                  String[] argNameStrs,
                  String[] argStrs)

RpcMessage

public RpcMessage(ClientMessage.ClientMessageId id,
                  int severity,
                  int generic,
                  String[] argStrs)
Method Detail

interpolateArgs

public static String interpolateArgs(String fmtStr,
                                     Map<String,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.


toMap

public Map<String,Object> toMap()
Return a Map'd version of this error in the format expected by the upper levels of the API.


getSeverity

public static int getSeverity(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(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(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 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)
 


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 String[] getFmtStrs()

setFmtStrs

public void setFmtStrs(String[] fmtStrs)

getArgStrs

public String[] getArgStrs()

setArgStrs

public void setArgStrs(String[] argStrs)

getArgNameStrs

public String[] getArgNameStrs()

setArgNameStrs

public void setArgNameStrs(String[] argNameStrs)


Copyright © 2015 Perforce Software. All Rights Reserved.