How to maintain different version of reports/documents? - java

What is the best and most flexible way of maintaining different version of documents for a web application?
Let's say you have a Pet store web application.You need to make changes to a printable document with info of your Pet, but these changes are only effective for every Pet object created from a x date , but for Pets created before x date then use the previous version of the report. Somehow keeping multiple versions of the files and choosing them with hardcoded rules seems messy, is there any other way?

If I understand you correctly you simply need to bind your Pet objects to DocumentTemplate objects. You could just add a field to the Pet object:
public class Pet {
private final String name;
private final Template template;
.
.
.
}
This way you would not need to make checks like:
if (pet.getCreationDate().after(date)) {
print(template1);
}
else {
print(template2);
}
but you can simply do:
print(pet.getTemplate());
This would be the standard way to do it if I understand you correctly.

Related

Design Pattern to use when you want apply some common functionality to some specific methods?

I am trying to figure out a design pattern to use (if any exists) to a situation where I would be re-doing some functionality across a bunch of classes. Below is a (simplified) overview of the problem I am facing:
I have some Java code to CREATE, UPDATE, DELETE Student objects, Professor objects, & Staff objects. And every time such an object is either created, deleted, or updated, I want to extract some information about the affected object (such as name, age, id) and notify an external service. So something like:
class StudentDAO {
public Student createStudent(Student studentToCreate) {
jdbcTemplate.update(INSERT_SQL, .....);
//===> extract some info of the student
//let external service know a student was created....
}
public Student deleteStudent(Student studentToDelete) {
jdbcTemplate.update(DELETE_SQL, .....);
//===> extract some info of the student
//let external service know a student was deleted....
}
//same thing for update
}
class ProfessortDAO {
public Professor createProfessor(Professor professorToCreate) {
jdbcTemplate.update(INSERT_SQL, .....);
//===> extract some info of the professor
//let external service know a Professor was created....
}
public Student deleteProfessor(Professor professorToDelete) {
jdbcTemplate.update(DELETE_SQL, .....);
//===> extract some info of the professor
//let external service know a professor was deleted....
}
//same thing for update
}
//repeat for Staff
The example is bit contrived but assume that Student, Professor, Staff share no common supertype. Is there a way to achieve this functionality without copying and pasting the logic for extracting the info and sending it in all the DAO classes for CREATE, DELETE, UPDATE methods ?
You should search for Generic Repository. You can learn more here:
https://www.youtube.com/results?search_query=generic+repository+java
Sample Code:
class Reposiory<T> {
public T create(T Create) {
jdbcTemplate.update(INSERT_SQL, .....);
}
public T delete(T Delete) {
jdbcTemplate.update(DELETE_SQL, .....);
}
}
Create ReportExternalService interface and add key property,
Implement this Interface if the object requires to be notified.
Create one method which takes the parameter as ReportExternalService and use key to report to external service.!
You can use aspect oriented programming. You can then write a general point cut which matches all your methods where you want to talk to your external server. What is aspect-oriented programming?
Not much info to go on but have you considered using generics for a specific type and implementing an interface to define the common information (phone, name, id) you want to access from each type of individual?
You should also be able to pass the operation (DELETE, ADD, UPDATE) as an argument. I would suggest using an enum for that.

Importing a file with different layouts to a database in Java

I need to import a text file, with values separated by pipes ( | ), into a database using Java and Hibernate. The text file is generated elsewhere, and has the following layout:
example-file.txt
|0150|A|B|C|
|0150|X|Y|Z|
|0190|1|2|
|0200|9|8|7|H|F|E|
Each line corresponds to a record.
The first value (i.e 0150, 0190, 0200) is the type of info it holds (to which table it should be stored).
The rest are the values to be stored in that table.
So far, I've been able to read the lines, find to which Object the record corresponds to - using a Factory pattern - separating the values into a String[] array and calling a method createInstance(String[] fields) to create the object and store it into the database - using a Template pattern:
ImportServiceInterface
public interface ImportServiceInterface {
public void createInstance(String[] fields);
}
AbstractImportService
public abstract class AbstractImportService implements ImportServiceInterface {
public static ImportServiceInterface getImportService(String line) {
// returns the correct subclass
}
public void import() {
createInstance(splitFields());
}
public String[] splitFields(String line) {
// splits the line
}
}
So I have 3 separate services, each implementing their own version of createInstance(String[] fields):
ImportExampleTypeService
public ImportExampleTypeService implements AbstractImportService {
public void createInstance(String[] fields) {
ExampleModel myExample = new myExampleModel(); // mapped with Hibernate
// find which object members corresponds to the fields
// call the DAO to store the object
}
}
My problem is that the user will be able to specify his own layout: to which fields the values correspond to, size and position.
I thought about creating a table to store the layouts, then matching the names of the attributes using Reflection.
But I must be missing something, perhaps there's an easier way to do this?
SuperCSV supports custom delimiters and population of java objects via reflection, so I think it would do most of your work for you in this case.
Furthermore, it supports the concept of a header row as the first line in the file which then defines which fields those columns are mapped to in the java object, or you can just customize the column mappings manually.
Thank you #increment1 and #Templar for your answers!
The requirements have changed. The system has to be able to import both the above format (which will not be user-defined) and a user-defined, CSV-like, flat file, with a single type of record per file. It makes my life easier. I have been looking at different flat-file parsing libraries, and I'm posting it here in case anyone stumbles upon the same problem:
jflat: simple to use, extensible and customizable framework. Probably the best choice for most.
BeanIO: a flat-file marshaller/unmarshaller that uses xml files to figure out how to parse the file. Supports many formats, more than one type of record per file etc.
FFP: Flat File Parsing. Also supports absolute and relative definitions, using POJOs instead of xml files. I would have chosen this one, but it seems to be dead?
Flatworm: very similar to BeanIO. It appears it has inspired BeanIO, and there is not much activity on Flatworm either...
I have chosen BeanIO, because its flexibility suits my project better. So here's what I am going to do:
1) Keep my design, implementing my createInstance() method as needed;
2) Use a different implementation using BeanIO for the user-defined files;
3) Use a Facade to call the parser I need:
FacadeInterface
public interface ImportFacadeInterface {
public void importFile();
}
ImportDefaultLayoutFacadeImpl
public class ImportDefaultLayoutFacadeImpl implements ImportFacadeInterface {
public void importFile() {
// use the ImportServiceInterface
}
}
ImportUserDefinedLayoutFacadeImpl
public class ImportUserDefinedLayoutFacadeImpl implements ImportFacadeInterface {
public void importFile() {
// use BeanIO
}
}
My approch to store the possible record structures would be a Map with |0150| as Key and |A|B|C| as Value. This could be an approch to parse a line.
String line = ...;
String structure = map.get(line.substring(1, 4));
// Now you have the line structure and can parse it into your own format.

Obfuscate source code using ProGuard

Recently I've had some problems with people cheating using an app for root users called Gamecih. Gamecih let's users pause games and change variables in runtime.
If I obfuscate my code I though it'll be hard for cheaters to know what variables to change in runtime, but I'm also worried it might cause some other problems.
I serialize game objects using Javas Serializable interface and then write them out to a file. Now let's say I'm serializing an object of the class "Player". It gets serialized and saved to a file. Then a user downloads the update with the Proguard implementation. Proguard will rename classes and class member names. Won't that cause major errors when trying to read in an already saved Player object?
If I had not yet launched my game, this wouldn't be a problem. But now some players are playing on the same saved game(it's an RPG) for months. They would be pretty pissed off if they downloaded an update and had to start over from scratch.
I know I can instruct Proguard not to obfuscate certain classes, but it's the Player class I really need to obfuscate.
Clarification: Let's say I have the following simple unobfuscated class:
public class Player {
private int gold;
private String name;
//Lots more.
public Player(String name)
{
this.name = name;
}
public int getGold() {
return gold;
}
public void setGold(int gold) {
this.gold = gold;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
A player is created, serialized and saved to a file. After I implement obfuscator, it might look like this:
public class Axynasf {
private int akdmakn;
private String anxcmjna;
public Axynasf(String adna)
{
anxcmjna=adna;
}
public int getAkdmakn() {
return akdmakn;
}
public void setAkdmakn(int akdmakn) {
this.akdmakn = akdmakn;
}
public String getAnxcmjna() {
return anxcmjna;
}
public void setAnxcmjna(String anxcmjna) {
this.anxcmjna = anxcmjna;
}
}
Imagine that I post an update now and a player that has an unobfuscated version of Player downloads that update. When trying to read that Object there will be different member names and a different class name. I'll most likely get ClassCastException or something of the sorts.
No expert in Proguard, but I think you're right to assume it is going to break serialisation.
One possible way of solving this might be to implement a layer over your current save structure - You can tell Proguard which classes you don't want to obfuscate. Leave the Player (and alike objects) the same for now and don't obfuscate. Once the object has been de-serialised, pass it up to your new layer (which is obfuscated) which the rest of the game deals with - if you don't retain the non-obfuscated object, then it'll cause cheaters problems tweaking during game play (although not at load time). At the same time, you could look at moving your player's game files over to another save option that doesn't depend on serialisation, which will probably make such issues easier in the future.
For ensuring compatible serialization in ProGuard:
ProGuard manual > Examples > Processing serializable classes
For upgrading a serialized class to a different class in Java:
JDK documentation > Serialization > Object Input Classes > readResolve
JDK documentation > Serialization > Object Serialization Examples > Evolution/Substitution
I understand ppl can update vars # runtime w/ the app you named.
If you change the member names, the values will still give hints.
If you obfuscate, the class name will change but new name will end on a forum anyway.
So this is not enough
What you could do in your update is, at startup, load serialized data in old object, transfer to "new" obfuscated class, use a custom serialization (with an XOR using the deviceID value or the gmail adress so to make it less obvious).
Try to have your player data into several classes too.
What I would do in your situation:
Release an update with obfuscated and non-obfuscated class. When player gets loaded it will try with both classes. If player got loaded with non-obf. class then map this class to your obfuscated class.
When player gets saved it will save with obfuscated class.
After a proper amount of time release an update with only the obfuscated classes.

Registering and updating application properties using JMX

I have to access some application through an mbean so that I can change its application properties. Now i think this can be done in two ways:
First, either I ask the developer of that application to register all the application properties in an arraylist which my mbean will access.
Secondly, if there is any other way, such that the developer will only need to register editable properties and still my mbean can access both readable/editable(r/w) application properties.
Now since I don't know where these application properties are stored in the JVM, is there a way to implement my second point so that the mbean will just need to access that object and it will get all application properties?
Seems like you have some contradicting requirements here.
You want to change minimal code in the application.
You want to be cause to expose all properties for read and/or write.
You may or may not be talking about System.getProperty(...). If not then I guess you are talking about just fields in various objects.
There are (at least) two ways of doing this. Without knowing how you are exporting the mbeans from the source code right now, I can't tailor my answer to your specific config. My answer will instead show how you might use my SimpleJMX package to expose your properties.
If you are talking about System.getProperty(...) then you could write a JMX mbean that could query any property and return the value:
#JmxOperation(description = "Query for property")
public String queryForProperty(String name) {
return System.getProperty(name);
}
If, instead, you need to export of fields from some list of objects then you are going to either have to add annotations to each fields you are exporting or you are going to have to write beans that export the fields through delegation. I see no easy way and I know of no package that will easily export a series of objects for you without some sort of information about what is to be exported and how.
Using SimpleJMX, you can export a field by annotating either the field or the get method:
#JmxAttributeField(description = "Number of hits in the cache")
private int hitCount;
...
// this can also be specified as #JmxAttributeMethod on the getter/setter methods
#JmxAttributeMethod(description = "Number of misses in the cache")
private int getMissCount() {
return missCount;
}
The #JmxAttributeField supports a isWritable = true to allow the value to be set by JMX. You can also annotation the setter with #JmxAttributeMethod to make it writable.
If you don't want to add annotations to each of your classes, then you are going to have to write some sort of JMX container class that exports the values through delegation:
public class JmxPublisher {
private Class1 object1;
private Class2 object2;
...
public JmxPublisher(Class1 object1, Class2 object2) {
this.object1 = object1;
this.object2 = object2;
...
}
#JmxAttributeMethod(description = "Number of hits in the cache")
public int getClass1HitCount() {
return object1.getHitCount();
}
#JmxAttributeMethod(description = "Shutdown the background thread")
public void setClass2Shutdown(boolean shutdown) {
return object2.setShutdown(shutdown);
}
...
}
I also think you should express yourself more clearly.
From what I understood - why not providing a way to query the remote application, and get information on all properties and if they are Read-only, Write-only or RW?
This way the list of properties will not be mentioned at the source code of the client application - maybe you should let the user of the client application see the list of properties, and let him edit the properties he can edit, and prevent him from editing the properties he can't.

Good practice to validate immutable values objects

Suppose a MailConfiguration class specifying settings for sending mails :
public class MailConfiguration {
private AddressesPart addressesPart;
private String subject;
private FilesAttachments filesAttachments;
private String bodyPart;
public MailConfiguration(AddressesPart addressesPart, String subject, FilesAttachments filesAttachements,
String bodyPart) {
Validate.notNull(addressesPart, "addressesPart must not be null");
Validate.notNull(subject, "subject must not be null");
Validate.notNull(filesAttachments, "filesAttachments must not be null");
Validate.notNull(bodyPart, "bodyPart must not be null");
this.addressesPart = addressesPart;
this.subject = subject;
this.filesAttachements = filesAttachements;
this.bodyPart = bodyPart;
}
// ... some useful getters ......
}
So, I'm using two values objects : AddressesPart and FilesAttachment.
Theses two values objects have similar structures so I'm only going to expose here AddressesPart :
public class AddressesPart {
private final String senderAddress;
private final Set recipientToMailAddresses;
private final Set recipientCCMailAdresses;
public AddressesPart(String senderAddress, Set recipientToMailAddresses, Set recipientCCMailAdresses) {
validate(senderAddress, recipientToMailAddresses, recipientCCMailAdresses);
this.senderAddress = senderAddress;
this.recipientToMailAddresses = recipientToMailAddresses;
this.recipientCCMailAdresses = recipientCCMailAdresses;
}
private void validate(String senderAddress, Set recipientToMailAddresses, Set recipientCCMailAdresses) {
AddressValidator addressValidator = new AddressValidator();
addressValidator.validate(senderAddress);
addressValidator.validate(recipientToMailAddresses);
addressValidator.validate(recipientCCMailAdresses);
}
public String getSenderAddress() {
return senderAddress;
}
public Set getRecipientToMailAddresses() {
return recipientToMailAddresses;
}
public Set getRecipientCCMailAdresses() {
return recipientCCMailAdresses;
}
}
And the associated validator : AddressValidator
public class AddressValidator {
private static final String EMAIL_PATTERN
= "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*#[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
public void validate(String address) {
validate(Collections.singleton(address));
}
public void validate(Set addresses) {
Validate.notNull(addresses, "List of mail addresses must not be null");
for (Iterator it = addresses.iterator(); it.hasNext(); ) {
String address = (String) it.next();
Validate.isTrue(address != null && isAddressWellFormed(address), "Invalid Mail address " + address);
}
}
private boolean isAddressWellFormed(String address) {
Pattern emailPattern = Pattern.compile(EMAIL_PATTERN);
Matcher matcher = emailPattern.matcher(address);
return matcher.matches();
}
}
Thus, I have two questions :
1) If for some reasons, later, we want to validate differently an address mail (for instance to include/exclude some aliases matching to existing mailingList), should I expose a kind of IValidator as a constructor parameter ? like the following rather than bringing concrete dependence (like I made):
public AddressValidator(IValidator myValidator) {
this.validator = myValidator;
}
Indeed, this will respect the D principle of SOLID principle : Dependency injection.
However, if we follow this logical, would a majority of Values Objects own an abstract validator or it's just an overkill the most of time (thinking to YAGNI ?) ?
2) I've read in some articles than in respect of DDD, all validations must be present and only present in Aggregate Root, means in this case : MailConfiguration.
Am I right if I consider that immutable objects should never be in an uncohesive state ? Thus, would validation in constructor as I made be preferred in the concerned entity (and so avoiding aggregate to worry about validation of it's "children" ?
There's a basic pattern in DDD that perfectly does the job of checking and assembling objects to create a new one : the Factory.
I've read in some articles than in respect of DDD, all validations
must be present and only present in Aggregate Root
I strongly disagree with that. There can be validation logic in a wide range of places in DDD :
Validation upon creation, performed by a Factory
Enforcement of an aggregate's invariants, usually done in the Aggregate Root
Validation spanning accross several objects can be found in Domain Services.
etc.
Also, I find it funny that you bothered to create an AddressesPart value object -which is a good thing, without considering making EMailAddress a value object in the first place. I think it complicates your code quite a bit because there's no encapsulated notion of what an email address is, so AddressesPart (and any object that will manipulate addresses for that matter) is forced to deal with the AddressValidator to perform validation of its addresses. I think it shouldn't be its responsibility but that of an AddressFactory.
I'm not quite sure if I follow you 100%, but one way to handle ensuring immutable objects are only allowed to be created if they are valid is to use the Essence Pattern.
In a nutshell, the idea is that the parent class contains a static factory that creates immutable instances of itself based on instances of an inner "essence" class. The inner essence is mutable and allows objects to be built up, so you can put the pieces together as you go, and can be validated along the way as well.
The SOLID principals and good DDD is abided by since the parent immutable class is still doing only one thing, but allows others to build it up through it's "essence".
For an example of this, check out the Ldap extension to the Spring Security library.
Some observations first.
Why no generics? J2SE5.0 came out in 2004.
Current version of Java SE has Objects.requiresNonNull as standard. Bit of a mouthful and the capitalisation is wrong. Also returns the passed object so doesn't need a separate line.
this.senderAddress = requiresNonNull(senderAddress);
Your classes are not quite immutable. They are subclassable. Also they don't make a safe copy of their mutable arguments (Sets - shame there aren't immutable collection types in the Java library yet). Note, copy before validation.
this.recipientToMailAddresses = validate(new HashSet<String>(
recipientToMailAddresses
));
The use of ^ and $ in the regex is a little misleading.
If the validation varies, then there's two obvious (sane) choices:
Only do the widest variation in this class. Validate more specifically in the context it is going to be used.
Pass in the validator used and have this as a property. To be useful, client code would have to check and do something reasonable with this information, which is unlikely.
It doesn't make a lot of sense to pass the validator into the constructor and then discard it. That's making the constructor overcomplicated. Put it in a static method, if you must.
The enclosing instance should check that its argument are valid for that particular use, but should not overlap with classes ensuring that they are generally valid. Where would it end?
Although an old question but for anyone stumbling upon the subject matter, please keep it simple with POJOs (Plain Old Java Objects).
As for validations, there is no single truth because for a pure DDD you need to keep the context always in mind.
For example a user with no credit card data can and should be allowed to create an account. But credit card data is needed when checking out on some shopping basket page.
How this is beautifully solved by DDD is by moving the bits and pieces of code to the Entities and Value Objects where it naturally belong.
As a second example, if address should never be empty in the context of a domain level task, then Address value object should force this assertion inside the object instead of using asking a third party library to check if a certain value object is null or not.
Moreover Address as a standalone value object doesn't convey much at its own when compared with ShippingAddress, HomeAddress or CurrentResidentialAddress ... the ubiquitous language, in other words names convey their intent.

Categories

Resources