I am working on a solution where I need to populate certain fields in a DataObject, though fields are predefined but source from where I need to populate this data is not in my control and I can not do any modification or changes.
This is a structure of my Source Object
SourceObject
-Collection<Features>
-Collection<FeatureData>
Attribute Name is defined in SourceObject which will help me to decided if I want that attribute value or not (There are many attributes (Framework Provided + Custom one)) and Value is being provided from Collection<FeatureData>
for(SourceData sourceData : productData.getSourceData())
{
if(sourceData.getCode().equalsIgnoreCase("classification"))
{
if(CollectionUtils.isNotEmpty(sourceData.getFeatures()))
{
for(FeatureData featureData : sourceData.getFeatures()){
if(CollectionUtils.isNotEmpty(featureData.getFeatureValues())){
if(featureData .getCode().contains("customValue1")){
for(FeatureValueData featureDataValue: featureData.getFeatureValues()){
productData.setPower(featureDataValue.getValue()));
break;
}
}
}
break;
}
}
}
}
But that means I have to do this (Check and Fill) for all my custom attributes. Is there way I can handle it in good way ?.
Please do not pay much attention to syntax or any potential NPE etc, as I will going to take care of those issues
From what I can comprehend from your code is that you are trying to find the very first sourceData whose code matches the "classification" value and also whose features collection isn't empty.
Then once such sourceData is found, you are trying to find the very first feature from the sourceData's features collection whose code contains the "customValue1" in it and whose featureValueData collection isn't empty.
Once such feature is found, you are effectively setting the productData's power as the value that is held by the very first featureValueData of the featureValueData collection of the feature.
Such code can be rewritten as follows:
// Start
SourceData sourceData = findFirstValidSource(productData.getSourceData());
if (sourceData == null) // Can remove this check if sure that at least one valid source data will always exist.
{
return;
}
FeatureData feature = findFirstValidFeature(sourceData.getFeatures());
if (feature == null) // Can also remove this check if sure that at least one valid feature data will always exist.
{
return;
}
FeatureValueData featureValueData = feature.getFeatureValues().iterator().next();
productData.setPower(featureValueData.getValue());
// End
The findFirstValidSource() method is implemented as follows:
private SourceData findFirstValidSource(Collection<SourceData> sources)
{
for (SourceData source : sources)
{
if (source.getCode().equalsIgnoreCase("classification") && CollectionUtils.isNotEmpty(source.getFeatures()))
{
return source;
}
}
return null;
}
The findFirstValidFeature() method is implemented as follows:
private FeatureData findFirstValidFeature(Collection<FeatureData> features)
{
for (FeatureData feature : features)
{
if (feature.getCode().contains("customValue1") && CollectionUtils.isNotEmpty(feature.getFeatureValues()))
{
return feature;
}
}
return null;
}
The above code will also do the exact same thing that your code is doing, except that its more readable and understandable now. The code can save some more processing if you make your getFeatureValues() method return a List instead of a Collection, as then it can grab the very first element through indexing (if implementation is ArrayList based) or by getting the first element (if implementation is LinkedList based), which will take constant time.
Not that the iterator().next() takes any more time, it just is useless to create an iterator in this case when there's no requirement of it as I did in the line:
FeatureValueData featureValueData = feature.getFeatureValues().iterator().next();
If getFeatureValues() would have returned a List, we could have written:
FeatureValueData featureValueData = feature.getFeatureValues().get(0);
instead.
Furthermore, the code can be made more compact by use of Lambda Expressions and Streams which are introduced in JDK 8. If you have no issues using the new features of Java 8, I can update my answer to incorporate a terser solution as well.
Let me know if my answer helped or if your expectations are still not met.
Related
I'm trying to add the RX Android pack library on a previous MVC project, wherein I'm trying to handle values from API responses to the Activity controller, passing by some controller that would do some additional operations on it.
The possibilities are that the value may be empty/optional/null by the API, in that case the controller would try to get the value from a cache storage, that also may be in the same condition, and finally pass it to the controller, where, depending the value, it would do some initing operation, or trying to make another API call with same mechanism, check that response, and then choose how to init the activity.
Example code (signatures are wrong)
In API:
Maybe<User> getUser(){
//...
}
In Controller:
Single<User> getUser(){
return API.getUser().switchIfEmpty(() -> Cache.getUser());
}
In Activity:
Disposable d = getUser().subscribe(user -> { if(user != null) init(user); else checkGuest(); } );
//...
void checkGuest(){
Disposable d = getGuest().subscribe(guest -> { init(guest) } );
}
All of this would be incredibly cool and smooth, except for a consideration, RX Java cannot handle null values. We may say that since Java 8 where are trying to get over null values in favor of Optional values (really?!?!?), so the Empty/Maybe pattern would be appropriate.
So, let's try this...
In API:
Maybe<User> getUser(){
//...
}
In Controller:
Single<User> getUser(){
return API.getUser().switchIfEmpty(() -> Cache.getUser()).switchIfEmpty(() -> ???);
}
In Activity:
Disposable d = getUser().subscribe(user -> { if(user != ???) init(user); else checkGuest(); } );
//...
void checkGuest(){
Disposable d = getGuest().subscribe(guest -> { init(guest) } );
}
I want to say that I hate and cannot accept at all to modify my models to add kind of additional attribute that would signs the instance as a Rx nulled instance, also because, this is an absolute violation of integrity, as of in any other method would be mandatory to check for that attribute, with a looooot of boilerplate.
Solutions:
1 I'm trying to handle this just by using single, and custom exception conditional checking in subscribe's error callable to decide where to proceed to next method in chain propagation, mixing functional and reactive programming.
2 I would have to modify my models, and use the RX Nulled instances in place of our beloved null values, but of course, also because I'm using Realm, and I can't even use polymorphism, and also, it violates integrity as said before.
3 Ideally, I would like to preserve the chain pattern and by using Maybe be able to execute a chain path if a previous value is Empty or another chain path if the value is not.
I would be happy if someone would feel like to front on the option 3, that would be the one that made me say "WOW" on the first time I seen a ReactiveX example.
After some searching, I found that eventually the best solution is in fact to... hold fast... to use Java 8 Optional!
First, this allows to keep the good old universal null like check pattern as always, so that we can't really need to forget about it, but also, to go on with the new technologies developments and so to conform to the new standard as we like to, and so to follow the new Java specifications as they come out.
This is also a "not" backward compatibility break, as in Android we can rely on some backporting dependencies to enable this before API level 24.
// support for optionals
compile "net.sourceforge.streamsupport:streamsupport:1.5.1"
And moreover, this permits to use chained operations, conditionality, ReactiveX and a Single value as we coders prefer to.
public Single<Optional<Model>> getMyModel(boolean offlineFallback) {
return apiInterface.getModel()
.map( model -> {
if( model.isPresent() ){
MyModel serverMyModel = model.get();
MyModel savedMyModel = databaseRepository.getMyModel();
if( serverMyModel != savedMyModel ){
serverMyModel.setMyAttribute(true);
databaseRepository.saveMyModel( serverMyModel );
}
return java8.util.Optional.ofNullable( serverMyModel );
}else{
if(offlineFallback){
MyModel MyModel = databaseRepository.getMyModel();
if(MyModel != null){
return java8.util.Optional.ofNullable(MyModel);
}
}
return Optional.empty();
}
});
}
Isn't this nice?
I have been using SnakeYAML for certain serialization/deserialization. My application combines Python and Java, so I need some "reasonable behaviour" on the Tags and the Types.
My problem / actual status on the YAML document:
!!mypackage.MyClassA
someFirstField: normal string
someSecondField:
a: !!mypackage.ThisIsIt
subField: 1
subOtherField: 2
b: !!mypackage.ThisIsIt
subField: 3
subOtherField: 4
someThirdField:
subField: 5
subOtherField: 6
I achieved the use of the tags inside collections (see example someSecondField) by reimplementing checkGlobalTag and simply performing return. This, if I understood correctly, ensures no smart cleanness of snakeyaml and maintains the tags. So far so good: I need the type everywhere.
However, this is not enough, because someThirdField is also a !!mypackage.ThisIsIt but it has implicit tag and this is a problem (Python does not understand it). There are some other corner cases which are not to the point (tried to take some shortcuts in the Python side, and they became a Bad Idea).
Which is the correct way to ensure that the tags appear for all user-defined classes? I assume that I should override some methods on the Representer, but I have not been able to find which one.
The line responsible for that "smart tag auto-clean" is the following:
if (property.getType() == propertyValue.getClass())
Which can be found in representJavaBeanProperty, for the class Representer.
The (ugly) solution I found is to extend the Representer and #Override the representJavaBeanProperty with the following:
protected NodeTuple representJavaBeanProperty(Object javaBean,
Property property,
Object propertyValue,
Tag customTag) {
// Copy paste starts here...
ScalarNode nodeKey = (ScalarNode) representData(property.getName());
// the first occurrence of the node must keep the tag
boolean hasAlias = this.representedObjects.containsKey(propertyValue);
Node nodeValue = representData(propertyValue);
if (propertyValue != null && !hasAlias) {
NodeId nodeId = nodeValue.getNodeId();
if (customTag == null) {
if (nodeId == NodeId.scalar) {
if (propertyValue instanceof Enum<?>) {
nodeValue.setTag(Tag.STR);
}
}
// Copy-paste ends here !!!
// Ignore the else block --always maintain the tag.
}
}
return new NodeTuple(nodeKey, nodeValue);
This also forces the explicit-tag-on-lists behaviour (previously enforced through the override of the checkGlobalTag method, now already implemented in the representJavaBeanProperty code).
I am implementing REST through RESTlet. This is an amazing framework to build such a restful web service; it is easy to learn, its syntax is compact. However, usually, I found that when somebody/someprogram want to access some resource, it takes time to print/output the XML, I use JaxbRepresentation. Let's see my code:
#Override
#Get
public Representation toXml() throws IOException {
if (this.requireAuthentication) {
if (!this.app.authenticate(getRequest(), getResponse()))
{
return new EmptyRepresentation();
}
}
//check if the representation already tried to be requested before
//and therefore the data has been in cache
Object dataInCache = this.app.getCachedData().get(getURI);
if (dataInCache != null) {
System.out.println("Representing from Cache");
//this is warning. unless we can check that dataInCache is of type T, we can
//get rid of this warning
this.dataToBeRepresented = (T)dataInCache;
} else {
System.out.println("NOT IN CACHE");
this.dataToBeRepresented = whenDataIsNotInCache();
//automatically add data to cache
this.app.getCachedData().put(getURI, this.dataToBeRepresented, cached_duration);
}
//now represent it (if not previously execute the EmptyRepresentation)
JaxbRepresentation<T> jaxb = new JaxbRepresentation<T>(dataToBeRepresented);
jaxb.setFormattedOutput(true);
return jaxb;
}
AS you can see, and you might asked me; yes I am implementing Cache through Kitty-Cache. So, if some XML that is expensive to produce, and really looks like will never change for 7 decades, then I will use cache... I also use it for likely static data. Maximum time limit for a cache is an hour to remain in memory.
Even when I cache the output, sometimes, output are irresponsive, like hang, printed partially, and takes time before it prints the remaining document. The XML document is accessible through browser and also program, it used GET.
What are actually the problem? I humbly would like to know also the answer from RESTlet developer, if possible. Thanks
I'm using Jena. I would like to know if there is a method that allows to modify or remove properties values of an instance?
Thanks
Statements in Jena are, by design, immutable. To change the value of a property p of some subject s, you need to add a new statement with the same subject and predicate, and remove the old statement. This is always true in Jena, even if the API sometimes hides this from you. For example, OntResource and its subclasses have a variety of setProperty variants, but under the hood these are performing the same add-the-new-triple-and-delete-the-old process.
It depends which Jena API you are using. For instance, if you are using Jena 3.0 and the Model API, you can use Model.remove(Statement) to remove a property by choosing the appropriate subject/predicate/object for the Statement. Modification can be achieved by removing the old version of a Statement and adding the new version.
To only remove the statement itself, i.e. the relation between the instance and the property value, you can use:
OntResource.removeProperty(Property, RDFNode)
If you want to remove the property value altogether, i.e. the value and all relations to it, you can use: OntResource.remove()
I had the similar task: I need to delete the property with the specified value. Hope the following code snippet will help someone.
public void removeLabel(String language, String value) {
NodeIterator nodeIterator = resource.getModel().listObjectsOfProperty(RDFS.label);
RDFNode foundToDelete = null;
while (nodeIterator.hasNext()) {
RDFNode next = nodeIterator.next();
boolean langsAreIdentical = next.asLiteral().getLanguage().equals(language);
boolean valuesAreIdentical = next.asLiteral().getLexicalForm().equals(value);
if (langsAreIdentical && valuesAreIdentical) {
foundToDelete = next;
break;
}
}
resource.getModel().remove(resource, RDFS.label, foundToDelete);
}
The situation seems to be abnormal, but I was asked to build serializer that will parse an object into string by concatenating results of "get" methods. The values should appear in the same order as their "get" equivalent is declared in source code file.
So, for example, we have
Class testBean1{
public String getValue1(){
return "value1";
}
public String getValue2(){
return "value2";
}
}
The result should be:
"value1 - value2"
An not
"value2 - value1"
It can't be done with Class object according to the documentation. But I wonder if I can find this information in "*.class" file or is it lost? If such data exists, maybe, someone knows a ready to use tool for that purpose? If such information can't be found, please, suggest the most professional way of achieving the goal. I thought about adding some kind of custom annotations to the getters of the class that should be serialized.
If you want that you have to parse the source code, not the byte code.
There are a number of libraries that parse a source file into a node tree, my favorite is the javaparser (hosted at code.google.com), which, in a slightly modified version, is also used by spring roo.
On the usage page you can find some samples. Basically you will want to use a Visitor that listens for MethodDefinitions.
Although reflection does not anymore (as of java 7 I think) give you the methods in the order in which they appear in the source code, the class file appears to still (as of Java 8) contain the methods in the order in which they appear in the source code.
So, you can parse the class file looking for method names and then sort the methods based on the file offset in which each method was found.
If you want to do it in a less hacky way you can use Javassist, which will give you the line number of each declared method, so you can sort methods by line number.
I don't think the information is retained.
JAXB, for example, has #XmlType(propOrder="field1, field2") where you define the order of the fields when they are serialized to xml. You can implemenet something similar
Edit: This works only on concrete classes (the class to inspect has its own .class file). I changed the code below to reflect this. Until diving deeper into the ClassFileAnalyzer library to work with classes directly instead of reading them from a temporary file this limitation exists.
Following approach works for me:
Download and import following libarary ClassFileAnalyzer
Add the following two static methods (Attention! getClussDump() needs a little modification for writing out the class file to a temporary file: I removed my code here because it's very special at this point):
public static String getClassDump(Class<?> c) throws Exception {
String classFileName = c.getSimpleName() + ".class";
URL resource = c.getResource(classFileName);
if (resource == null) {
throw new RuntimeException("Works only for concreate classes!");
}
String absolutePath = ...; // write to temp file and get absolute path
ClassFile classFile = new ClassFile(absolutePath);
classFile.parse();
Info infos = new Info(classFile, absolutePath);
StringBuffer infoBuffer = infos.getInfos();
return infoBuffer.toString();
}
public static <S extends List<Method>> S sortMethodsBySourceOrder(Class<?> c, S methods) throws Exception {
String classDump = getClassDump(c);
int index = classDump.indexOf("constant_pool_count:");
final String dump = classDump.substring(index);
Collections.sort(methods, new Comparator<Method>() {
public int compare(Method o1, Method o2) {
Integer i1 = Integer.valueOf(dump.indexOf(" " + o1.getName() + lineSeparator));
Integer i2 = Integer.valueOf(dump.indexOf(" " + o2.getName() + lineSeparator));
return i1.compareTo(i2);
}});
return methods;
}
Now you can call the sortMethodsBySourceOrder with any List of methods (because sorting arrays is not very comfortable) and you will get the list back sorted.
It works by looking at the class dumps constant pool which in turn can be determined by the library.
Greetz,
GHad
Write your custom annotation to store ordering data, then use Method.getAnnotation(Class annotationClass)