Birt with restful APIs - javascript

I am developing BIRT reports for a PHP project. I can easily develop reports by connecting directly to the database using JDBC Datasource. However certain data come from restful api and I am unable to create a datasource from those api endpoints.
Birt has option to create datasource from web services, however this seems to only accept SOAP APIs. I was wondering if someone can show me how to create birt datasources from REST APIs. I read through all the search results provided by google. Some recommend using POJO Datasource, while some recommend using scripted Datasource which requires knowledge in Java and which is little difficult for a PHP programmer to crack through. Most links redirect to devshare which now points to open text and the content doesnot exist anymore. I tried all the recommendations which are as follows.
Using Webservices Datasource: It requires the location of wsdl file which is not there for a REST API. It comes only with SOAP API. Would be great if there is an alternative to this.
Tried POJO Datasource and Scripted Datasource: But as a PHP developer couldn't get a good result as there is no step by step guide out there to do this.
Because REST is pretty popular today, I was wondering if there is any straight forward way to do this, or if there is anyone who can help with Java or Javascript program for scripted datasource for a PHP head. I have been trying this for the last 15 days and is desperate for some help.

Ended up with scripted datasource.
Create a scripted datasource with open() method as follows:
logger = java.util.logging.Logger.getLogger("birt.report.logger");
importPackage(Packages.java.io);
importPackage(Packages.java.net);
//if you have a parameter
var param= params["industryname"].value;
var inStream = new
URL("http://yourapi/endpoint/" + param).openStream();
var inStreamReader = new InputStreamReader(inStream);
var bufferedReader = new BufferedReader(inStreamReader);
var line;
var result = "";
while ((line = bufferedReader.readLine()) != null)
result += line;
inStream.close();
var json = JSON.parse(result);
vars["HTMLJSON"] = json;
logger.warning (result);
//logger.warning (json);
Then create a dataset with the following methods:
open()
recNum=0;
fetch()
len = vars["HTMLJSON"].length;
if (recNum >= len)
return false;
row["name"] = vars["HTMLJSON"][recNum].name;
row["id"] = vars["HTMLJSON"][recNum].id;
row["active"] = vars["HTMLJSON"][recNum].active;
recNum++;
return true;
You may need Apache Commons IO included in your scriptlib folder.

Related

Parsing a stringified JSON coming from a Google Sheet Web App

I'm trying to parse a stringified JSON output from a web app created from a google sheets script. I thought it couldn't be that complicated, but I've tried everything I could think of or find out online... so now asking for help if that's OK!
on the web app / Google Sheets side, the code is:
function doGet(e) {
var spreadsheet = SpreadsheetApp.openById('spreadsheetID');
var worksheet = spreadsheet.getSheetByName('Rankings C/U');
var output = JSON.stringify({ data: worksheet.getDataRange().getValues() });
return HtmlService.createHtmlOutput(output);
}
I've published the script, the web app works, I'm OK with that bit.
I've put random values on the spreadsheet: [[1,2],[3,4]] if we speak in matrix format.
on the other end, I've tried a bunch of stuff including .fetch, JSON.parse() to get the data in a usable format within the Google Sites embedded code, but the real issue is that I think I can't get to allocate the payload to a variable?
I'm using Google Sites to fetch the data.
with the basic module "<> embed", with the "by URL" option, with the following code:
https://script.google.com/macros/s/scriptID/exec
I get the following output - that looks what it should be:
{"data":[[1,2],[3,4]]}
but when trying to include this in a script module ("embed code") - no chance!
<form name="get-images">
<input name="test" id="test" value="we'll put the contents of cell A1 here">
</form>
<script>
const form = document.forms['get-images']
var usableVariable = JSON.parse("https://script.google.com/macros/s/scriptID/exec"); // here I'm trying to allocate the stringified JSON to a variable
form.elements['test'].value = usableVariable[1,1]; //allocating the first element of the parsed array
</script>
I'm pretty sure I'm missing something obvious - but now I ran out of ideas!
Thanks for any help :)
I believe your goal as follows.
In your situation, the bottom script is embedded to the Google site.
You want to retrieve the values from doGet and want to put the value of cell "B2" to the input tag.
The settings of Web Apps is Execute the app as: Me and Who has access to the app: Anyone, even Anonymous.
Modification points:
In your case, I think that return ContentService.createTextOutput(output); is suitable instead of return HtmlService.createHtmlOutput(output); in Google Apps Script.
In order to retrieve the values from doGet, in this modification, fetch is used.
You want to retrieve the cell "B2" from usableVariable[1,1];, please modify it to usableVariable[1][1];
When above points are reflected to your script, it becomes as follows.
Modified script:
Google Apps Script side:
function doGet(e) {
var spreadsheet = SpreadsheetApp.openById('spreadsheetID');
var worksheet = spreadsheet.getSheetByName('Rankings C/U');
var output = JSON.stringify({ data: worksheet.getDataRange().getValues() });
return ContentService.createTextOutput(output);
}
HTML & Javascript side:
<form name="get-images">
<input name="test" id="test" value="we'll put the contents of cell A1 here">
</form>
<script>
let url = "https://script.google.com/macros/s/###/exec";
fetch(url)
.then((res) => res.json())
.then((res) => {
const usableVariable = res.data;
const form = document.forms['get-images'];
form.elements['test'].value = usableVariable[1][1]; // usableVariable[1][1] is the cell "B2".
});
</script>
Note:
When you modified the Google Apps Script of Web Apps, please redeploy the Web Apps as new version. By this, the latest script is reflected to the Web Apps. Please be careful this.
In my environment, I could confirm that above HTML & Javascript worked in the Google site by embedding.
References:
Class ContentService
Using Fetch
Web Apps

Alfresco - How to create a Share web script that uses a Repository web script?

I'm trying to make a webscript on Alfresco Share (and potentially a dashlet) that uses/calls a webscript on the Repository tier.
I know I need a description XML file, a javascript and a result page being HTML or JSON. My question is what should be in those files?
This what I have compiled from various sources in the interwebs ;)
Desc:
<webscript>
<shortname>Some name</shortname>
<description>Some description</description>
<family>dashlet</family>
<url>/components/dashlets/upload/fileupload</url>
</webscript>
Javascript:
var connector = remote.connect("alfresco");
var data = connector.get("/upload/fileupload");//URL of Repository webscript
// create json object from data
var result = eval('(' + data + ')');//This will parse json data
model.resultaat = result["resultaat"];//For adding data to model.
HTML.ftl result:
<#if resultaat??>
${resultaat}
<#else>
Oh no, the folder name is empty!
</#if>
What I'm actually trying to do is call a Repo webscript that generates and put a report in the Repository. This works (see How to add a document to the Alfresco Repository with Java code?), but I want to call this from Share. So any suggestions?
EDIT: Updated the files.
Below is the code which you need to put in Share JS controller(webscript.get.js) for connecting to Repository webscript.
var connector = remote.connect("alfresco");
var data = connector.get("/sample/docprop.json");//URL of Repository webscript
// create json object from data
var result = eval('(' + data + ')');//This will parse json data
model.docprop = result["docprop"];//For adding data to model.

Export JSON data to Excel sheet using ASP.Net MVC Web Api

I have a Single Page App (SPA) built using Durandal, ASP.net MVC Web API, Breeze and knockout js.
I need to export a list to an Excel sheet that should be downloaded to the download folder on click of a button on the html page.
While I have successfully done that by converting the JSON data to csv format in javascript(on client side), it is taking too much time if the amount of data is large(3000 + rows or it can be around 12000).
I am having problem in sending the excel file as response type from the Web API call made through Breeze.js.
Is there a way to do this in a way which should be a bit fast as it might also be required on mobile devices?
EDIT
Below is the code I have written -
JavaScript code for binding -
function exportListToExcel() {
DataContext.exportListToExcel().then(function (data) {
//Do some stuff.
});
}
In the Data context file implemented in breeze, the code is returning the promise -
function exportListToExcel() {
function querySucceeded() {
//return data;
}
return util.sendRequest(config.baseApiPath + 'breeze/MyController/ExportListToExcel')
.then(querySucceeded)
.fail(queryFailed);
}
Below code is the request sent to the Web API. I don't know if it should be HttpPost or something else.
[HttpPost]
public HttpResponseMessage ExportListToExcel()
{
return ExportListToExcel();
}
And below is the back end code -
public static HttpResponseMessage ExportListToExcel()
{
//Method which returns table data. This is working fine though.
object listObject = GetListData();
Table listData = (Table)listObject;
string attachment = "attachment; filename=Report.xlsx";
HttpResponseMessage File = new HttpResponseMessage(HttpStatusCode.OK);
System.Web.HttpContext.Current.Response.ClearContent();
System.Web.HttpContext.Current.Response.AddHeader("content-disposition", attachment);
System.Web.HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
StringBuilder str = new StringBuilder();
str.Append("<table border=`" + "1px" + "`b>");
str.Append("<tr>");
foreach (DataColumn dc in listData.Columns)
{
str.Append("<td><b><font face=Arial Narrow size=3>" + dc.ColumnName + "</font></b></td>");
}
str.Append("</tr>");
foreach (DataRow dr in listData.Rows)
{
str.Append("<tr>");
for (int i = 0; i < listData.Columns.Count; i++)
{
str.Append("<td><font face=Arial Narrow size=" + "14px" + ">" + dr[i].ToString() + "</font></td>");
}
str.Append("</tr>");
}
str.Append("</table>");
byte[] temp = System.Text.Encoding.UTF8.GetBytes(str.ToString());
//To write the table to the File content.
File.Content = new StringContent(temp.ToString());
return File;
}
This however is not working and in the data context file, queryFailed() method is executed.
I don't know where I am going wrong or what I am missing out here. Also, it would be much help to let me know how to handle the file/data which the promise returns.
My instinct is that BreezeJS is the wrong tool for this particular job ... and I say that as a co-author of BreezeJS.
The trouble begins with the paradigm. I'm having trouble thinking of spreadsheet rows as "entities" in the usual sense of business objects. They seem more like simple data to me.
In this example, we're very far from entity-thinking. You appear to be preparing a big chunk of HTML for display on the client. There is nothing "entity-like" about this.
I have no quarrel with your intent. But I think you should treat this as you would any other raw resource (e.g., images) and fetch it with simple AJAX using whatever component is available to you.
You may be building a hybrid app in which you have both raw data (or HTML) and an entity model. Breeze is a fine tool for the app as long as you apply it appropriately. Your Breeze app is already delegating to a low level AJAX component (e.g., jQuery.ajax or Angular's $http) and you should be able to find that component in your code base and use it directly for this particular csv task.

How go I get csv data into netsuite?

I've got an update to my question.
What I really wanted to know was this:
How do I get csv data into netsuite?
Well, it seems I use the csv import tool to create a mapping and use this call to import the csv nlapiSubmitCSVImport(nlobjCSVImport).
Now my question is: How do I iterate through the object?!
That gets me half way - I get the csv data but I can't seem to find out how I iterate through it in order to manipulate the date. This is, of course, the whole point of a scheduled script.
This is really driving me mad.
#Robert H
I can think of a million reasons why you'd want to import data from a CSV. Billing, for instance. Various reports on data any company keeps and I wouldn't want to keep this in the file cabinet nor would I really want to keep the file at all. I just want the data. I want to manipulate it and I want to enter it.
Solution Steps:
To upload a CSV file we have to use a Suitelet script.
(Note: file - This field type is available only for Suitelets and will appear on the main tab of the Suitelet page. Setting the field type to file adds a file upload widget to the page.)
var fileField = form.addField('custpage_file', 'file', 'Select CSV File');
var id = nlapiSubmitFile(file);
Let's prepare to call a Restlet script and pass the file id to it.
var recordObj = new Object();
recordObj.fileId = fileId;
// Format input for Restlets for the JSON content type
var recordText = JSON.stringify(recordObj);//stringifying JSON
// Setting up the URL of the Restlet
var url = 'https://rest.na1.netsuite.com/app/site/hosting/restlet.nl?script=108&deploy=1';
// Setting up the headers for passing the credentials
var headers = new Array();
headers['Content-Type'] = 'application/json';
headers['Authorization'] = 'NLAuth nlauth_email=amit.kumar2#mindfiresolutions.com, nlauth_signature=*password*, nlauth_account=TSTDRV****, nlauth_role=3';
(Note: nlapiCreateCSVImport: This API is only supported for bundle installation scripts, scheduled scripts, and RESTlets)
Let's call the Restlet using nlapiRequestURL:
// Calling Restlet
var output = nlapiRequestURL(url, recordText, headers, null, "POST");
Create a mapping using Import CSV records available at Setup > Import/Export > Import CSV records.
Inside the Restlet script Fetch the file id from the Restlet parameter. Use nlapiCreateCSVImport() API and set its mapping with mapping id created in step 3. Set the CSV file using the setPrimaryFile() function.
var primaryFile = nlapiLoadFile(datain.fileId);
var job = nlapiCreateCSVImport();
job.setMapping(mappingFileId); // Set the mapping
// Set File
job.setPrimaryFile(primaryFile.getValue()); // Fetches the content of the file and sets it.
Submit using nlapiSubmitCSVImport().
nlapiSubmitCSVImport(job); // We are done
There is another way we can get around this although neither preferable nor would I suggest. (As it consumes a lot of API's if you have a large number of records in your CSV file.)
Let's say that we don't want to use the nlapiCreateCSVImport API, so let's continue from the step 4.
Just fetch the file Id as we did earlier, load the file, and get its contents.
var fileContent = primaryFile.getValue();
Split the lines of the file, then subsequently split the words and store the values into separate arrays.
var splitLine = fileContent.split("\n"); // Splitting the file on the basis of lines.
for (var lines = 1,count=0; lines < splitLine.length; lines++)
{
var words = (splitLine[lines]).split(","); // words stores all the words on a line
for (var word = 0; word < words.length; word++)
{
nlapiLogExecution("DEBUG", "Words:",words[word]);
}
}
Note: Make sure you don't have an additional blank line in your CSV file.
Finally create the record and set field values from the array that we created above.
var myRec = nlapiCreateRecord('cashsale'); // Here you create the record of your choice
myRec.setFieldValue('entity', arrCustomerId[i]); // For example, arrCustomerId is an array of customer ID.
var submitRec = nlapiSubmitRecord(myRec); // and we are done
fellow NetSuite user here, I've been using SuiteScripts for a while now but never saw nlobjCSVImport object nor nlapiSubmitCSVImport .. I looked in the documentation, it shows, but there is no page describing the details, care to share where you got the doc from?
With the doc for the CSVImport object I might be able to provide some more help.
P.S. I tried posting this message as a comment but the "Add comment" link didn't show up for some reason. Still new to SOF
CSV to JSON:
convert csv file to json object datatable
https://code.google.com/p/jquery-csv/
If you know the structure of the CSV file, just do a for loop and map the fields to the corresponding nlapiSetValue.
Should be pretty straightforward.

Parameter retrieval for HTTP PUT requests under IIS5.1 and ASP-classic?

I'm trying to implement a REST interface under IIS5.1/ASP-classic (XP-Pro development box). So far, I cannot find the incantation required to retrieve request content variables under the PUT HTTP method.
With a request like:
PUT http://localhost/rest/default.asp?/record/1336
Department=Sales&Name=Jonathan%20Doe%203548
how do I read Department and Name values into my ASP code?
Request.Form appears to only support POST requests. Request.ServerVariables only gets me to header information. Request.QueryString doesn't get me to the content either...
Based on the replies from AnthonyWJones and ars I went down the BinaryRead path and came up with the first attempt below:
var byteCount = Request.TotalBytes;
var binContent = Request.BinaryRead(byteCount);
var myBinary = '';
var rst = Server.CreateObject('ADODB.Recordset');
rst.Fields.Append('myBinary', 201, byteCount);
rst.Open();
rst.AddNew();
rst('myBinary').AppendChunk(binContent);
rst.update();
var binaryString = rst('myBinary');
var contentString = binaryString.Value;
var parameters = {};
var pairs = HtmlDecode(contentString).split(/&/);
for(var pair in pairs) {
var param = pairs[pair].split(/=/);
parameters[param[0]] = decodeURI(param[1]);
}
This blog post by David Wang, and an HtmlDecode() function taken from Andy Oakley at blogs.msdn.com, also helped a lot.
Doing this splitting and escaping by hand, I'm sure there are a 1001 bugs in here but at least I'm moving again. Thanks.
Unfortunately ASP predates the REST concept by quite some years.
If you are going RESTFull then I would consider not using url encoded form data. Use XML instead. You will be able to accept an XML entity body with:-
Dim xml : Set xml = CreateObject("MSXML2.DOMDocument.3.0")
xml.async = false
xml.Load Request
Otherwise you will need to use BinaryRead on the Request object and then laboriously convert the byte array to text then parse the url encoding yourself along with decoding the escape sequences.
Try using the BinaryRead method in the Request object:
http://www.w3schools.com/ASP/met_binaryread.asp
Other options are to write an ASP server component or ISAPI filter:
http://www.codeproject.com/KB/asp/cookie.aspx

Categories

Resources