Improving performance of WURFL code - wurfl

I tested the following code which prints the properties of the UserAgent. However I notice that it takes noticeable time to execute the code.
// Initialize the WURFL library.
String projRoot = System.getProperty("user.dir");
wurflFile = projRoot + File.separator + "wurfl-2.3.3" + File.separator + "wurfl.xml";
File dataFile = new File(wurflFile);
wurfl = new CustomWURFLHolder(dataFile);
String deviceUrl = "Apple-iPhone5C1";
WURFLManager manager = wurfl.getWURFLManager();
Device device = manager.getDeviceForRequest(deviceUrl);
System.out.println("Device: " + device.getId());
System.out.println("Capability: " + device.getCapability("preferred_markup"));
System.out.println("Device UA: " + device.getUserAgent());
Map capabilities = device.getCapabilities();
System.out.println("Size of the map: " + capabilities.keySet().size());
Iterator itr = capabilities.keySet().iterator();
while (itr.hasNext()) {
String str = (String) itr.next();
System.out.println(str);
}
One of the reason is that it takes time to load and parse the WURFL XML database file (which is about 20MB size).
I want to know if there is any different WURFL API, which will improve this performance? Eventually, I would be putting this code in a HTTP Proxy where I want to check the device profile parameter for adaptation of the content.
Thanks.

Related

How do I add precautions to get around Microsoft.ACE.OLEDB.12.0 not registered?

When I use the following code on my home computer it works fine for me. However, I have to use it on multiple different machines.
"Provider = Microsoft.ACE.OLEDB.12.0;"
I was thinking that there could be a get around to this because I need it in a more universal format so that it works on multiple machines.
I have hoped that there could be a work around, maybe by including an alternative provider in the code (if that is possible) or an catch or if statement that will rerun the code but with an alternate provider if it cannot find the first one.
It would be changed to Microsoft.Jet.OLEDB.4.0
If anyone could scratch up a little bit of code to work around this so that my program could take into account both providers that would be great as it would make my projects more universal.
Background code (ignore unsafe SQL unless you want to fix it):
OleDbDataReader^ openData(String^ fieldEntity, String^ field, String^ tableName)
{
String^ sqlstr = "SELECT * FROM ";
sqlstr += tableName + " WHERE " + field + " = " + fieldEntity;
OleDbConnection^ conn = nullptr;
conn = gcnew OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0;" +
"Data Source =" + "myDatabaseV3.accdb");
OleDbCommand^ cmd = nullptr;
//fix this so that it will consider both providers.
conn->Open();
cmd = gcnew OleDbCommand(sqlstr, conn);
OleDbDataReader^ reader = cmd->ExecuteReader(System::Data::CommandBehavior::CloseConnection);
return reader;
}
I have solved this problem myself. I realised that I could you another try catch statement in my class to change the connection string if there is an exception
conn = gcnew OleDbConnection("Provider = Microsoft.Jet.OLEDB.4.0;" +
"Data Source =" + "myDatabaseV3.mdb");
pause();
OleDbCommand^ cmd = nullptr;
//fix this so that it will come out of the current directiory
try {
conn->Open();
}
catch (Exception^ ex)
{
conn->ConnectionString = "Provider = Microsoft.ACE.OLEDB.12.0;" +
"Data Source =" + "myDatabaseV3.accdb";
conn->Open();
}
You could switch these around if you wanted the order of these doesn't really matter. Furthermore, if this solution is invalid you could have a nested try catch statement. However, my code in particular has this In a class and the way this is ran anyway is in a try catch in another part of the code so it is unnecessary for me.

Titanium Alloy Caching in Android/iOS? Or Preserving old views

Can we Cache Dynamically Created Lists or View till the webservices are called in background. I want to achieve something like the FaceBook App does. I know its possible in Android Core but wanted to try it in Titanium (Android and IOS).
I would further explain it,
Consider I have a app which has a list. Now When I open for first time, it will obviously hit the webservice and create a dynamic list.
Now I close the app and again open the app. The old list should be visible till the webservice provides any data.
Yes Titanium can do this. You should use a global variable like Ti.App.myList if it is just an array / a list / a variable. If you need to store more complex data like images or databases you should use the built-in file system. There is a really good Documentation on the Appcelerator website.
The procedure for you would be as follows:
Load your data for the first time
Store your data in your preferred way (Global variable, file system)
During future app starts read out your local list / data and display it until your sync is successfull.
You should consider to implement some variable to check wether any update is needed to minimize the network use (it saves energy and provides a better user experience if the users internet connection is slow).
if (response.state == "SUCCESS") {
Ti.API.info("Themes successfully checked");
Ti.API.info("RESPONSE TEST: " + response.value);
//Create a map of the layout names(as keys) and the corresponding url (as value).
var newImageMap = {};
for (var key in response.value) {
var url = response.value[key];
var filename = key + ".jpg"; //EDIT your type of the image
newImageMap[filename] = url;
}
if (Ti.App.ImageMap.length > 0) {
//Check for removed layouts
for (var image in Ti.App.imageMap) {
if (image in newImageMap) {
Ti.API.info("The image " + image + " is already in the local map");
//Do nothing
} else {
//Delete the removed layout
Ti.API.info("The image " + image + " is deleted from the local map");
delete Ti.App.imageMap[image];
}
}
//Check for new images
for (var image in newImageMap) {
if (image in Ti.App.imageMap) {
Ti.API.info("The image " + image + " is already in the local map");
//Do nothing
} else {
Ti.API.info("The image " + image + " is put into the local map");
//Put new image in local map
Ti.App.imageMap[image] = newImageMap[image];
}
}
} else {
Ti.App.imageMap = newImageMap;
}
//Check wether the file already exists
for (var key in response.value) {
var url = response.value[key];
var filename = key + ".png"; //EDIT YOUR FILE TYPE
Ti.API.info("URL: " + url);
Ti.API.info("FILENAME: " + filename);
imagesOrder[imagesOrder.length] = filename.match(/\d+/)[0]; //THIS SAVES THE FIRST NUMBER IN YOUR FILENAME AS ID
//Case1: download a new image
var file = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, "/media/" + filename);
if (file.exists()) {
// Do nothing
Titanium.API.info("File " + filename + " exists");
} else {
// Create the HTTP client to download the asset.
var xhr = Ti.Network.createHTTPClient();
xhr.onload = function() {
if (xhr.status == 200) {
// On successful load, take that image file we tried to grab before and
// save the remote image data to it.
Titanium.API.info("Successfully loaded");
file.write(xhr.responseData);
Titanium.API.info(file);
Titanium.API.info(file.getName());
};
};
// Issuing a GET request to the remote URL
xhr.open('GET', url);
// Finally, sending the request out.
xhr.send();
}
}
In addition to this code which should be placed in a success method of an API call, you need a global variable Ti.App.imageMap to store the map of keys and the corresponding urls. I guess you have to change the code a bit to fit your needs and your project but it should give you a good starting point.

GATE Embedded runtime

I want to use "GATE" through web. Then I decide to create a SOAP web service in java with help of GATE Embedded.
But for the same document and saved Pipeline, I have a different run-time duration, when GATE Embedded runs as a java web service.
The same code has a constant run-time when it runs as a Java Application project.
In the web service, the run-time will be increasing after each execution until I get a Timeout error.
Does any one have this kind of experience?
This is my Code:
#WebService(serviceName = "GateWS")
public class GateWS {
#WebMethod(operationName = "gateengineapi")
public String gateengineapi(#WebParam(name = "PipelineNumber") String PipelineNumber, #WebParam(name = "Documents") String Docs) throws Exception {
try {
System.setProperty("gate.home", "C:\\GATE\\");
System.setProperty("shell.path", "C:\\cygwin2\\bin\\sh.exe");
Gate.init();
File GateHome = Gate.getGateHome();
File FrenchGapp = new File(GateHome, PipelineNumber);
CorpusController FrenchController;
FrenchController = (CorpusController) PersistenceManager.loadObjectFromFile(FrenchGapp);
Corpus corpus = Factory.newCorpus("BatchProcessApp Corpus");
FrenchController.setCorpus(corpus);
File docFile = new File(GateHome, Docs);
Document doc = Factory.newDocument(docFile.toURL(), "utf-8");
corpus.add(doc);
FrenchController.execute();
String docXMLString = null;
docXMLString = doc.toXml();
String outputFileName = doc.getName() + ".out.xml";
File outputFile = new File(docFile.getParentFile(), outputFileName);
FileOutputStream fos = new FileOutputStream(outputFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
OutputStreamWriter out;
out = new OutputStreamWriter(bos, "utf-8");
out.write(docXMLString);
out.close();
gate.Factory.deleteResource(doc);
return outputFileName;
} catch (Exception ex) {
return "ERROR: -> " + ex.getMessage();
}
}
}
I really appreciate any help you can provide.
The problem is that you're loading a new instance of the pipeline for every request, but then not freeing it again at the end of the request. GATE maintains a list internally of every PR/LR/controller that is loaded, so anything you load with Factory.createResource or PersistenceManager.loadObjectFrom... must be freed using Factory.deleteResource once it is no longer needed, typically using a try-finally:
FrenchController = (CorpusController) PersistenceManager.loadObjectFromFile(FrenchGapp);
try {
// ...
} finally {
Factory.deleteResource(FrenchController);
}
But...
Rather than loading a new instance of the pipeline every time, I would strongly recommend you explore a more efficient approach to load a smaller number of instances of the pipeline but keep them in memory to serve multiple requests. There is a fully worked-through example of this technique in the training materials on the GATE wiki, in particular module number 8 (track 2 Thursday).

ColdFusion - Reading in lots of images

What is the most efficient way of reading in lots of images in CF / Railo and checking their width and height?
In my app, I need to typically read in about 20 images + and at the moment this takes up to 14 seconds to complete. A bit too long really.
theImageRead = ImageNew(theImageSrc);
if ( imageGetWidth(theImageRead) > 100 ) {
writeOutput('<img src="' & theImageSrc & '" />');
}
Images are read from a list of absolute URL's. I need to get images specified over a certain dimension.
If there's a quicker solution to this then I'd love to get your insight. Perhaps underlying java methods?
I am also using jSoup if there's anything in that which could help.
Thanks,
Michael.
I don't believe there's any way to determine the pixel dimensions of an image without reading the bytes and creating an image object. The main bottleneck here will be the http request overhead.
that said there are a few ways to speed up what you're trying to do.
use threads to concurrently request images, then when all threads have finished processing output the images.
If you display the same image or set of images more than once cache it. If you don't want to cache the actually image you can cache the metadata to avoid having to perform a http request for every image.
decide if you need to output all the images to the page immediately, or could some or all of these be deferred and loaded via and ajax request
I have written this utility function quite a while ago (it runs on older ColdFusion versions, too). Maybe it helps.
Note that this requires the Java Advanced Imaging Image I/O Tools (Jai-imageio). Download the .jar and put it in your class path (restarting CF is necessary).
/**
* Reads basic properties of many types of images. Values are
* returned as a struct consisting of the following elements:
*
* Property names, their types and default values:
* ImgInfo.width = 0 (pixels)
* ImgInfo.height = 0 (pixels)
* ImgInfo.size = 0 (bytes)
* ImgInfo.isGrayscale = false (boolean)
* ImgInfo.isFile = false (boolean)
* ImgInfo.success = false (boolean)
* ImgInfo.error = "" (string)
*
* #param FilePath Physical path to image file.
* #return A struct, as described.
*/
function GetImageProperties(FilePath) {
var ImgInfo = StructNew();
var jImageIO = CreateObject("java", "javax.imageio.ImageIO");
var jFile = CreateObject("java", "java.io.File").init(FilePath);
var jBufferedImage = 0;
var jColorSpace = 0;
ImgInfo.width = "";
ImgInfo.height = "";
ImgInfo.fileSize = 0;
ImgInfo.isGrayscale = false;
ImgInfo.isFile = jFile.isFile();
ImgInfo.success = false;
ImgInfo.error = "";
try {
jBufferedImage = jImageIO.read(jFile);
ImgInfo.fileSize = jFile.length();
ImgInfo.width = jBufferedImage.getWidth();
ImgInfo.height = jBufferedImage.getHeight();
jColorSpace = jBufferedImage.getColorModel().getColorSpace();
ImgInfo.isGrayscale = (jColorSpace.getType() eq jColorSpace.TYPE_GRAY);
ImgInfo.success = true;
}
catch (any ex) {
ImgInfo.error = ToString(ex);
}
jImageIO = JavaCast("null", "");
jFile = JavaCast("null", "");
jBufferedImage = JavaCast("null", "");
jColorSpace = JavaCast("null", "");
return ImgInfo;
}
Use like:
imageInfo = GetImageProperties(theImageSrc);
if (imageInfo.success and imageInfo.width > 100)
writeOutput('<img src="#HTMLEditFormat(theImageSrc)#" />');
}

WMI performance query

I am having an issue with a WMI query.
I use a WMI query to search and resume an instance in BizTalk.
When there are not that many instances (so when the data isn't that much) the query performs pretty good.
But when the data is large (about 3000 instances) the query takes about 6 - 10 seconds to execute, and this isn't tolerable.
Code is as following:
string query = "SELECT * FROM MSBTS_ServiceInstance WHERE InstanceID = \"" + OrchestrationId + "\"";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(new ManagementScope(#"root\MicrosoftBizTalkServer"), new WqlObjectQuery(query), null);
int count = searcher.Get().Count;
if (count > 0)
{
string[] strArray = new string[count];
string[] strArray2 = new string[count];
string[] strArray3 = new string[count];
string str2 = string.Empty;
string str3 = string.Empty;
int index = 0;
foreach (ManagementObject obj2 in searcher.Get())
{
if (str2 == string.Empty)
{
str2 = obj2["HostName"].ToString();
}
strArray2[index] = obj2["ServiceClassId"].ToString();
strArray3[index] = obj2["ServiceTypeId"].ToString();
strArray[index] = obj2["InstanceID"].ToString();
str3 = str3 + string.Format(" {0}\n", obj2["InstanceID"].ToString());
index++;
}
new ManagementObject(string.Format("root\\MicrosoftBizTalkServer:MSBTS_HostQueue.HostName=\"{0}\"", str2)).InvokeMethod("ResumeServiceInstancesByID", new object[] { strArray2, strArray3, strArray, 1 });
It's the first query (Select * from MSBS_ServiceInstance..) that takes to long when te data is getting bigger.
Any ideas how I can improve this?
The platform is Windows Server 2008 Enterprise..
Thx!
It looks like you are getting all service instances for your orchestration, not just the suspended ones.
Try adding the following to your query's where clause, so that only suspended and suspended-not-resumable service instances are returned:
and (ServiceStatus = 4 or ServiceStatus = 16)
Thank you for the replies.
The reason I got that many suspended instances sometimes is by design.
Whenever a message isn't in sequence, the orchestration gets suspended until the previous message went through.
I found another way to resume the instances using the BizTalkOperations class that is installed with BizTalk:
BizTalkOperations operations = new BizTalkOperations(dataSource, initialCatalog);
foreach (Guid id in instanceIds)
{
operations.ResumeInstance(id);
}
This code is much more performant then the WMI code (and less code ^^) :)
Thanks