tag:blogger.com,1999:blog-70251802404773783772024-02-08T04:37:49.210-08:00code's devourerAlexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.comBlogger12125tag:blogger.com,1999:blog-7025180240477378377.post-28932151440390946412016-04-12T06:20:00.002-07:002016-04-12T07:17:03.815-07:00What makes JMapper uniqueRegardless of the many features already mentioned on several occasions, the feature that makes JMapper unique compared to the competition is the separation between the <b>relation between variables</b> and <b>mapping logic</b>.<br />
<br />
<i>What is meant by relation between variables?</i><br />
It means the mapping configuration with one of the three permitted types, for example:<br />
<br />
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: consolas, 'liberation mono', menlo, courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><pre style="border-radius: 3px; box-sizing: border-box; font-family: consolas, 'liberation mono', menlo, courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">class</span> <span class="pl-en" style="box-sizing: border-box; color: #795da3;">User</span> { <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">class</span> <span class="pl-en" style="box-sizing: border-box; color: #795da3;">UserDTO</span> {
<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">@JMap</span> <span class="pl-smi" style="box-sizing: border-box;">String</span> name; <span class="pl-smi" style="box-sizing: border-box;">String</span> name;
<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">@JMap</span> <span class="pl-smi" style="box-sizing: border-box;">Integer</span> age; <span class="pl-smi" style="box-sizing: border-box;">Integer</span> age;
<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">@JMap</span> <span class="pl-smi" style="box-sizing: border-box;">String</span> address; <span class="pl-smi" style="box-sizing: border-box;">String</span> address;
<span class="pl-c" style="box-sizing: border-box; color: #969896;">// getters and setters.. // getters and setters..</span>
} }</pre>
</pre>
<br />
<i>What is meant by mapping logic?</i><br />
it means that you can choose what to take from the source and which fields of destination must be mapped.<br />
<br />
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.<br />
<br />
<b>Issue</b><br />
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.<br />
<br />
First of all we need of a Jmapper instance:<br />
<br />
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: consolas, 'liberation mono', menlo, courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">JMapper<<span class="pl-smi" style="box-sizing: border-box; color: #333333;">UserDTO</span>, <span class="pl-smi" style="box-sizing: border-box; color: #333333;">User</span>></span> mapper <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">=</span> <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">new</span> <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">JMapper<></span>(<span style="font-size: 13.6px; line-height: 1.45;">UserDTO</span><span class="pl-k" style="box-sizing: border-box; color: #a71d5d; font-size: 13.6px; line-height: 1.45;">.</span><span style="font-size: 13.6px; line-height: 1.45;">class, </span><span style="font-size: 13.6px; line-height: 1.45;">User</span><span class="pl-k" style="box-sizing: border-box; color: #a71d5d; font-size: 13.6px; line-height: 1.45;">.</span><span style="font-size: 13.6px; line-height: 1.45;">class);</span></pre>
<br />
<b>1° solution</b><br />
<b><br /></b>
We take only the valorized fields defined from user keeping the previous values.<br />
<br />
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: consolas, 'liberation mono', menlo, courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;">mapper<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span>getDestination(userDTO, user, <span class="pl-smi" style="box-sizing: border-box;">MappingType</span><span class="pl-c1" style="box-sizing: border-box; color: #0086b3;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span></span><span style="color: #0086b3; font-size: 13.6px; line-height: 1.45;">ALL_FIELDS</span><span style="font-size: 13.6px; line-height: 1.45;">, </span><span class="pl-smi" style="box-sizing: border-box; font-size: 13.6px; line-height: 1.45;">MappingType</span><span class="pl-c1" style="box-sizing: border-box; color: #0086b3; font-size: 13.6px; line-height: 1.45;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span>ONLY_VALUED_FIELDS</span><span style="font-size: 13.6px; line-height: 1.45;">);</span></pre>
<br />
What we are saying with this code is to consider only the fields of source that are valorized.<br />
<br />
<b>2° solution</b><br />
<br />
We also want to keep the fields left empty by user.<br />
<br />
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: consolas, 'liberation mono', menlo, courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;">mapper<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span>getDestination(userDTO, user, <span class="pl-smi" style="box-sizing: border-box;">MappingType</span><span class="pl-c1" style="box-sizing: border-box; color: #0086b3;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span></span><span style="color: #0086b3; font-size: 13.6px; line-height: 1.45;">ALL_FIELDS</span><span style="font-size: 13.6px; line-height: 1.45;">, </span><span class="pl-smi" style="box-sizing: border-box; font-size: 13.6px; line-height: 1.45;">MappingType</span><span class="pl-c1" style="box-sizing: border-box; color: #0086b3; font-size: 13.6px; line-height: 1.45;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span></span><span style="color: #0086b3; font-size: 13.6px; line-height: 1.45;">ALL_FIELDS</span><span style="font-size: 13.6px; line-height: 1.45;">);</span></pre>
<br />
In this case all field are mapped, also null fields.<br />
<b><br /></b>
<b>The results of this two solutions are different but the configuration is the same!</b><br />
This is the key of JMapper, the separation between configuration and mapping logic.<br />
<br />
With any other library you have to create a configuration for each type of mapping that you want to implement!<br />
<br />
This is definitely a topic on which reason before choosing which framework to use.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Alexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.com0tag:blogger.com,1999:blog-7025180240477378377.post-80208316007271347862015-10-01T03:13:00.002-07:002016-04-12T03:46:43.947-07:00Partial mapping with JMapperHi guys,<br />
<br />
with this post i will illustrate how is possible define a mapping strategy with JMapper.<br />
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.<br />
<br />
The following example will use these classes:<br />
<br />
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">class</span> <span class="pl-en" style="box-sizing: border-box; color: #795da3;">Destination</span> { <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">class</span> <span class="pl-en" style="box-sizing: border-box; color: #795da3;">Source</span> {
<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">@JMap</span> <span class="pl-smi" style="box-sizing: border-box;">String</span> name; <span class="pl-smi" style="box-sizing: border-box;">String</span> name;
<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">@JMap</span> <span class="pl-smi" style="box-sizing: border-box;">Integer</span> age; <span class="pl-smi" style="box-sizing: border-box;">Integer</span> age;
<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">@JMap</span> <span class="pl-smi" style="box-sizing: border-box;">String</span> company; <span class="pl-smi" style="box-sizing: border-box;">String</span> company;
<span class="pl-c" style="box-sizing: border-box; color: #969896;">// getters and setters.. // getters and setters..</span>
} }</pre>
<br />
JMapper istance generation:<br />
<br />
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">JMapper<<span class="pl-smi" style="box-sizing: border-box; color: #333333;">Destination</span>, <span class="pl-smi" style="box-sizing: border-box; color: #333333;">Source</span>></span> mapper <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">=</span> <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">new</span> <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">JMapper<></span>(<span class="pl-smi" style="box-sizing: border-box;">Destination</span><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span>class, <span class="pl-smi" style="box-sizing: border-box;">Source</span><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span>class);</pre>
<br />
Ok, it's arrived the moment to see what Jmapper permits to do.<br />
This are the filled beans:<br />
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: consolas, 'liberation mono', menlo, courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-smi" style="box-sizing: border-box;">Destination</span> destination <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">=</span> <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">new</span> <span class="pl-smi" style="box-sizing: border-box;">Destination</span>(<span class="pl-s" style="box-sizing: border-box; color: #183691;"><span class="pl-pds" style="box-sizing: border-box;">"</span>empty<span class="pl-pds" style="box-sizing: border-box;">"</span></span>, <span class="pl-c1" style="box-sizing: border-box; color: #0086b3;">null</span>, <span class="pl-s" style="box-sizing: border-box; color: #183691;"><span class="pl-pds" style="box-sizing: border-box;">"</span>Anonymous<span class="pl-pds" style="box-sizing: border-box;">"</span></span>);
<span class="pl-smi" style="box-sizing: border-box;">Source</span> source <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">=</span> <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">new</span> <span class="pl-smi" style="box-sizing: border-box;">Source</span>(<span class="pl-s" style="box-sizing: border-box; color: #183691;"><span class="pl-pds" style="box-sizing: border-box;">"</span>Alessandro<span class="pl-pds" style="box-sizing: border-box;">"</span></span>, <span class="pl-c1" style="box-sizing: border-box; color: #0086b3;">30</span>, <span class="pl-c1" style="box-sizing: border-box; color: #0086b3;">null</span>);</pre>
<br />
We want to take only the valued fields of Source:<br />
<br />
<div class="highlight highlight-source-java" style="background-color: white; box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;">
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-smi" style="box-sizing: border-box;">Destination</span> result <span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">=</span> mapper<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span>getDestination(destination, source, <span class="pl-smi" style="box-sizing: border-box;">MappingType</span><span class="pl-c1" style="box-sizing: border-box; color: #0086b3;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span>ALL_FIELDS</span>, <span class="pl-smi" style="box-sizing: border-box;">MappingType</span><span class="pl-c1" style="box-sizing: border-box; color: #0086b3;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span>ONLY_VALUED_FIELDS</span>);</pre>
</div>
Result:
<br />
<div class="highlight highlight-source-java" style="background-color: white; box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;">
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">Destination</span>[ name<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">=</span><span class="pl-s" style="box-sizing: border-box; color: #183691;"><span class="pl-pds" style="box-sizing: border-box;">"</span>Alessandro<span class="pl-pds" style="box-sizing: border-box;">"</span></span>, age<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">=</span><span style="color: #0086b3; font-size: 13.6px; line-height: 1.45;">30</span><span style="font-size: 13.6px; line-height: 1.45;">, company</span><span class="pl-k" style="box-sizing: border-box; color: #a71d5d; font-size: 13.6px; line-height: 1.45;">=</span><span class="pl-s" style="box-sizing: border-box; color: #183691; font-size: 13.6px; line-height: 1.45;"><span class="pl-pds" style="box-sizing: border-box;">"</span><span style="font-size: 13.6px; line-height: 1.45;">Anonymous</span></span><span class="pl-s" style="box-sizing: border-box; color: #183691; font-size: 13.6px; line-height: 1.45;"><span class="pl-pds" style="box-sizing: border-box;">"</span></span><span style="font-size: 13.6px; line-height: 1.45;">]</span></pre>
</div>
We want just fill null fields of Destination:
<br />
<br />
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-smi" style="box-sizing: border-box; font-size: 13.6px; line-height: 1.45;">Destination</span><span style="font-size: 13.6px; line-height: 1.45;"> result </span><span class="pl-k" style="box-sizing: border-box; color: #a71d5d; font-size: 13.6px; line-height: 1.45;">=</span><span style="font-size: 13.6px; line-height: 1.45;"> mapper</span><span class="pl-k" style="box-sizing: border-box; color: #a71d5d; font-size: 13.6px; line-height: 1.45;">.</span><span style="font-size: 13.6px; line-height: 1.45;">getDestination(destination, source, </span><span class="pl-smi" style="box-sizing: border-box; font-size: 13.6px; line-height: 1.45;">MappingType</span><span class="pl-c1" style="box-sizing: border-box; color: #0086b3; font-size: 13.6px; line-height: 1.45;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span>ONLY_NULL_FIELDS</span><span style="font-size: 13.6px; line-height: 1.45;">, </span><span class="pl-smi" style="box-sizing: border-box; font-size: 13.6px; line-height: 1.45;">MappingType</span><span class="pl-c1" style="box-sizing: border-box; color: #0086b3; font-size: 13.6px; line-height: 1.45;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">.</span>ALL_FIELDS</span><span style="font-size: 13.6px; line-height: 1.45;">);</span></pre>
<br />
Result:<br />
<div class="highlight highlight-source-java" style="background-color: white; box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;">
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">Destination</span>[ name<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">=</span><span class="pl-s" style="box-sizing: border-box; color: #183691;"><span class="pl-pds" style="box-sizing: border-box;">"</span>empty<span class="pl-pds" style="box-sizing: border-box;">"</span></span>, age<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">=</span><span class="pl-c1" style="box-sizing: border-box; color: #0086b3;">30</span>, company<span class="pl-k" style="box-sizing: border-box; color: #a71d5d;">=</span><span class="pl-s" style="box-sizing: border-box; color: #183691;"><span class="pl-pds" style="box-sizing: border-box;">"</span><span style="font-size: 13.6px; line-height: 1.45;">Anonymous</span></span><span class="pl-s" style="box-sizing: border-box; color: #183691; font-size: 13.6px; line-height: 1.45;"><span class="pl-pds" style="box-sizing: border-box;">"</span></span><span style="font-size: 13.6px; line-height: 1.45;">]</span></pre>
</div>
<br />
There are a lot of other <a href="https://github.com/jmapper-framework/jmapper-core/wiki/Enumeration-examples">combinations</a>.. try to find yourself :)Alexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.com0tag:blogger.com,1999:blog-7025180240477378377.post-15228971131862531112015-05-01T05:17:00.001-07:002016-04-13T01:38:27.717-07:00JMapper Framework philosophyThere are a lot of java mapping framework, each of them developed on a basic principle.<br />
For example MapStruct applies loose coupling using annotations, Orika the same using API, Model Mapper is convention based etc...<br />
<br />
JMapper Framework instead applies the <b>DRY</b> principle ( Don't repeat yourself ) using <b>Annotations</b>:<br />
<blockquote class="tr_bq">
<i>the mappings are defined on fields so that they are used as configuration,</i> </blockquote>
<blockquote class="tr_bq">
<i>the loose coupling imposes to repeat this information.</i></blockquote>
<br />
However, with JMapper, you can choose to apply <i>loose coupling</i> using the <b>XML </b>or<b> API </b>configuration.<br />
<br />
The second objective of JMapper is the <b>Relational Mapping</b>:<br />
<br />
<blockquote class="tr_bq">
<i>The relational mapping is the ability to map one bean toward many other and viceversa.</i></blockquote>
<br />
<b>REAL CASE</b><br />
<br />
Thinks you have a service that applies a method called "checkExistence" that needs of the fields: <b>name </b>and <b>surname</b>. This service takes as input a general object that can be everything, in our case takes three different bean: <b>Consultant</b>, <b>Employee </b>and <b>Manager</b>. This beans have in common only this two fields and we have need to map only these toward the service's bean.<br />
<br />
<b>SOLUTION</b><br />
<b><br /></b>
With JMapper you need to configure only the service's bean toward the others.<br />
<br />
<b>IMPLEMENTATION</b><br />
<b><br /></b>
@JGlobalMap(classes={Consultant.class, Employee.class, Manager.class})<br />
class ServiceBean{<br />
<br />
String name;<br />
String surname;<br />
<br />
//getters and setters..<br />
}<br />
<b><br /></b>
<b>USAGE</b><br />
<b><br /></b>
class Service {<br />
<br />
RelationalJMapper<ServiceBean> mapper = new RelationalJMapper<>(ServiceBean.class);<br />
<div>
<br /></div>
public void checkExistence(Object bean){<br />
ServiceBean serviceBean = mapper.manyToOne(bean);<br />
// some logic <br />
}<br />
}<br />
<br />
<b>CONCLUSION</b><br />
<b><br /></b>
<b>DRY principle </b>+<b> relational mapping </b>=<b> interesting implementations</b> <br />
<br />
Are you curious? have a look to the <a href="https://code.google.com/p/jmapper-framework/wiki/AdvancedExamples">relational mapping</a> wiki page, there a lot of complete and more complex examples.<br />
<br />
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 ;)<br />
<br />
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>Alexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.com1tag:blogger.com,1999:blog-7025180240477378377.post-84796742856981265382015-01-19T05:16:00.000-08:002015-02-02T02:23:36.257-08:00How to write a good XML schemaXML Schema is a formal description of a grammar for a markup language based on XML.<br />
There are a lot of guides and articles about this, i suggest to visit <a href="http://www.w3schools.com/schema/">W3C XML Schema (XSD)</a> as start point,<br />
for grammar analysis: <a href="http://www.utilities-online.info/xsdvalidation/#.VLOrCSuG9ul">W3C XML Schema (XSD) Validation online</a>.<br />
<br />
The purpose of this article is to give you some tips on how to write a better xml schema.<br />
<br />
It's very important to know<b> default values</b> of all tag, for several reasons:<br />
- define all parameters as maxOccurs, minOccurs, optional, use etc.. for all tag makes the xsd difficult to read and modify.<br />
- Alternatively define a few, ignoring the default values, leads to abnormal behavior, found only with test<br />
<a href="http://www.w3schools.com/schema/schema_elements_ref.asp">Here</a> you can found all default values for all tag.<br />
<br />
<b>Make your xsd more readable</b>, for this purpose you can use:<br />
- <a href="http://www.w3schools.com/schema/schema_complex.asp">complexType</a> to externalize a attribute type, for example:<br />
<br />
Before:<br />
<span style="font-family: Courier New, Courier, monospace;"><xs:element name="employee"></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:complextype></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element name="firstname" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element name="lastname" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> </xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"> </xs:complextype></span><br />
<span style="font-family: Courier New, Courier, monospace;"> </xs:element></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="white-space: pre;"> </span><xs:element name="student"></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="white-space: pre;"> </span> <xs:complextype></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> <xs:element name="firstname" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> <xs:element name="lastname" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="white-space: pre;"> </span></xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="white-space: pre;"> </span> </xs:complextype></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="white-space: pre;"> </span></xs:element></span><br />
<br />
after:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="font-family: Courier New, Courier, monospace;"><xs:element name="employee" type="personinfo"></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><xs:element name="student" type="personinfo"></span><br />
<span class="Apple-tab-span" style="font-family: Courier New, Courier, monospace; white-space: pre;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><xs:complextype name="personinfo"></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> <xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><xs:element name="firstname" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><xs:element name="lastname" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> </xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span></xs:complextype></span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
- import an external xsd and use it with <b><a href="http://www.w3schools.com/schema/schema_schema.asp">namespace</a></b><br />
- add<b> comments as markers</b>, it permits to go fast on the interested point, you have to think that not everyone uses XML tools.<br />
<br />
- use <a href="http://www.w3schools.com/schema/el_complexcontent.asp"><b>extension </b>or </a><b><a href="http://www.w3schools.com/schema/el_complexcontent.asp">restriction</a> </b>of complexContent if your element is almost equal to an existing.<br />
<br />
follow an example of extention:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><xs:element name="employee" type="fullpersoninfo"></span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: Courier New, Courier, monospace;"><xs:complextype name="personinfo"></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element name="firstname" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element name="lastname" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> </xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"></xs:complextype></span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: Courier New, Courier, monospace;"><xs:complextype name="fullpersoninfo"></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:complexcontent></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:extension base="personinfo"></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element name="address" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element name="city" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element name="country" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> </xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"> </xs:extension></span><br />
<span style="font-family: Courier New, Courier, monospace;"> </xs:complexcontent></span><br />
<span style="font-family: Courier New, Courier, monospace;"></xs:complextype></span><br />
<br />
an example of restriction:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><xs:complextype name="customer"></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element name="firstname" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element name="lastname" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element name="country" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> </xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"></xs:complextype></span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: Courier New, Courier, monospace;"><xs:complextype name="Norwegian_customer"></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:complexcontent></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:restriction base="customer"></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element name="firstname" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element name="lastname" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <xs:element fixed="Norway" name="country" type="xs:string"/></span><br />
<span style="font-family: Courier New, Courier, monospace;"> </xs:sequence></span><br />
<span style="font-family: Courier New, Courier, monospace;"> </xs:restriction></span><br />
<span style="font-family: Courier New, Courier, monospace;"> </xs:complexcontent></span><br />
<span style="font-family: Courier New, Courier, monospace;"></xs:complextype></span><br />
<br />
Few tips but if used makes the development, of large XSD file, sustainable.Alexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.com0tag:blogger.com,1999:blog-7025180240477378377.post-29139518443154471412014-09-29T06:10:00.001-07:002014-10-10T02:09:58.789-07:00java File WatcherWith the new features of java 7 was introduced the WatchService class, with it we know all action done on the watched folder.<br />
But there isn't an implementation that permits to watch a single file so.. follows a my implementation called FileWatcher:<br />
<br />
<pre class="brush:java">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<Path>)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() {}
}</path></pre>
<br />
An example of use:<br />
<br />
<pre class="brush:java">new Thread(new FileWatcher(filePath){
@Override
public void modify() {
System.out.println("modified");
}
}).start();</pre>
Alexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.com0tag:blogger.com,1999:blog-7025180240477378377.post-39078903240570056332013-10-03T10:37:00.000-07:002013-10-03T10:37:31.514-07:00Vaadin Tree: how to edit nodeChange the tree nodes is possible and I will show you how to do.<br />
<b>Purpose</b>: change the value of the selected node.<br />
<b>Solution</b>:
<br />
<pre class="brush:java">Object selectedNode = tree.getValue();
tree.setItemCaption(selectedNode, "new value");
</pre>
<br />
Make good use of it :)Alexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.com0tag:blogger.com,1999:blog-7025180240477378377.post-2663001307781028722013-07-05T07:16:00.001-07:002013-07-05T07:16:23.328-07:00Java CalendarIn this post i show how to obtain the calendar of the current month, and how to know the days of the week.<br />
First of all you need to obtain three parameters, number of days of the current month, the month and the year.<br />
<br />
<pre class="brush:java">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);
</pre>
<br />
To know which day of the week the date belongs:<br />
<br />
<pre class="brush:java">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 "";
}
}
</pre>
<br />
Output:
<br />
<br />
<pre class="brush:java">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
.......
</pre>
Alexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.com0tag:blogger.com,1999:blog-7025180240477378377.post-31189743341132881162013-02-18T03:51:00.001-08:002013-02-18T03:52:35.468-08:00merge optimized of two arrays<span class="short_text" id="result_box" lang="en"><span class="hps">the first code</span> <span class="hps">that you might think</span> <span class="hps">to write</span> <span class="hps">is:</span></span><br />
<pre class="brush:java">String[] newArray = new String[firstArray.length + secondArray.length];
int index = 0;
for(int i = 0; i < firstArray.length: i++){
newArray[index++] = firstArray[i];
}
for(int i = 0; i < secondArray.length: i++){
newArray[index++] = secondArray[i];
}
</pre>
This code is simple but slow, the best way to do this is to use system methods, as follow:
<br />
<pre class="brush:java">String[] newArray = Arrays.copyOf(firstArray, firstArray.length + secondArray.length);
System.arraycopy(secondArray, 0, newArray, firstArray.length, secondArray.length);
</pre>
This algorithm is three times faster and short.<br />
<span class="short_text" id="result_box" lang="en"><span class="hps">good optimization :)</span></span> Alexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.com0tag:blogger.com,1999:blog-7025180240477378377.post-43151004717258517022013-01-13T14:00:00.001-08:002013-01-14T12:14:10.470-08:00Class generation with JavassistWith this post you will see how it's easy to create at runtime a class with javassist.<br />
We will go to create a simple javaBean that extends an interface.<br />
The interface is defined at development time as follows:<br />
<pre class="brush:java">public interface IBean {
public String getField();
public void setField(String field);
}
</pre>
<br />
Now we will create the Bean class at runtime that extends the IBean interface:
<br />
<pre class="brush:java">public class Generate {
// If a program is running on a web application server such as JBoss and Tomcat,
// the ClassPool object may not be able to find user classes.
// In that case, an additional class path must be registered to the ClassPool.
static{
// ClassPool initialization
ClassPool.getDefault().insertClassPath(new ClassClassPath(IBean.class));
}
public static IBean bean(){
ClassPool cp = ClassPool.getDefault();
// creation of the class
CtClass Bean = cp.makeClass("Bean");
// addition of the interface
Bean.addInterface(cp.get(IBean.class.getName()));
// creation of an empty constructor
CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, Bean);
// its body
ctConstructor.setBody(";");
// addition of the constructor
Bean.addConstructor(ctConstructor);
// addition of the String field
Bean.addField(new CtField(cp.get(String.class.getName()), "field", Bean));
// creation of getField method
CtMethod getField = CtNewMethod.make("public String getField(){ return field; }",Bean);
// add method to CtClass
Bean.addMethod(getField);
// creation of setField method
CtMethod setField = CtNewMethod.make("public void setField(String field){ this.field = field; }",Bean);
// add method to CtClass
Bean.addMethod(setField);
return (IBean) Bean.toClass().newInstance();
}
}
</pre><br />
In this mode we can create an instance of IBean dynamically, using the IBean interface at development time:
<pre class="brush:java">
IBean bean = Generate.bean();
bean.setField("example");
assertEqual("example",bean.getField());
</pre><br />
The exceptions aren't handled to increase the readability.<br />This technique is used in the development of JMapper Framework:
http://code.google.com/p/jmapper-framework/
You can download the source.jar or checkout the code from svn.Alexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.com0tag:blogger.com,1999:blog-7025180240477378377.post-55300752049379555382013-01-10T01:36:00.000-08:002013-01-10T01:45:20.084-08:00JMapper Framework 1.1.1 released!With this released the features added are:<br />
<br />
<b>Inherited configuration</b><br />
<br />
Now we can define a common configuration/conversions in the superclass, less code, less redundance and less maintenance.<br />
<br />
<b>Implicit conversion between arrays and collections</b><br />
<br />
With this features we can configure arrays with collections and vice versa, with any type of items (primitive, wrapper and mapped).<br />
<br />
<b>OneToMany method changed</b><br />
<br />
To prevent unexpected behavior in case of singleton pattern usage in multi-threaded environment, the definition of the target class will be done through the passage of the class as input to the method.
For more information:
http://code.google.com/p/jmapper-framework/Alexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.com0tag:blogger.com,1999:blog-7025180240477378377.post-59994104368533899152013-01-04T11:37:00.000-08:002013-03-01T00:04:35.988-08:00how to generate the hql query from the instanceIn some cases we have the need to transform an object in an hql query considering only the valued properties, going in introspection also. For example, we have the following class:
<br />
<pre class="brush:java">class Bean{
Integer id;
String description;
String other;
// getter and setter..
}
</pre>
The scope is to include in the HQL query only the valorized properties of this bean.
then we immediately think of a cascade of if:
<br />
<pre class="brush:java">String hql = "Select Bean from Bean";
boolean isWhere = true;
if(bean.getId() != null) {
if(isWhere){
hql += " Where ";
isWhere = false;
}else{
hql += " and ";
}
hql += "Bean.id = " + bean.getId();
}
if(bean.getDescription() != null) {
if(isWhere){
hql += " Where ";
isWhere = false;
}else{
hql += " and ";
}
hql += "Bean.id = " + bean.getDescription();
}
// etc..
</pre>
The result is a HQL query generated at runtime, but the code written isn't generic and you must in all cases write custom code.
Follows an algorithm created by me, a recursive function that permits to write hql query in every situation:
<br />
<pre class="brush:java">import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
class Generate {
private boolean isWhere;
public String hql(Object obj){
isWhere = true;
String alias = ob.getClass().getSimpleName().toLowerCase();
return hql(obj, alias, true);
}
private String hql(Object ob, String alias, boolean isFirst){
Class<? extends Object> obClass = ob.getClass();
StringBuilder sb = new StringBuilder();
if (isFirst)
sb.append("SELECT "+alias+" FROM "+obClass.getSimpleName()+" as "+alias);
try {
for (Field field : obClass.getDeclaredFields()) {
Class<?> fieldType = field.getType();
String fieldName = field.getName();
if(!isCollection(fieldType) && !isSerialVersionUID(fieldName)){
Object fieldValue = null;
try{ fieldValue = obClass.getMethod(mGet(fieldName)).invoke(ob);
}catch(Exception e){
// some fields don't have get method
// for example serialVersionUID
}
if (fieldValue != null)
// if the field is complex type it goes into introspection
if (isFk(fieldType))
sb.append(hql(fieldValue, alias+"."+fieldName, false));
else {
if (isWhere) {
sb.append(" WHERE ");
isWhere = false;
} else
sb.append(" AND ");
sb.append(alias+"."+fieldName+" = "+getValue(fieldValue, fieldType));
}
}
}
} catch (Exception e) { /** to handle **/ }
return sb.toString();
}
private String getValue(Object value, Class<?> field) {
StringBuilder sb = new StringBuilder();
try { if (field.equals(String.class)
|| field.equals(Character.class)
|| field.equals(char.class)) sb.append("'"+value+"'");
else
if(field.equals(Date.class)) sb.append("to_timestamp('"+value+"')");
else sb.append(value);
} catch (Exception e) { /** to handle **/ }
return sb.toString();
}
public static final ArrayList<string> basicTypes =
new ArrayList<string>(){
private static final long serialVersionUID = -5567529960231273742L;
{
add(byte.class.getName());
add(short.class.getName());
add(int.class.getName());
add(long.class.getName());
add(float.class.getName());
add(double.class.getName());
add(char.class.getName());
add(boolean.class.getName());
add(Byte.class.getName());
add(Short.class.getName());
add(Integer.class.getName());
add(Long.class.getName());
add(Float.class.getName());
add(Double.class.getName());
add(Character.class.getName());
add(Boolean.class.getName());
add(String.class.getName());
add(Date.class.getName());
}
};
private boolean isCollection(Class<?> aClass){
return Collection.class.isAssignableFrom(aClass);
}
private String mGet(String s) {
return "get" + s.substring(0, 1).toUpperCase() + s.substring(1);
}
private boolean isSerialVersionUID(String field) {
return field.equals("serialVersionUID");
}
private boolean isFk(Class<?> field) {
return !basicTypes.contains(field.getName());
}
}
</string></string></pre>
The exceptions aren't handled so to focalize the attention on the algorithm.
An example of use:
<br />
<pre class="brush:java"> Bean bean = new Bean(2013,"description");
String hql = new Generate().hql(bean);
assertEqual("SELECT bean FROM Bean as bean WHERE bean.id = 2013 and bean.description = 'description'", hql);
</pre>
Alexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.com1tag:blogger.com,1999:blog-7025180240477378377.post-46363277126751049552013-01-02T04:04:00.000-08:002013-01-05T04:24:34.804-08:00JMapper FrameworkHello to All,<br />
<br />
with this my first post <span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">i wanted to bring to your attention a new java bean mapping framework "JMapper" that allows</span><span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;"> </span><br />
<span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">you to perform dynamic mappings with annotations and / or XML bringing </span><br />
<span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">several advantages as: </span><br />
<span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">- create and enrich target objects </span><br />
<span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">- apply specific logic to the mapping (only valued fields, null fields </span><br />
<span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">only, etc. ..) </span><br />
<span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">- automated management of the XML file </span><br />
<span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">- Possibility of Implementing the 1 to N and N to 1 relationships </span><br />
<span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">- explicit conversions </span><br />
<br style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;" />
<span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">JMapper permits to have all advantages of dynamic mapping with the </span><br />
<span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">performance of static code. </span><br />
<br />
<a href="http://code.google.com/p/jmapper-framework/" link="external" rel="nofollow" style="background-color: white; color: #551a8b; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;" target="_top">http://code.google.com/p/jmapper-framework/</a><br />
<br style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;" />
<span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">thank you for your attention!</span>Alexhttp://www.blogger.com/profile/04473724197958574482noreply@blogger.com0