How to save ODocument in map field in Vertex with Java - java

Assuming I have a Vertex (let's call it "PokemonMaster")
PokemonMaster
{
name, (STRING)
age, (INTEGER)
pokemons, (EMBEDDEDMAP) of Pokemon
}
in my DB containing an EMBEDDEDMAP (I also tried with LINKMAP but I'm not sure of what i'm doing) of a class "Pokemon".
I'm trying with Java to create the Vertex and put in the field "pokemons", some pokemons.
let's say a Pokemon looks like :
Pokemon
{
name, (STRING)
}
I'm doing something like :
Vertex v = graph.addVertex("class:PokemonMaster",
"name", "Sacha",
"age", "42",
"pokemons", new ODocument("Pokemon").field("name", "Pikachu"));
I assume this would create a first element (Pikachu) in the map. And I was hoping to be able to add some Pokemons to my map later by doing something like :
v.setProperty("pokemons", new ODocument("Pokemon").field("name", "Raichu"));
All of this is actually not working and that's why i'm here, am I totally wrong?
I get the error :
The field 'PokemonMaster.pokemons' has been declared as EMBEDDEDMAP but an incompatible type is used. Value: Pokemon{name:Pikachu}
Thank you !
Edit
I found the solution.
Creating a map like :
Map<String, ODocument> foo = new HashMap<>();
Putting some pokemons in it :
ODocument doc = new ODocument("Pokemon").field("name", "Pikachu");
ODocument doc2 = new ODocument("Pokemon").field("name", "Raichu");
foo.put("pikachu", doc);
foo.put("raichu", doc2);
doc.save();
doc2.save();
and simply giving the map as parameter :
Vertex v = graph.addVertex("class:PokemonMaster",
"name", "Sacha",
"age", "42",
"pokemons", foo);
Hope it will help someone !

UPDATE:
In case of embeddedmap, to create the schema:
OrientGraphNoTx graphOne = new OrientGraphNoTx(URL, USER, USER);
try {
OSchema schema = graphOne.getRawGraph().getMetadata().getSchema();
OClass pokemon = schema.createClass("Pokemon");
pokemon.createProperty("name", OType.STRING);
OClass vClass = schema.getClass("V");
OClass pokemonMaster = schema.createClass("PokemonMaster");
pokemonMaster.setSuperClass(vClass);
pokemonMaster.createProperty("name", OType.STRING);
pokemonMaster.createProperty("age", OType.INTEGER);
pokemonMaster.createProperty("pokemons", OType.EMBEDDEDMAP, pokemon);
} finally {
graphOne.shutdown();
}
Create a master with a pokemon:
String pmRID = "";
OrientGraph graphTwo = new OrientGraph(URL, USER, USER);
try {
ODocument pokemon = new ODocument("Pokemon");
pokemon.field("name", "Pikachu");
Map<String,ODocument> foo = new HashMap();
foo.put("pikachu", pokemon);
OrientVertex v = graphTwo.addVertex("class:PokemonMaster",
"name", "Sacha",
"age", "42",
"pokemons", foo);
graphTwo.commit();
pmRID = v.getIdentity().toString();
} catch (Exception e) {
// ...
} finally {
graphTwo.shutdown();
}
Add a second pokemon:
OrientGraph graphThree = new OrientGraph(URL, USER, USER);
try {
ODocument pokemon = new ODocument("Pokemon");
pokemon.field("name", "Raichu");
OrientVertex v = graphThree.getVertex(pmRID);
Map<String, ODocument> pokemons = v.getProperty("pokemons");
if (pokemons == null) {
pokemons = new HashMap();
}
pokemons.put("raichu", pokemon);
v.setProperty("pokemons", pokemons);
graphThree.commit();
} catch (Exception e) {
// ...
} finally {
graphThree.shutdown();
}
You could also use an embeddedlist. See here.

Related

I want these 3 data to be stacked but the problem is when one data completes another does not start when previous one ends ! should change in backend

public BarChartModel getBcmMarineSH() {
BarChartSeries F1 = new BarChartSeries();
BarChartSeries F2 = new BarChartSeries();
BarChartSeries F3 = new BarChartSeries();
String txtFy = "";
bcmMarine = new BarChartModel();
stacked = new BarChartModel();
try {
ArrayList vec = new ArrayList();
vec.add(getTrade_Type());
ArrayList parm = new ArrayList();
parm.add(vec);
DaoReq[] req = new DaoReq[1];
req[0] = new DaoReq();
req[0].setMethodSignature("225"); // getChaPdb() //getMarinePdbBarChartSM
req[0].setParamCount(1);
req[0].setParamList(parm);
DaoRes res[] = (DaoRes[]) aPosCdbReg.PerformTask(req);
if (res[0].isStatus()) {
ArrayList aRes = (ArrayList) res[0].getResult();
//FY.setLabel((String) aRes.get(0)); /// problem starts here
F1.setLabel("Coastal Bill");
F2.setLabel("Foreign Bill");
F3.setLabel("Total");
//Map
//ArrayList aReq =(ArrayList) res[1].getResult();
F1.setData((Map<Object, Number>) aRes.get(0));
F2.setData((Map<Object, Number>) aRes.get(1));
F3.setData((Map<Object,Number>) aRes.get(2));
} else {
System.out.println(res[0].getMessage());
System.out.println(res[1].getMessage());
System.out.println(res[2].getMessage());
}
bcmMarine.addSeries(F1);
bcmMarine.addSeries(F2);
bcmMarine.addSeries(F3);
bcmMarine.setSeriesColors("FF0066,42EFF5,03FC3D");
bcmMarine.setTitle("Marine Bills for Foreign and Coastal(In Lakhs)");
bcmMarine.setStacked(true);
bcmMarine.setAnimate(true);
bcmMarine.setShowPointLabels(true);
bcmMarine.setShowDatatip(false);
bcmMarine.setLegendPosition("e");
bcmMarine.setLegendCols(1);
bcmMarine.getAxis(AxisType.X).setLabel("Financial Year");
/*stacked.addSeries(F2);
stacked.setSeriesColors("42EFF5");
stacked.setTitle("Marine Bills for Foreign and Coastal(In Lakhs)");
stacked.setStacked(true);
stacked.setAnimate(true);
stacked.setShowPointLabels(true);
stacked.setShowDatatip(false);
stacked.setLegendPosition("e");
stacked.setLegendCols(1);
stacked.getAxis(AxisType.X).setLabel("Financial Year");*/
/*Axis yAxis = bcmMarine.getAxis(AxisType.Y);
yAxis.setMin(0);
yAxis.setMax(1000);*/
} catch (Exception ex) {
System.out.println(ex.getMessage());
} catch (Throwable th) {
System.out.println(th.getMessage());
}
return bcmMarine;
//return stacked;
}
These graph should be stacked but when one ends other one is not showing completely(including previous one It is showing). Should I change my program in backend or what changes should I do In given code.

How to avoid duplicate values in a JComboBox?

cmbMake = new JComboBox();
cmbMake.addItem("**Please Select**");
Iterator i = products.entrySet().iterator();
while (i.hasNext())
{
Map.Entry me = (Map.Entry) i.next();
Product p = (Product) me.getValue();
if(!p.getMake().equals(cmbMake.getSelectedItem()))
{
cmbMake.addItem("" + p.getMake());
}
}
I have a class which holds product details is there anyway to stop the same make being added to the combo box?
You can try this code (I added some code to yours). The code gets the values of makes and stores them in a Set collection, and then populates the combo box.
cmbMake = new JComboBox();
cmbMake.addItem("**Please Select**");
Iterator i = products.entrySet().iterator();
Set<String> uniqueMakes = new HashSet<>(); // this stores unique makes
while (i.hasNext())
{
Map.Entry me = (Map.Entry) i.next();
Product p = (Product) me.getValue();
//if(! p.getMake().equals(cmbMake.getSelectedItem()))
//{
// cmbMake.addItem("" + p.getMake());
//}
uniqueMakes.add(p.getMake());
}
System.out.println(uniqueMakes); // this prints the makes
// Add makes to the combo box
for (String make : uniqueMakes) {
cmbMake.addItem(make);
}
Suggestions: You can use type parameters while using some of these, for example:
JComboBox<String> cmbMake = new JComboBox<>();
Iterator<Product> i = products.entrySet().iterator();
EDIT: Here are tutorials on using Set collection and using Generics.
EDIT (another way of coding the same functionality using functional-style programming):
cmbMake = new JComboBox<String>();
cmbMake.addItem("**Please Select**");
products.values()
.map(product -> product.getMake())
.collect(Collectors.toCollection(HashSet::new))
.forEach(make -> cmbMake.addItem(make));
Add all values to a Set and iterate over it :
for(Object o : new HashSet<>(products.values())){
Product p = (Product) o.getValue();
if(!p.getMake().equals(cmbMake.getSelectedItem())) {
cmbMake.addItem("" + p.getMake());
}
}
Assuming make is String, just create a set with all the different values and then add them to the ComboBox:
Set<String> productMakes = new HashSet<String>();
for (Map.Entry<KeyClass, Product> productEntry: products.entrySet()) {
productMakes.add(productEntry.getValue().getMake());
}
// How about sorting the items before adding them to the ComboBox?
List<String> sortedProductMakes = new ArrayList<String>(productMakes);
java.util.Collections.sort(sortedProductMakes);
for (String productMake : sortedProductMakes ) {
cmbMake.addItem(productMake);
}
Try this code,
cmbMake = new JComboBox();
cmbMake.addItem("**Please Select**");
Map products = null;
Iterator i = products.entrySet().iterator();
while (i.hasNext()) {
Map.Entry me = (Map.Entry) i.next();
Product p = (Product) me.getValue();
Set<String> productSet = new HashSet<String>();
productSet.add(p.getMake());
if (!p.getMake().equals(cmbMake.getSelectedItem())) {
if (productSet.size() > 0) {
productSet.forEach(action -> {
cmbMake.addItem("" + action);
});
}
}
}

Is It possible to change value of Range key in DynamoDB Table?

I know it may be a very silly question, but I am new to DynamoDB.
My doubt is is it possible to update the value of a Range Key in DynamoDB.
Suppose My Table is "TEST"
{
ID : PK/HK
Date : RK
Name : GSI
Add : LSI
}
I want to modify Date Attribute.
Initial Values in Table was:
{
ID = "344"
Date = "5656"
Name = "ABC"
}
Running this code below. I am able to change the Name Attribute which is GSI.
Map<String,AttributeValue> item = new HashMap<String,AttributeValue>();
item.put("ID", new AttributeValue("344"));
item.put("Date", new AttributeValue("5656"));
Map<String,AttributeValueUpdate> item1 = new HashMap<String,AttributeValueUpdate>();
AttributeValueUpdate update = new AttributeValueUpdate().withValue(new AttributeValue("AMIT")).withAction("PUT");
item1.put("Name", update);
UpdateItemRequest updateItemreq = new UpdateItemRequest("Test",item,item1);
UpdateItemResult updateItemres = dynamoDBUSEast.updateItem(updateItemreq);
But When I change this line
item1.put("Name", update);
with
item1.put("Date", update);
I am getting some error as
Exception in thread "main" com.amazonaws.AmazonServiceException: One or more parameter values were invalid: Cannot update attribute Date. This attribute is part of the key (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: HRRP24Q7C48AMD8ASAI992L6MBVV4KQNSO5AEMVJF66Q9ASUAAJG)
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:820)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:439)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:245)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:2908)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.updateItem(AmazonDynamoDBClient.java:1256)
So Is it possible to change the range Key value?
No, like the exception message states, you Cannot update attribute Date. This attribute is part of the key.
You can also see this under the AttributeUpdates documentation:
The names of attributes to be modified, the action to perform on each,
and the new value for each. If you are updating an attribute that is
an index key attribute for any indexes on that table, the attribute
type must match the index key type defined in the AttributesDefinition
of the table description. You can use UpdateItem to update any nonkey
attributes.
The documentation states that you can update any attribute for "an attribute that is an index key attribute for any indexes on that table", which means that when you update an attribute that is projected onto an index, even it is is part of that indexes key, that index will also be updated to reflect the original item.
From the docs of AttributeValueUpdate
You cannot use UpdateItem to update any primary key attributes.
Instead, you will need to delete the item, and then use PutItem to
create a new item with new attributes.
It's a little buried but in docs for UpdateItem it says:
"You can use UpdateItem to update any nonkey attributes."
So, currently the only way to update the primary key of an item is to delete the old item and write a new one.
Here is my implementation of updating id in .net by deleting the item and then recreating it with the new id. I assume java is very similar:
// Based on https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LowLevelDotNetItemsExample.html
public class UpdateId
{
private static string tableName = "MyTableName";
private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();
private static bool isVerbose = false;
public static void ChangeId(string currentId, string newId)
{
try
{
var deletedItem = DeleteItem(currentId);
if (deletedItem.Count == 0)
{
Console.WriteLine($"ERROR: Item to delete not found: {currentId}");
return;
}
deletedItem["Id"] = new AttributeValue
{
S = newId
};
CreateItem(deletedItem);
var updatedItem = RetrieveItem(newId);
if (updatedItem.Count > 0 && updatedItem["Id"].S == newId)
{
Console.WriteLine($"Item id successfully changed from ({currentId}) to ({newId})");
}
else
{
Console.WriteLine($"ERROR: Item id didn't change from ({currentId}) to ({newId})");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("To continue, press Enter");
Console.ReadLine();
}
}
private static void CreateItem(Dictionary<string, AttributeValue> item)
{
var request = new PutItemRequest
{
TableName = tableName,
Item = item
};
client.PutItem(request);
}
private static Dictionary<string, AttributeValue> RetrieveItem(string id)
{
var request = new GetItemRequest
{
TableName = tableName,
Key = new Dictionary<string, AttributeValue>()
{
{ "Id", new AttributeValue {
S = id
} }
},
ConsistentRead = true
};
var response = client.GetItem(request);
// Check the response.
var attributeList = response.Item; // attribute list in the response.
if (isVerbose)
{
Console.WriteLine("\nPrinting item after retrieving it ............");
PrintItem(attributeList);
}
return attributeList;
}
private static Dictionary<string, AttributeValue> DeleteItem(string id)
{
var request = new DeleteItemRequest
{
TableName = tableName,
Key = new Dictionary<string, AttributeValue>()
{
{ "Id", new AttributeValue {
S = id
} }
},
// Return the entire item as it appeared before the update.
ReturnValues = "ALL_OLD",
// ExpressionAttributeNames = new Dictionary<string, string>()
// {
// {"#IP", "InPublication"}
// },
// ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
// {
// {":inpub",new AttributeValue {
// BOOL = false
// }}
// },
// ConditionExpression = "#IP = :inpub"
};
var response = client.DeleteItem(request);
// Check the response.
var attributeList = response.Attributes; // Attribute list in the response.
// Print item.
if (isVerbose)
{
Console.WriteLine("\nPrinting item that was just deleted ............");
PrintItem(attributeList);
}
return attributeList;
}
private static void PrintItem(Dictionary<string, AttributeValue> attributeList)
{
foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
{
string attributeName = kvp.Key;
AttributeValue value = kvp.Value;
Console.WriteLine(
attributeName + " " +
(value.S == null ? "" : "S=[" + value.S + "]") +
(value.N == null ? "" : "N=[" + value.N + "]") +
(value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") +
(value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]")
);
}
Console.WriteLine("************************************************");
}
}
To call it just do this:
UpdateId.ChangeId("OriginalId", "NewId");

Checking among multiple values

I have the below results as part of resultset.
Name Dept
John IT
Mike IT
Cathy CS
Julie CS
Aria Electronics
Shann Electronics
I should be able to separate the resultset based on Dept and put the results in a map. E.g: After Mike, the dept changes and hence I should put John and Mike in a map. Then Cathy and Julie in a map and so on. How do I do it?
public void loadMap(ResultSet inputResultSet, MbGlobalMap inputTranslationObjMap) throws Exception {
String key = "";
List < dept > list = new ArrayList < dept > ();
while (inputResultSet.next()) {
String name = inputResultSet.getString(1);
String key = inputResultSet.getString(2);
dept d1 = new dept(name, key);
list.add(d1);
}
if (inputTranslationObjMap.containsKey(key)) {
inputTranslationObjMap.update(key, list);
} else {
inputTranslationObjMap.put(key, list);
}
}
Try something like this -
public void loadMap(ResultSet inputResultSet,
MbGlobalMap inputTranslationObjMap) throws Exception {
// String key = "";
List<dept> list = null;
while (inputResultSet.next()) {
String name = inputResultSet.getString(1);
String key = inputResultSet.getString(2);
// first check if the map has a list already.
if (inputTranslationObjMap.containsKey(key)) {
list = inputTranslationObjMap.get(key);
} else {
// No... add a new list to the map.
list = new ArrayList<dept>();
inputTranslationObjMap.put(key, list);
}
dept d1 = new dept(name, key);
list.add(d1);
}
}

Searching in an Array that is parsed from a XML in Android

I have this XML file which I parse into an ArrayList
In this ArrayList I have countries and the alarmnumbers for the countries in it.
I want to search to a country and get it's police, ambulance or firedep. number.
Here is the code to help you out.
Parsing XML into ArrayList:
protected ArrayList<Alarmdiensten> getAlarmdiensten() {
ArrayList<Alarmdiensten> lijst = new ArrayList<Alarmdiensten>();
try {
DocumentBuilder builder =DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(getAssets().open("alarmdiensten.xml"));
NodeList nl = doc.getElementsByTagName("land");
for (int i=0;i<nl.getLength();i++) {
Node node = nl.item(i);
Alarmdiensten land = new Alarmdiensten();
land.land = Xml.innerHtml(Xml.getChildByTagName(node, "naam"));
land.landcode = Xml.innerHtml(Xml.getChildByTagName(node, "code"));
land.politie = Xml.innerHtml(Xml.getChildByTagName(node, "politie"));
land.ambulance = Xml.innerHtml(Xml.getChildByTagName(node, "ambulance"));
land.brandweer = Xml.innerHtml(Xml.getChildByTagName(node, "brandweer"));
land.telamba = Xml.innerHtml(Xml.getChildByTagName(node, "telamba"));
land.adresamba = Xml.innerHtml(Xml.getChildByTagName(node, "adresamba"));
lijst.add(land);
}
} catch (Exception e) {;
}
return lijst;
}
The method that will use the alarmnumbers:
public void AlarmMenu(){
String landcode;
ArrayList<Alarmdiensten> diensten = getAlarmdiensten();
if(fakelocation = true) {
landcode = sfakelocation;
}
else {
try {
landcode = getAddressForLocation(this, locationNow).getCountryCode();
} catch (IOException e) {
e.printStackTrace();
}
}
So I have the landcode, and I want to search in the ArrayList diensten for the numbers that belong with the landcode.
How can I do this?
Well at the moment you've got an ArrayList of Alarmdiensten objects. I would suggest you might want to change that to a Map so that you are storing a Map of land codes vs your Alarmdiensten objects.
That way you get the Alarmdiensten out of the Map using the landcode and then simply call the getPolitie() etc methods on your Alarmdiensten object.
I would make sure that you encapsulate your Alarmdiensten object BTW, accessing it's private members directly is a bit of a no-no :)
So something like:
protected Map<String, Alarmdiensten> getAlarmdiensten()
{
Map<String, Alarmdiensten> alarmNumbersForCountries
= new HashMap<String, Alarmdiensten>();
try
{
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(getAssets().open("alarmdiensten.xml"));
NodeList nl = doc.getElementsByTagName("land");
for (int i = 0; i < nl.getLength(); i++)
{
Node node = nl.item(i);
Alarmdiensten land = new Alarmdiensten();
land.setLand(Xml.innerHtml(Xml.getChildByTagName(node, "naam")));
land.setLandcode(Xml.innerHtml(Xml.getChildByTagName(node, "code")));
land.setPolitie(Xml.innerHtml(Xml.getChildByTagName(node, "politie")));
land.setAmbulance(Xml.innerHtml(Xml.getChildByTagName(node, "ambulance")));
land.setBrandweer(Xml.innerHtml(Xml.getChildByTagName(node, "brandweer")));
land.setTelamba(Xml.innerHtml(Xml.getChildByTagName(node, "telamba")));
land.setAdresamba(Xml.innerHtml(Xml.getChildByTagName(node, "adresamba")));
alarmNumbersForCountries.put(land.getLandCode(), land);
}
}
catch (Exception e)
{
// Handle Exception
}
return alarmNumbersForCountries;
}
To get the entry out of the Map
Alarmdiensten land = alarmNumbersForCountries.get(landcode);
Another YMMV point is that you might want to split out the part of your method that builds Alarmdiensten objects from the XML parsing. "Each method should do one thing and one thign well."
Use a for loop and search for it
for(Alarmdiensten land :diensten){
if(land.landcode.equals(landcode) ){
// yes i got it, The current land.
break;
}
}
Just iterate over the list:
String landcode = getLandCode();
for (Alarmdiensten dienst:diensten) {
if (dienst.landcode.equals(landcode)) {
// do what has to be done
}
}
Consider using a map instead of a list, if you have to lookup the values more frequently:
Map<String, List<Alarmdiensten>> servicesInCountry
= new HashMap<String, List<Alarmdiensten>>();
for (Alarmdiensten dienst:diensten) {
List<Alarmdiensten> list = servicesInCountry.get(dienst.landcode);
if (list == null) {
list = new ArrayList<Alarmdiensten>();
servicesInCountry.put(dienst.landcode, list);
}
list.add(dienst);
}
// ... and later on
List<Alarmdiensten> servicesInSweden = servicesInCountry.get("SWE");

Categories

Resources