I'm using MQ JMS interface with MQ 6.0.2.
It seems that only pre defined properties are suported and not arbitrary ones.
for instance, I can properly getJMSCorrelationID(), getJMSPriority() etc. However, when i set an arbitrary property on the sender:
message.setStringProperty("my arbitrary name", "value");
I can't get the property from the message on the receiver:
message.getStringProperty("my arbitrary name");
I simply get null.
Is there a way to do that as in any JMS implementation, or is that an MQ JMS limitation?
If you have the complete client install, you can go to C:\Program Files\IBM\WebSphere MQ\tools\jms\samples\interactive\ or somewhere in /opt/mqm/samp and look for SampleConsumerJava.java and SampleProducerJava.java.
From the sample Producer program:
// Set custom properties
msg.setStringProperty("MyStringProperty", "My Year Of Birth");
msg.setIntProperty("MyIntProperty", 2007);
And from the sample Consumer:
// Get values for custom properties, if available
String property1 = msg.getStringProperty("MyStringProperty");
// Get value for an int property, store the result in long to validate
// the get operation.
long property2 = ((long) Integer.MAX_VALUE) + 1;
property2 = msg.getIntProperty("MyIntProperty");
if ((property1 != null) && (property2 < Integer.MAX_VALUE)) {
System.out.println("[Message has my custom properties]");
Property names follow the rules for Java variable names and cant have spaces in them.
Per the JMS 1.1 specification:
An identifier is an unlimited-length
character sequence that must begin
with a Java identifier start
character; all following characters
must be Java identifier part
characters. An identifier start
character is any character for which
the method
Character.isJavaIdentifierStart
returns true. This includes ‘_’ and
‘$’. An identifier part character is
any character for which the method
Character.isJavaIdentifierPart returns
true.
Following the clues here takes us to the Javadoc for the Character.isJavaIdentifierPart method which lists the valid characters for an identifier:
A character may be part of a Java
identifier if any of the following are
true:
* it is a letter
* it is a currency symbol (such as '$')
* it is a connecting punctuation character (such as '_')
* it is a digit
* it is a numeric letter (such as a Roman numeral character)
* it is a combining mark
* it is a non-spacing mark
* isIdentifierIgnorable(codePoint) returns true for the character
Note that white space is specifically excluded from the set of valid identifier characters. The set of valid first characters is a little more restrictive and includes the following characters:
* isLetter(ch) returns true
* getType(ch) returns LETTER_NUMBER
* ch is a currency symbol (such as "$")
* ch is a connecting punctuation character (such as "_").
Use a valid identifier and try again. For example:
message.setStringProperty("my.arbitrary.name", "value");
message.getStringProperty("my.arbitrary.name");
Or possibly...
message.setStringProperty("myArbitraryName", "value");
message.getStringProperty("myArbitraryName");
By the way, switch to V7 at your earliest opportunity. Not only is the support for properties much better in general, but the ability to directly read/write MQMD headers is vastly improved as shown in the IBM example.
Related
I'm working with an API that returns an array of objects. I can get all the keys, but two of those have numbers as keys, and I cannot get it. Give me an error.
I really dont know why I can not get it those keys.
Is there something different due to are numbers?
BTW Im using axios.
If you're using dot notation, you should change to bracket notation to access properties start by a number.
The code below uses dot notation, it throws an error
const test = {"1h" : "test value"};
console.log(test.1h); // error
Why :
In the object.property syntax, the property must be a valid JavaScript
identifier.
An identifier is a sequence of characters in the code that identifies a variable, function, or property.
In JavaScript, identifiers are case-sensitive and can contain Unicode letters, $, _, and digits (0-9), but may not start with a digit.
The code below uses bracket notation, works fine
const test = {"1h" : "test value"};
console.log(test["1h"]); // works
Why :
In the object[property_name] syntax, the property_name is just a
string or Symbol. So, it can be any string, including '1foo', '!bar!',
or even ' ' (a space).
Check out the document here
What is the equivalent for DBMS_SQL.LAST_ERROR_POSITION in PostgreSQL to get the offset of an error?
You don't specify in what programming language you want to access this information, and not all APIs give you access to the location of the error, but it is sent with the PostgreSQL error message.
See the documentation for the C API:
PQresultErrorField
Returns an individual field of an error report.
char *PQresultErrorField(const PGresult *res, int fieldcode);
fieldcode is an error field identifier; see the symbols listed below. NULL is returned if the PGresult is not an error or warning result, or does not include the specified field. Field values will normally not include a trailing newline. The caller should not free the result directly. It will be freed when the associated PGresult handle is passed to PQclear.
The following field codes are available:
[...]
PG_DIAG_STATEMENT_POSITION
A string containing a decimal integer indicating an error cursor position as an index into the original statement string. The first character has index 1, and positions are measured in characters not bytes.
PG_DIAG_INTERNAL_POSITION
This is defined the same as the PG_DIAG_STATEMENT_POSITION field, but it is used when the cursor position refers to an internally generated command rather than the one submitted by the client. The PG_DIAG_INTERNAL_QUERY field will always appear when this field appears.
Why velocity gives the following output for the string
VelocityContext vc = new VelocityContext();
vc.put("foo", "bar");
String inString = "THis is ${{foo}} and this is ${foo}.Hello and ${foo}-Hello";
StringWriter sw = new StringWriter();
ve.evaluate(vc, sw, "Tag", inString);
Output:
THis is ${{} and this is bar.Hello and bar-Hello
I was expecting it would either print ${{foo}} or {bar}, why ${{}? Would double curly act as escape character?
I'm using this under strict reference mode set as true. And I neither see an exception nor I see it print it as is and that's what is confusing me.
Well, you made me look into the code and I'm not sure if I understood it correctly. The problem seems to be that in ${...}, the xxx is treated as an ASTReference, which then gets tokenized differently than a standalone string "{bar}". Specifically, it get tokenized into 3 tokens {, bar and }. Then the engine tries to find the so-called root of the reference (in ${x}, the root is x), does not recognize the pattern and goes into a fallback reference type RUNT, which says that the first token, i.e. "{" matters. This way "{bar}" becomes "{".
In other words, the expression ${{bar}} does not make sense and Velocity fails to throw an error here. In other nonsensical combinations like ${[bar]} it actually throws an error.
Velocity Variables or VTL Identifier
Must start with an alphabetic character (a .. z or A .. Z). The rest of the characters are limited to the following types of characters:
alphabetic (a .. z, A .. Z)
numeric (0 .. 9)
hyphen ("-")
underscore ("_")
You are using Formal Reference Notation as ${varName}
${{foo}} - so velocity try to get variable {foo} which is invalid VTL Identifier so it doesn't try to load the variable.
It probably then try to reference it as a JSON map {"a":"b"} and failed again, probably only { is accepted, so you remain with:
${{}
I tested your template in new velocity 2.0 and this issue isn't reproduce (in strict or non strict mode)
Output:
THis is ${{foo}} and this is bar.Hello and bar-Hello
So you have now a reason to upgrade to velocity 2.0.
(Question by John Williams, from a Coursera forum, which I decided to share with the community, since I haven't been able to find this answered anywhere.)
The following code runs without error:
int _j = 1;
//int 2var = 2;
int var2 = 2;
int Kvar = 3; // first letter can be uppercase
int spec$var = 4;
int com_pound_var = 5; // compounding without camel case
int com$pound$two = 6;
int $var = 199;
println(_j);
println(var2);
println(Kvar);
println(spec$var);
println(com_pound_var);
println(com$pound$two);
println($var); //first character can be special
Since the compiler accepts _j, Kvar, and $var as valid variable names, it is clear that variable names do not need to start with a lowercase letter.
I was unable to locate the variable naming rules anywhere in the reference.
What are the variable naming rules for the Processing language?
Quick answer: can start with any letter, underscore and dollar signs, continue with letters, numbers, underscore and dollar signs. Details below.
I could also not find anything in the reference or the documentation at all. However, inspecting the source code, I found that Processing is not a language of its own, but rather a framework in which you run some commands. The difference is that you're actually writing a different language, and Processing just gives you some basic scaffolding where you build on top of.
For some technical details: Processing compiles a Java Build with some flags, spins up a virtual machine (Java VM, not same thing as a full fledged virtual machine) and connects to it to get input and output streams (this is why you can interact with the mouse or get the console output of your own program in a separate window). (Source.)
This language, which you may have guessed already, is Java.
With that said, the actual docs that answer this question is the Java Language Specification, which, to simplify things, is as close as you can get to an answer. (But if you really want to know, it's a mess.)
Specifically, the section on Identifiers, which I'll sum up below:
Can start with any letter (A-Z, a-z), underscore (_), dollar sign ($), or any unicode "letter" (accented, chinese, etc. Details.)
Can continue with any of the above, and can also continue with digits (0-9). Can also contain other unicode "letters" (Details.)
Can have unlimited length
Cannot be any Java keyword (list here)
Cannot be false, true, null
They can look the same and still be different if their codes are different (some Unicode letters look just like letters but are different ones)
I hope this helps! Investigating was fun.
I tried error reporting in following manner.
#members{
public String getErrorMessage(RecognitionException e,String[] tokenNames)
{
List stack=getRuleInvocationStack(e,this.getClass().getName());
String msg=null;
if(e instanceof NoViableAltException){
<some code>
}
else{
msg=super.getErrorMessage(e,tokenNames);
}
String[] inputLines = e.input.toString().split("\r\n");
String line = "";
if(e.token.getCharPositionInLine()==0)
line = "at \"" + inputLines[e.token.getLine() - 2];
else if(e.token.getCharPositionInLine()>0)
line = "at \"" + inputLines[e.token.getLine() - 1];
return ": " + msg.split("at")[0] + line + "\" => [" + stack.get(stack.size() - 1) + "]";
}
public String getTokenErrorDisplay(Token t){
return t.toString();
}
}
And now errors are displayed as follows.
line 6:7 : missing CLOSSB at "int a[6;" => [var_declaration]
line 8:0 : missing SEMICOL at "int p" => [var_declaration]
line 8:5 : missing CLOSB at "get(2;" => [call]
I have 2 questions.
1) Is there a proper way to do the same thing I have done?
2) I want to replace CLOSSB, SEMICOL, CLOSB etc. with their real symbols. How can I do that using the map in .g file?
Thank you.
1) Is there a proper way to do the same thing I have done?
I don't know if there is a defined proper way of showing errors. My take on showing errors is a litmis test. If the user can figure out how to fix the error based on what you have given them then it is good. If the user is confued by the error message then the message needs more work. Based on the examples given in the question, symbols were only char constants.
My favorite way of seeing errors is with the line with an arrow pointing at the location.
i.e.
Expected closing brace on line 6.
int a[6;
^
2) I want to replace CLOSSB, SEMICOL, CLOSB etc. with their real symbols. How can I do that using the map in .g file?
You will have to read the separately generated token file and then make a map, i.e. a dictionary data structure, to translate the token name into the token character(s).
EDIT
First we have to clarify what is meant by symbol. If you limit the definition of symbol to only tokens that are defined in the tokens file with a char or string then this can be done, i.e. '!'=13, or 'public'=92, if however you chose to use the definition of symbol to be any text associated with a token, then that is something other than what I was or plan to address.
When ANTLR generates its token map it uses three different sources:
The char or string constants in the lexer
The char or string constants in the parser.
Internal tokens such as Invalid, Down, Up
Since the tokens in the lexer are not the complete set, one should use the tokens file as a starting point. If you look at the tokens file you will note that the lowest value is 4. If you look at the TokenTypes file (This is the C# version name) you will find the remaining defined tokens.
If you find names like T__ in the tokens file, those are the names ANTLR generated for the char/string literals in the parser.
If you are using string and/or char literals in parser rules, then ANTLR must create a new set of lexer rules that include all of the string and/or char literals in the parser rules. Remember that the parser can only see tokens and not raw text. So string and/or char literals cannot be passed to the parser.
To see the new set of lexer rules, use org.antlr.Tool –Xsavelexer, and then open the created grammar file. The name may be like.g . If you have string and/or char literals in your parser rules you will see lexer rules with name starting with T .
Now that you know all of the tokens and their values you can create a mapping table from the info given in the error to the string you want to output instead for the symbol.
The code at http://markmail.org/message/2vtaukxw5kbdnhdv#query:+page:1+mid:2vtaukxw5kbdnhdv+state:results
is an example.
However the mapping of the tokens can change for such things as changing rules in the lexer or changing char/string literals in the parser. So if the message all of a sudden output the wrong string for a symbol you will have to update the mapping table by hand.
While this is not a perfect solution, it is a possible solution depending on how you define symbol.
Note: Last time I looked ANTLR 4.x creates the table automatically for access within the parser because it was such a problem for so many with ANTLR 3.x.
Bhathiya wrote:
*1) Is there a proper way to do the same thing I have done?
There is no single way to do this. Note that proper error-handling and reporting is tricky. Terence Parr spends a whole chapter on this in The Definitive ANTLR Reference (chapter 10). I recommend you get hold of a copy and read it.
Bhathiya wrote:
2) I want to replace CLOSSB, SEMICOL, CLOSB etc. with their real symbols. How can I do that using the map in .g file?
You can't. For SEMICOL this may seem easy to do, but how would you get this information for a token like FOO:
FOO : (X | Y)+;
fragment X : '4'..'6';
fragment Y : 'a' | 'bc' | . ;