Transparently storing class state without exposing implementation - java

I have a model (MVC) class whose internal state (which basically contains of private int fields) I want to store.
The program is running on Android (for now) so I need to store the in a Bundle, but I'll be using the same class later in a desktop application where I'll have to store the state some other way, so I can't reference Bundle directly in my class.
So my question is: What is the best way to store (and retrieve) the state of a class without exposing it's implementation?
The best I could think of removing the private access modifier so that the fields become package accessible and create read/write helper classes in the same package, but that somehow seems wrong.

I'm not familiar with the persistence mechanisms on Android, but in general, it's a good idea to separate your persistence logic (i.e. the code that stores objects' state) from the domain objects that actually contain the data. That's the approach taken by JPA and virtually all modern object-relational mapping tools in Java, for example. So yes, referencing Bundle objects directly in your domain classes doesn't sound like the right strategy, especially if you plan to use the same classes in a non-Android environment, too.
My advice is to serialize the object state into XML, which is portable across environments. There are lots of open source tools available that help make this easy and don't require any special code in your domain classes. The two I'm most familiar with are JiBX and Castor. I don't know if either will work on Android, but even if Android has its own tools to transform objects to and from XML, you still might be able to use JiBX or Castor on the desktop side, since they can adapt to many different XML formats.
Once you have the data in XML form, you can persist it using whatever means is most appropriate on the target environment. On the desktop app, that probably means files in the user's home directory. On Android, I guess it would be bundles, but that's not my area of expertise. Good luck!

Take a look at the bridge pattern, as well: http://en.wikipedia.org/wiki/Bridge_pattern
As Rob said, you need to decouple the persistence from the data objects, so you can handle data uniformly and use a bridge to handle the persistence in different platforms.

Related

Dynamically generating mappings between POJOs and REST API

I have a POJO class and I need to call a RESTful web service using some properties from the POJO as parameters to the service. The caveat is that I won't know the endpoint and its parameters 'till runtime. Basically, the user will configure at runtime the endpoint, input/output schemas and mappings from/to those schemas to the POJO class. Then I have to call the API with the appropriate values.
This is going to be a really broad answer.
It sounds like a question that would benefit as 'code as data'.
What I mean by this, is that the amount of possibilities that you have to be able to deal with at runtime, is close to the complexities of using a programming language itself.
When this happens, there's generally a few choices that people either choose by accident, or consciously choose depending on who the user is.
Limit the scope of the problem, and make your configuration that complex it may as well be a programming language itself.
Embed a scripting language, or create some runtime loading of plugins in the native language.
Use an off the shelf library / solution.
I'd recommend 2 or 3 over 1 if your user is yourself or the configuration can be provided by another programmer.

Cross-framework Solutions for field Annotations

Does anyone have any strategies or examples of cross-framework libraries?
I am working on a project with an android app, a java server and a Java desktop client, which all use different frameworks. I need to refactor some core business logic into a separate library that can be used across all of these to ensure consistent behavior, but the field annotations are killing me.
The problem is that I am using Room in the Android app (which requires the #PrimaryKey annotation on the primary key field of a database entity) and JPA in the server and JavaFX client (which requires #Id).
Given this level of difficulty with the models, we initially copy-pasted the fields without annotations to the others when changing them. However, the business logic needs to make use of the models and accommodate each platform's specific ORM, Http client and Json serializer. (I know that it is technically possible to get Gson, Apache Http and Hibernate to run on all of these platforms, but actually doing any of these solutions created too many nightmares of its own)
As far as I can tell, there isn't a nice solution to this. Fortunately, the same #Inject is used in Dagger2 and CDI/CDI-SE so I have created some interfaces that each platform/framework will implement.
Does anybody have any examples or case studies I could look at which might help me arrive at a solution?
(I realize this question doesn't include any code samples, but it's more of a general programming strategy question.)
Disclaimer: I am the architect of JDX for Java and JDXA for Android ORMs.
You may consider using JDX for Java and JDXA for Android ORM frameworks to share the common object model, the core business logic code, and the data integration code across Java server, Java desktop, and Android platforms.
JDX and JDXA don't use annotations to define the mapping - instead they use an external text file to define the mapping specification based on a simple ORM grammar. So you may use the same mapping specification for your common object model across different platforms. Also, the APIs for both JDX and JDXA are simliar.
So, you just need to use the appropriate JDX(A) ORM library for your target platform and an appropriate JDBC driver for your target database without needing to change your object model or business logic.

Accessing Play Framework Model Outside of Play Framework

We have a large offline process that updates the model I designed inside of Play Framework. I think it makes sense to keep this code as a stand-alone project -- but I would like it to be able to use the JPA Model designed inside Play.
I'm wondering if there's a good way to handle this -- a way to reference the JPA Model independently of Play Framework (inside another vanilla Java project).
Another option is to create an API that the external process calls, which is what I've done so far, but it introduces a lot of unnecessary network latency.
Any pointers on how to accomplish this?
Passing around a Play specific JPA entity (ie. that extends Model) is probably not a good idea. You'd be introducing a dependency on the Play jars where they are not required.
As I see it you have two viable options:
Create the object as a POJO and use a Hibernate Xml Config (for Play
versions less than 2.0) to define the mapping to the database. You
can keep the pojo and the config entirely separate - ie. keep the
config in the classpath of your Play App.
Pass your object around in a serialized form eg. XML or JSON.

How to create Java POJO class dynamically?

I have seen a post in this website regarding the dynamic POJO generation. I have the similar requirement now.
I have some tables in the database. I want to have a POJO class for each table with fields and corresponding getters and setters. These classes are to be created dynamically. Once these classes are created I should use those setters and getters in other class to get and set the data and return the Java object.
I have seen BCEL, CGLIB and some other open source tools for this, but couldnt find the proper example. Can you help me?
Have you looked at any of the ORM (Object Relational Mapping) frameworks out there that have been created for just this purpose? Hibernate or the Java EE 6 standard JPA, for instance. It sounds like you are starting down on a path of re-inventing something that is both pretty complex and very time consuming - never a good idea.
UPDATE: in response to comment
Well, I can only say that you guys are building yourselves into a world of hurt. Consider:
If you rely on completely dynamic classes, you are you going to reference those classes and objects from other classes? Through reflection? And how are you going to keep track of all the created classes, their names and the names of their setters and getters?
What happens when you have to restart your system? How are you going to re-create all those dynamic classes?
With a completely dynamic database, how are you going to be able to do any performance optimization on it? Like indexing, for instance.
I can only strongly advise you to re-think your architecture. Dynamic datamodels are a mess to begin with, and next to impossible to maintain, optimize and debug. I've seen systems based on it and it's not pretty. IBM Lotus WCM is a prime example of data model horror. A properly designed and normalized relational model will be better in 99,99999999% of the cases.
Combining this with a harness of dynamic, run time ORM classes will be utterly impossible to maintain (and understand).

Suggest a persistent strategy for a workflow system

I am in the process of creating a UI configuration tool for my pet project. One aspect of this tool lets the end user DEFINE his orchestration. I then need to save this orchestration definition into a database. There will be a executable version of this definition in a running system. The executable version is created dynamically on-demand.
Idea is to separate the DEFINITION from EXECUTABLE version so that I have the flexibility to choose the runtime version among BPMN or JPDL or a POJO based workflow solution (BeanFlow).
Limitation: I can't use the BPMN editors that come with frameworks like jBPM, Activiti etc as I wan't to use my own UI that is specific to my domain.
I need suggestions on HOW to PERSIST the definition.
Should I use rdbms tables? If so, is there a db schema I can borrow that is close to orchestration concepts?
Should I serialize my definition to BPMN/JPDL XML instance document?
Are there any other simple formats that I can use?
By "orchestration" I'm assuming you mean a finite state machine. Where the current state dictates what transitions can be followed to other states. The representation of states and transitions as edges and vertices often produces a directed acyclic graph, however there are times when the graph will cycle (e.g. draft -- submit for approval --> pending approval -- reject --> draft).
In practice, separating the definition from execution calls for a persistence format that can easily accommodate customization. As your system evolves you will find a number of unanticipated edge cases whose solution should not require altering a persistence schema, only code. This implies XML or a NoSQL solution - something whose schema is easily changed or non existent.
Now, having written my own XML definition for this purpose (for uninteresting reasons I'll exclude), my suggestion is using JPDL (or BPMN). Reason is their definitions likely incorporate whatever you're considering now, will in the future, and enable customization - such as hanging arbitrary data or behavior off them at a given point. You also get the advantage of tools already built - not just UI - for dealing with cycle detection and ensuring there is a path to completion for example.
Some of the interesting features I know JPDL possesses are an ability to help merge forked processes, timed tasks (including those that repeat periodically), and facilities for sending notification. This last item - notification - bears some further exposition. One of the things I've found with my own system is the need for sending out configurable email whose content is based on the data flowing through. These existing engines make that relatively easy by providing a way to plugin variables for instance into text that's then dynamically evaluated at run time before transmission. Also they provide bridges between the engine and whatever user store for the purpose of sending notifications to groups of people, tasking them and enforcing security policy.
Finally, depending on the scope of your system, you will probably still be using a database as well. What I suggest is storing off the XML and data being orchestrated into the database in a serialized format. Then, if the data is being altered as it travels through the execution, write out serializations of the data - and perhaps workflow if it is also changed - into a history/audit log table as well.
I would NOT use rdbms tables, or if you do, store the definitions as text blobs. Trying to make records for the definition is a bad idea because it's much more inflexible and difficult to change your definition over time. Many people would use different approaches, but I'd use JSON or YAML, and avoid XML. The motivation for that is to make it as simple as possible. Trying to use XML, especially a formalized specific format of XML is going to make you spend much more time meeting an exact specification that doesn't actually do anything to help what you're trying to accomplish. JSON and YAML are both very easy to work with from a code perspective. YAML is more easily readable by humans and easier to edit, and isn't as tricky for punctuation and escaping as JSON. JSON is more widely used, and is smaller than YAML. JSON also has a binary counterpart, BSON, if document size is a concern.
Once you have an importer/exporter that goes to/from your internal objects to your data format, then persisting using RDBMS, or other mechanisms, will be straightforward. You could even use CouchDB, which could offer other benefits to your application and may be a great fit.
Very good question! Here is my two cents:
RDBMS: if you do this you will be able to query the workflow instances, for example which tokens are at 'node X'?
Storing XML as clob: the simplicity is the truth of this solution, but you can't really query these just get them by id
NOSQL: there are a lot of different solutions for different problems. MongoDB is a popular solution, it provides document oriented persistence.
How about a simple serialisation of the composed UI using for example XStream and then store the serialised bits into the database as a binary column. Then when user logs in, get the associated data, deserialise, initialise if required and display.

Categories

Resources