Mapping a string (key) to an XML schema (value) - java

I am trying to map a String (key) to an XML schema with few variable that will change (marked with $ sign).
I am not sure what is the best way to do this in terms of the map to use (hashmap?) and the type to use for the xml schema (map a string to ..?)
Also, I am not entirely sure if passing the strings that will change (let's say: id and name for example) as part of the key and replace them or get the schema back and replace the variable once I process the schema again.
Any help is appreciated.

Instead of implementing this on your own, bind the schema types to Java classes or use some sort of templating engine like StringTemplate.

So is it not simplest to treat the Schema as a string, and just hold it in a Map. Then when you pull it out, do a replace/replaceAll on the schema, and return it. I think that covers what you want?

Related

How to use special characters in XML tag like <abc-name> using JAXB?

I have one requirement where I need to generate XML from JAXB.
I have used basic object where we have only key value pair with parent child relationship but never encountered situation like below.
Expected XML
<swExtended>
<swx-mandatory>FALSE</swx-mandatory>
<swx-period/>
</swExtended>
In Java Object, I dont know how to name tag with special character <swx-mandatory> while defining java variable.
As BretC mention, Answer was very simple
#XmlElement(name = "dave-123")

JPA Access Constants from XML File

i'm trying to map some classes using the Hibernate JPA implementation. My problem is, that I can't use hardcoded Strings or constants in the xml-file you can see below.
It is also no possible to use a constant like in the name-attribute of the entity-tag. dst.ass1.jpa.util.Constants.T_CLASSROOM
this is the error message I get:
I don't know why I can use a constant in den name attribute of the entity tag, but not inside the column-tag.
I'm using IntelliJ IDEA 14.0.3
Hope you understand my problem.
regards.
For an attribute be used in an entity it must be "non-static".
If you map it in your XML, the JPA/Intellij will understand that you are trying to map an static attribute into the entity, and that is not possible.

Best practice design pattern for defining "types" in a database with potential multi language requirement?

My question more specificity is this:
I want users on multiple front ends to see the "Type" of a database row. Let's say for ease that I have a person table and the types can be Student, Teacher, Parent etc.
The specific program would be java with hibernate, however I doubt that's important for the question, but let's say my data is modelled in to Entity beans and a Person "type" field is an enum that contains my 3 options, ideally I want my Person object to have a getType() method that my front end can use to display the type, and also I need a way for my front end to know the potential types.
With the enum method I have this functionality but what I don't have is the ability to easily add new types without re-compiling.
So next thought is that I put my types in to a config file and simply story them in the database as strings. my getType() method works, but now my front end has to load a config file to get the potential types AND now there's nothing to keep them in sync, I could remove a type from my config file and the type in the database would point to nothing. I don't like this either.
Final thought is that I create a PersonTypes database table, this table has a number for type_id and a string defining the type. This is OK, and if the foreign key is set up I can't delete types that I'm using, my front end will need to get sight of potential types, I guess the best way is to provide a service that will use the hibernate layer to do this.
The problem with this method is that my types are all in English in the database, and I want my application to support multiple languages (eventually) so I need some sort of properties file to store the labels for the types. so do I have a PersonType table the purely contains integers and then a properties file that describes the label per integer? That seems backwards?
Is there a common design pattern to achieve this kind of behaviour? Or can anyone suggest a good way to do this?
Regards,
Glen x
I would go with the last approach that you have described. Having the type information in separate table should be good enought and it will let you use all the benefits of SQL for managing additional constraints (types will be probably Unique and foreign keys checks will assure you that you won't introduce any misbehaviour while you delete some records).
When each type will have i18n value defined in property files, then you are safe. If the type is removed - this value will not be used. If you want, you can change properties files as runtime.
The last approach I can think of would be to store i18n strings along with type information in PersonType. This is acceptable for small amount of languages, altough might be concidered an antipattern. But it would allow you having such method:
public String getName(PersonType type, Locale loc) {
if (loc.equals(Locale.EN)) {
return type.getEnglishName();
} else if (loc.equals(Locale.DE)){
return type.getGermanName();
} else {
return type.getDefaultName();
}
}
Internationalizing dynamic values is always difficult. Your last method for storing the types is the right one.
If you want to be able to i18n them, you can use resource bundles as properties files in your app. This forces you to modify the properties files and redeploy and restart the app each time a new type is added. You can also fall back to the English string stored in database if the type is not found in the resource bundle.
Or you can implement a custom ResourceBundle class that fetches its keys and values from the database directly, and have an additional PersonTypeI18n table which contains the translations for all the locales you want to support.
You can use following practices:
Use singleton design pattern
Use cashing framework such as EhCashe for cashe type of person and reload when need.

Storing ArrayList and HashMap using java.util.properties

How can I store an ArrayList and/or a HashMap variable using java.util.properties? If it's not possible what other class can I use to store application configuration?
If you just need to serialize your collections into Strings, I highly recommend XStream. It uses reflection to serialize a class into XML. There is documentation if the default behavior doesn't work for the class you want to serialize, but the following has worked for me every time so far:
XStream xstream = new XStream();
String xml = xstream.toXML(myObject);
MyClass deserializedObject = (MyClass)xstream.fromXML(xml);
assert deserializedObject.equals(myObject);
So... if "don't do that" doesn't work for you, then you need to encode the data somehow. One common technique is to prepend some string to the name of each element. For example if I have a map MyMap containing a->1, b->2, c->3, I might store in the properties file:
MyMap.a=1
MyMap.b=2
MyMap.c=3
For lists, you can do the same, just mapping indices to values. So if MyList contains {a,b,c}
MyList.0=a
MyList.1=b
MyList.2=c
This is a hack, and everything everyone else said is true. But sometimes you gotta do what you gotta do.
Properties is basically Map<String, String> meaning both key and value must be String objects. If you want more advanced configuration, you could go with Spring. Its an excellent framework and I use it in every project. Spring config files are extremely flexible.
java.util.Properties is only intended to be used with String keys and values. It does inherit the put() and putAll() methods from Hashtable, but it's rarely a good idea to use those to "cheat". Have you considered just storing your configuration information in a HashMap rather than a Properties object? You would have to customize the serialization a bit, but you're going to have to do that in any case as you can't take advantage of the default loading functionality of the Properties class.
Storing a HashMap would be easy, since each key and value in the Map can be represented by a corresponding key and value in the Properties object (see the setProperty method in Properties.
For the ArrayList you could do something similar, the keys would be the indexes and the values the items in the corresponding indexes.
In both cases, remember that a properties file only stores strings, so you'd have to devise a way to represent the keys and values in your objects as strings.

Serializing java objects with respect to xml schema loaded at runtime

I call an XML document three-layered if its structure is laid out as following: the root element contains some container elements (I'll call them entities), each of them has some simpleType elements inside (I'll call them properties).
Something like that:
<data>
<spaceship>
<number>1024</number>
<name>KTHX</name>
</spaceship>
<spaceship>
<number>1624</number>
<name>LEXX</name>
</spaceship>
<knife>
<length>10</length>
</knife>
</data>
where spaceship is an entity, and number is a property.
My problem is stated below:
Given
schema: an arbitrary xsd file describing a three-layered document, loaded at runtime.
xmlDocument: an xml document conforming to the schema.
Create
A Map<String, Map <String, Object>> containing data from the xmlDocument, where first key corresponds to entity, second key correponds to this entity's property, and the value corresponds to this property's value, after casting it to a proper java type (for example, if the schema sets the property value to be xs:int, then it should be cast to Integer).
What is the easiest way to achieve this result with existing libraries?
P. S.
JAXB is not really an option here. The schema might be arbitrary and unknown at compile-time. Also I wish to avoid an excessive use of reflection (associated with converting the beans to maps). I'm looking for something that would allow me to make the typecasts while xml is being parsed.
I think XMLBeans is worth a shot; saved the day more than once...
Basically you run an ant script to generate the beans handling the schema, then you iterate over the nodes to build your map.
I think JAXB (tutorial here) is the easiest way to do this.
Create your XML structure like:
#XmlRootElement
class data {
public List<SpaceShipType> spaceship;
public KnifeType knife;
}
class SpaceShipType {
public int number;
public String name;
}
class KnifeType {
public int length;
}
Then create the object tree, and use JAXB.marshall() to write the XML.
If you have an existing XSD, use the xjc tool to create the classes for you.
You will need reflections if the schema is unknown at compile time.
I suggest to take a look at some other tools like xstream.
I could recommend the simple framework or you could do parsing/wrinting xml with pure dom4j as I did in the timefinder project. I used the 'pure' approach because I had cycles in my object graph, but I wanted that the xml could be validated with an xml schema (and I did not want to use JAXB)
I have finally went with using Castor library for parsing the schema and assigning data types manually.

Categories