Implementing article revision history for Java based web application - java

Any ideas of how best i can implement article revision history for a Java based web application and save it in AuditLog
StackOverflow already has such a feature allowing one to see the differences from one version to another, almost like SVN clients.
This is more of a design than implementation question.
addition: How would one display these changes on the web page?
addition: Proposed solution
Article
--------------------------------
Integer id
String title
String body
List<Tag> tags
AppUser createdBy
Date createdDate
AuditLog
--------------------------------
Integer id
Integer objectId
Operation operation // enum with UPDATE and DELETE. I won't audit an insert
Date createdDate
AppUser createdBy
String class
String revisionXML
String comment
A Hibernate Interceptor will intercept
the save process and use Castor XML to create an XML string of the old object.
The class and id is used to get the revisions of a particular object.
google-diff-match-patch will be used for creating HTML diff files

The best solution would be to use a database or storage which already supports versions, for example Apache Jackrabbit.
If that's not an option, then you must decide where you want to store the articles. On the file system? Then make each article a directory and save the revisions as numbers (00001, 00002, etc.) and put the number of the last revision in a special file (like current). Then you can quickly find out how many versions there are (just look into current) and go forward and back.
If you use a database, then add a version number field to the article table and add a second table or a flag which says which one the current version is. You could also select with max(version) but those SQL constructs tend to be pretty ugly and confusing. It's much more simple to save this information elsewhere.
[EDIT] To generate diffs, look at this project: google-diff-match-patch

I would use an existing VCS (for instance, SVN) under the hood. There you have the revision history - all that's left to make is an interface from your app to the VCS.

Related

Best practice confirm data changes of second perosn

I'm looking for the best practice/ design pattern to permit changes on data in a database.
The requirement is that a person A want to update some data. For example email, address or company name. All the changes from person A are not visible on the webpage until Person B check these changes and confirm that. The data are stored in a database.
My question is now what is the best practice/ design pattern for the database? Duplicate the database and copy the data by commit to the other? Only one database and copy the whole dataset with the changed value and tag in that extra column(has to check).
I tried to find something with Google, but I think I don't use the right buzzwords.
My only buzzword was four eyes principal and a solution was workflow engine like camunda or to use dms or ecm.
There has to be simple solution for that problem or is that problem so uncommon?
Thanks for help.
PS.: the user change the data on a website, not directly in the database.
You have to design a data structure such as "generic order" or "generic job". Here you will have a master table that describes a job or an order. The fields would be:
job_id
created_at
created_by
job_ident
job_name
permit_at
permit_by
Any job/order has a key/value set of data. Which would be modeled like this:
job_id (fk_job_id)
key
value
Every job must have an implementation. So the interpretation of the key value pairs is up to this implementation. The implementation would be triggered by a user as he permits the changes associated with the current job or order.
The generic model allows you to have one data structure regardless of any table your application has.
You can also draw some inspiration from transaction logs of a database. Please note, that changes have an order to it. So you can detect conflicts.
However you can enhance the data structure above to lock an entity until approval.
You can also have a look on spring-batch where there is a similar data structure and processing.
Please see the apache camel project. Maybe you can use apache-camel as well.

Need to know the date when user joins group in Liferay

I'm using Liferay 6.2 ga4.
I need to know the date when user joins some group (in default meaning of Liferay) and storage it in database.
However, there is only users_groups default table which I can not expand. What should I do in my situation? Of course, I can create one more entity using ServiceBuilder, but I don't think it's a good idea to duplicate data.
if there is no such type of info already in your liferay database, you could write an service wrapper hook and write the date into an expando value.

Store meta information as a simple Enum or in database?

I need to store a meta information - this information is really does not affect the system in anyway at all and really just informational purposes.
For example - If I have several applications: ios app, android app, mobile web, desktop web - where a logged in user can create content and the content will be displayed across applications. I was thinking it may be useful to store where did that content created from.
So if I have in the database:
- USER table (user_id, username, password, email)
- CONTENT table (content_id, user_id, content)
I want to add the information about where the content came from, so I'll modify the content table as follow:
- CONTENT table (content_id, user_id, content, source)
How should I store the source?
Should it be just an enum class (i am using Java)
public enum Source{ IOS_APP, ANDROID_APP, MOBILE_WEB, DESKTOP_WEB }
and then simply store it a String (varchar) in the database?
Or, should I actually create an extra table and use foreign key relationship
SOURCE table (source_id, source_description)
CONTENT table (content_id, user_id, content, source_id)
Which approach would be more desirable? Pros / cons?
The information here reall does not affect the application anyway. In a way, it's just for statistics informational purposes so if we look back for curiosity we can answer the question "where did most of the content come from"
IMO, you should not choose one over the other, but instead have both.
The enum will help keep your Java code clean, and the table will help keep that data organized.
It would be good to have a separate (master) table for that type of information. And the other tables can reference it as a foreign key. With that you will have a central location for possible values. You wouldn't have to go every where looking for all the possible values.
You can create an enum representing that (master) table. And it can be used as field type if you create entities for other tables. You can see this for an example. Also (optionally) you could valid the enum with table content at application start, to make sure the enum stays in sync with the table, in case new values or added or some existing ones are updated.
I use to have enums in the code and a table with the data represented by the enum in the database. Also, I make the IDs in the table to match with the value of the enum and have easy access to well-known enum values.
Another approach is not having an enum, but a class with ID + Name (maybe the enum exists anyway, to match the IDs with the enum values and have easy access to well-known enum values). If you have code like "if myEnum = MyEnum.SomeValue then" (this is, you have to take a decision on an enum value) maybe it's better to have polimorphic behavior using the class.
PS: I'm not a Java developer, I work with C#, I think that enums in Java are actually real classes that are able to have behaviour, aren't they?

JAVA : file exists Vs searching large xml db

I'm quite new to Java Programming and am writing my first desktop app, this app takes a unique isbn and first checks to see if its all ready held in the local DB, if it is then it just reads from the local DB, if not it requests the data from isbndb.com and enters it into the DB the local DB is in XML format. Now what im wondering is which of the following two methods would create the least overhead when checking to see if the entry all ready exists.
Method 1.) File Exists.
On creating said DB entry the app would create a seperate file for every isbn number named isbn number.xml (ie. 3846504937540.xml) and when checking would use the file exists method to check if an entry all ready exists using the user provided isbn .
Method 2.) SAX XML Parser.
All entries would be entered into a single large XML file and when checking for existing entries the SAX XML Parser would be used to parse the file and then the user provided isbn would be checked against those in the XML DB for a match.
Note :
The resulting entries could number in the thousands over time.
Any information would be greatly appreciated.
I don't think either of your methods is all that great. I strongly suggest using a DBMS to store the data. If you don't have a DBMS on the system, or if you want an app that can run on systems without an installed DBMS, take a look at using SQLite. You can use it from Java with SQLiteJDBC by David Crawshaw.
As far as your two methods are concerned, the first will generate a huge amount of file clutter, not to mention maintenance and consistency headaches. The second method will be slow once you have a sizable number of entries because you basically have to read (on the average) half the data base for every query. With a DBMS, you can avoid this by defining indexes for the info you need to look up quickly. The DBMS will automatically maintain the indexes.
I don't like too much the idea of relying on the file system for that task: I don't know how critical is your application, but many things may happen to these xml files :) plus, if the folder gets very very big, you would need to think about splitting these files in some hierarchcal folder structure, to have decent performance.
On the other hand, I don't see why using an xml file as a database, if you need to update frequently.
I would use a relational database, and add a new record in a table for each entry, with an index on the isbn_number column.
If you are in the thousands records, you may very well go with sqlite, and you can replace it with a more powerful non-embedded DB if you ever need it, with no (or little :) ) code modification.
I think you'd better use DBMS instead of your 2 methods.
If you want least overhead just for checking existence, then option 1 is probably what you want, since it's direct look up. Parsing XML each time for checking requires you to to pass through the whole XML file in worst case. Although you can do caching with option 2 but that gets more complicated than option 1.
With option 1 though, you need to beware that there is a limit of how many files you can store under a directory, so you probably have to store the XML files by multiple layer (for example /xmldb/38/46/3846504937540.xml).
That said, neither of your options is good way to store data in the long run, you will find them become quite restrictive and hard to manage as data grows.
People already recommended using DBMS and I agree. On top of that I would suggest you to look into document-based database like MongoDB as your database.
Extend your db table to not only include the XML string but also the ISBN number.
Then you select the XML column based on the ISBN column.
Query: Java escaped, "select XMLString from cacheTable where isbn='"+ isbn +"'"
A different approach could be to use an ORM like Hibernate.
In ORM instead of saving the whole XML document in one column you use different different columns for each element and attribute and you could even split upp your document over several tables for a simpler long term design.

Short code generator for long text in java

I have long text that identifies few things in my application
For example my code: U2Cd3c7a781856c69559539a78e9492e9772dfe1b67.2.nrg
As I am sharing this key in public, it is bit long and I would like to make short by transforming just like shorturl so that is shorter in public and internally i would like to map this long text as it includes few information such as encrypted record id, user id and etc..
I am looking for a java code that does above, I never mind using my database to store in case a short code generator needs database.
Thank you
Rams
You will have to store in a database, and it should be as simple as adding the file name to a table with an autoincrement ID column, and using the ID column to build the URL. Make sure to put a cache in there somewhere. You don't want to hit the database every time you need to render a link.
Marcelo's answer is good if the links are of temporary nature. If the links are long-lived, I'd add another column that used a short but dense randomly generated key (such as a 10-digit base 36 number A-Z0-9) and use that for the URL. The reason is that if you needed to do any kind of table maintenance (such as merging test and QA data, for example), you could do so without worrying too much about conflicts resulting from the same autokey value referring to two different URLs.
Where I worked previously, they thought nothing about hard-coding PK values for status and code tables. This meant that these tables in prod, QA, Test, and Dev had to be identical to the PK. What a pain!
Thus I don't like to give my PKs to users...

Categories