Design Pattern Questions in Java - java

I have a Design pattern Question in Java/J2EE
Problem Statement::
Suppose there are 2 files as below
XYZ.properties file --> name = value pair
abc.xml file --> attribute=value pair.
Both the above files have <name,value> pairs.
The question is "Design a component/jsp page such that you can read,edit,save the name,value pairs of either a Property file or xml file.?"
So which Design pattern would you suggest i should be using in Java.?
The name,values pair are then fetched and displayed in another jsp page where i should be able to read,edit,save the name,value pairs such that
1>read operation results in reading the name,value pair
2>Edit operation results in editing the name,value pair
3>Save operation results in saving the value for the corresponding name,value pair in database and consequently updates either the property/xml file.
**My Initial Analysis** : i would use a Factory design pattern since i have 2 files which have name,value pairs and at run time decide which one to choose depending on the name of file invoked,Once done i would pass the parameters to jsp file for Read,edit and save operation.Save would save the name,value pair to Database but i dont know how will it update the corresponding value for that name in either the property/xml file as well.
Is my Understanding correct ? If not please provide a design/solution in java for the same,such that READ,EDIT,SAVE operation for pairs in either ".properties file" or ".xml file" are carried out?

This looks like homework.
Without giving away too much, Properties can read/write both .properties and .xml files, more info on http://download.oracle.com/javase/7/docs/api/java/util/Properties.html.

The Factory Pattern would do the job.
Create an abstract class with abstract read, modify, save methods and getter and setter for key and value
create two separate classes for .properties and .xml implementation who extend the abstract class.
Whenever you want to save check for the instance of the class and call the appropriate method.

I think Factory pattern is correct. Make abstracted getInstance(fileName), read, create, update, remove methods.
As a suggestion, you might want to return implemented instance after checking into the file content -- whther it's XML (by checking XML header or presence of root tag) or it's a properties file.
Ideally, I would create a MyFileFactory class that looks like this
public class MyFileFactory{
public static final MyFileFactory getInstance(String filename){
//read the file header or first line to guess what instance to call
int fileType = getFileType(fileName);
if(fileType == MyFileFactory.XML_FILE)
return new XMLFileEditor(fileName);
else
return new PropsFileEditor(fileName);
}
public abstract readFile();
public abstract writeToFile();
public abstract editFile();
}
have these classes to implement the methods
public class XMLFileEditor extends MyFileFactory{
...
private File f;
}
and
public class PropsFileEditor extends MyFileFactory{
...
private File f;
}
And I think you are good to go.
If you want to save in database as well as in the file:
writeToFile(String new_Node_or_property){
//parseNode converts the property or XML node to an object
MyNode node = MyNode.parseNode(new_Node_or_property);
MyFileDAO.insert(node);//write a code that parse
// write here code to append in the file based on what
// filetype implentation it is -- XML, .properties, YAML whatever
}

Related

How to read YAML configuration sections

I'm creating a Yaml configuration reader. I'm having some problems to get the values
from sections. I have already created a way to read not sectioned-keys but when a section like
Test:
Yes:
True: a
False: b
No:
True:
Default: c
False: d
is on the yml file, I want to add the path of the values to a HashMap. In the case above,
the path in the HashMap would be
Test.Yes.True = a
Test.Yes.False = b
Test.No.True.Default = c
Test.No.False = d
notice that Yes and No are sections inside Test. True and False values are inside the section Yes that is in Test etc.
I have no idea how read like the block above.
First of all, you should show what you have tried and where you failed. That helps us to provide very specific answer to your question.
For now, Try converting yaml to corresponding Java POJO. You can do this directly or in steps. You can do it by yourself or can use online converters.
Firstly, you can convert from yaml file to Json. https://www.json2yaml.com/
then with the json, you can create Java POJO's. http://pojo.sodhanalibrary.com/ OR http://www.jsonschema2pojo.org/
The converted json to java POJO will automatically create proper mapping format for you and then you can easily use them.
for your most nested "Default" value case, you can take HashMap with name "HashMap<String, String> trueHashMap = new HashMap<String, String>()" if you wish, otherwise a new POJO with "True.java" will also work".
public class True
{
private String false;
private String true;
// getters setters
}
And then, You need to do some research to map them and pick the configuration.
NOTE:
You can do it by multiple online converters. I have provided only the popular ones.

Creating JsonLd + Hydra based Generic Client API in java. Is there any projects exist for reference?

I am creating Client API in Java using :+ Apache Jena FrameWork+ Hydra(for Hypermedia driven) + my private vocab similar to Markus Lanther Event-API Vocab instead of schema.org(for Ontology/Vocabulary part)
Section 1 :
After looking this Markus Lanther EventDemo repo and hydra-java.I found that they are creating classes for each hydra:Class that can break client in future .For example :
A Person class (Person.java)
public class Person
{
String name;
};
But in future requirement name is also a class eg:
public class Name
{
String firstName;
String LastName;
};
So to fulfill this requirement I have to update Person class like this:
public class Person
{
Name name;
};
Question 1:
Is my understanding correct or not of this Section? If yes then what is the way to deal with this part ?
Section 2:
To avoid above problem I created a GenericResource class(GenericResource.java)
public class GenericResource
{
private Model model;
public void addProperty(String propertyName,Object propertyValue)
{
propertyName = "myvocab:"+propertyName;
//Because he will pass propertyName only eg: "name" and I will map it to "myvocab:name"
//Some logic to add propertyName and propertyValue to model
}
public GenericResource retriveProperty(String propertyName)
{
propertyName = "myvocab:"+propertyName;
//Some logic to query and retrieve propertyName data from this Object add it to new GenericResource Object and return
}
public GenericResouce performAction(String actionName,String postData)
{
//Some logic to make http call give response in return
}
}
But again I stuck in lots of problem :
Problem 1: It is not necessary that every propertyName is mapped to myvocab:propertyName. Some may be mapped to some other vocab eg: hydra:propertyName, schema:propertyName, rdfs:propertyName, newVocab:propertyName, etc.
Problem 2: How to validate whether this propertyName belongs to this class ?
Suggestion: Put type field/variable in GenericResource class.And then check supportedProperty in vocab corresponding to that class.To more clarity assume above Person class which is also defined in vocab and having supportedProperty : [name,age,etc] .So my GenericResource have type "Person" and at time of addProperty or some other operation , I will query through vocab for that property is in supportedProperty list or in supportedOperation list in case of performAction().
Is it correct way ? Any other suggestion will be most welcomed?
Question 1: Is my understanding correct or not of this Section? If yes
then what is the way to deal with this part ?
Yes, that seems to be correct. Just because hydra-java decided to creates classes doesn't mean you have to do the same in your implementation though. I would rather write a mapper and annotate an internal class that can then stay stable (you need to update the mapping instead). Your GenericResource approach also looks good btw.
Problem 1: It is not necessary that every propertyName is mapped to
myvocab:propertyName. Some may be mapped to some other vocab eg:
hydra:propertyName, schema:propertyName, rdfs:propertyName,
newVocab:propertyName, etc.
Why don't you store and access the properties with full URLs, i.e., including the vocab? You can of course implement some convenience methods to simplify the work with your vocab.
Problem 2: How to validate whether this propertyName belongs to this
class
Suggestion: Put type field/variable in GenericResource class
JSON-LD's #type in node objects (not in #value objects) corresponds to rdf:type. So simply add it as every other property.
And then check supportedProperty in vocab corresponding to that class.
Please keep in mind that supportedProperty only tells you which properties are known to be supported. It doesn't tell you which aren't. In other words, it is valid to have properties other than the ones listed as supportedProperty on an object/resource.
Ad Q1:
For the flexibility you want, the client has to be prepared for semantic and structural changes.
In HTML that is possible. The server can change the structure of an html form in the way outlined by you, by having a firstName and lastName field rather than just a name field. The client does not break, rather it adjusts its UI, following the new semantics. The trick is that the UI is generated, not fixed.
A client which tries to unmarshal the incoming message into a fixed representation, such as a Java bean, is out of luck, and I do not think there is any solution how you could deserialize into a Java bean and survive a change like yours.
If you do not try to deserialize, but stick to reading and processing the incoming message into a more flexible representation, then you can achieve the kind of evolvability you're after. The client must be able to handle the flexible representation accordingly. It could generate UIs rather than binding data to fixed markup, which means, it makes no assumptions about the semantics and structure of the data. If the client absolutely has to know what a data element means, then the server cannot change the related semantics, it can only add new items with the new semantics while keeping the old ones around.
If there were a way how a server could hand out a new structure with a code-on-demand adapter for existing clients, then the server would gain a lot of evolvability. But I am not aware of any such solutions yet.
Ad Q2:
If your goal is to read an incoming json-ld response into a Jena Model on the client side, please see https://jena.apache.org/documentation/io/rdf-input.html
Model model = ModelFactory.createDefaultModel() ;
String base = null;
model.read(inputStream, base, "JSON-LD");
Thus your client will not break in the sense that it cannot read the incoming response. I think that is what your GenericResource achieves, too. But you could use Jena directly on the client side. Basically, you would avoid unmarshalling into a fixed type.

Which pattern to use reading from configuration and start different runners using Java

I have simple problem and want advice how to improve the design I will try not to give details of my implementation but to be more abstract.
I have a configuration file with xml structure.(but can be changed)
<configurations>
<conf>
<path1></path1>
<path2></path2>
<conf>
<conf>
<path1></path1>
<path2></path2>
<conf>
</configurations>
where path1 and 2 are paths to some files which are needed in the business logic where I do repeatable actions with this paths many times(like banchmarks)
Then using this paths I need to do some operations but the content of every conf is separated from one another they can run in parallel without problems.
So first I read the configuration and store them in a List and then iterate over the list and execute consecutively the business logic.
I am wondering how can I improve the design of my decision?
I think I can use Iterator patter to iterate over the structure and to accomplished the repeatable logic for every cong to use the Strategy pattern.
Am wondering how to separate logic to use different runners for operations in every conf tag?
I think in many things that could be change for your implementation.
It's important to take the parts that vary and encapsulate them, by this way, later, you can alter or extend the parts that vary without affecting
those that don’t.
The parts that I suppose that could change are :
The source of your conf, it could come from a file (XML, CSV, XLSX, Properties File ...), your data base, etc.
The configuration. New attributes could be added to one conf.
Maybe you don't go to use all the configurations, so I vote for load some configuration when you need this one.
If one business logic needs one conf from your xml file and another business logic needs one conf from your csv file, your flexibility is not the best.
I propose the use of an utility class with the methods that you need to create/load your configuration from different sources.
I suppose that each conf has a name or an id. You could also add more properties as the list of path, the source type, etc.
A map is a better option to store your configurations. You could use a key as (confName, SourceType).
You could use MultiKey from (apache.commons) to create the key of your map.
Ex:
Multikey key = new Multikey(confName, sourceType);
You could create an enum for the source types:
public enum SourceType {
XML,
HTML,
CSV,
ORACLE_DB,
PROPERTIES;
}
Create one Singleton as utility class to create and load your configurations.(I recommend you to read the section of "Singleton" in the book Effective Java)
public enum ConfigurationLoader {
INSTANCE;
private Map<Multikey<String, SourceType>, Configuration> configurations = new HashMap<>();
public Configuration getConfiguration(String confName, SourceType sourceType) {
Multikey<String, SourceType> key = new Multikey<>(confName, sourceType);
if (!isConfigurationLoaded(key)) {
loadConfiguration(confName, sourceType);
}
return configurations.get(key);
}
//helper meethod to know if the configuration has been loaded
private boolean isConfigurationLoaded(Multikey<String, SourceType> key) {
return configurations.get(key) != null;
}
private void loadConfiguration(String confName, SourceType sourceType) {
if (SourceType.XML == sourceType) {
loadConfigurationFromXml(confName);
return;
}
if (SourceType.CSV == sourceType) {
loadConfigurationFromCSV(confName);
return;
}
if (SourceType.ORACLE_DB == sourceType) {
loadConfigurationFromOracleDb(confName);
return;
}
}
private void loadConfigurationFromXml(String confName) {
//your imlementation to create the configuration from XML file
// at the end you put the conf in the map
//.....
//configurations.put(key, configuration);
}
//Equals for the others methods
//private Configuration loadConfigurationFromCsv(String confName) { ....}
//private Configuration loadConfFromDb(String confName){...}
}
The Configuration class (I think that you need only this class, you go to have only fields to add and not behaviors):
public class Configuration {
private String name;
private SourceType sourceType;
private List<String> paths = new ArrayList<String>();
public Configuration(String name, SourceType sourceType) {
super();
this.name = name;
this.sourceType = sourceType;
}
public void addPath(String path) {
paths.add(path);
}
public List<String> getPaths() {
return paths;
}
}
You need to know the configuration that you want,so in your business layer, you could call your configuration as:
Configuration configuration = ConfigurationLoader.INSTANCE.getConfiguration(confName, SourceType.XML);
Next step, create your threads and iterate over you business logic with your configuration...
Hm, sounds a bit like you are desparately trying to apply design patterns to everything :)
(Which is actually not a bad thing as long as your main goal is to learn about patterns.)
As for the Iterator pattern, ok, you store your data in a list and somehow iterate over it. I would not call this applying the Iterator pattern. Iterators are already defined for most containers of the standard library. In most cases you do not directly use these. It is much more convenient to use an enhanced for loop or Java 8 streams, which can also automatically parallelize the iteration.
As for the Strategy pattern, this would be useful if you need to implement the logic of the different configurations in different classes. But as long as you only want to use different paths, this is probably overkill.

xstream: only parsing child element

I have following xml
<root>
<child-1>
</child-1>
<child-2>
<subchild-21>
</subchild-22>
</child-2>
</root>
My requirement is such that I only want to parse child-2. I am unaware of root and child-1.
Is it possible with xstream because I couldn't find a way to ignore root.
There are several ways to go, depending on your requirements.
If you know the name of the class to parse (child-2 here), you could look for the <child-2> and </child-2> entry in the XML, copy them along with the content in-between to a new temporary XML file (you can create temporary files using createTempFile() from the standard File class). This is the way I would suggest.
If you want to take out the child-2 instance without knowing its name, but you know the names of the surrounding classes, you could mock their classes, that is create classes of the same name, but without their specific content. In your example there is no content (might have been ignored at export time), but it's important to have the same member data in the mock classes for the import to succeed. (unless you use ignoreUnknownElements() as stated by Philipi Willemann)
Of course, if you're the one creating the XML, you should be able to export only the child-2 instance in the first place.
If you know the root name you can create a simple class has an attribute of the class you have mapped to child-2:
#XStreamAlias("root")
class Root {
#XStreamAlias("child-2")
private Child2 child;
//get and set
}
Then when you are processing the XML you can set XStream to ignore unknown elements with xstream.ignoreUnknownElements();

Create new child in Dom

I have created test class that created DOM object ,currently I created some attributes
Hard coded ,for example I have create element name structure and for the structure we have attributes,I have created different class that handle the attribute with constructor .
These is the code from the main method
Properties properties = new Properties(document);
Element Property = properties.getProperty();
Properties.setProperty(Property, "product_id","10", "Pro ID");
Type.appendChild(Property);
Properties properties1 = new Properties(document);
Element Property1 = properties1.getProperty();
Properties.setProperty(Property1, "curr","5", "Curr Code");
Type.appendChild(Property1);
The code in the constructor is
public Properties(Document document) {
Property = document.createElement(PROPERTY);
}
As you can see for create new property I have created element property and property1 etc hard coded,which is problematic since what will happen
If I will have table that with list of properties with there data ,how should I handle it?
I am not sure if the constructor is the right solution and my question is how to do that better ?
Thanks!!!
It depends on what you're trying to do.
If you want to create a DOM so that you can test your classes that build DOM's, then simply hard-coding calls will work just fine. You just have to make sure you use enough combinations of calls to thoroughly test you API.
If, on the other hand, you need to create a DOM so that you can then proceed to test your API's that require some sort of DOM input, you might want to consider simply creating those DOM's in the form of XML documents and then using the org.w3c.dom API's to create the DOM from the XML.

Categories