MonoTouch: Refreshing a UITableView - uitableview

Many thanks to Jonathan Peppers for the advice on how to refresh a tableview.
Update: Here is a link to my solution: https://github.com/Videlia/Veggies.git. Also, I have discovered that once I have added 5 items in landscape view, or about 7 or 8 in portrait view, the list starts to display the top items over again, instead of continuing down the list. However, if I select a row, it selects the value that should have been displayed.
My tableview is now working perfectly if I add or edit a row (both of which require that I go to another screen and then return to this one). For some reason, the delete operation, which is executed on the same screen, does not reload the data.
Here is my updated code:
View Controller
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace TableViewTest
{
public partial class vc_ManageVeggies : UIViewController
{
public vc_ManageVeggies () : base ("vc_ManageVeggies", null)
{
}
public override void DidReceiveMemoryWarning ()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// connect table to source.
VeggieTableSource source = new VeggieTableSource ();
Console.WriteLine ("\n vc_ManageVeggies.ViewDidLoad: " + Veggies.CountVeggies ().ToString () + " veggies found! :-)");
if (Veggies.CountVeggies () > 0) {
this.tblVeggies.Source = source;
}
btnNewVeggie.TouchUpInside += delegate {
Veggies.SelectedVeggie = string.Empty;
vc_VeggieAddEdit newScreen = new vc_VeggieAddEdit ();
try {
this.NavigationController.PushViewController (newScreen, false);
} catch (Exception ex) {
Console.WriteLine ("btnNewVeggie error: " + ex.ToString ());
}
};
btnEditVeggie.TouchUpInside += delegate {
if (Veggies.SelectedVeggie == string.Empty) {
UIAlertView alert = new UIAlertView ("Oops!", "Please select a veggie to edit.", null, "OK");
alert.Show ();
} else {
vc_VeggieAddEdit newScreen = new vc_VeggieAddEdit ();
this.NavigationController.PushViewController (newScreen, false);
}
};
btnDeleteVeggie.TouchUpInside += delegate {
Veggies.DeleteVeggie (Veggies.SelectedVeggie);
// update VeggieNames list and reload tableview data.
//Veggies.RefreshVeggieList ();
Veggies.VeggieNames.Remove (Veggies.SelectedVeggie);
tblVeggies.ReloadData ();
};
btnDone.TouchUpInside += delegate {
vc_MainMenu newScreen = new vc_MainMenu ();
NavigationController.PushViewController (newScreen, false);
};
}
public override void ViewDidUnload ()
{
base.ViewDidUnload ();
// Clear any references to subviews of the main view in order to
// allow the Garbage Collector to collect them sooner.
//
// e.g. myOutlet.Dispose (); myOutlet = null;
ReleaseDesignerOutlets ();
}
public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
{
// Return true for supported orientations
return (toInterfaceOrientation != UIInterfaceOrientation.PortraitUpsideDown);
}
public void RefreshVeggieTable ()
{
}
}
}
Table Source
using System;
using MonoTouch.UIKit;
using MonoTouch.Foundation;
using System.Collections.Generic;
namespace TableViewTest
{
public class VeggieTableSource: UITableViewSource
{
//List<string> veggieNames;
public VeggieTableSource ()
{
Veggies.GetVeggieNames ();
}
#region implemented abstract members of MonoTouch.UIKit.UITableViewSource
public override int RowsInSection (UITableView tableview, int section)
{
//return veggieNames.Count;
return Veggies.VeggieNames.Count;
}
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell ("cell");
if (cell == null) {
cell = new UITableViewCell (UITableViewCellStyle.Default, "cell");
var text = string.Format ("{0}", Veggies.VeggieNames [indexPath.Row]);
cell.TextLabel.Text = text;
}
return cell;
}
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
Veggies.SelectedVeggie = Veggies.VeggieNames [indexPath.Row].ToString ();
}
#endregion
}
}
Veggie Class
using System;
using System.Collections.Generic;
using MonoTouch.UIKit;
using MonoTouch.Foundation;
using MyDataLayer;
namespace TableViewTest
{
public static class Veggies
{
public static List<string> VeggieNames;
public static string SelectedVeggie;
public static int NumberOfVeggies;
public static int CountVeggies ()
{
NumberOfVeggies = DataLayer.CountRecords ("tVeggies");
return NumberOfVeggies;
}
public static List<string> GetVeggieNames ()
{
//VeggieName ntext, Description ntext, Yummy int
string sql = "Select VeggieName from tVeggies ORDER BY VeggieName";
VeggieNames = DataLayer.GetStringList (sql);
Console.WriteLine ("\n GetVeggieNames: " + VeggieNames.ToString ());
return VeggieNames;
}
public static void CreateVeggie (string veggieName, int yummy, string description)
{
// 1. Declare variables and set initial values
DataLayer dataLayer = new DataLayer ();
DataField[] dataFields;
DataField NameField = new DataField ();
DataField YummyField = new DataField ();
DataField DescriptionField = new DataField ();
string sql = string.Empty;
// unselect any other players because the new player will also become the selected player.
MyDataLayer.DataLayer.ExecuteNonQuery (sql);
//3. Create data field objects for each field to be created.
NameField.FieldName = "VeggieName";
NameField.FieldType = "string";
NameField.FieldValue = '"' + veggieName + '"';
YummyField.FieldName = "Yummy";
YummyField.FieldType = "int";
YummyField.FieldValue = yummy.ToString ();
DescriptionField.FieldName = "Description";
DescriptionField.FieldType = "string";
DescriptionField.FieldValue = '"' + description + '"';
dataFields = new DataField[] { NameField, YummyField, DescriptionField };
// Insert Record into database.
dataLayer.InsertRecord ("tVeggies", dataFields);
RefreshVeggieList ();
}
public static void DeleteVeggie (string veggieName)
{
string sql = "DELETE FROM tVeggies WHERE VeggieName = '" + veggieName + "'";
try {
DataLayer.ExecuteNonQuery (sql);
} catch (Exception ex) {
Console.WriteLine ("Player.Delete error: " + ex.ToString ());
}
RefreshVeggieList ();
}
public static void UpdateVeggie (string veggieName, int yummy, string description)
{
// create variables and set initial values
//DataLayer dataLayer = new DataLayer ();
string sql = "UPDATE tVeggies SET VeggieName = '" + veggieName + "', yummy = " + yummy.ToString () + ", description = '" + description + "' where VeggieName = '" + Veggies.SelectedVeggie + "'";
//string response = string.Empty; //this will hold a response such as "success" or the error message.
Console.WriteLine ("Veggie.UpdateVeggie sql statement: " + sql);
try {
DataLayer.ExecuteNonQuery (sql);
Console.WriteLine ("PVeggie.UpdateVeggie: veggie updated successfully.");
} catch (Exception ex) {
Console.WriteLine ("Veggie.UpdateVeggie: " + ex.ToString ());
}
RefreshVeggieList ();
}
// Update list of Veggie names
// the TableView on the ManageVeggies view controller needs the VeggieList to be updated whenever veggie records are changed.
//so the tableview will refresh properly.
public static void RefreshVeggieList ()
{
string sql = "Select VeggieName from tVeggies ORDER BY VeggieName";
VeggieNames = DataLayer.GetStringList (sql);
}
}
}
Data Layer
using System;
using System.IO;
using Mono.Data.Sqlite;
using System.Data;
using System.Collections.Generic;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace MyDataLayer
{
// DataField class is used to create data for each data field in a table to be created, updated, or deleted.
public class DataField
{
public string FieldName { get; set; }
public string FieldValue { get; set; }
public string FieldType { get; set; }
}
public class DataLayer
{
//declare variables used by all DataLayer methods;
private static string dbFileName = "myFunDatabase.db3";
//private string dbFileAndPath = string.Empty;
private static SqliteConnection connection;
public DataLayer ()
{
}
public static int CountRecords (string tableName)
{
int count = 0;
string sql = "SELECT count(*) FROM " + tableName;
count = DataLayer.ExecuteScalar_Int16 (sql);
Console.WriteLine ("\n DataLayer.CountRecords: " + count.ToString () + "records found in the datatable.");
return count;
}
public static void ExecuteNonQuery (string sql)
{
SqliteCommand sqlCommand = new SqliteCommand ();
try {
// create and open connection
connection = GetConnection ();
using (connection) {
connection.Open ();
Console.WriteLine ("\n DataLayer.ExecuteNonQuery: connection opened. Connection state is " + connection.State);
// create and execute command
sqlCommand.CommandText = sql;
sqlCommand.Connection = connection;
sqlCommand.ExecuteNonQuery ();
connection.Close ();
Console.WriteLine ("\n DataLayer.ExecuteNonQuery: Connection was closed. Connection state is " + connection.State);
}
connection.Close ();
Console.WriteLine ("DataLayer.ExecuteNonQuery: NonQuery Executed: " + sql);
} catch (Exception ex) {
Console.WriteLine ("\n >>> DataLayer.ExecuteNonQuery Exception: " + ex.ToString ());
Console.WriteLine ("\n >>> SQL statement: " + sql);
}
}
public static Int16 ExecuteScalar_Int16 (string sql)
{
int result = 0;
SqliteCommand sqlCommand = new SqliteCommand ();
try {
//connection = new SqliteConnection (string.Format ("Data Source = {0};", dbFileName));
connection = GetConnection ();
connection.Open ();
sqlCommand.CommandText = sql;
sqlCommand.Connection = connection;
result = Convert.ToInt16 (sqlCommand.ExecuteScalar ());
connection.Close ();
} catch (Exception ex) {
Console.WriteLine ("\n >>>DataLayer.ExecuteScalar_Int Exception: " + ex.ToString ());
}
return Convert.ToInt16 (result);
}
public static string ExecuteScalar_String (string sql)
{
string result = string.Empty;
SqliteCommand sqlCommand = new SqliteCommand ();
try {
//connection = new SqliteConnection (string.Format ("Data Source = {0};", dbFileName));
connection = GetConnection ();
connection.Open ();
sqlCommand.CommandText = sql;
sqlCommand.Connection = connection;
result = Convert.ToString (sqlCommand.ExecuteScalar ());
connection.Close ();
} catch (Exception ex) {
Console.WriteLine ("\n >>>DataLayer.ExecuteScalar_Int Exception: " + ex.ToString ());
}
return result;
}
public void CreateDatabaseFolder ()
{
}
//public string InsertRecord(string tableName, string variableNames, string variableTypes, string variableValues)
public string InsertRecord (string tableName, DataField[] dataFields)
{
string sql = string.Empty;
string fieldNameList = string.Empty;
string fieldValueList = string.Empty;
string response = string.Empty;
SqliteCommand sqlCommand = new SqliteCommand ();
connection = GetConnection ();
try {
connection.Open ();
// Begin transaction for multiple updates (improves efficiency)
sqlCommand = new SqliteCommand ("BEGIN", connection);
sqlCommand.ExecuteNonQuery ();
// begin individual inserts. I will nest this later to accommodate batch updates.l
sql = "INSERT INTO " + tableName + " (";
sqlCommand = new SqliteCommand ();
sqlCommand.Connection = connection;
foreach (DataField dataField in dataFields) {
fieldNameList += dataField.FieldName + ", ";
fieldValueList += dataField.FieldValue + ", ";
sqlCommand.Parameters.AddWithValue ("#" + dataField.FieldName, dataField.FieldValue);
}
// remove extra commas at the end of the lists, and append to the sql statement
sql += fieldNameList.Substring (0, fieldNameList.Length - 2);
sql += ") VALUES (";
sql += fieldValueList.Substring (0, fieldValueList.Length - 2);
sql += ")";
Console.WriteLine (sql);
// load and run sql insert statement.
sqlCommand.CommandText = sql;
sqlCommand.ExecuteNonQuery ();
sqlCommand = new SqliteCommand ("END", connection);
sqlCommand.ExecuteNonQuery ();
connection.Close ();
response = "Success";
} catch (Exception ex) {
response = ">>> DataLayer.InsertRecord Error: " + ex.ToString ();
}
// End batch commmand and close connection to the database.
Console.WriteLine ("\n DataLayer.InsertRecord Response to be returned: " + response);
return response;
}
public static List<string> GetStringList (string sql)
{
SqliteDataReader dataReader;
SqliteCommand sqlCommand = new SqliteCommand ();
List<string> values = new List<string> ();
int i = 0; //used to increment through records.
int count = 0;
connection = GetConnection ();
try {
using (connection) {
connection.Open ();
Console.WriteLine ("\n DataLayer.GetStringList: sql statement: " + sql);
sqlCommand.CommandText = sql;
sqlCommand.Connection = connection;
dataReader = sqlCommand.ExecuteReader ();
if (dataReader.HasRows) {
Console.WriteLine ("\n DataLayer.GetStringList: dataReader has" + " rows. ");
while (dataReader.Read ()) {
values.Add (dataReader [0].ToString ());
Console.WriteLine ("\n DataLayer.GetStringList: value added to list: " + dataReader [0].ToString ());
i++;
}
count = i + 1;
Console.WriteLine ("\n DataLayer.GetStringList: dataReader has" + count + " rows. ");
Console.WriteLine ("\n DataLayer.GetStringList: successfully populated value string array from data reader");
connection.Close ();
}
}
} catch (Exception ex) {
Console.WriteLine ("\n >>> DataLayer.GetStringList error: " + ex.ToString ());
}
return values;
}
public void GetSchema ()
{
}
public static void DeleteDatabase ()
{
// Declare variables
var path = Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments);
string db; // full name and path of database file.
// set initial values;
path = Path.Combine (path, "..", "Library");
db = Path.Combine (path, dbFileName);
bool databaseExists = File.Exists (db);
Console.WriteLine ("\n DataLayer.GetConnection: Getting ready to create database if it does not exist.");
if (databaseExists) {
try {
File.Delete (db);
Console.WriteLine ("\n DataLayer.DeleteDatabase: database deleted: " + dbFileName);
} catch (Exception ex) {
Console.WriteLine ("\n >>> DataLayer.DeleteDatabase: Unable to delete database: " + dbFileName);
Console.WriteLine ("\n >>> DataLayer.DeleteDatabase: Cause of error: " + ex.ToString ());
}
}
}
static SqliteConnection GetConnection ()
{
// Declare variables
var path = Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments);
string db; // full name and path of database file.
var conn = new SqliteConnection ();
// set initial values;
path = Path.Combine (path, "..", "Library");
db = Path.Combine (path, dbFileName);
bool databaseExists = File.Exists (db);
Console.WriteLine ("\n DataLayer.GetConnection: Getting ready to create database if it does not exist.");
if (!databaseExists) {
CreateDatabase (db);
}
conn = new SqliteConnection ("\n Data Source=" + db);
return conn;
}
static void CreateDatabase (string db)
{
// Declare variables
var conn = new SqliteConnection ();
// set initial values;
bool databaseExists = File.Exists (db);
Console.WriteLine ("\n DataLayer.GetConnection: Getting ready to create database if it does not exist.");
if (!databaseExists) {
try {
SqliteConnection.CreateFile (db);
Console.WriteLine ("\n DataLayer.GetConnection: Database created successfully.");
} catch (Exception ex) {
Console.WriteLine ("\n >>> DataLayer.GetConnection: Error creating database: " + ex.ToString ());
}
if (!File.Exists (db)) {
Console.WriteLine ("\n >>> DataLayer.GetConnection: Database NOT created.");
}
conn = new SqliteConnection ("Data Source=" + db);
var commands = new[] {
"CREATE TABLE tVeggies (VeggieName ntext, Description ntext, Yummy int)",
"INSERT INTO tVeggies (VeggieName, Description, Yummy) VALUES ('Carrots', 'An orange root', 0)",
"INSERT INTO tVeggies (VeggieName, Description, Yummy) VALUES ('Spinach', 'Green leafy veggie', 1)",
"INSERT INTO tVeggies (VeggieName, Description, Yummy) VALUES ('Onion', 'Round with layers', 1)",
};
foreach (var cmd in commands) {
using (var c = conn.CreateCommand()) {
c.CommandText = cmd;
//c.CommandType = CommandType.Text; //this code does not work.
conn.Open ();
c.ExecuteNonQuery ();
conn.Close ();
Console.WriteLine ("\n DataLayer.GetConnection: command executed: " + cmd.ToString ());
}
}
}
}
public static System.Data.DataTable GetData (string sql)
{
// declare variables and set initial values
SqliteCommand command = new SqliteCommand ();
System.Data.DataTable dataTable = new System.Data.DataTable ();
SqliteDataAdapter adapter = new SqliteDataAdapter ();
System.Data.DataRow iRow;
//open connection and retrieve desired data.
try {
connection = GetConnection ();
using (connection) {
Console.WriteLine ("\n DataLayer.GetData: sql statement: " + sql);
command.CommandText = sql;
command.Connection = connection;
adapter = new SqliteDataAdapter (command);
connection.Open ();
adapter.Fill (dataTable);
// check to see if we got some data.
Console.WriteLine ("\n DataLayer.GetData: retrieved dataTable with " + dataTable.Rows.Count.ToString () + " rows.");
for (int i = 0; i< dataTable.Rows.Count; i++) {
iRow = dataTable.Rows [i];
}
Console.WriteLine ("\n DataLayer.GetData: successfully populated data table");
connection.Close ();
}
} catch (Exception ex) {
Console.WriteLine ("\n >>> error: " + ex.ToString ());
}
return dataTable;
}
}
}

Looking at your code, what is visible on your screen should be directly correlated to your list of veggieNames.
So to remove, replace, or add an item:
Perform this operation on the List<string>
call tblVeggies.ReloadData()
You don't have to create new table source or anything, which is likely what is messing you up. I would recommend creating the table source in ViewDidLoad.
If you want to get really fancy, an optimization you can do is call tblVeggies.ReloadRows on a specific row, but I would get it working in general first.

Related

How to Populate DropDownList from the Database in MVC

I am new to ASP NET MVC
I need Populate a drop down list from values obtained from a database table using MySql database and view model, after checking if the current user is application enabled, using ASP NET MVC.
This is the tutorial
My code below return
Error: returns void, a return keyword must not be followed by an object expression
On this line
return items;
Any help really appreciated.
Controller
public ActionResult Recovery()
{
try
{
string cs = ConfigurationManager.ConnectionStrings["cnj"].ConnectionString;
using (var connection =
new MySqlConnection(cs))
{
string commandText = " SELECT cCountry FROM `dotable_user` " +
" WHERE cName = #Username; ";
using (var command =
new MySqlCommand(commandText, connection))
{
if (!String.IsNullOrEmpty(HttpContext.User.Identity.Name.ToString()))
{
command.Parameters.AddWithValue("#Username", HttpContext.User.Identity.Name.ToString());
}
connection.Open();
string cCountry = (string)command.ExecuteScalar();
if (String.IsNullOrEmpty(cCountry))
{
TempData["Message"] = "No user.";
ViewBag.Message = String.Format("No user.");
}
List<SelectListItem> items = new List<SelectListItem>();
using (MySqlConnection con = new MySqlConnection(cs))
{
string query = " SELECT cCountry FROM `dotable_countries` " +
" WHERE cCountry = '" + cCountry.ToString() + "' ";
using (MySqlCommand cmd = new MySqlCommand(query))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
items.Add(new SelectListItem
{
Text = sdr["cCountry"].ToString(),
Value = sdr["cCountry"].ToString()
});
}
}
connection.Close();
}
}
return items;
}
}
}
catch (Exception ex)
{
TempData["Message"] = "Login failed.Error - " + ex.Message;
}
}
Update
I have tried with this code.
I have error
Error CS0103 The name 'cCountry' does not exist in the current context
public ActionResult Recovery()
{
try
{
string cs = ConfigurationManager.ConnectionStrings["cnj"].ConnectionString;
using (var connection =
new MySqlConnection(cs))
{
string commandText = " SELECT cCountry FROM `dotable_user` " +
" WHERE cName = #Username; ";
using (var command =
new MySqlCommand(commandText, connection))
{
if (!String.IsNullOrEmpty(HttpContext.User.Identity.Name.ToString()))
{
command.Parameters.AddWithValue("#Username", HttpContext.User.Identity.Name.ToString());
}
connection.Open();
string cCountry = (string)command.ExecuteScalar();
if (String.IsNullOrEmpty(cCountry))
{
TempData["Message"] = "No user.";
ViewBag.Message = String.Format("No user.");
}
TempData["Dates"] = PopulateDates();
}
}
}
catch (Exception ex)
{
TempData["Message"] = "Login failed.Error - " + ex.Message;
}
}
private static List<SelectListItem> PopulateDates()
{
List<SelectListItem> items = new List<SelectListItem>();
string cs = ConfigurationManager.ConnectionStrings["cnj"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(cs))
{
string query = " SELECT cCountry FROM `dotable_countries` " +
" WHERE cCountry = '" + cCountry.ToString() + "'; ";
using (MySqlCommand cmd = new MySqlCommand(query))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
items.Add(new SelectListItem
{
Text = sdr["cCountry"].ToString(),
Value = sdr["cCountry"].ToString()
});
}
}
cmd.Connection.Close();
}
}
return items;
}
You are not passing cCountry value to populateDates.That's why you are getting this error. You can do something like below to get drop down populated. However it is not good idea to write Business Logic directly in controller. You should move it to model or Business layer.
private static List<SelectListItem> PopulateDates(string country)
{
List<SelectListItem> items = new List<SelectListItem>();
string cs = ConfigurationManager.ConnectionStrings["cnj"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(cs))
{
string query = " SELECT cCountry FROM dotable_countries WHERE cCountry = #country";
using (MySqlCommand cmd = new MySqlCommand(query))
{
cmd.Parameters.AddWithValue("#country",country);
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
items.Add(new SelectListItem
{
Text = sdr["cCountry"].ToString(),
Value = sdr["cCountry"].ToString()
});
}
}
cmd.Connection.Close();
}
}
return items;
}
and while calling this method in Action pass country value to it like below
TempData["Dates"] = PopulateDates(cCountry);

Neo4j 3.1.2 Embedded db shutdown is not working with apoc.periodic.iterate

I am starting Neo4j embedded application with shutdown hook and apoc procedures registration. I am using apoc.periodic.iterate procedure call with {batchSize:100,parallel:true,iterateList:true} config. After getting Result, i am calling graphdb.shutdown. DB is not getting shutdown after calling shutdown method. Am i missing anything?
public class APOCTest {
private static final File DB_PATH = new File("I://apps//neo4j-enterprise-3.1.2//data//databases//graph.db");
public static void main(String[] args) throws JsonParseException, UnsupportedEncodingException, IOException {
System.out.println("Neo4j starting " + new Date());
GraphDatabaseService graphDb = new HighlyAvailableGraphDatabaseFactory().newEmbeddedDatabaseBuilder(DB_PATH)
.loadPropertiesFromFile("I://apps//standalone//neo4j.conf").newGraphDatabase();
registerShutdownHook(graphDb);
registerProcedures(graphDb);
System.out.println("Neo4j started:: " + new Date());
createData(graphDb);
deleteData(graphDb);
graphDb.shutdown();
}
private static void registerProcedures(final GraphDatabaseService graphDb) {
Procedures procedures = ((GraphDatabaseAPI) graphDb).getDependencyResolver()
.resolveDependency(Procedures.class);
List<Class<?>> apocProcedures = asList(Coll.class, apoc.map.Maps.class, Json.class, Create.class,
apoc.date.Date.class, FulltextIndex.class, apoc.lock.Lock.class, LoadJson.class, Xml.class,
PathExplorer.class, Meta.class, GraphRefactoring.class, apoc.periodic.Periodic.class);
apocProcedures.forEach((proc) -> {
try {
procedures.registerProcedure(proc);
procedures.registerFunction(proc);
} catch (KernelException e) {
throw new RuntimeException("Error registering " + proc, e);
}
});
}
private static void registerShutdownHook(final GraphDatabaseService graphDb) {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
graphDb.shutdown();
}
});
}
private static void createData(final GraphDatabaseService graphDb) {
System.out.println("createData " + new Date());
Transaction tx = graphDb.beginTx();
try {
for (int i = 1; i < 900000; i++) {
Node n = graphDb.createNode(Label.label("Test"));
n.setProperty("createDate", System.currentTimeMillis());
if (i % 30000 == 0) {
tx.success();
tx.close();
tx = graphDb.beginTx();
}
}
tx.success();
} finally {
tx.close();
}
System.out.println("createData " + new Date());
}
private static void deleteData(final GraphDatabaseService graphDb) {
System.out.println("deleteData " + new Date());
try (Transaction tx = graphDb.beginTx()) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("oldStmtDate1", 1);
String query = "CALL apoc.periodic.iterate(\"MATCH (n:Test) WHERE n.createDate > {oldStmtDate} RETURN n \",\"DETACH DELETE n\",{batchSize:100,parallel:true,iterateList:true,params:{oldStmtDate:{oldStmtDate1}}})";
Result r = graphDb.execute(query, map);
System.out.println(r.next());
tx.success();
}
System.out.println("deleteData " + new Date());
}
}

Blackberry java show recieved push message

After referring tons of tutorials finally somehow I managed to develop java push client for Blackberry OS 7.0 (registering in RIM and server side are completely ok, this is the server script). Now the program running on the device and when new push massage revived there is a little arrow blinking on right up corner of the device, but I haven't that much knowledge to show that message in a label field or any other UI component. Please tell me how to show the revived push message in a screen. I'm beginner in programming so I haven't that much of knowledge need your help. Here I post all the codes that I have used.
Here is the application class
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
/**
* This class extends the UiApplication class, providing a
* graphical user interface.
*/
public class MyApp extends UiApplication
{
public static void main(String[] args)
{
//every time we start the application we register to BIS for push
if (args.length > 0 && args[0].equals("BlackBerryCity")) {
System.out.println("!!!!!!!!!!!!!!I am inside if");
//registering for push
Push_main.registerBpas();
MyApp app = new MyApp();
app.enterEventDispatcher();
}
//every time we restart the phone , we call this background process that is responsible for listening for push
else {
System.out.println("!!!!!!!!!!!!!!I am inside else");
//should put the background classes for listening to pushed msgs :D
BackgroundApplication backApp=new BackgroundApplication();
backApp.setupBackgroundApplication();
backApp.enterEventDispatcher();
}
}
public MyApp(){
pushScreen(new MyAppScreen());
}
}
class MyAppScreen extends MainScreen
{
public MyAppScreen()
{
// What to add here no idea :(
}
}
Push_main class
public class Push_main {
private static final String REGISTER_SUCCESSFUL = "rc=200";
private static final String DEREGISTER_SUCCESSFUL = REGISTER_SUCCESSFUL;
private static final String USER_ALREADY_SUBSCRIBED = "rc=10003";
private static final String ALREADY_UNSUSCRIBED_BY_USER = "rc=10004";
private static final String ALREADY_UNSUSCRIBED_BY_PROVIDER = "rc=10005";
private static final String PUSH_PORT = ""+"XXXXXX"; //push port
private static final String BPAS_URL = "http://cpXXXX.pushapi.eval.blackberry.com";
private static final String APP_ID = ""+ "XXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXX"; // add application id
private static String URL = "http://:"+ "XXXXXX"; // add your push port.
private static final int CHUNK_SIZE = 256;
public static ListeningThread _listeningThread;
public static StreamConnectionNotifier _notify;
private static final long ID = 0x954a603c0dee81e0L;
public Push_main(){
if(_listeningThread==null)
{
System.out.println("msg on listening thread 1");
_listeningThread = new ListeningThread();
System.out.println("msg on listening thread 2");
_listeningThread.start();
System.out.println("msg on listhning thread 3 ");
}
}
public static class ListeningThread extends Thread
{
private boolean _stop = false;
/**
* Stops the thread from listening.
*/
private synchronized void stop()
{
_stop = true;
try
{
// Close the connection so the thread will return.
_notify.close();
}
catch (Exception e)
{
}
}
/**
* Listen for data from the HTTP url. After the data has been read,
* render the data onto the screen.
* #see java.lang.Runnable#run()
*/
public void run()
{
StreamConnection stream = null;
InputStream input = null;
MDSPushInputStream pushInputStream=null;
while (!_stop)
{
try
{
// Synchronize here so that we don't end up creating a connection that is never closed.
synchronized(this)
{
// Open the connection once (or re-open after an IOException), so we don't end up
// in a race condition, where a push is lost if it comes in before the connection
// is open again. We open the url with a parameter that indicates that we should
// always use MDS when attempting to connect.
System.out.println("\n\n msg connection 1");
_notify = (StreamConnectionNotifier)Connector.open(URL);
System.out.println("\n\n msg connection 2");
}
while (!_stop)
{
// NOTE: the following will block until data is received.
System.out.println("\n\n msg notify 1");
stream = _notify.acceptAndOpen();
System.out.println("\n\n msg 1 ");
try
{
System.out.println("\n\n msg 2");
input = stream.openInputStream();
System.out.println("\n\n msg 3 ");
pushInputStream= new MDSPushInputStream((HttpServerConnection)stream, input);
System.out.println("\n\n msg 4");
// Extract the data from the input stream.
DataBuffer db = new DataBuffer();
byte[] data = new byte[CHUNK_SIZE];
int chunk = 0;
while ( -1 != (chunk = input.read(data)) )
{
db.write(data, 0, chunk);
}
updateMessage(data);
// This method is called to accept the push.
pushInputStream.accept();
data = db.getArray();
}
catch (IOException e1)
{
// A problem occurred with the input stream , however, the original
// StreamConnectionNotifier is still valid.
// errorDialog(e1.toString());
}
finally
{
if ( input != null )
{
try
{
input.close();
}
catch (IOException e2)
{
}
}
if ( stream != null )
{
try
{
stream.close();
}
catch (IOException e2)
{
}
}
}
}
}
catch (IOException ioe)
{
// Likely the stream was closed. Catches the exception thrown by
// _notify.acceptAndOpen() when this program exits.
errorDialog(ioe.toString());
}
finally
{
/*
if ( _notify != null )
{
try
{
_notify.close();
_notify = null;
}
catch ( IOException e )
{
}
}
*/
}
}
}
}
private static void updateMessage(final byte[] data)
{
System.out.println("\n\n msg 6");
Application.getApplication().invokeLater(new Runnable()
{
public void run()
{
// Query the user to load the received message.
// Dialog.alert( new String(data));
UiApplication.getUiApplication().invokeLater( new Runnable() {
public void run()
{
NotificationsManager.triggerImmediateEvent(ID, 0, null, null);
Dialog d = new Dialog( Dialog.D_OK, new String(data) ,0, null, Screen.DEFAULT_CLOSE);
// _dialogShowing = true;
UiApplication.getUiApplication().pushGlobalScreen( d, 10, UiApplication.GLOBAL_MODAL );
// Dialog is closed at this point, so we cancel the event.
}
} );
}
});
}
public static void registerBpas() {
/**
* As the connection suffix is fixed I just use a Thread to call the connection code
*
**/
new Thread() {
public void run() {
try {
String registerUrl = formRegisterRequest(BPAS_URL, APP_ID, null) + ";deviceside=false;ConnectionType=mds-public";
//Dialog.alert(registerUrl);
if ((WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)
&& RadioInfo
.areWAFsSupported(RadioInfo.WAF_WLAN)) {
registerUrl += ";interface=wifi";
}
System.out.println("\n\n\n !!msg registerBPAS URL is: "+ registerUrl + "\n\n");
HttpConnection httpConnection = (HttpConnection) Connector.open(registerUrl);
InputStream is = httpConnection.openInputStream();
System.out.println("\n\n\n !!!!!!!!!!!I am here ");
String response = new String(IOUtilities.streamToBytes(is));
System.out.println("\n\n\n\n\n\n msg RESPOSE CODE : " + response);
System.out.println("\n\n\n !!!!!!!!!!!I am here2 ");
httpConnection.close();
String nextUrl = formRegisterRequest(BPAS_URL, APP_ID, response) + ";deviceside=false;ConnectionType=mds-public";
System.out.println("\n\n\n\n\n\n msg nextUrl : " + nextUrl);
System.out.println("\n\n\n !!!!!!!!!!!I am here 3");
if ((WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)
&& RadioInfo
.areWAFsSupported(RadioInfo.WAF_WLAN)) {
nextUrl += ";interface=wifi";
System.out.println("\n\n\n !!!!!!!!!!!I am here 4");
}
HttpConnection nextHttpConnection = (HttpConnection) Connector.open(nextUrl);
InputStream nextInputStream = nextHttpConnection.openInputStream();
response = new String(IOUtilities.streamToBytes(nextInputStream));
System.out.println("\n\n\n !!!!!!!!!!!I am here 5");
System.out.println("\n\n\n\n\n\n msg RESPOSE CODE 1: " + response);
nextHttpConnection.close();
if (REGISTER_SUCCESSFUL.equals(response) || USER_ALREADY_SUBSCRIBED.equals(response)) {
Dialog.alert("msg Registered successfully for BIS push");
System.out.println("\n\n\n !!!!!!!!!!!I am here 6");
System.out.println("msg Registered successfully for BIS push");
} else {
Dialog.alert("msg BPAS rejected registration");
System.out.println("msg BPAS rejected registration");
}
} catch (final IOException e) {
Dialog.alert("msg IOException on register() " + e + " " + e.getMessage());
System.out.println("msg IOException on register() " + e + " " + e.getMessage());
}
}
}.start();
}
public static void close(Connection conn, InputStream is, OutputStream os) {
if (os != null) {
try {
os.close();
} catch (IOException e) {
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
if (conn != null) {
try {
conn.close();
} catch (IOException e) {
}
}
}
public static void errorDialog(final String message)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert(message);
}
});
}
private static String formRegisterRequest(String bpasUrl, String appId, String token) {
StringBuffer sb = new StringBuffer(bpasUrl);
sb.append("/mss/PD_subReg?");
sb.append("serviceid=").append(appId);
sb.append("&osversion=").append(DeviceInfo.getSoftwareVersion());
sb.append("&model=").append(DeviceInfo.getDeviceName());
if (token != null && token.length() > 0) {
sb.append("&").append(token);
}
return sb.toString();
}
}
Push Message Reader
public final class PushMessageReader {
//added by me
static String msgId;
// HTTP header property that carries unique push message ID
private static final String MESSAGE_ID_HEADER = "Push-Message-ID";
// content type constant for text messages
private static final String MESSAGE_TYPE_TEXT = "text";
// content type constant for image messages
private static final String MESSAGE_TYPE_IMAGE = "image";
private static final int MESSAGE_ID_HISTORY_LENGTH = 10;
private static String[] messageIdHistory = new String[MESSAGE_ID_HISTORY_LENGTH];
private static byte historyIndex;
private static byte[] buffer = new byte[15 * 1024];
private static byte[] imageBuffer = new byte[10 * 1024];
/**
* Utility classes should have a private constructor.
*/
public PushMessageReader() {
}
/**
* Reads the incoming push message from the given streams in the current thread and notifies controller to display the information.
*
* #param pis
* the pis
* #param conn
* the conn
*/
public static void process(PushInputStream pis, Connection conn) {
System.out.println("Reading incoming push message ...");
try {
HttpServerConnection httpConn;
if (conn instanceof HttpServerConnection) {
httpConn = (HttpServerConnection) conn;
} else {
throw new IllegalArgumentException("Can not process non-http pushes, expected HttpServerConnection but have "
+ conn.getClass().getName());
}
//changed here
msgId = httpConn.getHeaderField(MESSAGE_ID_HEADER);
String msgType = httpConn.getType();
String encoding = httpConn.getEncoding();
System.out.println("Message props: ID=" + msgId + ", Type=" + msgType + ", Encoding=" + encoding);
boolean accept = true;
if (!alreadyReceived(msgId)) {
byte[] binaryData;
if (msgId == null) {
msgId = String.valueOf(System.currentTimeMillis());
}
if (msgType == null) {
System.out.println("Message content type is NULL");
accept = false;
} else if (msgType.indexOf(MESSAGE_TYPE_TEXT) >= 0) {
// a string
int size = pis.read(buffer);
binaryData = new byte[size];
System.arraycopy(buffer, 0, binaryData, 0, size);
// TODO report message
} else if (msgType.indexOf(MESSAGE_TYPE_IMAGE) >= 0) {
// an image in binary or Base64 encoding
int size = pis.read(buffer);
if (encoding != null && encoding.equalsIgnoreCase("base64")) {
// image is in Base64 encoding, decode it
Base64InputStream bis = new Base64InputStream(new ByteArrayInputStream(buffer, 0, size));
size = bis.read(imageBuffer);
}
binaryData = new byte[size];
System.arraycopy(buffer, 0, binaryData, 0, size);
// TODO report message
} else {
System.out.println("Unknown message type " + msgType);
accept = false;
}
} else {
System.out.println("Received duplicate message with ID " + msgId);
}
pis.accept();
} catch (Exception e) {
System.out.println("Failed to process push message: " + e);
} finally {
Push_main.close(conn, pis, null);
}
}
/**
* Check whether the message with this ID has been already received.
*
* #param id
* the id
* #return true, if successful
*/
private static boolean alreadyReceived(String id) {
if (id == null) {
return false;
}
if (Arrays.contains(messageIdHistory, id)) {
return true;
}
// new ID, append to the history (oldest element will be eliminated)
messageIdHistory[historyIndex++] = id;
if (historyIndex >= MESSAGE_ID_HISTORY_LENGTH) {
historyIndex = 0;
}
return false;
}
}
BackGroundApplication
public class BackgroundApplication extends Application {
public BackgroundApplication() {
// TODO Auto-generated constructor stub
}
public void setupBackgroundApplication(){
MessageReadingThread messageReadingThread = new MessageReadingThread();
messageReadingThread.start();
}
private static class MessageReadingThread extends Thread {
private boolean running;
private ServerSocketConnection socket;
private HttpServerConnection conn;
private InputStream inputStream;
private PushInputStream pushInputStream;
public MessageReadingThread() {
this.running = true;
}
public void run() {
String url = "http://:" + "XXXXXX" ;//here after the + add your port number
url += ";deviceside=true;ConnectionType=mds-public";
if ((WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) && RadioInfo.areWAFsSupported(RadioInfo.WAF_WLAN)) {
url += ";interface=wifi";
}
try {
socket = (ServerSocketConnection) Connector.open( url );
} catch( IOException ex ) {
// can't open the port, probably taken by another application
onListenError( ex );
}
while( running ) {
try {
Object o = socket.acceptAndOpen();
conn = (HttpServerConnection) o;
inputStream = conn.openInputStream();
pushInputStream = new MDSPushInputStream( conn, inputStream );
PushMessageReader.process( pushInputStream, conn );
} catch( Exception e ) {
if( running ) {
// Logger.warn( "Failed to read push message, caused by " + e.getMessage() );
running = false;
}
} finally {
// PushUtils.close( conn, pushInputStream, null );
}
}
// Logger.log( "Stopped listening for push messages" );
}
public void stopRunning() {
running = false;
//PushUtils.close( socket, null, null );
}
private void onListenError( final Exception ex ) {
// Logger.warn( "Failed to open port, caused by " + ex );
System.out.println(ex);
}
}
}
What I have to add for the main screen to show in coming message ??
Thank you in advance.

IMAP Response limited size

I am working on an email client that will connect to Gmail mailbox and retrieve a specific email.
Now i can connect to my mailbox and can retrieve part of the emails not all of it and no matter how large is my buffer still i get only 1400 char from my email and then Null for the rest of the mail body.
You can find a screen shot for the email body in this link
http://www.elzouhery.com/Mail%20Snapshot.png
Thanks in Advance
EDIT
See below the Full Code
static void Main(string[] args)
{
TcpIMAP imap = ConnectToEmail();
Console.WriteLine("Total Messages " + imap.MailCount());
Console.WriteLine("Total Unread Messages " + imap.MailUnreadCount());
Console.WriteLine("******************************************************");
imap.SelectInbox();
StreamWriter writer = null;
int mailCount = imap.MailCount();
var mailSize = string.Empty;
var content = string.Empty;
var subject = string.Empty;
for (int i = 1; i < mailCount; i++)
{
try
{
writer = new StreamWriter(#"c:\Mails\" + i + ".txt", true);
content = imap.GetMessage(i).ToString();
writer.Write(content);
writer.Close();
}
catch(Exception ex)
{
writer.Write(content);
Console.Write(ex.Message);
writer.Close();
}
}
}
private static TcpIMAP ConnectToEmail()
{
string host = "imap.gmail.com";
string username = "************";
string password = "************";
TcpIMAP imap = new TcpIMAP();
imap.Connect(host, 993);
imap.AuthenticateUser(username, password);
return imap;
}
public static string GetMailSubject(string Header)
{
var headerLines = Header.Split(Environment.NewLine.ToCharArray());
foreach (var line in headerLines)
{
if (line.IndexOf("Subject") > -1)
{
return line.Replace("Subject: ", "");
}
}
return "";
}
/***************************************************/
class TcpIMAP
{
private TcpClient _imapClient;
private Stream _imapNs;
private StreamWriter _imapSw;
private StreamReader _imapSr;
public TcpIMAP()
{
}
public TcpIMAP(string hostname, int port)
{
InitializeConnection(hostname, port);
}
public void Connect(string hostname, int port)
{
InitializeConnection(hostname, port);
}
private void InitializeConnection(string hostname, int port)
{
try
{
_imapClient = new TcpClient(hostname, port);
System.Net.Security.SslStream sslstream = new System.Net.Security.SslStream(_imapClient.GetStream());
sslstream.AuthenticateAsClient("imap.gmail.com");
_imapNs = sslstream;
_imapSw = new StreamWriter(_imapNs);
_imapSr = new StreamReader(_imapNs);
Console.WriteLine("*** Connected ***");
Response();
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
}
}
public void AuthenticateUser(string username, string password)
{
_imapSw.WriteLine("$ LOGIN " + username + " " + password);
_imapSw.Flush();
Response();
}
public int MailCount()
{
_imapSw.WriteLine("$ STATUS INBOX (messages)");
_imapSw.Flush();
string res = Response();
Match m = Regex.Match(res, "[0-9]*[0-9]");
return Convert.ToInt32(m.ToString());
}
public int MailUnreadCount()
{
_imapSw.WriteLine("$ STATUS INBOX (unseen)");
_imapSw.Flush();
string res = Response();
Match m = Regex.Match(res, "[0-9]*[0-9]");
return Convert.ToInt32(m.ToString());
}
public string SelectInbox()
{
_imapSw.WriteLine("$ SELECT INBOX");
_imapSw.Flush();
return Response();
}
public object GetMessageHeaders(int index)
{
_imapSw.WriteLine("$ FETCH " + index + " (body[header.fields (from subject date)])");
_imapSw.Flush();
return Response();
}
public object GetMessage(int index)
{
_imapSw.WriteLine("$ FETCH " + index + " BODY.PEEK[]");
_imapSw.Flush();
return Response();
}
private string Response()
{
byte[] data = new byte[_imapClient.ReceiveBufferSize];
int ret = _imapNs.Read(data, 0, data.Length);
string output = Encoding.ASCII.GetString(data).TrimEnd().Replace("\0", "");
return output;
}
public void Disconnect()
{
_imapSw.WriteLine("$ LOGOUT");
_imapSw.Flush();
_imapClient.Close();
}
public string SendCommand(string command)
{
_imapSw.WriteLine("$ " + command);
_imapSw.Flush();
return Response();
}
It looks like you are using code from here, or similar:
http://www.codeproject.com/Articles/29594/How-to-Access-Emails-Using-the-IMAP-Protocol
That code as written is wrong and won't work for larger messages. The Response() call needs to loop over calls to .Read(), appending the results until the method returns 0 (which indicates there is no more data available.) Look at the documentation for NetworkStream.Read.
Also, you'd be much better off using an IMAP library (see Accessing Imap in C#).
You Just Have To Change Your Receive Buffer Size

blackberry sax XML parsing

i am very new in blackberry, now i am trying to do XML programming, using defaulthandler in sax parser blackberry.
any sample code, url or any advice highly appreciated.
thanks
Regards..
Find the sample code here. Cheers. ;-)
// IBMRssXMLHandler.java
//
// MSI Services, Inc.
// Frank Ableson
// 973.448.0070
// fableson#msiservices.com
// code free to use for any purpose, commercial or otherwise
package com.msi.ibm.rssreader;
import org.xml.sax.helpers.*;
import org.xml.sax.*;
import java.lang.StringBuffer;
import com.msi.ibm.rssreader.IBMRssStorage.*;
/**
*
*/
class IBMRssXMLHandler extends DefaultHandler {
StringBuffer sb = null;
IBMRssFeed _feed = null;
IBMRssItem item = null;
boolean bStarted = false;
IBMRssStorage rssStore = null;
IBMRssXMLHandler(IBMRssFeed feed) {
_feed = feed;
rssStore = new IBMRssStorage();
}
public void warning(SAXParseException e) {
System.err.println("warning: " + e.getMessage());
bStarted = false;
}
public void error(SAXParseException e) {
System.err.println("error: " + e.getMessage());
}
public void fatalError(SAXParseException e) {
System.err.println("fatalError: " + e.getMessage());
bStarted = false;
}
public void startDocument() throws SAXException {
System.out.println("startDocument");
}
public void endDocument() throws SAXException {
System.out.println("endDocument");
// we've concluded this document, safe to create the feed.
rssStore.closeStore();
}
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) throws SAXException {
System.out.println("startElement [" + localName + "]");// Attributes
// [" + atts.toString() + "]");
sb = new StringBuffer("");
if (localName.equals("item")) {
bStarted = true;
// new item, let's set up!
item = rssStore.createItem();
}
}
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
System.out.println("endElement [" + localName + "] value = ["
+ sb.toString() + "]");
if (bStarted == false)
return;
if (localName.equals("item")) {
// store this item!
item.setName(_feed.getName());
System.out.println("Storing item! [" + item.toString());
rssStore.addRecord(item);
}
if (localName.equals("title")) {
item.setTitle(sb.toString());
}
if (localName.equals("link")) {
item.setLink(sb.toString());
}
if (localName.equals("description")) {
item.setDescription(sb.toString());
}
if (localName.equals("category")) {
item.setCategory(sb.toString());
}
if (localName.equals("pubDate")) {
item.setPubDate(sb.toString());
}
sb = new StringBuffer("");
}
public void characters(char ch[], int start, int length) {
String theString = new String(ch, start, length);
System.out.println("characters [" + theString + "]");
sb.append(theString);
}
}

Resources