Problem with J2ME RecordStore update, delete operation - java-me

I create a List showing data from a RecordStore. I tried to update a record and the re-display the list (re-open the same RecordStore), but the updated item doesn't change (still contain the old data).
I also tried to delete an item and the deleted item is still displayed in the list.
I run the program using emulator from NetBeans 7.0 with Java ME SDK 3.0
This is the code for updating the record
public void updateClient(Client cl) throws Exception{
RecordStore rs=RecordStore.openRecordStore(String.valueOf(clientsStoreKey), true);
int recNum=rs.getNumRecords();
if (recNum>0){
RecordEnumeration renum=rs.enumerateRecords(null, null,false);
while(renum.hasNextElement()){
int id = renum.nextRecordId();
byte[] buff=rs.getRecord(id);
Client temp=Client.createFrom(buff);
if(temp.clientId.compareTo(cl.clientId)==0){
temp.firstName=cl.firstName;
temp.lastName=cl.lastName;
temp.city=cl.city;
temp.state=cl.state;
temp.company=cl.company;
temp.phone=cl.phone;
ByteArrayOutputStream bos=new ByteArrayOutputStream();
DataOutputStream dos=new DataOutputStream(bos);
temp.writeTo(dos);
byte[] sData=bos.toByteArray();
rs.setRecord(id, sData, 0, sData.length);
dos.close();
bos.close();
break;
}
}
renum.destroy();
}
rs.closeRecordStore();
}
And this is the code to get the records
public Vector getClients()
throws Exception{
RecordStore rs=RecordStore.openRecordStore(String.valueOf(clientsStoreKey), true);
int recNum=rs.getNumRecords();
Vector cls=new Vector();
if (recNum>0){
RecordEnumeration renum=rs.enumerateRecords(null, null,false);
while(renum.hasNextElement()){
byte[] buff=renum.nextRecord();
Client cl=Client.createFrom(buff);
cls.addElement(cl);
}
renum.destroy();
}
rs.closeRecordStore();
return cls;
}

interesting - your code dealing with record store looks rather OK to me. Is there a chance for some glitch in UI - like say using old or incorrectly updated screen object?
How do you debug your application? Since you mention emulator, System.out/println looks like a natural choice doesn't it? I'd use it to output content of the record right after setting it in updateClient and after getting it in getClients

Related

dynamic template generation and formatting using freemarker

My goal is to format a collection of java map to a string (basically a csv) using free marker or anything else that would do smartly. I want to generate the template using a configuration data stored in database and managed from an admin application.
The configuration will tell me at what position a given data (key in hash map) need to go and also if any script need to run on this data before applying it at a given position. Several positions may be blank if the data in not in map.
I am thinking to use free-marker to build this generic tool and would appreciate if you could share how I should go about this.
Also would like to know if there is any built is support in spring-integration for building such process as the application is a SI application.
I am no freemarker expert, but a quick look at their quick start docs led me here...
public class FreemarkerTransformerPojo {
private final Configuration configuration;
private final Template template;
public FreemarkerTransformerPojo(String ftl) throws Exception {
this.configuration = new Configuration(Configuration.VERSION_2_3_23);
this.configuration.setDirectoryForTemplateLoading(new File("/"));
this.configuration.setDefaultEncoding("UTF-8");
this.template = this.configuration.getTemplate(ftl);
}
public String transform(Map<?, ?> map) throws Exception {
StringWriter writer = new StringWriter();
this.template.process(map, writer);
return writer.toString();
}
}
and
public class FreemarkerTransformerPojoTests {
#Test
public void test() throws Exception {
String template = System.getProperty("user.home") + "/Development/tmp/test.ftl";
OutputStream os = new FileOutputStream(new File(template));
os.write("foo=${foo}, bar=${bar}".getBytes());
os.close();
FreemarkerTransformerPojo transformer = new FreemarkerTransformerPojo(template);
Map<String, String> map = new HashMap<String, String>();
map.put("foo", "baz");
map.put("bar", "qux");
String result = transformer.transform(map);
assertEquals("foo=baz, bar=qux", result);
}
}
From a Spring Integration flow, send a message with a Map payload to
<int:transformer ... ref="fmTransformer" method="transform" />
Or you could do it with a groovy script (or other supported scripting language) using Spring Integration's existing scripting support without writing any code (except the script).

Tyrus - pass object from client to server

Is it posible to pass custom object from client to server, using Tyrus project for websocket communication. I want to build simple desktop application using JavaFX. How can I pass data that I "collect" on client side (e.g. Object Person with name and lastname fields) so I can save that data to database (on my server logic) ?
It is possible and the form of transferred data is completely your choice.
WebSocket can transfer text or binary data, that's it. You can serialize your obect to ObjectStream and send the data as binary stream, or You can use use JAXB to marshall and umarshall data to/from XML, or JSON-P for JSON (note that there are lots of other possibilities, like GSON, Jackson, ...).
If I would be in your position, I'd use JSON with whatever library I find usable - this way, when you'll extend the application scope to javascript clients, you'll be able to reuse (hopefully) everything.
In addition to Pavel Bucek explanation, sample code is here
Base64 for conversion
import java.util.Base64;
Serverendpoint
ArrayList listobj=new ArrayList();
listobj.add("data1");
listobj.add("data2");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(listobj);
String str = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
session.getBasicRemote().sendText(str);
Client (Tyrus)
#OnMessage
public void onMessage(Session session, final String message) throws IOException {
try {
byte data[] = Base64.getDecoder().decode(message);
bis = new ByteArrayInputStream(data);
ois = new ObjectInputStream(bis);
ArrayList list= (ArrayList) ois.readObject();
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
} catch (Exception e) {
System.out.println("error : " + e.getMessage());
} finally {
if (bis != null) {
bis.close();
}
if (ois != null) {
ois.close();
}
}
}

Primefaces is not immediately closing the stream of DefaultStreamedContent after read

I have the following problem:
I am displaying an image in my webapp using a <p:graphicImage> from Primefaces
The image displayed is delivered by a bean as a DefaultStreamedContent. In my application I am sometimes deleting images displayed this way during runtime.
This always takes a little time till I can delete the image. After debugging a little i used the Files.delete of Java 7 and got the following exception:
The process cannot access the file because it is being used by another process.
I thus suspect that Primefaces is not immediately closing the stream behind the DefaultStreamedContent after displaying and i am not able to delete the file whenever I want.
Is there any way to tell the DefaultStreamedContent to close itself imediately after read (I already looked into the documentation and didn't find any fitting method within the DefaultStreamedContent, but maybe one can tell the stream or something like that?)
Ok I finally found out what is happening using the Unlocker tool
(can be downloaded here: http://www.emptyloop.com/unlocker/#download)
I saw that the java.exe is locking the file once it is displayed. Therefor the Stream behind the StreamedContent is NOT immediately closed after reading.
My solution was as follows:
I made a superclass extending the StreamedContent and let it read the inputstream and "feed" the read bytes into a new InputStream. After that i closed the given stream so that the ressource behind it is released again.
the class looks something like this:
public class PersonalStreamedContent extends DefaultStreamedContent {
/**
* Copies the given Inputstream and closes it afterwards
*/
public PersonalStreamedContent(FileInputStream stream, String contentType) {
super(copyInputStream(stream), contentType);
}
public static InputStream copyInputStream(InputStream stream) {
if (stream != null) {
try {
byte[] bytes = IOUtils.toByteArray(stream);
stream.close();
return new ByteArrayInputStream(bytes);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
System.out.println("inputStream was null");
}
return new ByteArrayInputStream(new byte[] {});
}
}
I am quite sure that the image is retrieved 2 times by Primefaces but only closed the FIRST time it is loaded. I didn't realize this in the beginning.
I hope this can help some other people too :)

"Location not available"?

In my android app that I want to develope, I would like the users can find their position. To do this I have this code in the MainActivity but on the device (when i run it) it can't find latitute longitude and the address.Why?
public class MainActivity extends Activity implements LocationListener {
private TextView latituteField;
private TextView longitudeField;
private TextView addressField; //Add a new TextView to your activity_main to display the address
private LocationManager locationManager;
private String provider;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
latituteField = (TextView) findViewById(R.id.TextView02);
longitudeField = (TextView) findViewById(R.id.TextView04);
addressField = (TextView) findViewById(R.id.TextView05); //Make sure you add this to activity_main
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
System.out.println("Provider " + provider + " has been selected.");
onLocationChanged(location);
} else {
latituteField.setText("Location not available");
longitudeField.setText("Location not available");
}
}
#Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
#Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location) {
double lat = location.getLatitude();
double lng = location.getLongitude();
Geocoder geoCoder = new Geocoder(this, Locale.getDefault());
StringBuilder builder = new StringBuilder();
try {
List<Address> address = geoCoder.getFromLocation(lat, lng, 1);
int maxLines = address.get(0).getMaxAddressLineIndex();
for (int i=0; i<maxLines; i++) {
String addressStr = address.get(0).getAddressLine(i);
builder.append(addressStr);
builder.append(" ");
}
String fnialAddress = builder.toString(); //This is the complete address.
latituteField.setText(String.valueOf(lat));
longitudeField.setText(String.valueOf(lng));
addressField.setText(fnialAddress); //This will display the final address.
} catch (IOException e) {}
catch (NullPointerException e) {}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(this, "Enabled new provider " + provider,
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(this, "Disabled provider " + provider,
Toast.LENGTH_SHORT).show();
}
}
Note: This is an old answer which did not help solve the particular problem. However, it is valuable information so I don't delete it.
The blinking GPS icon is a good sign. It means that your app is asking the operating system for the location and the operating system tries to fetch it.
The blinking indicates that the operating system did not complete fetching the location via GPS. If this problem persists for, e.g. more than 1 or 2 minutes, it can have the following reasons:
You do not receive the GPS signal (e.g. because you are in a building with too thick walls).
You do not have a data connection to the internet (on some versions of phones and/or android, GPS doesn't work without data connection. Sounds stupid, but it's true. I am a proud owner of such a phone.)
There is some other bug that causes your GPS to be in a state where it does not generate any more location updates. This happened for me sometimes and I do not know any more background info. After a reboot of the phone, it always worked again.
My guess would be that the best provider is not enabled.
try calling getBestProvider(criteria, true)
also Log.d the provider and you can use isProviderEnabled(provider) to see if the provider is enabled.
I've compiled your example and tested it on a Galaxy S2. Here are my findings:
You have code in your examples for two different approaches of getting the location. One approach is to use LocationManager.getLastKnownLocation(...) to fetch the location directly and the other approach is to implement the LocationListener interface and registering for location updates to get notified about new location updates later.
Upfront info: I got the second approach work fine, but I did not get the approach with the getLastKnownLocation method to work reliably.
The location fetching does not work because as provider, "network" is returned. This happens although GPS is on. The subsequent effect is that, because I have the network location provider switched off, the getLastKnowLocation method returns null as documented there: "If the provider is currently disabled, null is returned." (from getLastKnownLocation )
You can fix this by changing
provider = locationManager.getBestProvider(criteria, false);
to
provider = locationManager.getBestProvider(criteria, true);
.
This will give you the GPS provider, if it is available (switched on). However, the getLastKnownLocation(...) method still returns null for me, although the correct provider (gps) is selected and the provider is available. That means that the documentation of the getLastKnownLocation method is lacking information about another case when it returns null. This seems to be because no last known location was saved for this provider. You can not know if this is the case when starting your application, so you can not rely on this method returning a non-null value at application startup.
And here is the good news: Now that we got the correct location provider, the location updates through the second approach (the registering for future location update notifications) works as expected through the gps provider. Updates are coming in and the locations are shown and updated in the textfields on my test phone.

Custom FileResult on Azure: Browser Waits forever

I have an action that returns an Excel as a custom FileResult. My solution is based on the ClosedXml library (internaly using OpenXml).
My XlsxResult class uses a read-only .xlsx file on the server as a template. It then passes on the template into a memory stream that gets manipulated and saved back with ClosedXml. In the end the memory stream get written to the response.
This works fine both on Cassini as well as IIS Express but fails when deployed on azure with no error whatsoever. The only effect I am experiencing is the request sent to the server never gets any response. I am still waiting for something to happen after 60 minutes or so...
My action:
[OutputCache(Location= System.Web.UI.OutputCacheLocation.None, Duration=0)]
public FileResult Export(int year, int month, int day) {
var date = new DateTime(year, month, day);
var filename = string.Format("MyTemplate_{0:yyyyMMdd}.xlsx", date);
//return new FilePathResult("~/Content/templates/MyTemplate.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
var result = new XlsxExportTemplatedResult("MyTemplate.xlsx", filename, (workbook) => {
var ws = workbook.Worksheets.Worksheet("My Export Sheet");
ws.Cell("B3").Value = date;
// Using a OpenXML's predefined formats (15 stands for date)
ws.Cell("B3").Style.NumberFormat.NumberFormatId = 15;
ws.Columns().AdjustToContents(); // You can also specify the range of columns to adjust, e.g.
return workbook;
});
return result;
}
My FileResult
public class XlsxExportTemplatedResult : FileResult
{
// default buffer size as defined in BufferedStream type
private const int BufferSize = 0x1000;
public static readonly string TEMPLATE_FOLDER_LOCATION = #"~\Content\templates";
public XlsxExportTemplatedResult(string templateName, string fileDownloadName, Func<XLWorkbook, XLWorkbook> generate)
: base("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
this.TempalteName = templateName;
this.FileDownloadName = fileDownloadName;
this.Generate = generate;
}
public string TempalteName { get; protected set; }
public Func<XLWorkbook, XLWorkbook> Generate { get; protected set; }
protected string templatePath = string.Empty;
public override void ExecuteResult(ControllerContext context) {
templatePath = context.HttpContext.Server.MapPath(System.IO.Path.Combine(TEMPLATE_FOLDER_LOCATION, this.TempalteName));
base.ExecuteResult(context);
}
//http://msdn.microsoft.com/en-us/library/office/ee945362(v=office.11).aspx
protected override void WriteFile(System.Web.HttpResponseBase response) {
FileStream fileStream = new FileStream(templatePath, FileMode.Open, FileAccess.Read);
using (MemoryStream memoryStream = new MemoryStream()) {
CopyStream(fileStream, memoryStream);
using (var workbook = new XLWorkbook(memoryStream)) {
Generate(workbook);
workbook.Save();
}
// At this point, the memory stream contains the modified document.
// grab chunks of data and write to the output stream
Stream outputStream = response.OutputStream;
byte[] buffer = new byte[BufferSize];
while (true) {
int bytesRead = memoryStream.Read(buffer, 0, BufferSize);
if (bytesRead == 0) {
// no more data
break;
}
outputStream.Write(buffer, 0, bytesRead);
}
}
fileStream.Dispose();
}
static private void CopyStream(Stream source, Stream destination) {
byte[] buffer = new byte[BufferSize];
int bytesRead;
do {
bytesRead = source.Read(buffer, 0, buffer.Length);
destination.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
}
}
So am I missing something (apparently I am).
Please Note:
There are no dlls missing from Azure because I checked using RemoteAccess feature of the Windows Azure Tools 1.7
My export is not a heavy long running task.
when I changed the action to just return a FilePathResult with the template xlsx it worked on azure. But I need to process the file before returning it as u might suspect :-)
Tanks.
UPDATE:
After I logged extensively in my code the execution hangs with no error at the ClosedXml "Save" method call. But still no error. Abstract from the WADLogsTable:
Opening template file from path:
E:\sitesroot\0\Content\templates\MyTemplate.xlsx
Opened template from path:
E:\sitesroot\0\Content\templates\MyTemplate.xlsx just
copied template to editable memory stream. Bytes copied: 15955,
Position: 15955
modified the excel document in memory.
here it hangs when a it calls to workbook.Save(); This is a ClosedXml method call.
I was facing the exact same error situation as you. I can't offer a fix in your specific situation, and I know you switched tracks, but after going through the same frustrating steps you had faced, I'd like to "pave the way" for an answer for you (or others).
Drop into your package manager console in Visual Studio and install Elmah with the MVC goodies (routing):
Install-Package elmah.MVC
Now, in your root web.config, update your Elmah entry. It's likely at the end of the file, looking like this:
<elmah></elmah>
Update that bad boy to allow remote access and set up your log path:
<elmah>
<security allowRemoteAccess="1" />
<errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/app_data/elmah" />
</elmah>
Now, push that up to Azure.
Finally, visit your site, force the error then navigate to http://your-site-here.azurewebsites.net/elmah and you'll see the exact cause of the error.
Elmah is so the awesome.
Sheepish confession: The error for me wasn't in the third party code, it turned out to be in my connection string, for which I hadn't set MultipleActiveResultsSets to true. The other fix I had to do was pass my entities in after calling ToList() to one of the internal methods on that library, leaving it as IQueryable borked the method up.

Resources