Rep exposure documentation - java

I am implementing a graph data structure in java. In this structure, vertices are represented as Vertex objects containing a private final String value field.
One of my methods vertices() returns the set of values of all vertices. In particular, a client who gets this set cannot get a particular value from the set and set it to another string (because of the final modifier). How should I document this behavior in the javadocs of vertices()?

Unfortunately the Java standard library doesn't have an interface for immutable collections.
I think all you can do is to wrap the Set you return in an UnmodifiableSet via Collections.unmodifiableSet and mention in the Javadoc that the Set being returned is immutable.

Related

Indexing a simple Java Record

I have a Java Object, Record . It represents a single record as a result of SQL execution. Can CQEngine index collection of Record ?
My class is of the form
public class Record {
private List<String> columnNames;
private List<Object> values;
... Other getters
}
I have looked through some examples, but I have no luck there.
I want to index only specific column(s) with its name and corresponding value. Can this be achived using cqengine or is there any other alternatives to achieve the same.
Thanks.
That seems to be a strange way to model data, but you can use CQEngine with that model if you wish.
(First off, CQEngine will have no use for your column names so you can remove that field.)
To do this, you will need to define a CQEngine virtual attribute for each of the indexes in your list of values.
Each attribute will need to be declared with the data type which will be stored in that column/index, and will need to be able to cast the object at that index in your list of values, to the appropriate data type (String, Double, Integer etc.).
So let's say your Record has a column called 'price', which is of type Double, and is stored at index 5 in the list of values. You could define an attribute which reads it as follows:
public static final Attribute<Record, Double> PRICE =
attribute("PRICE", record -> ((Double) record.values.get(5));
If this sounds complicated, it's because that way of modelling data makes things a bit complicated :) It's usually easier to work with a data model which leverages the Java type system (which your model does not). As such, you will need to keep track of the data types etc. of each field programmatically yourself.
CQEngine itself will work fine with that model though, because at the end of the day CQEngine attributes don't need to read fields, the attributes are just functions which are programmed to fetch values.
There's a bunch of stuff not covered above. For example can your values be null? (if so, you should use the nullable variety of attributes as discussed in the CQEngine docs. Or, might each of your Record objects have different sets of columns? (if so, you can create attributes on-the-fly when you encounter a new column, but you should probably cache the attributes you have created somewhere).
Hope that helps,
Niall (CQEngine author)

Multiple default values for collections with Jersey

I'm using Jersey and want a set that, when not added as a query param, defaults to a set containing more than one object.
I basically want this:
#DefaultValue("test1", "test2")
#QueryParam("test")
private Set<MyEnum> test;
to return a set containing the enums "test1" and "test2".
I'm having no problem getting a single default value to work but I would like multiple. The docs are a bit cryptical, is it possible?
According to this source from stackoverflow and the official documentation you can only do this by manually checking if the object is null then set the default value

Updating values of functional data properties doesn't remove old values, only adds new triples

I have an RDF Ontology with a functional property hasTrendValue which relates instances of a class with integer values. I want to change these values programmatically using Jena. I tried the following code:
Property hasTrend = ontModel.getDatatypeProperty(preFix+"hasTrendValue");
Individual regionQualifier = ontModel.getIndividual(activityName);
ontModel.addLiteral(regionQualifier,hasTrend,34);
PrintStream p = new PrintStream(ontoPath);
ontModel.write(p,null);
p.close();
This code executes correctly but, it does not update the already hasTrendValue value in the RDF; instead it adds a new hasTrendValue to the RDF ontology even though it declared as a functional property. What is the better way of doing this?
RDF does not have the concept of "change", only "add" and "remove". To change a value, you need to remove the old one and add the new one.
Declaring it as a functional property does not change this. Jena does not check the ontology on every operation. In fact, a functional property says that the object identifies one thing - it may be written in many ways. 001 and 1 are the same value. There may be multiple triples, it's not automatically wrong.

Java classes with dynamic fields

I'm looking for clever ways to build dynamic Java classes, that is classes where you can add/remove fields at runtime. Usage scenario: I have an editor where users should be able to add fields to the model at runtime or maybe even create the whole model at runtime.
Some design goals:
Type safe without casts if possible for custom code that works on the dynamic fields (that code would come from plugins which extend the model in unforeseen ways).
Good performance (can you beat HashMap? Maybe use an array and assign indexes to the fields during setup?)
Field "reuse" (i.e. if you use the same type of field in several places, it should be possible to define it once and then reuse it).
Calculated fields which depend on the value of other fields
Signals should be sent when fields change value (no necessarily via the Beans API)
"Automatic" parent child relations (when you add a child to a parent, then the parent pointer in the child should be set for "free").
Easy to understand
Easy to use
Note that this is a "think outside the circle" question. I'll post an example below to get you in the mood :-)
Type safe without casts if possible for custom code that works on the dynamic fields (that code would come from plugins which extend the model in unforeseen ways)
AFAIK, this is not possible. You can only get type-safety without type casts if you use static typing. Static typing means method signatures (in classes or interfaces) that are known at compile time.
The best you can do is have an interface with a bunch of methods like String getStringValue(String field), int getIntValue(String field) and so on. And of course you can only do that for a predetermined set of types. Any field whose type is not in that set will require a typecast.
The obvious answer is to use a HashMap (or a LinkedHashMap if you care for the order of fields). Then, you can add dynamic fields via a get(String name) and a set(String name, Object value) method.
This code can be implemented in a common base class. Since there are only a few methods, it's also simple to use delegation if you need to extend something else.
To avoid the casting issue, you can use a type-safe object map:
TypedMap map = new TypedMap();
String expected = "Hallo";
map.set( KEY1, expected );
String value = map.get( KEY1 ); // Look Ma, no cast!
assertEquals( expected, value );
List<String> list = new ArrayList<String> ();
map.set( KEY2, list );
List<String> valueList = map.get( KEY2 ); // Even with generics
assertEquals( list, valueList );
The trick here is the key which contains the type information:
TypedMapKey<String> KEY1 = new TypedMapKey<String>( "key1" );
TypedMapKey<List<String>> KEY2 = new TypedMapKey<List<String>>( "key2" );
The performance will be OK.
Field reuse is by using the same value type or by extending the key class of the type-safe object map with additional functionality.
Calculated fields could be implemented with a second map that stores Future instances which do the calculation.
Since all the manipulation happens in just two (or at least a few) methods, sending signals is simple and can be done any way you like.
To implement automatic parent/child handling, install a signal listener on the "set parent" signal of the child and then add the child to the new parent (and remove it from the old one if necessary).
Since no framework is used and no tricks are necessary, the resulting code should be pretty clean and easy to understand. Not using String as keys has the additional benefit that people won't litter the code with string literals.
So basically you're trying to create a new kind of object model with more dynamic properties, a bit like a dynamic language?
Might be worth looking at the source code for Rhino (i.e. Javascript implemented in Java), which faces a similar challenge of implementing a dynamic type system in Java.
Off the top of my head, I suspect you will find that internal HashMaps ultimately work best for your purposes.
I wrote a little game (Tyrant - GPL source available) using a similar sort of dynamic object model featuring HashMaps, it worked great and performance was not an issue. I used a few tricks in the get and set methods to allow dynamic property modifiers, I'm sure you could do the same kind of thing to implement your signals and parent/child relations etc.
[EDIT] See the source of BaseObject how it is implemented.
You can use the bytecode manipulation libraries for it. Shortcoming of this approach is that you need to do create own classloader to load changes in classes dynamically.
I do almost the same, it's pure Java solution:
Users generate their own models, which are stored as JAXB schema.
Schema is compiled in Java classes on the fly and stored in
user jars
All classes are forced to extend one "root" class, where you could put every extra functionality you want.
Appropriate classloaders are implemented with "model change"
listeners.
Speaking of performance (which is important in my case), you can hardly beat this solution. Reusability is the same of XML document.

Empty list in App Engine Datastore: Java vs Python

I have the following java model class in App Engine:
public class Xyz ... {
#Persistent
private Set<Long> uvw;
}
When saving an object Xyz with an empty set uvw in Java, I get a "null" field (as listed in the appengine datastore viewer).
When I try to load the same object in Python (through remote_api), as defined by the following python model class:
class Xyz(db.Model):
uvw = db.ListProperty(int)
I get a "BadValueError: Property uvw is required".
When saving another object of the same class in Python with an empty uvw list, the Datastore viewer prints a "missing" field.
Apparently empty lists storage handling differs between Java and Python and lead to "incompatible" objects.
Thus my question: Is there a way to, either:
force Java to store an empty list as a "missing" field,
force Python to gracefully accept a "null" list as an empty list when loading the object?
Or any other suggestion on how to handle empty list field in both languages.
Thanks for your answers!
It should work if you assign a default value to your Python property:
uvw = db.ListProperty(int, default=[])
I use the low-level java api, so perhaps what I am doing would be different. But before I save a collection-type data structure to the datastore, I convert it into something that the datastore naturally handles. This would include mainly Strings and ByteArrays.
It sounds like java app engine is interpreting the empty set as a null value. And python is not reading this null value correctly. You might try saving an empty set as the String value "empty set". And then have python check to see if the datastore holds that string value. If it does, it could allocate a new empty set, if not, it could read the property as a set.
The Java Set behavior is because Java's Collections are reference types, which default to being null.
To actually create an empty Set, declare it like this:
#Persistent
private Set<Long> uvw = new HashSet<Long>();
or using some other implementation of Set on the right side. HashSet is the most commonly used Set type, though. Other interesting set types are the two thread-safe Sets CopyOnWriteArraySet and ConcurrentSkipListSet; also the Ordered Set type LinkedHashSet and the Sorted Set type TreeSet.
It may work to you
uvw = db.ListProperty(int, default=[])
Its the most comment way to short it out...

Categories

Resources