Blackberry: Command line build and application auto-start - blackberry

I have an application which is built from command line (ANT) using J2ME Polish. As such, this application is defined through a build.xml, not from Blackberry JDE project files.
What I need to do is have this application auto-start. This is easy enough to do once the application has been run for the first time (example). However, this does require the application to be manually run by the user (which I want to avoid).
The JDE provides options which you can check to enable auto-start, and from ANT:
<cldc runonstartup=="true"...
Will do the trick. The question is, how do I integrate this into a Polish buiild (i.e. into a Polish build.xml which is also building for other platforms)?
Anyone know what the auto-start option in the JDE actually does / what it changes?

So, the way to do this is, unfortunately, to change the J2ME-Polish source! As outlined in this bug report the J2ME Polish build framework (at version 2.1.4) doesn't pass on the RIM-MIDlet-Flags-x JAD attribute to RAPC.
The changes are relatively simple - merely passing on the RIM-MIDlet-Flags-1 value if defined in the JAD, otherwise setting it to zero (as the original 2.1.4 source does).
The diff (from 2.1.4) source:
Index: /enough-polish-build/source/extensions/de/enough/polish/blackberry/JarToCodFinalizer.java
===================================================================
--- /enough-polish-build/source/extensions/de/enough/polish/blackberry/JarToCodFinalizer.java (revision 315)
+++ /enough-polish-build/source/extensions/de/enough/polish/blackberry/JarToCodFinalizer.java (revision 316)
## -36,6 +36,7 ##
import java.util.Calendar;
import java.util.Locale;
import java.util.Map;
+import java.util.List;
import java.util.Properties;
import org.apache.tools.ant.BuildException;
## -185,6 +186,13 ##
}
}
File iconFile = null;
+ Map jadProperties;
+ try {
+ jadProperties = FileUtil.readPropertiesFile( jadFile, ':' );
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new BuildException("Unable to read JAD file " + e.toString() );
+ }
if (mainClassName != null) {
try {
/*
## -230,12 +238,26 ##
"MicroEdition-Configuration: CLDC-1.1",
//"MIDlet-1: Demo," + iconUrl + ",",
"MIDlet-1: " + env.getVariable("MIDlet-Name") + "," + iconUrl + ",",
- //"MIDlet-Icon: " + iconUrl,
- "RIM-MIDlet-Flags-1: 0"
+ //"MIDlet-Icon: " + iconUrl
};
+ /* Ensure that if RIM-MIDlet-Flags is defined in the JAD, it is
+ * passed on to RAPC to create the COD file.
+ * See https://developer.berlios.de/bugs/?func=detailbug&group_id=1246&bug_id=16901
+ * for details.
+ */
+ ArrayList newEntriesList = new ArrayList(Arrays.asList(newEntries));
+ final String flagsKey = "RIM-MIDlet-Flags-1";
+ String flagString = (String)jadProperties.get(flagsKey);
+ if (flagString == null) {
+ flagString = "0";
+ }
+ flagString = flagString.trim();
+ System.out.println("JarToCodFinalizer setting " + flagsKey + ": " + flagString);
+ newEntriesList.add(flagsKey+ ": " + flagString);
+
File rapcFile = new File( jadFile.getParent(), codName + ".rapc");
- FileUtil.writeTextFile( rapcFile, newEntries );
+ FileUtil.writeTextFile( rapcFile, newEntriesList );
} catch ( IOException e ) {
// this shouldn't happen
e.printStackTrace();
## -367,7 +389,6 ##
// now rewrite JAD file so that it is ready for OTA download:
// (first backup JAD file:)
//FileUtil.copy(jadFile, new File(jadFile.getParent(), jadFile.getName() + ".bak") );
- Map jadProperties = FileUtil.readPropertiesFile( jadFile, ':' );
Object[] keys = jadProperties.keySet().toArray();
for (int i = 0; i < keys.length; i++) {
String key = (String) keys[i];

Another polish user :)
Take a look at BB forums the 2nd post. Then using what we know about polish and jad attributes
Add this to your jad section of your build.xml
<jad>
<attribute name="RIM-MIDlet-Flags"
value="1"
if="polish.vendor == BlackBerry" />
</jad>
I haven't tested this but the logic seems to be valid :) Let me know if it works or not.

Related

Screenshot is not attached to the extend report when ran in Jenkins only

When using remote-webdriver instance of BrowserStack, only when ran in Jenkins, the failed screenshot is not attached to the report. please help. folder structure is ExtentReport\Screenshots
I tried Extent Report: Not able to see the screenshots on other machine
this but it's not resolve the issue.
public void onTestFailure(ITestResult result) {
testMap.get().fail(result.getThrowable());
//add screenshot for failed test.
WebDriver driver= WebDriverFactory.getDriver();
//experimental to get screenshot
driver = new Augmenter().augment(driver);
String dateName = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
TakesScreenshot ts = (TakesScreenshot) driver;
File source = ts.getScreenshotAs(OutputType.FILE);
String destination = System.getProperty("user.dir") + "/ExtentReport/" + "/Screenshots/" + result.getMethod().getMethodName() + dateName + ".png";
File finalDestination = new File(destination);
try {
FileUtils.copyFile(source, finalDestination);
} catch (IOException e) {
e.printStackTrace();
}
testMap.get().addScreenCaptureFromPath(destination,result.getMethod().getMethodName());
}
Different operating systems use different characters as file and path separators. When our application has to run on multiple platforms, we need to handle these correctly.
To handle this issue Java provide File.separator.
So, instead of
String destination = System.getProperty("user.dir") + "/ExtentReport/" + "/Screenshots/" + result.getMethod().getMethodName() + dateName + ".png";
Try this:
String destination = System.getProperty("user.dir") + File.separator + "ExtentReport" + File.separator +"Screenshots" + File.separator + result.getMethod().getMethodName() + dateName + ".png";
To use it you will have to add this import
import java.io.File;
Based on the answer of ravi creed,
HTML : Unable to view the base64 image in html report
String base64Screenshot ="data:image/png;base64," + ((TakesScreenshot) Objects.requireNonNull(driver)).getScreenshotAs(OutputType.BASE64);
testMap.get().addScreenCaptureFromBase64String(base64Screenshot).getModel().getMedia().get(0);
I managed to solve this using above code.Once click on base64 img, it opens the actual screenshot.

How to create a connected app through API?

We are building a data integration platform to connect to Salesforce.
Would like to know if there is any documentation to create a connected app programmatically using APIs. I see lot of documentation for creating connected apps via UI but not through API.
You can create Connected Apps through the Metadata API, like any other Salesforce metadata.
The easiest way to do this is to build the Connected App in a Salesforce org and then extract it with a Metadata API client (SFDX, Workbench, CumulusCI, Ant...). Excise the Consumer Key from the metadata, and you'll then be able to deploy that Connected App cleanly into another org.
Note, though, that this is rarely necessary. Connected Apps are global metadata: you typically maintain your Connected App in a single org that you control, and it's then available everywhere. I've really only seen the need to deploy Connected Apps when a different one is needed in each subscriber org.
This code creates connected app.
MetadataService.MetadataPort service = createService();
MetadataService.ConnectedApp connectedApp = new MetadataService.ConnectedApp();
connectedApp.label = 'Test 005';
connectedApp.fullName = 'Test_005';
connectedApp.contactEmail = 'email#email.com';
MetadataService.ConnectedAppOauthConfig oauthConfig = new
MetadataService.ConnectedAppOauthConfig();
oauthConfig.consumerKey = 'yourConsumerKey';
oauthConfig.consumerSecret = 'yourConsumerSecret';
oauthConfig.scopes = new List<String>{'Basic', 'Api', 'Web', 'Full'};
oauthConfig.callbackUrl = 'https://www.google.com/';
connectedApp.oauthConfig = oauthConfig;
List<MetadataService.SaveResult> results = service.createMetadata(new
MetadataService.Metadata[] { connectedApp });
If you don't want to use Metadata API library, you could use the following snippet of code
private static String getSoapBodyXml(String endpoint, String name) {
return ''
+ '<?xml version="1.0" encoding="utf-8"?>'
+ '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
+ '<env:Header>'
+ '<urn:SessionHeader xmlns:urn="http://soap.sforce.com/2006/04/metadata">'
+ '<urn:sessionId>' + userInfo.getSessionId() + '</urn:sessionId>'
+ '</urn:SessionHeader>'
+ '</env:Header>'
+ '<env:Body>'
+ '<createMetadata xmlns="http://soap.sforce.com/2006/04/metadata">'
+ '<metadata xsi:type="ConnectedApp">'
+ '<fullName>' + name + String.valueOf(DateTime.now().getTime()).right(4) + '</fullName>'
+ '<label>' + name + String.valueOf(DateTime.now().getTime()).right(4) + '</label>'
+ '<contactEmail>julfy#i.ua</contactEmail>'
+ '<oauthConfig>'+
+ '<callbackUrl>' + endpoint + '</callbackUrl>'
+ '<scopes>Full</scopes>'
+ '<scopes>RefreshToken</scopes>'
+ '</oauthConfig>'
+ '</metadata>'
+ '</createMetadata>'
+ '</env:Body>'
+ '</env:Envelope>'
;
}
public static HttpResponse add(String endpoint, String name) {
HttpRequest req = new HttpRequest();
req.setEndpoint(URL.getOrgDomainUrl().toExternalForm() + '/services/Soap/m/50.0');
req.setMethod('POST');
req.setHeader('Content-Type', 'text/xml');
req.setHeader('SOAPAction', '""');
req.setBody(getSoapBodyXml(endpoint, name));
HttpResponse r = new Http().send(req);
System.debug('add getBody: ' + r.getBody());
System.debug('add getStatus: ' + r.getStatus());
System.debug('add getStatusCode: ' + r.getStatusCode());
val(r);
return r;
}
private static void val(HttpResponse r) {
System.debug('success? ' + r.getBody().contains('<success>true</success>'));
if (!r.getBody().contains('<success>true</success>')) {
throw new UnexpectedException(r.getBody().substringBetween('<statusCode>', '</statusCode>') + ': ' + r.getBody().substringBetween('<message>', '</message>'));
}
}
public static HttpResponse deploy(Integer i) {
return add(
'https://google.com',
'DeployedApp' + i
);
}

File Read-Write Error in iOS

I have used following code for file reading and writing.
private void StorePuzzleData ()
{
FileInfo fileInfo = new FileInfo (Application.persistentDataPath + "\\" + difficultyLevel + puzzleId + ".txt");
if (fileInfo.Exists)
fileInfo.Delete ();
string fileData = string.Empty;
foreach (CellInformation cellInfo in cellInfoList)
fileData += cellInfo.RowIndex + "#" + cellInfo.ColIndex + "#" + cellInfo.number + "#" + cellInfo.CellColor + "#" + cellInfo.CellDisplayColor + "#" + (cellInfo.IsGroupComplete ? 1 : 0) + ",";
StreamWriter streamWriter = fileInfo.CreateText ();
streamWriter.WriteLine (fileData);
streamWriter.Close ();
DataStorage.StorePuzzleTimePassed (difficultyLevel, puzzleId, GameController.gamePlayTime);
}
private void ReadPuzzleData ()
{
// format: rownumber, colnumber, number, cellcolor, celldisplaycolor, isgroupcomplete
StreamReader streamReader = File.OpenText (Application.persistentDataPath + "\\" + difficultyLevel + puzzleId + ".txt");
string fileData = streamReader.ReadLine ();
}
But I am getting following error in actual iOS device running. This code working correct in iMac as well in android device.
Please give me some suggestion what changes I need to do to make this correct.
It seems you're using Windows-style paths in a Unix-like (Apple Mac OS) environment. Notice that on windows you have paths with a backslash like
C:\Users\Maxi\Desktop
On Unix-like system however something like
/var/mobile/Containers
You notice that in your faulty path you have mixed forward and backward slashes, which makes the path invalid.
/var/mobile/Containers/Data/Application/2.....\debutan1.txt
The correct way to always generate the correct path is to use the Path.Combine(string, string) function. This will combine two paths using the correct directory path seperator, which can also be seperatly accessed through Path.DirectorySeparatorChar.
So, in order to make your code correct, you would do
using System.IO; /* must be imported */
private void StorePuzzleData ()
{
FileInfo fileInfo = new FileInfo (Path.Combine(Application.persistentDataPath, difficultyLevel + puzzleId + ".txt"));
if (fileInfo.Exists)
fileInfo.Delete ();
string fileData = string.Empty;
foreach (CellInformation cellInfo in cellInfoList)
fileData += cellInfo.RowIndex + "#" + cellInfo.ColIndex + "#" + cellInfo.number + "#" + cellInfo.CellColor + "#" + cellInfo.CellDisplayColor + "#" + (cellInfo.IsGroupComplete ? 1 : 0) + ",";
StreamWriter streamWriter = fileInfo.CreateText ();
streamWriter.WriteLine (fileData);
streamWriter.Close ();
DataStorage.StorePuzzleTimePassed (difficultyLevel, puzzleId, GameController.gamePlayTime);
}
private void ReadPuzzleData ()
{
// format: rownumber, colnumber, number, cellcolor, celldisplaycolor, isgroupcomplete
StreamReader streamReader = File.OpenText (Path.Combine(Application.persistentDataPath, difficultyLevel + puzzleId + ".txt"));
string fileData = streamReader.ReadLine ();
}
If this still gives an "Access denied" error it must be because of filepermissions. Post the output of ls -la <thatpath> then.

How to oAuth weather yahoo api

I use this code to access weather data from yahoo and everything just work fine.
Somehow this stops working getting a "Bad request" from yahoo...
"Please provide valid credentials. OAuth oauth_problem="OST_OAUTH_PARAMETER_ABSENT_ERROR", realm="yahooapis.com"
"
I try to understood what happed and i think that has to do with the oAuth from yahoo but i don't know how to use it and the documentation from yahoo sucks...
code below..
mForcastTown.Add(MainForm.ExtraFE_IdHttp.Get('http://weather.yahooapis.com/forecastrss?w='+ mAdd_Town[mTonwNum].mWoeID +'&u='+ mAdd_Town[mTonwNum].mDegree);
Thank you...
UPDATE...
I found this below and when run in the browser i get the xml i need but when i run it to the
IdHttp.get('http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid=55903793%20and%20u=%27c%27&format=xml')
i get unknown version found...
What is this...
Thank you...
I had the same problem for Java, maybe this will direct you to something.
In this link there is a sample java code:
// Copyright 2019 Oath Inc. Licensed under the terms of the zLib license see https://opensource.org/licenses/Zlib for terms.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
import java.util.Base64;
import java.util.Base64.Encoder;
import java.util.Random;
import java.util.Collections;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.net.URI;
/**
*
* <pre>
* % java --version
* % java 11.0.1 2018-10-16 LTS
*
* % javac WeatherYdnJava.java && java -ea WeatherYdnJava
* </pre>
*
*/
public class WeatherYdnJava {
public static void main(String[] args) throws Exception {
final String appId = "test-app-id";
final String consumerKey = "your-consumer-key";
final String consumerSecret = "your-consumer-secret";
final String url = "https://weather-ydn-yql.media.yahoo.com/forecastrss";
long timestamp = new Date().getTime() / 1000;
byte[] nonce = new byte[32];
Random rand = new Random();
rand.nextBytes(nonce);
String oauthNonce = new String(nonce).replaceAll("\\W", "");
List<String> parameters = new ArrayList<>();
parameters.add("oauth_consumer_key=" + consumerKey);
parameters.add("oauth_nonce=" + oauthNonce);
parameters.add("oauth_signature_method=HMAC-SHA1");
parameters.add("oauth_timestamp=" + timestamp);
parameters.add("oauth_version=1.0");
// Make sure value is encoded
parameters.add("location=" + URLEncoder.encode("sunnyvale,ca", "UTF-8"));
parameters.add("format=json");
Collections.sort(parameters);
StringBuffer parametersList = new StringBuffer();
for (int i = 0; i < parameters.size(); i++) {
parametersList.append(((i > 0) ? "&" : "") + parameters.get(i));
}
String signatureString = "GET&" +
URLEncoder.encode(url, "UTF-8") + "&" +
URLEncoder.encode(parametersList.toString(), "UTF-8");
String signature = null;
try {
SecretKeySpec signingKey = new SecretKeySpec((consumerSecret + "&").getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
byte[] rawHMAC = mac.doFinal(signatureString.getBytes());
Encoder encoder = Base64.getEncoder();
signature = encoder.encodeToString(rawHMAC);
} catch (Exception e) {
System.err.println("Unable to append signature");
System.exit(0);
}
String authorizationLine = "OAuth " +
"oauth_consumer_key=\"" + consumerKey + "\", " +
"oauth_nonce=\"" + oauthNonce + "\", " +
"oauth_timestamp=\"" + timestamp + "\", " +
"oauth_signature_method=\"HMAC-SHA1\", " +
"oauth_signature=\"" + signature + "\", " +
"oauth_version=\"1.0\"";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url + "?location=sunnyvale,ca&format=json"))
.header("Authorization", authorizationLine)
.header("X-Yahoo-App-Id", appId)
.header("Content-Type", "application/json")
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.body());
}
}
The problem with this code is where the oauthNonce generated with random bytes. Here, the error is caused by the unrecognized chars. Because for any random byte there can be any char that your system doesn't recognize and can't process because it converts it into a string.
I replace the whole part with this:
String oauthNonce = RandomStringUtils.random(10, true, true);
It worked like a charm. I currently don't have any errors now and able to get the response. I hope this helps.

externalize properties in grails

I am trying to just externalize some custom properties in grails.
I cannot find a clear way on how to externalize some string properties and use them in my code.
Can any one please help me out.
You have to specify the location of the external configuration file in the config.groovy.
For example like this:
if (!grails.config.locations || !(grails.config.locations instanceof List)) {
grails.config.locations = []
}
// Internal Jetty: config-files are locates inside the /web-app/WEB-INF directory
if( GrailsUtil.isDevelopmentEnv() ) {
def dir = System.properties["base.dir"]
def f1 = "${dir}" + File.separator + "web-app" + File.separator + "WEB-INF" + File.separator + "${appName}-config.groovy"
grails.config.locations << "file:${f1}"
}
// TIER Tomcat: config-files are locates inside Tomcat's conf-directory
else if( System.properties["catalina.home"] ) {
def dir = System.properties["catalina.home"]
def f1 = "${dir}" + File.separator + "conf" + File.separator + "${appName}-config.groovy"
grails.config.locations << "file:${f1}"
}
// JBOSS, Glassfish etc
else {
//
}
// Further choices: command line argument (-D{$appName}.config.location=xxx)
if( System.properties["${appName}.config.location"] ) {
grails.config.locations << "file:" + System.properties["${appName}.config.location"]
}
So on local development the config file is locate under the WEB-INF directory.
While going life you have various choices of where to put your configuration file.
You can adapt, if needed, the code to works for config.properties in the same way.

Resources