Pagination not working for a Lazy Loaded Data Table on First Loading - jpa

I am using JPA named queries for Loading a Lazy Loaded DataTable. and setting first and Max results as shown below.
Query query = entityManager.createNamedQuery("StudyplanCategory.findByStatusAndLimit");
int end=(start*pageNumber);
query.setParameter("status", status);
query.setParameter("start", start);
query.setParameter("end", end);
query.setMaxResults(end - start);
The load method is given below:
public List<StudyplanCategory> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters) {
List<StudyplanCategory> data = new ArrayList<StudyplanCategory>();
//System.out.println("Page First Value:"+first+"PageSize Value:"+pageSize);
datasource=categoryService.findDynaEditStudyPlan("NOT_USER_SPECIFIC",first,pageSize);
//filter
for(StudyplanCategory studyplanCategory : datasource) {
boolean match = true;
for(Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
try {
String filterProperty = it.next();
String filterValue = filters.get(filterProperty).toLowerCase();
String fieldValue = String.valueOf(studyplanCategory.getClass().getDeclaredField(filterProperty).get(studyplanCategory)).toLowerCase();
//System.out.println("fieldValue............."+fieldValue);
if(filterValue == null || fieldValue.startsWith(filterValue)) {
match = true;
}
else {
match = false;
break;
}
} catch(Exception e) {
match = false;
System.out.println("The Exception occured at"+e);
}
}
if(match) {
data.add(studyplanCategory);
}
}
//sort
if(sortField != null) {
Collections.sort(data, new LazySorter(sortField, sortOrder));
}
//rowCount
int dataSize = data.size();
this.setRowCount(dataSize);
//paginate
if(dataSize > pageSize) {
try {
return data.subList(first, first + pageSize);
}
catch(IndexOutOfBoundsException e) {
return data.subList(first, first + (dataSize % pageSize));
}
}
else {
return data;
}
}
But when the table is loaded Next Buttons are not active because I am loading only those data required to load the first page. How can I Solve this.

You need to fire another query which sets the total rowcount. Basically, in LazyDataModel#load():
public List<StudyplanCategory> load(...) {
setRowCount(studyplanCategoryService.count());
return studyplanCategoryService.list(...);
}
Unrelated to the concrete problem, you should actually be using Query#setFirstResult() to set the first record index.

Related

Getting WorkbookPart from row

I am writing and extension for OpenXML like shown in the sample. I would like to avoid having to pass the WorkbookPart as parameter. Is there any way to get the WorkbookPart directly from the row?
public static string GetCellTextValue(this Row row, WorkbookPart workbookPart, string column)
{
var cells = row.Elements<Cell>();
var cell = cells.Where(p => p.CellReference == column + row.RowIndex.ToString()).FirstOrDefault();
if (cell.DataType != null)
{
if (cell.DataType == CellValues.SharedString)
{
int id = -1;
if (Int32.TryParse(cell.InnerText, out id))
{
SharedStringItem item = workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(id);
if (item.Text != null)
{
return item.Text.Text;
}
else if (item.InnerText != null)
{
return item.InnerText;
}
else if (item.InnerXml != null)
{
return item.InnerXml;
}
}
}
}
return string.Empty;
}
Unfortunately, none of the strongly-typed classes of the Open XML SDK (e.g., Workbook, Worksheet, Row) have properties pointing back to the OpenXmlPart (e.g., WorkbookPart, WorksheetPart) in which they are contained or any other part related to their immediate container. Unless you amend your API in other ways, you will have to pass that WorkbookPart.

How can I get all post ids for a Facebook page?

I am using https://graph.facebook.com/v2.4/page_id/posts?fields=id to get all post ids from a Facebook page, but I am running into an infinite loop issue with pagination due to paging.next property always returning a url. It looks like the last page points to the first page. How would I know I have reached the end of results.
Here is a code example:
public static Dictionary<string,string> GetPagePostIds(string accessToken, string pageId)
{
Dictionary<string, string> postIds = new Dictionary<string, string>();
StringBuilder sb = new StringBuilder(graphAPIURL);
sb.Append("/").Append(pageId).Append("/posts/?access_token=").Append(accessToken);
sb.Append("&fields=id");
string url = sb.ToString();
int pages = 0;
int rows = 0;
while (url != null)
{
System.Net.WebRequest req = System.Net.WebRequest.Create(url);
System.Net.WebResponse response = req.GetResponse();
string json = null;
using (System.IO.StreamReader sr = new System.IO.StreamReader(response.GetResponseStream()))
{
json = sr.ReadToEnd();
Console.WriteLine(json);
}
if (json != null)
{
pages++;
Dictionary<string, dynamic> data = (Dictionary<string, dynamic>)Newtonsoft.Json.JsonConvert.DeserializeObject(json, typeof(Dictionary<string, dynamic>));
if (data.ContainsKey("data"))
{
Newtonsoft.Json.Linq.JArray a = (Newtonsoft.Json.Linq.JArray)data["data"];
foreach (Newtonsoft.Json.Linq.JObject o in a)
{
rows++;
postIds.Add(o["id"].ToString(), o["id"].ToString());
}
}
if (data.ContainsKey("paging"))
{
try
{
if (data["paging"]["next"] == url)
{
//otherwise we will be stuck in the infinite loop, as next url of the last page is not null
break;
}
//if next link is present, there are more pages available
url = null;
url = data["paging"]["next"];
}
catch (Exception)
{
}
}
}
}
return postIds;
}
You can break the loop, if you reach to the point, where you only receive empty results.
So you just simply extend your while loop with a second condition. Here is some simple pseudocode:
while (url != null && resultsOnPage) {
[...]
if (data.ContainsKey("data") && data['data'].Count > 0 ) {
[...]
} else {
resultsOnPage = false;
}
[...]
}
Just leave the rest as it is.

Add OR condition to query

I am wondering how it is possible to add an OR condition to the Envers criteria api:
public IEnumerable<Guid> GetHistory(object id, params string[] props)
{
var auditQuery = AuditReaderFactory.Get(Session).CreateQuery()
.ForRevisionsOfEntity(typeof(T), false, true);
foreach (var prop in props)
{
auditQuery.Add(AuditEntity.RelatedId(prop).Eq(id)); // <-- adds AND, while OR is required!
}
return auditQuery
.GetResultList<object[]>()
.Select(i => ((T)i[0]).ID)
.Distinct();
}
Use AuditEntity.Disjunction().
In your example, something like...
[..]
var disjunction = AuditEntity.Disjunction();
foreach (var prop in props)
{
disjunction.Add(AuditEntity.RelatedId(prop).Eq(id));
}
auditQuery.Add(disjunction);
[..]
I did like this in Java as #Roger mentioned above. (Just in case if anybody needs)
public List<Employee> getAuditHistory(Session session, int id, String property) {
AuditReader auditReader = AuditReaderFactory.get(session);
List<Employee> employeeHistory = new ArrayList<>();
if (auditReader != null) {
AuditQuery auditQuery = auditReader.createQuery().forRevisionsOfEntity(Employee.class, true, false)
.add(AuditEntity.property(ResultsConstants.Employee_ID).eq(id));
AuditDisjunction auditDisjunction = null;
if (property.equalsIgnoreCase("FULL_NAME")) {
auditDisjunction = AuditEntity.disjunction().add(AuditEntity.property("FIRST_NAME".toUpperCase()).hasChanged())
.add(AuditEntity.property("LAST_NAME".toUpperCase()).hasChanged());
} else {
auditQuery = auditQuery.add(AuditEntity.property(property.toUpperCase()).hasChanged());
}
auditQuery = auditQuery.addOrder(AuditEntity.property("MODIFIED_DATE").desc());
if(null != auditDisjunction){
auditQuery = auditQuery.add(auditDisjunction);
}
if (auditQuery != null) {
if (auditQuery.getResultList().isEmpty()) {
// Log here or throw it back to caller
}
employeeHistory.addAll(auditQuery.getResultList());
}
}
return employeeHistory;
}

Replace bookmark contents in Word using OpenXml

I can't find any working code examples for replacing bookmark contents. The code should be able to handle both the case replace empty bookmark and replace bookmark with preexisting content.
For example: If I have this text in a Word document:
"Between the following periods comes Bookmark1.. Between next periods comes Bookmark2.."
and I want to insert the text "BM1" between the first periods, and "BM2" between the next.
After the first replacement run, the replacements are inserted correctly.
But after the next replacement run, all of the text on the line after Bookmark1 gets deleted, and then the replacement for Bookmark2 gets inserted.
This is my c# code:
var doc = WordprocessingDocument.Open(#"file.docx", true);
public static Dictionary<string, wd.BookmarkStart> FindAllBookmarksInWordFile(WordprocessingDocument file)
{
var bookmarkMap = new Dictionary<String, wd.BookmarkStart>();
foreach (var headerPart in file.MainDocumentPart.HeaderParts)
{
foreach (var bookmarkStart in headerPart.RootElement.Descendants<wd.BookmarkStart>())
{
if (!bookmarkStart.Name.ToString().StartsWith("_"))
bookmarkMap[bookmarkStart.Name] = bookmarkStart;
}
}
foreach (var bookmarkStart in file.MainDocumentPart.RootElement.Descendants<wd.BookmarkStart>())
{
if (!bookmarkStart.Name.ToString().StartsWith("_"))
bookmarkMap[bookmarkStart.Name] = bookmarkStart;
}
return bookmarkMap;
}
/*extension methods*/
public static bool IsEndBookmark(this OpenXmlElement element, BookmarkStart startBookmark)
{
return IsEndBookmark(element as BookmarkEnd, startBookmark);
}
public static bool IsEndBookmark(this BookmarkEnd endBookmark, BookmarkStart startBookmark)
{
if (endBookmark == null)
return false;
return endBookmark.Id.Value == startBookmark.Id.Value;
}
/* end of extension methods */
public static void SetText(BookmarkStart bookmark, string value)
{
RemoveAllTexts(bookmark);
bookmark.Parent.InsertAfter(new Run(new Text(value)), bookmark);
}
private static void RemoveAllTexts(BookmarkStart bookmark)
{
if (bookmark.ColumnFirst != null) return;
var nextSibling = bookmark.NextSibling();
while (nextSibling != null)
{
if (nextSibling.IsEndBookmark(bookmark) || nextSibling.GetType() == typeof(BookmarkStart))
break;
foreach (var item in nextSibling.Descendants<Text>())
{
item.Remove();
}
nextSibling = nextSibling.NextSibling();
}
}
I have looked around a long time for a general solution.
Any help is appreciated! -Victor
Maybe this can help you
first:delete bookmarkContent
second:find bookMark => insert value
public static void InsertTest1(WordprocessingDocument doc, string bookMark, string txt)
{
try
{
RemoveBookMarkContent(doc, bookMark);
MainDocumentPart mainPart = doc.MainDocumentPart;
BookmarkStart bmStart = findBookMarkStart(doc, bookMark);
if (bmStart == null)
{
return;
}
Run run = new Run(new Text(txt));
bmStart.Parent.InsertAfter<Run>(run, bmStart);
}
catch (Exception c)
{
//not Exception
}
}
public static void RemoveBookMarkContent(WordprocessingDocument doc, string bmName)
{
BookmarkStart bmStart = findBookMarkStart(doc, bmName);
BookmarkEnd bmEnd = findBookMarkEnd(doc, bmStart.Id);
while (true)
{
var run = bmStart.NextSibling();
if (run == null)
{
break;
}
if (run is BookmarkEnd && (BookmarkEnd)run == bmEnd)
{
break;
}
run.Remove();
}
}
private static BookmarkStart findBookMarkStart(WordprocessingDocument doc, string bmName)
{
foreach (var footer in doc.MainDocumentPart.FooterParts)
{
foreach (var inst in footer.Footer.Descendants<BookmarkStart>())
{
if (inst.Name == bmName)
{
return inst;
}
}
}
foreach (var header in doc.MainDocumentPart.HeaderParts)
{
foreach (var inst in header.Header.Descendants<BookmarkStart>())
{
if (inst.Name == bmName)
{
return inst;
}
}
}
foreach (var inst in doc.MainDocumentPart.RootElement.Descendants<BookmarkStart>())
{
if (inst is BookmarkStart)
{
if (inst.Name == bmName)
{
return inst;
}
}
}
return null;
}
This code works but not when the bookmark is placed within a field/formtext (a gray box).
private static void SetNewContents(wd.BookmarkStart bookmarkStart, string text)
{
if (bookmarkStart.ColumnFirst != null) return;
var itemsToRemove = new List<OpenXmlElement>();
var nextSibling = bookmarkStart.NextSibling();
while (nextSibling != null)
{
if (IsEndBookmark(nextSibling, bookmarkStart))
break;
if (nextSibling is wd.Run)
itemsToRemove.Add(nextSibling);
nextSibling = nextSibling.NextSibling();
}
foreach (var item in itemsToRemove)
{
item.RemoveAllChildren();
item.Remove();
}
bookmarkStart.Parent.InsertAfter(new wd.Run(new wd.Text(text)), bookmarkStart);
}

Change label's text with using property

I am working on my C# ADO.NET app. I have connected my SQL Server database with C# app, and I can perform simple CRUD operations. I want to make that my app open my reminder form when someone in my database have birthday, so I made my query and all persons who have birthday on today's day are in my query, and with using property from my reminder form I change label's text with name and surname of person who have birthday. Now I just dont know how to change next label's text when more than one person have birthday in my query... I dont know how to get next element in my foreach loop...
Here is my code:
Form2 forma = new Form2();
TBirthDayEntities today_born = new TBirthDayEntities();
public Form1()
{
InitializeComponent();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 1000;
timer1.Enabled = true;
timer1.Start();
}
private Boolean provjera_rodj()
{
Boolean flag = false;
int cnt = 0;
IQueryable<TBD> query;
using (var data = new TBirthDayEntities())
{
query = (from x in data.TBD
where x.BirthDay.Day == System.DateTime.Now.Day && x.BirthDay.Month == System.DateTime.Now.Month
select x);
foreach (var x in query)
{
today_born.TBD.Add(x);
cnt += 1;
flag = true;
}
}
switch (cnt)
{
case 1:
{
foreach (var x in today_born.TBD)
{
forma.p_label2 = x.FName + " " + x.LName;
}
break;
}
case 2:
{
foreach (var x in today_born.TBD)
{
forma.p_label2 = x.FName + x.LName;
forma.p_label3 = x.FName + x.LName; //wrong
}
break;
}
}
return flag;
}
private void timer1_Tick(object sender, EventArgs e)
{
Boolean flag = provjera_rodj();
if (flag == true)
{
forma.Show();
timer1.Stop();
}
}
switch (cnt)
{
case 1:
case 2:
{
var lstLabel = new List<Label>()
{
forma.p_label2
, forma.p_label3
};
for(int i = 0; i < today_born.TBD.Count; i++)
{
var x in today_born.TBD[i];
lstLabel[x].Text = x.FName + x.LName;
}
break;
}
}
EDIT:
switch (cnt)
{
case 1:
case 2:
{
var lstLabel = new List<Action<string>>()
{
new Action<string>(s =>forma.p_label2 = s)
, new Action<string>(s =>forma.p_label3 = s)
};
for(int i = 0; i < today_born.TBD.Count; i++)
{
var x = today_born.TBD[i];
lstLabel[x](x.FName + x.LName);
}
break;
}
}