How to compare two JSONArray and find differencer when JSONArrays itself contain JSONObject which in turn contain JSONArray - comparison

I am new to this forum.I am trying to compare two directory structure one that is on remote and another one that is on local.
Currently what I am doing is based on certain things I am making a JSONArray of directury structure from server side(remote) . Same way I am making a JSONArray of directory structure of client side. Now I want to compare those two JSONArray and get the difference between them.
Also I want to maintain the level of directory structure also . Meaning that in the resulting JSONArray the difference should be at proper level which I can may directly with directory.
Please guide me If I make any mistake here as I am new to the forum.
I have tried below code.
public static boolean jsonObjsAreEqual (JSONObject js1, JSONObject js2) throws JSONException {
if (js1 == null || js2 == null) {
System.out.println(METHOD+"js1 or js2 null");
return (js1 == js2);
}
List<String> l1 = Arrays.asList(JSONObject.getNames(js1));
Collections.sort(l1);
Collections.reverse(l1);
List<String> l2 = Arrays.asList(JSONObject.getNames(js2));
Collections.sort(l2);
Collections.reverse(l2);
if (!l1.equals(l2)) {
return false;
}
for (String key : l1) {
Object val1 = js1.get(key);
Object val2 = js2.get(key);
if (val1 instanceof JSONObject) {
if (!(val2 instanceof JSONObject)) {
return false;
}
if (jsonObjsAreEqual((JSONObject)val1, (JSONObject)val2)) {
return true;
}else{
return false;
}
}
if (val1 instanceof JSONArray) {
if (!(val2 instanceof JSONArray)) {
return false;
}
JSONArray arr1=JsonSorter.sortJsonByKey((JSONArray) val1, "name");
JSONArray arr2=JsonSorter.sortJsonByKey((JSONArray) val2, "name");
int flag=0;
int count=0;
int []arr=new int[100];
for(int k=0;k<arr1.length();k++){
flag=0;
for(int l=0;l<arr2.length();l++){
boolean returnval=jsonObjsAreEqual((JSONObject)arr1.get(k), (JSONObject)arr2.get(l));
if (returnval) {
flag=1;
break;
}
}
if(flag==0){
return false;
}
}
}else{
if (val1 == null) {
if (val2 != null) {
return false;
}
} else if (!val1.equals(val2)) {
return false;
}
}
}
return true;
}
For example I am using below JSONs as arguments;
js1={"JSArray":[{"folder":1,"name":"My Music","innerJSON":[]},{"folder":1,"name":"My Videos","innerJSON":[]},{"folder":1,"name":"RW-By-10-No-New-Folder","innerJSON":[]},{"folder":1,"name":"RW-By-11-plus-New-Folder","innerJSON":[{"folder":1,"name":"ab25249asset.001829.PNG","innerJSON":[]}]},{"folder":1,"name":"My Documents","innerJSON":[]},{"folder":1,"name":"My Tunes","innerJSON":[]},{"folder":1,"name":"Music","innerJSON":[{"folder":1,"name":"ROnly-SubFolder-to-user10","innerJSON":[]}]},{"folder":1,"name":"kamal","innerJSON":[]},{"folder":1,"name":"zxcvb","innerJSON":[]},{"folder":1,"name":"My Pictures","innerJSON":[]},{"folder":1,"name":"abc","innerJSON":[]}]}
js2={"JSArray":[{"folder":1,"name":"Music","innerJSON":[{"folder":0,"name":"Track_12_[1].mp3"},{"folder":1,"name":"ROnly-SubFolder-to-user10","innerJSON":[]},{"folder":0,"name":"08_Track_8.wma"}]},{"folder":1,"name":"My Documents","innerJSON":[{"folder":0,"name":"temp.ico"},{"folder":0,"name":"logo-mdpi.png"}]},{"folder":1,"name":"My Music","innerJSON":[]},{"folder":1,"name":"My Pictures","innerJSON":[{"folder":0,"name":"ab16807asset.JPG"}]},{"folder":1,"name":"My Tunes","innerJSON":[{"folder":0,"name":"dharamshala.jpg"},{"folder":0,"name":"Logo.gif"}]},{"folder":1,"name":"My Videos","innerJSON":[]},{"folder":1,"name":"RW-By-10-No-New-Folder","innerJSON":[]},{"folder":1,"name":"RW-By-11-plus-New-Folder","innerJSON":[{"folder":1,"name":"ab25249asset.001829.PNG","innerJSON":[]}]}]}
Tell me if anything more is needed. I want diff of this type of JSONs. They represent directory structure and file inside them so there can be n level of folder.so need to keep that thing in mind.
In a JSON an "innerJSON" key represents a folder inside a folder upto n level from that folder.
Thanks

Related

Android studio with java

I have trouble getting data here from database there isn't data,
Data is not displayed outside of the method.
Could you please help me?
List<Person> Refresh() {
Person p = new Person();
ParseQuery <ParseObject> query = ParseQuery.getQuery(NAME_DATABASE);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> scoreList , ParseException e) {
if (e == null) {
for (int i = 0; i < scoreList.size(); i++){
p.setId(scoreList.get(i).getInt(Key.ID));
p.setName(scoreList.get(i).getString(Key.NAME));
p.setAge(scoreList.get(i).getString(Key.AGE)); p.setDate_start(scoreList.get(i).getString(Key.DATE_START));
p.setMonth_number(scoreList.get(i).getString(Key.MONTH_NUMBER));
p.setPropriety(scoreList.get(i).getString(Key.PROPRIETY));
p.setPrice(scoreList.get(i).getString(Key.PRICE));
p.setGender(scoreList.get(i).getString(Key.GENDER));
persons.add(p); //there is find data
}
}
else {
Log.d("score", "Error: " + e.getMessage());
}
}
});
return persons; //here there isn't data (size=0)
}
The answer is simple really. You are returning persons outside the findInBackground() method.
else{
Log.d("score", "Error: " + e.getMessage());
}
//Return here after the else statement
return persons;
}
Note : you might want to make persons a global variable or else android studio will tell you to declare it as a final variable.

Doubly linked list java remove

I have a problem when deleting many nodes.
I can delete them if I select nodes like this:
But if I do something like this, I cannot delete them:
My Code:
public boolean remove(ProductNode<E> data) {
if (isEmpty()) {
throw new NoSuchElementException();
}
for (ProductNode<E> current = this.head; current != null; current = current.next) {
ProductNode<E> pre = current.prev;
ProductNode<E> next = current.next;
if (data != null) {
if (current.data.equals(data.data)) {
if (pre == null) {
head = next;
current.next = null;
} else {
if (next != null) {
next.prev = pre;
}
}
if (next == null) {
pre.next = null;
current.prev = null;
tail = pre;
} else {
if (pre != null) {
pre.next = next;
}
}
}
}
}
size--;
return false;
}
Search node
public ProductNode<E> search(E data) {
for (ProductNode<E> current = this.head; current != null; current = current.next) {
if (current.data.equals(data)) {
return current;
}
}
return null;
}
Remove
public void remove(E e) {
remove(search(e));
}
Delete:
for(Tab_Product p : remove_list){
List_Products.list_products.remove(p);
}
Your remove function (ProductNode data), is a bit complicated and may be affecting your code's ability to delete multiple nodes. In the case of this remove function you do not need traverse the whole data set. If you already have a reference to the node you can just directly modify the list with it.
public boolean remove(ProductNode<E> data) {
if (isEmpty()) {
throw new NoSuchElementException();
}
ProductNode<E> pre = data.prev;
ProductNode<E> next = data.next;
//First remove the nodes references to its neighbors.
data.prev = null;
data.next = null;
// Now check the neighbors and update their references
// to remove all references to the deleted node.
if (pre != null) pre.next = next;
if (next != null) next.prev = pre;
if (data == head) { //This checks the actual memory address.
head = next;
}
size--;
}
Since you already have the ProductNode, you do not need to search the list. your search() function is already doing that for you. since you already have the node you just need to make its references to its neighbors null then you just have to access the neighbors (if there are any) and make their old references skip over the deleted node.
I noticed a few reference errors where a deleted node was not getting completely removed from the list but i will not mention them because this delete function is rather complicated. Try simplifying the delete function and then see what your results are.
It also might be helpful if you show us the structure of the List_Products object.
Additionally you should verify that the data you select in the UI is getting passed correctly. This could be a UI bug.

Reflection + Entity Framework to update data in MVC app

I've got a complex form on a page that is bound to a POCO representing a rather complex entity. One of the requirements is that, on blur, I update the database.
I'm currently passing the property (as key), value, and CampaignId via ajax. The key might look something like: Campaign.FanSettings.SocialSharing.FacebookLinkText.
I am using the code below, and getting "close". My final propertyToSet is the FacebookLinkText is not being set, because my object source is of type Entities.Campaign, while my object value is simply a string. I understand these need to be the same type, but I don't understand how to do that. Two questions:
How do I modify the code below to be able to execute the propertyToSet.SetValue method
Since I'm casting this to an object, I don't see how this would actually update my entity, so when I call SaveChanges it updates appropriately. What am I missing?
Thanks!
Code:
public void UpdateCampaign(int id, string key, string value)
{
using (var context = new BetaEntities())
{
var camp = context.Campaigns.Where(e => e.Id == id).Single();
SetProperty(camp, key,value);
}
}
public void SetProperty(object source, string property, object value)
{
string[] bits = property.Split('.');
for (int i = 0; i < bits.Length - 1; i++)
{
PropertyInfo prop = source.GetType().GetProperty(bits[i]);
source = prop.GetValue(source, null);
}
PropertyInfo propertyToSet = null;
if (source is IEnumerable)
{
foreach (object o in (source as IEnumerable))
{
propertyToSet = o.GetType().GetProperty(bits[bits.Length - 1]);
break;
}
}
else
{
propertyToSet = source.GetType().GetProperty(bits[bits.Length - 1]);
}
propertyToSet.SetValue(source, value, null);
}
Solved.
public void UpdateCampaign(int id, string key, string value)
{
using (var context = new BetaEntities())
{
var camp = context.Campaigns.Where(e => e.Id == id).Single();
SetProperty(camp, key, value);
context.SaveChanges()
}
}
public void SetProperty(object source, string property, object value)
{
string[] bits = property.Split('.');
for (int i = 0; i < bits.Length - 1; i++)
{
PropertyInfo prop = source.GetType().GetProperty(bits[i]);
source = prop.GetValue(source, null);
}
PropertyInfo propertyToSet = null;
if (source is IEnumerable)
{
foreach (object o in (source as IEnumerable))
{
propertyToSet = o.GetType().GetProperty(bits[bits.Length - 1]);
propertyToSet.SetValue(o, value,null);
break;
}
}
else
{
propertyToSet = source.GetType().GetProperty(bits[bits.Length - 1]);
propertyToSet.SetValue(source, value, null);
}
}

Accessing a Service from within an XNA Content Pipeline Extension

I need to allow my content pipeline extension to use a pattern similar to a factory. I start with a dictionary type:
public delegate T Mapper<T>(MapFactory<T> mf, XElement d);
public class MapFactory<T>
{
Dictionary<string, Mapper<T>> map = new Dictionary<string, Mapper<T>>();
public void Add(string s, Mapper<T> m)
{
map.Add(s, m);
}
public T Get(XElement xe)
{
if (xe == null) throw new ArgumentNullException(
"Invalid document");
var key = xe.Name.ToString();
if (!map.ContainsKey(key)) throw new ArgumentException(
key + " is not a valid key.");
return map[key](this, xe);
}
public IEnumerable<T> GetAll(XElement xe)
{
if (xe == null) throw new ArgumentNullException(
"Invalid document");
foreach (var e in xe.Elements())
{
var val = e.Name.ToString();
if (map.ContainsKey(val))
yield return map[val](this, e);
}
}
}
Here is one type of object I want to store:
public partial class TestContent
{
// Test type
public string title;
// Once test if true
public bool once;
// Parameters
public Dictionary<string, object> args;
public TestContent()
{
title = string.Empty;
args = new Dictionary<string, object>();
}
public TestContent(XElement xe)
{
title = xe.Name.ToString();
args = new Dictionary<string, object>();
xe.ParseAttribute("once", once);
}
}
XElement.ParseAttribute is an extension method that works as one might expect. It returns a boolean that is true if successful.
The issue is that I have many different types of tests, each of which populates the object in a way unique to the specific test. The element name is the key to MapFactory's dictionary. This type of test, while atypical, illustrates my problem.
public class LogicTest : TestBase
{
string opkey;
List<TestBase> items;
public override bool Test(BehaviorArgs args)
{
if (items == null) return false;
if (items.Count == 0) return false;
bool result = items[0].Test(args);
for (int i = 1; i < items.Count; i++)
{
bool other = items[i].Test(args);
switch (opkey)
{
case "And":
result &= other;
if (!result) return false;
break;
case "Or":
result |= other;
if (result) return true;
break;
case "Xor":
result ^= other;
break;
case "Nand":
result = !(result & other);
break;
case "Nor":
result = !(result | other);
break;
default:
result = false;
break;
}
}
return result;
}
public static TestContent Build(MapFactory<TestContent> mf, XElement xe)
{
var result = new TestContent(xe);
string key = "Or";
xe.GetAttribute("op", key);
result.args.Add("key", key);
var names = mf.GetAll(xe).ToList();
if (names.Count() < 2) throw new ArgumentException(
"LogicTest requires at least two entries.");
result.args.Add("items", names);
return result;
}
}
My actual code is more involved as the factory has two dictionaries, one that turns an XElement into a content type to write and another used by the reader to create the actual game objects.
I need to build these factories in code because they map strings to delegates. I have a service that contains several of these factories. The mission is to make these factory classes available to a content processor. Neither the processor itself nor the context it uses as a parameter have any known hooks to attach an IServiceProvider or equivalent.
Any ideas?
I needed to create a data structure essentially on demand without access to the underlying classes as they came from a third party, in this case XNA Game Studio. There is only one way to do this I know of... statically.
public class TestMap : Dictionary<string, string>
{
private static readonly TestMap map = new TestMap();
private TestMap()
{
Add("Logic", "LogicProcessor");
Add("Sequence", "SequenceProcessor");
Add("Key", "KeyProcessor");
Add("KeyVector", "KeyVectorProcessor");
Add("Mouse", "MouseProcessor");
Add("Pad", "PadProcessor");
Add("PadVector", "PadVectorProcessor");
}
public static TestMap Map
{
get { return map; }
}
public IEnumerable<TestContent> Collect(XElement xe, ContentProcessorContext cpc)
{
foreach(var e in xe.Elements().Where(e => ContainsKey(e.Name.ToString())))
{
yield return cpc.Convert<XElement, TestContent>(
e, this[e.Name.ToString()]);
}
}
}
I took this a step further and created content processors for each type of TestBase:
/// <summary>
/// Turns an imported XElement into a TestContent used for a LogicTest
/// </summary>
[ContentProcessor(DisplayName = "LogicProcessor")]
public class LogicProcessor : ContentProcessor<XElement, TestContent>
{
public override TestContent Process(XElement input, ContentProcessorContext context)
{
var result = new TestContent(input);
string key = "Or";
input.GetAttribute("op", key);
result.args.Add("key", key);
var items = TestMap.Map.Collect(input, context);
if (items.Count() < 2) throw new ArgumentNullException(
"LogicProcessor requires at least two items.");
result.args.Add("items", items);
return result;
}
}
Any attempt to reference or access the class such as calling TestMap.Collect will generate the underlying static class if needed. I basically moved the code from LogicTest.Build to the processor. I also carry out any needed validation in the processor.
When I get to reading these classes I will have the ContentService to help.

how to set a BasicEditField to accept dotted decimal numbers

I have added a BasicEditField to a GridFieldManager. When I test it, it allows input values like 11.11.11. How can I make my BasicEditField accept only correct double numbers, like 101.1 or 123.123. That is, allow only one decimal point.
gfm = new GridFieldManager(1, 2, 0);
gfm.add(new LabelField(" Enter value : "));
bef = new BasicEditField(BasicEditField.NO_NEWLINE|BasicEditField.FILTER_REAL_NUMERIC);
bef.setFilter(TextFilter.get(NumericTextFilter.REAL_NUMERIC));
bef.setFilter(TextFilter.get(TextFilter.REAL_NUMERIC));
bef.setText("1");
bef.setMaxSize(8);
gfm.add(bef);
add(gfm);
i had tried everything that i can. but the problem is yet in my app. can anyone give me a proper way to design a input field tha accepts decimal numbers?
Please add all the objects into the mainScreen with add(field);.
and then trying to get value of that fields.
now in your code put
String s = bef.getText();
Dialog.alert(s);
after
add(gfm);
and
To accept number like 1.1111.
then add
BasicEditField.FILTER_REAL_NUMERIC
in BasicEditFieldConstructor.
Now i think you got your solution.
finally i got the solution for a forum(forgot to copy the link)..
here it is...
inside my class i put the variables...
private int maxIntDigits = -1;
private int maxFractDigits = -1;
private String old;
i had added a BasicEditField, bef..
bef = new BasicEditField("","1");
bef.setMaxSize(8);
bef.setChangeListener(this);
add(bef);
And then in its fieldChanged().
public void fieldChanged(Field field, int context)
{
if(field==bef)
{
String str = bef.getText();
if(str.equals(""))
{
old = "";
//return;
}
if(str.indexOf('.') == str.lastIndexOf('.'))
{
if(str.indexOf('-') >= 0)
{
bef.setText(old);
}
if(validateIntPart(str) && validateFractPart(str))
{
old = str;
//return;
}
else
{
bef.setText(old);
}
}
else
{
bef.setText(old);
//return;
}
}
}
and then two functions in it...
private boolean validateIntPart(String str) {
if(maxIntDigits == -1) {
return true; //no limit has been set
}
int p = str.indexOf('.');
if(p == -1) {
p = str.length();
}
int digits = str.substring(0, p).length();
if(digits > maxIntDigits) {
return false;
} else {
return true;
}
}
private boolean validateFractPart(String str) {
if(maxFractDigits == -1) {
return true; //no limit has been set
}
int p = str.indexOf('.');
if(p == -1) {
return true; //if no '.' found then the fract part can't be too big
}
int digits = str.substring(p + 1, str.length()).length();
if(digits > maxFractDigits) {
return false;
} else {
return true;
}
}

Resources