Is there any way to customise the accessor strategy used in clojure.java.data/from-java? from-java is part of the java.data function lib.
I recently updated a third-pary Java-library that used to follow the JavaBean get and set pattern. However, after the update they went from getProperty() to property()...
I guess this change renders the from-java function not suitable in this case, no surprise since the objects are no longer proper JavaBeans.
Is there any way of making from-java aware of this accessor-pattern, or are there any other recursive mapping-mechanisms that supports this?
from-java is a multimethod, do you can override it for any class you like. There is no mechanism for teaching it an alternate naming convention (and if there were such a mechanism, I imagine it would have trouble with "every method with any name at all represents a property"). Therefore you'll have to write manual conversions, but at least the recursion will be handled for you.
It seems you will have to extend the multimethod to support the classes yourself, however, you can probably use reflection (slow, I know) to build something very generic:
For a given object instance, find its class, then the class' DeclaredFields, and from each fields get their name and type
For the same instance, use .getDeclaredMethod or .getDeclaredMethods to find methods for the given name that take no params (use an empty array for this). Those methods should be the new "getters" and you can call these in your instance to extract the values.
Use the Cognitect aws-api instead :)
Related
Question/Problem
Given a plain Java class coming from a non-EMF-aware API such as
public class BankAccount {
String ownerName;
int accountNumber;
// ...
}
and also let's assume that I am not allowed to change or recompile this class (because it is from an API).
Is there any simple way to use this class as an ESuperType for an EClass in EMF? (And, of course, the single class is just an example. I'd need to wrap an API consisting of 30-50 classes ...).
Own thoughts
Personally, I think it is not possible out of the box.
I could only think of two ways, both with quite some effort and not easy to realize.
Create an Ecore model which reflects the original class (EBankAccount, having ownerName and accountNumber as EAttributes) and a utility method/mechanism that wraps the original object by copying its fields into the corresponding EStructuralFeatures and adds EAdapters which are responsible to synchonize both objects.
Hook into EMF.CodeGen and do some magic there which makes it possible to have the original class as super class in the generated code which at the same time still fulfilling the EMF contract (= implement the EObject interface etc.).
But maybe there's some hidden feature of EMF (or an existing extension) which does something along these lines, and I am not aware of it?
It's not clear to me what you real want, but I will try to describe the several options.
If you want just to extend the POJO (which is what the question text suggests), the answer is YES, you can simply add a new EClass to your model and refer to the POJO qualified name in the "Instance Type Name" attribute. Then you can create other classes that extend from this one, but its state won't be managed by EMF.
But if you want EMF to track that POJO state as if it was a real EMF object (so those properties are also EStructuralFeature), then I don't see another solution, you really need to model it completely in EMF.
In this second case, both options you described seem possible.
The first option you described (and I assume you mean you want to synchronize the 2 objects, and not the 2 classes) seems the easiest one, and I don't think it would take so much effort if you use some generic method via reflection.
This might be a good solution if you get the objects in very concrete locations, so you only need to wrap and unwrap in specific places. Otherwise you will need to convert be converting (wraping/unwrapping) the object all the time.
It may be also possible but it requires more effort for sure, since it's not easy to extend the Java JET templates
I'm not aware of any extension for this.
I'm heavily using Java.lang.Class.getField() method which requires a String variable as an argument. The problem I'm facing is when I change field names, that getField() refers to, Eclipse doesn't warn me that argument points nowhere (since it's String) and I end up having methods working improperly unnoticed.
So far I can see two ways out. It's either using try-catch blocks around every getField() call and running application to see what will be the next line to throw an exception. Fix it and watch out for the next exception. Or it's using Find/Replace feature every time I change a field name to manually look for the String value and replace it. Is there a more friendly (i.e. automatic) way to update String parameters in such cases?
Maybe there's a method (which I fail to find) that accepts a full field path as a non-String argument and returns a Field object? Something like turnToFieldObject(car.speed) returning Field object corresponding to speed field so that Eclipse would automatically check if there's such a field car.speed.
PS
First of all, thank you for your replies.
I can see that a lot of you, guys, suggest that I'm using reflection too much. That's why I feel I need to add extra explanation and would be glad to hear suggestions as well.
I'm doing a research about modeling social evolution and I need the entities to evolve new features that they don't have at the start. And it seemed to me that adding new fields to represent some evolutional changes is better understanding wise than adding new elements to arrays or collections. And the task suggests I shouldn't be able to know what feature will be evolved. That's why I rely so heavily on reflection.
AFAIK, there is no such method. You pass a reference (if it's an object) or value (if it's primitive); all data about the variables that they were originally assigned to is not available at runtime.
This is the huge downside of using reflection, and if you're "heavily" using this feature in such way, you're probably doing something wrong. Why not access the field directly, using getters and setters?
Don't get me wrong, reflection has its uses (for example, when you want to scan for fields with certain annotations and inject their values), but if you're referencing fields or methods by their name using a simple string, you could just as well access fields or methods directly. It implies that you know the field beforehand. If it's private, there is probably a reason why it's encapsulated. You're losing the content assist and refactoring possibilities by overusing reflection.
If you're modeling social evolution, I'd go with a more flexible solution. Adding new fields at runtime is (near?) impossible, so you are basically forced to implement a new class for each entity and create a new object each time the entity "evolves". That's why I suggest you to go with one of these solutions:
Use Map<String, Object> to store entities' properties. This is a very flexible solution which will allow you easily add and remove "fields" at the cost of losing their type data. Checking if the entity has a certain property will be a cheap contains call.
If you really want to stick to a million custom classes, use interfaces with getters and setters in addition to fields. For example, convert private String name to interface Named { String getName(); void setName(String name); }. This is much easier to refactor and does not rely on reflection. A class can implement as many interfaces as you want, so this is pretty much like the field solution, except it allows you to create custom getters/setters with extra logic if desperately needed. And determining if entity has a certain property is a entity instanceof MyInterface call, which is still cheaper than reflection.
I would suggest writing a method that use to get your fields supply it a string and then if the exception is thrown notify whatever needs to be notified that it was not valid and if the exception isn't caught return the field.
Although I do agree with the above that reflection should not be used heavily.
If I have a constructor for an immutable object that requires several (4+ parameters), is having a single constructor with all the required parameters the correct approach?
I feel this becomes a candidate for the Builder pattern, but I also feel like shying away from it since the parameters are required, and a Builder seems more appropriate when you get to pick and choose.
The example in my mind is a model object that does not change once created.
If you want to create an immutable object, you have to provide a constructor with all necessary fields.
You cannot set the state partially as later you would have to add some notion of "setters" which would by definition add mutability.
Builder pattern is really about partial object building.
Both options have their drawbacks, as you suggest. A four argument constructor is hard to use correctly and makes the code hard to read. However, it communicates the intent that all parameters are mandatory.
A builder would be easier to use and make the code easier to read, but communicate the intent that the arguments are optional.
Since code is more often read than written, I recommend to use the option that promotes readability in this case. Go for a builder and make sure that all paramters are validated when the build() method is called to fail as fast as possible when using the builder incorrectly. Use javadoc to assist with communicating that all parameters are mandatory.
I have a class named ActivityLog. This class holds a list of ActivityRecords. I want to return a list of ActivityRecords by these criterias: Environment and Condition. Should the method name include the "criteria"? See example:
activityLog.allRecords();
activityLog.allRecordsBy(Environment environment);
activityLog.allRecordsBy(Condition condition);
activityLog.allRecordsBy(Condition condition, Environment environment);
or
activityLog.allRecordsByEnvironment(Environment environment);
activityLog.allRecordsByCondtion(Condition condition);
I probably think the first is better because you will read the method name and you will understand from the parameter what it does, but I may be wrong? Which is the best, or are there even better alternatives?
I could have named the methods records(), recordsBy etc. too, but I want to have a consitency through my API where you always start writing all for lists of objects so you get help from for example Intelli Sense.
I like putting the criteria in the actual method name. So I would use:
activityLog.allRecordsByEnvironment(Environment environment);
To me proper method naming expresses a small summary of what the method does. Since the parameters are included in the method signature I would not consider the parameters to be part of the actual name, therefore not placing the criteria in the name gives the user of an api incomplete information about the methods functionality. (IMO)
I applaud your effort to practice self documenting code, great practice.
I like the overloaded variant (your first example), because it communicates that the methods are all related and provide largely the same functionality, aka, you are returning records, filtered by some criteria. You will see examples of this in many open source libraries and even the SDK itself.
I'd treat it the same as static factory methods, which are named constructors. And there not only parameter says what this method does, its name itself does it. So I'd choose 2nd option.
#Bob, about names being too long - even if you would put 2 parameters into its name, it still would be ok for me. Anyway you should avoid having methods with more than 3 parameters. Following this rule will prevent your methods' names from being enormous long.
I would take the first one.
If these methods are doing the same thing or providing the same functionality then they should have the same name. But be aware of Effective Java Item 41 and 42. You've to ensure that at least one corresponding param of overloaded method are having radically different types.
The 2nd approach becomes ugly very fast with every param added. I see this in often in Broker classes at work. There are people writing methods like findByFirstnameAndLastnameAndBirthdayOrderByUgliness(blablub). No comment.
Methods in OOP represent behavior, so I would name all of them getRecords() and made them overloaded.
In my opinion, specifying criteria in the name of method looks like naming heirarchy classes like this
Car -> BMW_Car -> X5_BMW_Car
I am looking for an efficient (code-wise, and runtime-wise) means to identify whether a JavaBean object has changed.
I was thinking of holding a clone of the class that could be compared on demand to the class instance. This is similar to the strategy used by CSLA.net.
The question is, is there already a means to achieve this using native JRE JavaBeans, or with the addition of some library (Apache commons BeanUtils?) or, even by adding the constraint of JEE6 EJB's.
Ideas and theories both welcome...
bean-properties might have something helpful (although it's not JavaBean strictly speaking). Otherwise you can add a call to a notifyPropertyChanged(..) method from each setter - it's ugly, though.