martedì 12 aprile 2016

What makes JMapper unique

Regardless of the many features already mentioned on several occasions, the feature that makes JMapper unique compared to the competition is the separation between the  relation between variables and mapping logic.

What is meant by relation between variables?
It means the mapping configuration with one of the three permitted types, for example:

class User {              class UserDTO {

   @JMap String name;               String name;
   @JMap Integer age;               Integer age;
   @JMap String address;            String address;

   // getters and setters..         // getters and setters..

}                                }

What is meant by mapping logic?
it means that you can choose what to take from the source and which fields of destination must be mapped.

There may be cases in which the relationship is the same but must be taken into account only valued source fields, or in the case of enrichment, to be considered only the null destination fields.

Issue
we need to combine the data from the database with the user entries, many fields are optional and the user only has updated some of their own profile fields.

First of all we need of a Jmapper instance:

JMapper<UserDTO, User> mapper = new JMapper<>(UserDTO.class, User.class);

1° solution

We take only the valorized fields defined from user keeping the previous values.

mapper.getDestination(userDTO, user, MappingType.ALL_FIELDS, MappingType.ONLY_VALUED_FIELDS);

What we are saying with this code is to consider only the fields of source that are valorized.

2° solution

We also want to keep the fields left empty by user.

mapper.getDestination(userDTO, user, MappingType.ALL_FIELDS, MappingType.ALL_FIELDS);

In this case all field are mapped, also null fields.

The results of this two solutions are different but the configuration is the same!
This is the key of JMapper, the separation between configuration and mapping logic.

With any other library you have to create a configuration for each type of mapping that you want to implement!

This is definitely a topic on which reason before choosing which framework to use.











giovedì 1 ottobre 2015

Partial mapping with JMapper

Hi guys,

with this post i will illustrate how is possible define a mapping strategy with JMapper.
The classic scenario is a mapping where value from source must be passed to destination, but there are cases where what we need is pass from source only valorized fields or.. we want that only the null fields of destination will be mapped.. this cases are handled very well by JMapper.

The following example will use these classes:

class Destination {              class Source {

   @JMap String name;               String name;
   @JMap Integer age;               Integer age;
   @JMap String company;            String company;

   // getters and setters..         // getters and setters..

}                                }

JMapper istance generation:

JMapper<Destination, Source> mapper = new JMapper<>(Destination.class, Source.class);

Ok, it's arrived the moment to see what Jmapper permits to do.
This are the filled beans:
Destination destination = new Destination("empty", null, "Anonymous");
Source source = new Source("Alessandro", 30, null);

We want to take only the valued fields of Source:

Destination result = mapper.getDestination(destination, source, MappingType.ALL_FIELDS, MappingType.ONLY_VALUED_FIELDS);
Result:
Destination[ name="Alessandro", age=30, company="Anonymous"]
We want just fill null fields of Destination:

Destination result = mapper.getDestination(destination, source, MappingType.ONLY_NULL_FIELDS, MappingType.ALL_FIELDS);

Result:
Destination[ name="empty", age=30, company="Anonymous"]

There are a lot of other combinations.. try to find yourself    :)

venerdì 1 maggio 2015

JMapper Framework philosophy

There are a lot of java mapping framework, each of them developed on a basic principle.
For example MapStruct applies loose coupling using annotations, Orika the same using API, Model Mapper is convention based etc...

JMapper Framework instead applies the DRY principle ( Don't repeat yourself ) using Annotations:
the mappings are defined on fields so that they are used as configuration, 
the loose coupling imposes to repeat this information.

However, with JMapper, you can choose to apply loose coupling using the XML or API configuration.

The second objective of JMapper is the Relational Mapping:

The relational mapping is the ability to map one bean toward many other and viceversa.

REAL CASE

Thinks you have a service that applies a method called "checkExistence" that needs of the fields: name and surname. This service takes as input a general object that can be everything, in our case takes three different bean: Consultant, Employee and Manager. This beans have in common only this two fields and we have need to map only these toward the service's bean.

SOLUTION

With JMapper you need to configure only the service's bean toward the others.

IMPLEMENTATION

@JGlobalMap(classes={Consultant.class, Employee.class, Manager.class})
class ServiceBean{

     String name;
     String surname;

     //getters and setters..
}

USAGE

class Service {

RelationalJMapper<ServiceBean> mapper = new RelationalJMapper<>(ServiceBean.class);

   public void checkExistence(Object bean){
        ServiceBean serviceBean =  mapper.manyToOne(bean);
        // some logic  
   }
}

CONCLUSION

DRY principle + relational mapping  = interesting implementations

Are you curious? have a look to the relational mapping wiki page, there a lot of complete and more complex examples.

p.s. JMapper has more other interesting features as static/dynamic conversions, enrichment, mapping type etc.., don't worry in the next articles i'll describe all of it ;)





lunedì 19 gennaio 2015

How to write a good XML schema

XML Schema is a formal description of a grammar for a markup language based on XML.
 There are a lot of guides and articles about this, i suggest to visit W3C XML Schema (XSD) as start point,
 for grammar analysis: W3C XML Schema (XSD) Validation online.

The purpose of this article is to give you some tips on how to write a better xml schema.

 It's very important to know default values of all tag, for several reasons:
 - define all parameters as maxOccurs, minOccurs, optional, use etc.. for all tag makes the xsd difficult to read and modify.
 - Alternatively define a few, ignoring the default values, leads to abnormal behavior, found only with test
Here you can found all default values for all tag.

Make your xsd more readable, for this purpose you can use:
 - complexType to externalize a attribute type, for example:

 Before:
        <xs:element name="employee">
      <xs:complextype>
        <xs:sequence>
          <xs:element name="firstname" type="xs:string"/>
          <xs:element name="lastname" type="xs:string"/>
        </xs:sequence>
      </xs:complextype>
    </xs:element>
  <xs:element name="student">
   <xs:complextype>
<xs:sequence>
         <xs:element name="firstname" type="xs:string"/>
         <xs:element name="lastname" type="xs:string"/>
  </xs:sequence>
    </xs:complextype>
  </xs:element>

 after:
<xs:element name="employee" type="personinfo">
<xs:element name="student" type="personinfo">

<xs:complextype name="personinfo">
  <xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
  </xs:sequence>
</xs:complextype>

 - import an external xsd and use it with namespace
 - add comments as markers, it permits to go fast on the interested point, you have to think that not everyone uses XML tools.

 - use extension or restriction of complexContent if your element is almost equal to an existing.

 follow an example of extention:

<xs:element name="employee" type="fullpersoninfo">

<xs:complextype name="personinfo">
  <xs:sequence>
    <xs:element name="firstname" type="xs:string"/>
    <xs:element name="lastname" type="xs:string"/>
  </xs:sequence>
</xs:complextype>

<xs:complextype name="fullpersoninfo">
  <xs:complexcontent>
    <xs:extension base="personinfo">
      <xs:sequence>
        <xs:element name="address" type="xs:string"/>
        <xs:element name="city" type="xs:string"/>
        <xs:element name="country" type="xs:string"/>
      </xs:sequence>
    </xs:extension>
  </xs:complexcontent>
</xs:complextype>

an example of restriction:

<xs:complextype name="customer">
  <xs:sequence>
    <xs:element name="firstname" type="xs:string"/>
    <xs:element name="lastname" type="xs:string"/>
    <xs:element name="country" type="xs:string"/>
  </xs:sequence>
</xs:complextype>

<xs:complextype name="Norwegian_customer">
  <xs:complexcontent>
    <xs:restriction base="customer">
      <xs:sequence>
        <xs:element name="firstname" type="xs:string"/>
        <xs:element name="lastname" type="xs:string"/>
        <xs:element fixed="Norway" name="country" type="xs:string"/>
      </xs:sequence>
    </xs:restriction>
  </xs:complexcontent>
</xs:complextype>

 Few tips but if used makes the development, of large XSD file, sustainable.

lunedì 29 settembre 2014

java File Watcher

With the new features of java 7 was introduced the WatchService class, with it we know all action done on the watched folder.
But there isn't an implementation that permits to watch a single file so.. follows a my implementation called FileWatcher:

import java.io.IOException;
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.*;

public class FileWatcher implements Runnable{

 private final WatchService watcher;
 private Path fileToWatch;
 
 
 public FileWatcher(String filePath) throws IOException {
  Path path = Paths.get(filePath);
  this.fileToWatch = path.getFileName();
  path.getParent().register(watcher, ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY);
 }

 @Override
 public void run() {
  for (;;) {
   
   // wait for key to be signaled
      WatchKey key;
      try {
          key = watcher.take();
      } catch (InterruptedException x) {
          return;
      }
      
      for (WatchEvent event: key.pollEvents()) {
          WatchEvent.Kind kind = event.kind();

          if (kind == OVERFLOW) continue;
          
          // The filename is the
          // context of the event.
          @SuppressWarnings("unchecked")
          Path fileName = ((WatchEvent)event).context();
             
          if(!fileName.equals(fileToWatch))
              continue;
             
          if(kind == ENTRY_CREATE) create();
             
          if(kind == ENTRY_DELETE) delete();             
     
          if(kind == ENTRY_MODIFY) modify();
     
      }

      // Reset the key -- this step is critical if you want to
      // receive further watch events.  If the key is no longer valid,
      // the directory is inaccessible so exit the loop.
      boolean valid = key.reset();
      if (!valid) {
          break;
      }
  }
 }

 public void modify() {}
 
 public void delete() {}
 
 public void create() {}
 
}

An example of use:

new Thread(new FileWatcher(filePath){
               @Override
               public void modify() {
                  System.out.println("modified");
               }
           }).start();

giovedì 3 ottobre 2013

Vaadin Tree: how to edit node

Change the tree nodes is possible and I will show you how to do.
Purpose: change the value of the selected node.
Solution:
Object selectedNode = tree.getValue();
tree.setItemCaption(selectedNode, "new value");

Make good use of it :)

venerdì 5 luglio 2013

Java Calendar

In this post i show how to obtain the calendar of the current month, and how to know the days of the week.
First of all you need to obtain three parameters, number of days of the current month, the month and the year.

GregorianCalendar cal = new GregorianCalendar();
cal.setTime(new Date());
int numDays = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
int month = cal.get(Calendar.MONTH);
int year = cal.get(Calendar.YEAR);

To know which day of the week the date belongs:

for (int date = 1; date <= numDays; date++) {
   cal.set(year, month, date);
   String dayName = dayName(cal.get(Calendar.DAY_OF_WEEK));
   System.out.println(date + "-" + month + "-" + year + " " + dayName);    
}

String dayName(int day) {
   switch (day) {
      case Calendar.MONDAY:   return "Monday";
      case Calendar.TUESDAY:  return "Tuesday";
      case Calendar.WEDNESDAY:return "Wednesday";
      case Calendar.THURSDAY: return "Thursday";
      case Calendar.FRIDAY:   return "Friday";
      case Calendar.SATURDAY: return "Saturday";
      case Calendar.SUNDAY:   return "Sunday";
      default:                return "";
   }
}

Output:

1-6-2013 Monday
2-6-2013 Tuesday
3-6-2013 Wednesday
4-6-2013 Thursday
5-6-2013 Friday
6-6-2013 Saturday
7-6-2013 Sunday
8-6-2013 Monday
9-6-2013 Tuesday
10-6-2013 Wednesday
.......