Pass a String[] as parameter not working - java

I have this class now working fine, but I've been struggling with it many hours to end of changing in it on a different logic from my first approach.
public class MyClass {
public static MyClass tablas;
public static String[] GROUPS;
public static String[] ESTATUS
public static String[] CLIENTS;
public void init(){
this.tablas = new MyClass();
this.setGroups();
CLIENTS=this.setAny("/servlets/CLIENTS","page_rows","nombre");
ESTADO_PEDIDO= new String[]{"str1","str2","str3","str4","str5"};
}
private String[] setAny(String sevlet,String bigNode,String smallNode){
String[] ret=null;
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("operation", "4");
parameters.put("avance", "0");
InputStream is = Connection.con.processRequest("GET", sevlet, parameters);
Document dom = null;
try {
dom = UtilesDom.parseXML(is);
NodeList lines = dom.getElementsByTagName(bigNode);
Element el = (Element)lines.item(0);
NodeList nlist = el.getElementsByTagName(smallNode);
ret = new String[nlist.getLength()];
for (int i = 0; i < nlist.getLength(); i++) {
ret[i] = nlist.item(i).getTextContent();
}
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
return ret;
}
private void setGroups(){
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("operation", "4");
parameters.put("avance", "0");
InputStream is = Connection.con.processRequest("GET", "/servlets/GROUPS_CLIENTS", parameters);
Document dom = null;
try {
dom = UtilesDom.parseXML(is);
NodeList lines = dom.getElementsByTagName("lines");
Element el = (Element)lines.item(0);
NodeList nlist = el.getElementsByTagName("GROUP");
GROUPS = new String[nlist.getLength()];
for (int i = 0; i < nlist.getLength(); i++) {
GROUPS[i] = nlist.item(i).getTextContent();
}
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
As you can see there is two similar methods setGroups and setAny these are used to fill the Strings[] on top.setGroups was my original method but when I needed different Strings[] thought that a "less hard-coded" and most flexible method would be nice, so I tried this:
private void setAny(String sevlet,String bigNode,String smallNode,String[] which){
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("operation", "4");
parameters.put("avance", "0");
InputStream is = Connection.con.processRequest("GET", sevlet, parameters);
Document dom = null;
try {
dom = UtilesDom.parseXML(is);
NodeList lines = dom.getElementsByTagName(bigNode);
Element el = (Element)lines.item(0);
NodeList nlist = el.getElementsByTagName(smallNode);
which = new String[nlist.getLength()];
for (int i = 0; i < nlist.getLength(); i++) {
which[i] = nlist.item(i).getTextContent();
System.out.println(which[i]);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
Using the call like:
this.setAny("/principal/Clientes","page_rows","nombre",CLIENTS);
also
this.setAny("/principal/Clientes","page_rows","nombre",this.CLIENTS);
and
this.setAny("/principal/Clientes","page_rows","nombre",this.tablas.CLIENTS);
The problem with it is that the String[] passed as parameter (aka CLIENTS) just stay null , and yes at the en of the for loop its populated properly and the console shows what it supposed to.So the question is:
Why String[] CLIENTS cant be populated when passed as a parameter,and just stay as null?
PD: As you may notice English is not my language so please suggest any grammar/redaction/spelling... corrections.

Okay so I'm gonna pretend your parameter is a String[] and not a String here.
Your problem is that once you create a new array with the new operator, your reference changes to that new array. So the old one isn't affected.
So yes, you create a new array and fill it properly, but sadly it won't be CLIENTS. If you do it like in your first example and return the String Array to save it, that will work.
Another option would be to create a static HashMap of String Arrays instead of just three different static String Arrays. Then you can pass the key to the method and just replace the Array at the given key. That way you don't need to work with a return value.

It is null at runtime and the compile dont know about that. It strictly checks the type at compile time it self.
setAny(String sevlet,String bigNode,String smallNode)
That last parameter is a String and you are trying to pass an Array. Probably you need to change the signature as
setAny(String sevlet,String bigNode,String smallNode[])
So that it receives an array.

Related

How to put in array the children of the children

private static JSONArray getListOfChildPagesAsJSON(Page page) {
JSONArray pagesArray = new JSONArray();
try {
Iterator<Page> childPages = page.listChildren();
while (childPages.hasNext()) {
Page childPage = childPages.next();
JSONObject pageObject = new JSONObject();
pageObject.put(childPage.getTitle(), childPage.getPath());
pagesArray.put(pageObject);
}
} catch (JSONException e) {
LOG.error(e.getMessage(), e);
}
return pagesArray;
}
So that not only the children of the transferred page put into array, but also the children of the children.
This is a classical case for recursion, like reading directoy tree on filesystem. My suggestion is as follows:
First step: Change the scope of variable JSONArray pagesArray = new JSONArray(); from function to class scope.
public MyClass {
private JSONArray pagesArray = new JSONArray();
...
}
Step two: Change return value to void and the modifier of your function by removing static.
private void getListOfChildPagesAsJSON(Page page) { }
Step three add the missing recusion to your its body.
//JSONArray pagesArray = new JSONArray();
try {
Iterator<Page> childPages = page.listChildren();
while (childPages.hasNext()) {
Page childPage = childPages.next();
JSONObject pageObject = new JSONObject();
pageObject.put(childPage.getTitle(), childPage.getPath());
//Add the created object to your array which is class variable
this.pagesArray.put(pageObject);
//--Check for each single page for child pages again
Iterator<Page> childPagesOfChildpage = childPage.listChildren();
while (childPagesOfChildpage.hasNext()) {
getListOfChildPagesAsJSON(childPagesOfChildpage.next());
}
//--
}
} catch (JSONException e) {
LOG.error(e.getMessage(), e);
}
Note: The check childPage.hasChild() does not work here, because the node jcr:content is a valid child of passed page.

Java code keeps overriding old elements in list to the new element

I'm having trouble with my code here.
I have a list of recipe objects taken from a json file, but whenever I try to put in a new recipe object, it makes all the previous objects into this new object. This means I would have a list of 8 (or whatever) of the same recipe - i.e. the last object in the json file.
Does anyone know what I'm doing wrong here?
Hope I have provided enough material.
private void fillItemsDB(String filename) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(sContext.getAssets().open(filename)));
String jsonString = reader.readLine();
JSONArray recipeA = new JSONArray(jsonString);
for (int i = 0; i < recipeA.length(); i++) {
RecipeItem ri = new RecipeItem();
String rName = recipeA.getJSONObject(i).getString("gname");
String rGuide = recipeA.getJSONObject(i).getString("gguide");
ri.setRecipeName(rName);
ri.setRecipeGuide(rGuide);
list.add(ri); //arraylist
addRecipe(ri);
}
} catch (JSONException je) {
Log.e(TAG, "Failed to parse JSON", je);
} catch (IOException e) {
Log.e(TAG, "Failed to read file", e);
}
this.setChanged();
notifyObservers();
}
public void addRecipe(RecipeItem recipeItem) {
ContentValues values = getContentValues(recipeItem);
mDatabase.insert(RecipeDbSchema.ItemTable.NAME, null, values);
this.setChanged();
notifyObservers();
}
private static ContentValues getContentValues(RecipeItem recipe) {
ContentValues values = new ContentValues();
values.put(RecipeDbSchema.ItemTable.Cols.RecipeName, recipe.getRecipeName());
values.put(RecipeDbSchema.ItemTable.Cols.RecipeGuide, recipe.getRecipeGuide());
return values;
}

Java reference inner class attributes through outer class object

I'm having the problem my title describes. I have an outer class called GAINEntities with an inner class in it called Entities. My goal is to reference the attributes of the inner class through objects of the outer class. I have a function readGainEntities(String inputUrl) which returns a Vector. Thus, in my method i call readGainEntities method and set its content to a new Vector
Example Code:
protected static Vector<LinkedHashTreeMap> getGainEntities(String inputUrl) {
URL url = null;
try {
url = new URL(inputUrl);
} catch (MalformedURLException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
URLConnection yc = null;
try {
yc = url.openConnection();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
String userpass = "" + ":" + "";
String basicAuth = "Basic "
+ new String(new Base64().encode(userpass.getBytes()));
yc.setRequestProperty("Authorization", basicAuth);
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Gson gson = new Gson();
List<LinkedHashTreeMap> items = null;
try {
items = gson.fromJson(in.readLine(),
new TypeToken<List<LinkedHashTreeMap>>() {
}.getType());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Vector<LinkedHashTreeMap> sessions = new Vector<LinkedHashTreeMap>();
for (int i = 0; i < items.size(); i++) {
sessions.add(items.get(i));
}
return sessions;
}
public static Vector<GAINEntities> readGainentities(String inputUrl) {
Vector<GAINEntities> exp = new Vector<GAINEntities>();
Vector<LinkedHashTreeMap> sessions = getGainEntities(inputUrl);
Iterator it = sessions.iterator();
while (it.hasNext()) {
LinkedHashTreeMap next = (LinkedHashTreeMap) it.next();
GAINEntities input = new GAINEntities();
input.setObjectID((String) next.get("objectId"));
input.setSubobjectID((String) next.get("subobjectId"));
LinkedHashTreeMap<String, String> lhmt = (LinkedHashTreeMap<String, String>) next
.get("attributes");
data.GAINEntities.Attributes atts = input.new Attributes();
atts.setAttributeStart(Double.parseDouble(String.valueOf(lhmt
.get("start"))));
atts.setAttributeEnd(Double.parseDouble(String.valueOf(lhmt
.get("end"))));
input.setAttributes(atts);
input.setAccountID((String) next.get("accountId"));
input.setID((String) next.get("_id"));
input.setV(Double.parseDouble(String.valueOf(next.get("__v"))));
ArrayList<LinkedHashTreeMap<String, String>> al = (ArrayList<LinkedHashTreeMap<String, String>>) next
.get("entities");
ArrayList<Entities> ents = new ArrayList<Entities>();
for (int i = 0; i < al.size(); i++) {
ents.add(input.new Entities(al.get(i).get("ntype"), al.get(i)
.get("source"), al.get(i).get("lod"), al.get(i).get(
"type"), al.get(i).get("label"), Double
.parseDouble(String
.valueOf(al.get(i).get("confidence"))),
Double.parseDouble(String.valueOf(al.get(i).get(
"relevance")))));
}
input.setEntities(ents);
exp.add(input);
// System.out.println(input);
// System.out.println(input);
}
return exp;
}
Then in my Translate method:
public static String translateGAINEntities(String url) {
LogicFactory.initialize();
Vector<GAINEntities> exp = readGainEntities.readGainentities(url);
for (int i = 0; i < exp.size(); i++) {
LogicFactory.initialize();
GAINEntities gexp = exp.get(i);
System.out.println("HEREEE \t" + gexp.getEntities()); <-- returns empty.
So,is there something wrong with my code as im still unsure how to reference the Entities attributes through the GAINEntities objects which readGainEntities returns
Generally you can reference the attributes of the Inner class outside the Outer class only when you have an Object of the Outer class:
new Outer().new Inner().doStuff();
provided that the doStuff() method is public.
If the Inner class is static then you can reference it as:
new Outer.Inner().doStuff();
In your example you do not show the classes involved.

Elasticsearch: Adding manual mapping using Java

I cant change the mapping. Can anybody help me to find the bug in my code?
I have found this standard way to change the mapping according to several tutorials. But when i'm try to call the mapping structure there just appear a blank mapping structure after manuall mapping creation.
But after inserting some data there appear the mapping specification because ES is using of course the default one. To be more specific see the code below.
public class ElasticTest {
private String dbname = "ElasticSearch";
private String index = "indextest";
private String type = "table";
private Client client = null;
private Node node = null;
public ElasticTest(){
this.node = nodeBuilder().local(true).node();
this.client = node.client();
if(isIndexExist(index)){
deleteIndex(this.client, index);
createIndex(index);
}
else{
createIndex(index);
}
System.out.println("mapping structure before data insertion");
getMappings();
System.out.println("----------------------------------------");
createData();
System.out.println("mapping structure after data insertion");
getMappings();
}
public void getMappings() {
ClusterState clusterState = client.admin().cluster().prepareState()
.setFilterIndices(index).execute().actionGet().getState();
IndexMetaData inMetaData = clusterState.getMetaData().index(index);
MappingMetaData metad = inMetaData.mapping(type);
if (metad != null) {
try {
String structure = metad.getSourceAsMap().toString();
System.out.println(structure);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void createIndex(String index) {
XContentBuilder typemapping = buildJsonMappings();
String mappingstring = null;
try {
mappingstring = buildJsonMappings().string();
} catch (IOException e1) {
e1.printStackTrace();
}
client.admin().indices().create(new CreateIndexRequest(index)
.mapping(type, typemapping)).actionGet();
//try put mapping after index creation
/*
* PutMappingResponse response = null; try { response =
* client.admin().indices() .preparePutMapping(index) .setType(type)
* .setSource(typemapping.string()) .execute().actionGet(); } catch
* (ElasticSearchException e) { e.printStackTrace(); } catch
* (IOException e) { e.printStackTrace(); }
*/
}
private void deleteIndex(Client client, String index) {
try {
DeleteIndexResponse delete = client.admin().indices()
.delete(new DeleteIndexRequest(index)).actionGet();
if (!delete.isAcknowledged()) {
} else {
}
} catch (Exception e) {
}
}
private XContentBuilder buildJsonMappings(){
XContentBuilder builder = null;
try {
builder = XContentFactory.jsonBuilder();
builder.startObject()
.startObject("properties")
.startObject("ATTR1")
.field("type", "string")
.field("store", "yes")
.field("index", "analyzed")
.endObject()
.endObject()
.endObject();
} catch (IOException e) {
e.printStackTrace();
}
return builder;
}
private boolean isIndexExist(String index) {
ActionFuture<IndicesExistsResponse> exists = client.admin().indices()
.exists(new IndicesExistsRequest(index));
IndicesExistsResponse actionGet = exists.actionGet();
return actionGet.isExists();
}
private void createData(){
System.out.println("Data creation");
IndexResponse response=null;
for (int i=0;i<10;i++){
Map<String, Object> json = new HashMap<String, Object>();
json.put("ATTR1", "new value" + i);
response = this.client.prepareIndex(index, type)
.setSource(json)
.setOperationThreaded(false)
.execute()
.actionGet();
}
String _index = response.getIndex();
String _type = response.getType();
long _version = response.getVersion();
System.out.println("Index : "+_index+" Type : "+_type+" Version : "+_version);
System.out.println("----------------------------------");
}
public static void main(String[] args)
{
new ElasticTest();
}
}
I just wanna change the property of ATTR1 field to analyzed to ensure fast queries.
What im doing wrong? I also tried to create the mapping after index creation but it leads to the same affect.
Ok i found the answer by my own. On the type level i had to wrap the "properties" with the type name. E.g:
"type1" : {
"properties" : {
.....
}
}
See the following code:
private XContentBuilder getMappingsByJson(){
XContentBuilder builder = null;
try {
builder = XContentFactory.jsonBuilder().startObject().startObject(type).startObject("properties");
for(int i = 1; i<5; i++){
builder.startObject("ATTR" + i)
.field("type", "integer")
.field("store", "yes")
.field("index", "analyzed")
.endObject();
}
builder.endObject().endObject().endObject();
}
catch (IOException e) {
e.printStackTrace();
}
return builder;
}
It creates mappings for the attributes ATTR1 - ATTR4. Now it is possible to define mapping for Example a list of different attributes dynamically. Hope it helps someone else.

Finding differences in two XML files using XMLUnit

How to check for only particular nodes and not all nodes for difference while using the DetailedDiff function of XMLUnit
this is my code:
public static void main(String[] args)
{
//URL url1 = xmlunittest.class.getResource("MSHIS1.xml");
// URL url2 = xmlunittest.class.getResource("MSHIS.xml");
Logger L = new Logger();
FileReader fr1 = null;
int countofdifferences = 0;
FileReader fr2 = null;
try {
fr1 = new FileReader("MSHIS.xml");
fr2 = new FileReader("MSHIS1.xml");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
Diff diff = new Diff(fr1, fr2);
L.writeToBVTLOG("Similar? " + diff.similar());
L.writeToBVTLOG("Identical? " + diff.identical());
DetailedDiff detDiff = new DetailedDiff(diff);
List differences = detDiff.getAllDifferences();
for (Object object : differences) {
Difference difference = (Difference)object;
L.writeToBVTLOG("------------------------");
L.writeToBVTLOG(difference.toString());
L.writeToBVTLOG("------------------------");
countofdifferences++;
}
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
L.writeToBVTLOG(countofdifferences);
}
But the thing is that, I just want the program to tell me if 4 particular nodes have undergone any changes. So how to get there from listing all the differences.
You can implement your own DifferenceListener that ignores some nodes (or only pays attention to some nodes) and tell XMLUnit to use it when checking differences. Here's a DifferenceListener that ignores any elements named "myelement":
public class IgnoreMyAttributeElements implements DifferenceListener()
{
#Override
public int differenceFound(Difference differenceIn)
{
Node controlNode = differenceIn.getControlNodeDetail().getNode();
if(controlNode.getNodeType() == Node.ELEMENT_NODE)
{
if(controlNode.getLocalName().equals("myelement");
{
return DifferenceListener.RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
}
}
return DifferenceListener.RETURN_ACCEPT_DIFFERENCE;
}
#Override
public void skippedComparison(Node nodeIn, Node nodeIn2)
{
//don't care about these events
}
}
Then pass it to the DetailedDiff:
DetailedDiff diff = new DetailedDiff(XMLUnit.compareXML(oldXml, newXml));
diff.overrideDifferenceListener(new IgnoreMyAttributeElements());
List<?> allDifferences = diff.getAllDifferences();
//do something with differences
You might transform both documents first with javax.xml.transform.TransformerFactory so that it only contains the nodes you are interested. Or you could use getControlNodeDetail() and getTestNodeDetail() on Difference to see if the difference applies to the nodes you want.

Categories