in an XPage repeat control I'm trying to compute a string based upon date values in the underlying Notes view. The first two columns of the view are StartDate and EndDate respectively.
In my code (see below) the print statements work fine and prints lovely looking dates on the console. As soon as it gets to the date comparisons it throws some horrible errors.
var vReturn = "unknown";
try {
var vNow = new java.util.Date();
var vDateToday:org.openntf.domino.DateTime = session.createDateTime(vNow);
print("Today=" + vDateToday);
var vStartDate:org.openntf.domino.DateTime = row.getColumnValues()[0];
print("vStartDate=" + vStartDate);
var vEndDate:org.openntf.domino.DateTime = row.getColumnValues()[1];
print("vEndDate=" + vEndDate);
if (vDateToday.isBefore(vStartDate)) {
vReturn = "Forthcoming";
}
if (vDateToday.isAfter(vStartDate) && vDateToday.isBefore(vEndDate)) {
vReturn = "Current";
}
if (vDateToday.isAfter(vEndDate)) {
vReturn = "Completed";
}
}catch(e){
print("Travellog: " + e.toString());
}
return vReturn;
The first dozen or so lines output to the console looks like this:
19/12/2016 11:25:45 HTTP JVM: Today=19/12/2016 11:25:45 GMT
19/12/2016 11:25:45 HTTP JVM: vStartDate=19/12/2016 00:00:00 GMT
19/12/2016 11:25:45 HTTP JVM: vEndDate=27/12/2016 00:00:00 GMT
19/12/2016 11:25:45 HTTP JVM: java.lang.NullPointerException
19/12/2016 11:25:45 HTTP JVM: at org.openntf.domino.xsp.script.WrapperOpenDomino$OpenFunction.call(WrapperOpenDomino.java:400)
19/12/2016 11:25:45 HTTP JVM: at com.ibm.jscript.types.BuiltinFunction.call(BuiltinFunction.java:75)
19/12/2016 11:25:45 HTTP JVM: at com.ibm.jscript.types.FBSObject.call(FBSObject.java:161)
19/12/2016 11:25:45 HTTP JVM: at com.ibm.jscript.ASTTree.ASTCall.interpret(ASTCall.java:197)
19/12/2016 11:25:45 HTTP JVM: at com.ibm.jscript.ASTTree.ASTIf.interpret(ASTIf.java:79)
19/12/2016 11:25:45 HTTP JVM: at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100)
19/12/2016 11:25:45 HTTP JVM: at com.ibm.jscript.ASTTree.ASTTry.interpret(ASTTry.java:109)
19/12/2016 11:25:45 HTTP JVM: at com.ibm.jscript.ASTTree.ASTProgram.interpret(ASTProgram.java:119)
19/12/2016 11:25:45 HTTP JVM: at com.ibm.jscript.ASTTree.ASTProgram.interpretEx(ASTProgram.java:139)
...
I have tried wrapping getColumnValues in session.CreateDateTime like so:
var vStartDate:org.openntf.domino.DateTime = session.createDateTime(row.getColumnValues()[0])
but that throws errors too.
Can anyone point me in the right direction? I've tried every variation I can think of!
P.S. The examples in the OpenNTF Domino example database look simple but they only ever use the current system date, never dates from documents or view entries.
It sounds like your columns aren't displaying dates. The following button code in that demo database works successfully for me:
<xp:button value="Run SSJS Tests" id="button4"
xp:key="SSJSButton">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="SSJSDiv">
<xp:this.action><![CDATA[#{javascript:try {
var now = new java.util.Date();
var vw:NotesView = database.getView("AllContacts");
var ec:NotesViewEntryCollection = vw.getAllEntries();
var ent1 = ec.getFirstEntry();
var ent2 = ec.getNextEntry();
print(ent1.getColumnValues());
print(ent1.getColumnValues().get(6).getClass().getName());
var date1:org.openntf.domino.DateTime = ent1.getColumnValues().get(6);
var date2:org.openntf.domino.DateTime = ent2.getColumnValues().get(6);
date1.adjustDay(1);
retVal = "Running SSJS date1.isAfter(date2)<br/>";
if (date1.isAfter(date2)) {
retVal += #Text(date1) + " is after " + #Text(date2) + "<br/>";
} else {
retVal += #Text(date1) + " is NOT after " + #Text(date2) + "<br/>";
}
retVal += "<br/><br/>Running SSJS date2.isAfter(date1)<br/>";
if (date2.isAfter(date1)) {
retVal += #Text(date2) + " is after " + #Text(date1) + "<br/>";
} else {
retVal += #Text(date2) + " is NOT after " + #Text(date1) + "<br/>";
}
viewScope.put("SSJSTest",retVal);
} catch (e) {
#ErrorMessage(e.toString());
}}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
Possibly a better option is to use row.setPreferJavaDates(). That then ensures a Java Date (java.util.Date) is outputted instead of a NotesDateTime. That also removes the need to recycle. The isBefore() and isAfter() methods just convert the NotesDateTime to a java.util.Date and use the in-built isBefore() and isAfter() methods available in that class anyway.
Paul's comment where he points out that there is a difference between NotesViewEntry and NotesXspViewEntry pointed me in the right direction. My code is in a repeat control and it turns out that repeat controls return NotesXspViewEntries. I messed about trying to get the underlying NotesViewEntry but after reading a comment by Tim Tripconey about the dangers of doing this (see How do I get the parent NotesViewEntry from the NotesXSPViewEntry?) I decided to go for the underlying document instead. Here is my code:
var vReturn = "unknown";
try {
var vNow = new java.util.Date();
var vDateToday:org.openntf.domino.DateTime = session.createDateTime(vNow);
var vDoc:NotesDocument = row.getDocument();
var vStartDate:org.openntf.domino.DateTime = vDoc.getItemValueDateTimeArray("DateStart").get(0);
var vEndDate:org.openntf.domino.DateTime = vDoc.getItemValueDateTimeArray("DateEnd").get(0);
if (vDateToday.isBeforeIgnoreTime(vStartDate)) {
vReturn = "Forthcoming";
}
if ((vDateToday.equalsIgnoreTime(vStartDate) || vDateToday.isAfterIgnoreTime(vStartDate))
&& (vDateToday.equalsIgnoreTime(vEndDate) || vDateToday.isBefore(vEndDate))) {
vReturn = "Currently Away";
}
if (vDateToday.isAfterIgnoreTime(vEndDate)) {
vReturn = "Completed";
}
}catch(e){
print("Travellog: error in itinerary status link on home page: " + e.toString());
}
return vReturn;
I probably need to make it a bit more robust - e.g. if one of the date fields does not contain a value (because a date field with no value returns an empty string which causes .getItemValueDateTimeArray to throw an error).
Thanks for your help Paul. Once again you've pulled me out of the coding bottomless pit!
Related
I have problem with Golang to generate the correct the correct Authorization string for API access. I try with JS and the string is okay to use while the string from golang can not be used for authentication. Can you help me check what is the different and correct me?
Here is my golang code:
func generateSalt(dataToSign string) string {
token := hmac.New(sha256.New, []byte("secret"))
token.Write([]byte(dataToSign))
macSum := token.Sum(nil)
return base64.StdEncoding.EncodeToString(macSum)
}
func main() {
date = "Wed, 25 May 2022 09:16:45 GMT"
uri := "groups"
url := fmt.Sprintf("https://api-worldcheck.refinitiv.com/v2/%s", uri)
dataToSign := fmt.Sprintf(`(request-target): get %s%vhost: %s%vdate: %s`, "/v2/groups", "\r\n", "api-worldcheck.refinitiv.com", "\r\n", date)
log.Printf("dateToSign: %s", dataToSign)
hmac := generateSalt(dataToSign)
authorization := fmt.Sprintf(`Signature keyId="%s",algorithm="hmac-sha256",headers="(request-target) host date",signature="%s"`, "api-key", hmac)
log.Printf("authorization: %s", authorization)
}
The result from golang is dZzRZfa0yVZsTWof+qEz5VhsFyV83b6DDKXzG9pp/yk=
The code on JS
function generateAuthHeader(dataToSign){
var hash = CryptoJS.HmacSHA256(dataToSign,environment["api-secret"]);
return hash.toString(CryptoJS.enc.Base64);
}
var date = "Wed, 25 May 2022 09:16:45 GMT";
var dataToSign = "(request-target): get " + environment["gateway-url"] + "groups\n" +
"host: " + environment["gateway-host"] + "\n" +
"date: " + date;
console.log("date", date)
console.log({dataToSign})
var hmac = generateAuthHeader(dataToSign);
var authorisation = "Signature keyId=\"" + environment["api-key"] + "\",algorithm=\"hmac-sha256\",headers=\"(request-target) host date\",signature=\"" + hmac + "\"";
console.log({authorisation})
The result is nx5uyMlq4kOxY1fD5OpoLE6UGI+f5p3OUy+l6G8+oxc=
Both the snippets have different data to sign. The JS has some env vars that are used which might be different. I have taken those values from the Go code.
Go code: Go Playground example
// You can edit this code!
// Click here and start typing.
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
"log"
)
func generateSalt(dataToSign string) string {
token := hmac.New(sha256.New, []byte("secret"))
token.Write([]byte(dataToSign))
macSum := token.Sum(nil)
return base64.StdEncoding.EncodeToString(macSum)
}
func main() {
date := "Wed, 25 May 2022 09:16:45 GMT"
uri := "groups"
url := fmt.Sprintf("https://api-worldcheck.refinitiv.com/v2/%s", uri)
host := "api-worldcheck.refinitiv.com"
dataToSign := fmt.Sprintf("(request-target): get %s\nhost: %s\ndate: %s", url, host, date)
log.Printf("dateToSign: %s", dataToSign)
hmac := generateSalt(dataToSign)
authorization := fmt.Sprintf(`Signature keyId="%s",algorithm="hmac-sha256",headers="(request-target) host date",signature="%s"`, "api-key", hmac)
log.Printf("authorization: %s", authorization)
}
JS Code:
function generateAuthHeader(dataToSign){
var hash = CryptoJS.HmacSHA256(dataToSign, "secret");
return hash.toString(CryptoJS.enc.Base64);
}
var date = "Wed, 25 May 2022 09:16:45 GMT";
var url = "https://api-worldcheck.refinitiv.com/v2/";
var host = "api-worldcheck.refinitiv.com";
var apiKey = "api-key";
var dataToSign = "(request-target): get " + url + "groups\n" +
"host: " + host + "\n" +
"date: " + date;
console.log("date", date)
console.log("dataToSign", dataToSign)
var hmac = generateAuthHeader(dataToSign);
var authorisation = "Signature keyId=\"" + apiKey + "\",algorithm=\"hmac-sha256\",headers=\"(request-target) host date\",signature=\"" + hmac + "\"";
console.log(authorisation);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
Both have the signature as pZjwRvunAPwUs7tFdbFtY6xOLjbpKUYMpnb
I need help. While passing a datetime parameter to a web service, i am getting an error: Input XML was not in a correct format. The value "date" is not a valid AllXsd value.
I have installed npm date-time and npm dateformat.
Code snippet:
Var datetime=require("date-time");
Var dateformat = require("dateformat");
Var dt="#6/2/2017 5:02:03 PM#";
Var d=new date(dt); //tried with this but getting error
Var d=new date(dt).toISOString(); //this throws error too but a diff one..input string was not in a correct format
Var d=datetime({local:false}); //also not working
Var d=dateformat(dt, "m/d/yyyy hh:mm:ss TT"); // throws error
Var dtime = [d.getMonth() + 1,
d.getDate(),
d.getYear()].join('/')]; //this also throws error
//Service call
service.method(<d>/<dt>, (result) => {
res(result);
});
Use var d = new Date(dt);
Notice the 'D' in Date(dt). You used date(dt).
I have the code which calls java agent from lotusscript agent
Sub insertDealDetails()
On Error GoTo errhandler
MsgBox "inside deal details"
Dim agent As NotesAgent
On Error GoTo errhandler
Set agent = db.GetAgent("Procs")
If agent.RunOnServer(doc.Noteid) = 0 Then
MessageBox "Agent ran",, "Success"
Else
MessageBox "Agent did not run",, "Failure"
End If
Exit Sub
errhandler:
MsgBox "Error in function insertDealDetails in agtSubmit Agent" & Erl & Error
End Sub
Now if any exception occurs in Procs agent,how the main agent calling insertDealDetails() can be supplied with exception so that it stops the main agent.
Use an In-Memory Document,
write your error message into this document in Java agent and
read the error message in LotusScript code.
LotusScript
Call agent.RunWithDocumentContext(doc)
If doc.ErrorMessage(0) <> "" Then
print doc.ErrorMessage(0)
' handle the error
End If
Java agent
Document doc = agentContext.getDocumentContext();
...
doc.replaceItemValue("ErrorMessage", "Your Error Message from Java Agent");
You don't need to save the In-Memory document at any time.
it is updated code
`Sub insertDealDetails()
On Error GoTo errhandler
MsgBox "inside deal details"
Dim agent As NotesAgent
Dim in_doc As Notesdocument
On Error GoTo errhandler
Set agent = db.GetAgent("Procs")
Set in_doc = db.createDocument()
If agent.Runwithdocumentcontext(in_doc,doc.Noteid) Then`
MsgBox "doc.ErrorMessage(0):::::::::"&in_doc.ErrorMessage(0)
If in_doc.ErrorMessage(0)<>"" Then
Call prompt("2")
End If
End If
Exit Sub
errhandler:
MsgBox "Error in function insertDealDetails in agtSubmit Agent" & Erl & Error
End Sub
the problem now here is it is not returning from java code called in Procs agent.What i will be doing wrong here.
public class JavaAgent extends AgentBase {
public void NotesMain() {
Connection con = null;
CallableStatement stmt = null;
Database db;
lotus.domino.Document doc = null;
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
doc = agentContext.getDocumentContext();
con = JavaAgent.getConnection(); //making connectiion here
//executing code here and exception occurs
System.out.println("success");
} catch(Exception e) {
try {
doc.replaceItemValue("ErrorMessage", e.getMessage());
} catch (NotesException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally{
try {
stmt.close();
con.close();
} catch (SQLException e) {
try {
doc.replaceItemValue("ErrorMessage", e.getMessage());
} catch (NotesException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
}
The logs for the same is as follows:
**[0DCC:01AD-053C] 01/27/2016 01:24:56 PM HTTP JVM: class load: JavaAgent from: <unknown>
[0DCC:04B2-199C] 01/27/2016 01:24:56 PM HTTP JVM: before connection:::::
[0DCC:04B2-199C] 01/27/2016 01:24:56 PM HTTP JVM: inside dobi
[0DCC:04B2-199C] 01/27/2016 01:24:56 PM HTTP JVM: inside dobi 2
[0DCC:04B2-199C] 01/27/2016 01:25:28 PM HTTP JVM: inside dobi 3
[0DCC:04B2-199C] 01/27/2016 01:25:28 PM HTTP JVM: after connection:::::Oracle Database 11g Release 11.1.0.0.0 - Production
[0DCC:04B2-199C] 01/27/2016 01:25:28 PM HTTP JVM: message is Invalid column index
[0DCC:04B2-199C] 01/27/2016 01:25:28 PM HTTP JVM: java.sql.SQLException: Invalid column index
[0DCC:04B2-199C] 01/27/2016 01:25:28 PM HTTP JVM: at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:125)
[0DCC:04B2-199C] 01/27/2016 01:25:28 PM HTTP JVM: at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:162)
[0DCC:04B2-199C] 01/27/2016 01:25:28 PM HTTP JVM: at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:227)
[0DCC:04B2-199C] 01/27/2016 01:25:28 PM HTTP JVM: at oracle.jdbc.driver.OraclePreparedStatement.setStringInternal(OraclePreparedStatement.java:4596)
[0DCC:04B2-199C] 01/27/2016 01:25:28 PM HTTP JVM: at oracle.jdbc.driver.OracleCallableStatement.setString(OracleCallableStatement.java:4249)
[0DCC:04B2-199C] 01/27/2016 01:25:28 PM HTTP JVM: at JavaAgent.NotesMain(Unknown Source)
[0DCC:04B2-199C] 01/27/2016 01:25:28 PM HTTP JVM: at lotus.domino.AgentBase.runNotes(Unknown Source)
[0DCC:04B2-199C] 01/27/2016 01:25:28 PM HTTP JVM: at lotus.domino.NotesThread.run(Unknown Source)
[0DF8:000A-0F84] Router: DNS server returned an error searching for MX records. The destination domain may not exist: 11.17.108.223, Error: Not implemented(NOTIMP)**
The working code with steps for the same is as follows:
%REM
Sub insertDetailsOracle
Description: To insert details in Oracle Table
Date: 28/03/2014
'******************* Logic ***************************
'Validation In submit agent
'1)Create in-memory document
'2)Run java agent with Runwithdocumentcontext passing newly created in-memory document
' as well as note-id of original request document context
'If pass i.e. no exceptions in Java agent
'1) submit the Case
'Else
'1) Log Error message and exit the agent
'***************************************************
%END REM
Function insertDetailsOracle() As String
On Error GoTo errhandler
Dim agent As NotesAgent
Dim agentValue As Boolean
Set agent = db.GetAgent("Procs")
'Create in-memory document
Set in_doc = db.createDocument()
'Running java agent with Runwithdocumentcontext
agentValue = agent.Runwithdocumentcontext(in_doc,doc.Noteid)
'Return error message as per message passed by java agent in in-memory document's field
If in_doc.ErrorMessage(0)<>"" Then
insertDealDetails = in_doc.ErrorMessage(0)
Else
insertDealDetails = "1"
End If
Exit Function
errhandler:
MsgBox "Error in function insertDealDetailsOracle in agtSubmit Agent" & Erl & Error
End Function
The java method will be same as below.
how are you doing? I hope fine.
So I'm trying to send an urlRequest and I can't pass the parameters by url so I'm trying to use the URLVariable, but no matter what I try my php always get null.
var request:URLRequest = new URLRequest(SITE_DOMAIN + "/check_login.php");
request.method = URLRequestMethod.POST;
var variables:URLVariables = new URLVariables();
variables.login = emailInput.text;
variables.password = senhaInput.text;
variables.gotogame = "BURACO";
Reflect.setField(variables, "login", emailInput.text);
Reflect.setField(variables, "password", senhaInput.text);
Reflect.setField(variables, "gotogame", "BURACO");
request.data = variables;
request.method = URLRequestMethod.POST;
openfl.Lib.getURL(request);
As you guys can see I'm trying to set the variables in two ways but neither of they are working and I kind of don't know what to do anymore, please help.
Ive used this without problems:
var request:Http = new Http(SERVER + "actions/layout-builder?random=" + Math.random());
request.addParameter("action", "retrieve");
request.addParameter("layoutId", layoutId);
request.onError = function(msg) {
showSimplePopup("Problem loading layout:\n\n" + msg);
}
request.onStatus = function(status:Int) {
}
request.onData = function(response) {
response = StringTools.replace(response, "\r\n", "\n");
layoutCode.text = response;
}
request.request(false);
I Have a HTML response. I need to parse it and generate a DOM object. After generation of DOM object I need to search a particular string inside it and get complete hierarchy of HTML tags in which it resides. Is there any NPM package available.
There's an even simpler API for this now in htmlparser2:
var htmlparser = require("htmlparser2");
var dom = htmlparser.parseDOM("<html>your html string</html>");
console.log(dom);
You have htmlparser2 package that can parse HTML stream. You can get the DOM with DomHandler which is bundled with htmlparser2 itself. See the example given there. E.g.
var htmlparser = require("htmlparser2");
var rawHtml = "<html>your html string</html>";
var handler = new htmlparser.DomHandler(function (error, dom) {
console.log(dom);
});
var parser = new htmlparser.Parser(handler);
parser.write(rawHtml);
parser.done();
Parsing DOM object manually is tedious job.
I think that everyone needs a Soup Select(soupselect package) to parse complex DOM objects.
A soupselect is great package in handling DOM.
See following example:
var htmlparser = require("htmlparser2");
var select = require('soupselect').select;
var handler = new htmlparser.DomHandler(function (error, dom) {
if (error)
console.log('error:', error);
else {
// selector reference:
// http://www.w3schools.com/jquery/jquery_ref_selectors.asp
var sel = select(dom, 'body p');
console.log("text in the first <p>: '" + sel[0].children[0].data + "'");
}
});
var parser = new htmlparser.Parser(handler);
var rawHtml =
"<html>"
+ "<head><title>My Title</title></head>"
+ "<body>"
+ "<p>"
+ " Hello World"
+ "</p></body></html>";
parser.parseComplete(rawHtml);
output:
text in the first <p>: ' Hello World'
parseDOM function is now deprecated in htmlparser2 package. You can use parseDocument function now.
const { parseDocument } = require("htmlparser2");
let dom = parseDocument(row_html);
console.log('DOM: ', dom);