<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3815776380138759375</id><updated>2026-01-19T16:46:50.430+01:00</updated><category term="Java"/><category term="grails"/><category term="programming"/><category term="Scala"/><category term="SSC (Scala Stock Charts)"/><category term="stocks"/><category term="JSF2"/><category term="REST"/><category term="Webservice"/><category term="Glassfish v3"/><category term="Jersey"/><category term="Jetty"/><category term="Microservice"/><category term="Payara"/><category term="Scala swing"/><category term="CDI"/><category term="JSF"/><category term="Java EE"/><category term="Primefaces"/><category term="RESTful"/><category term="glassfish"/><category term="Ajax"/><category term="EJB"/><category term="Hazelcast"/><category term="JEE"/><category term="Netbeans 6.8"/><category term="RichFaces"/><category term="SSL"/><category term="Servlet"/><category term="Web Service"/><category term="database"/><category term="gradle"/><category term="i18n"/><category term="japser"/><category term="pdf"/><category term="reports"/><category term="sbt"/><category term="tutorial"/><category term="web-fragments"/><title type='text'>Ironic programmer</title><subtitle type='html'>Programming in (mostly) Java, Grails, Ruby and Rails. Sharing thoughts, solution ideas and tricks to work around. Maybe also giving .NET and Microsoft some ironic comments. And ironic, yes often if it is called for.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>33</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-5901708391109101165</id><published>2015-10-11T12:40:00.000+02:00</published><updated>2015-10-11T12:40:02.166+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CDI"/><category scheme="http://www.blogger.com/atom/ns#" term="Hazelcast"/><category scheme="http://www.blogger.com/atom/ns#" term="Payara"/><category scheme="http://www.blogger.com/atom/ns#" term="RESTful"/><title type='text'>Playing with Hazelcast on Payara</title><content type='html'>I have been reading a bit about Hazelcast, came up to chapter 5 in &lt;a href=&quot;http://hazelcast.org/mastering-hazelcast/&quot;&gt;http://hazelcast.org/mastering-hazelcast/&lt;/a&gt;, but as I am a bit impatient and wanted to try out some stuff before reading the whole book and thinking about possibilities to use Hazelcast in my current work, this Weekend I set up to solve the following:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Hazelcast &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;IMap&lt;/span&gt; in a Java EE container&lt;/li&gt;
&lt;li&gt;Use &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MapLoader&lt;/span&gt; to load into a IMap with JPA&lt;/li&gt;
&lt;li&gt;As far as possible, use CDI&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Payara comes with a Hazelcast, but solving this tasks may not be so straightforward, and I will try to explain why.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
As usual I use a simple blog &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Post&lt;/span&gt; RESTful service as an example.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;#%RAML 0.8
title: Blog post service 
baseUri: http://localhost:8080/hazelblog/api
version: v1
/posts:   
   get:
      description: Gets a list of &quot;Posts&quot;
      queryParameters:
         author: 
            displayName: Author
            type: string
            description: Name of the author
            example: @ironic
      responses:
         200:
            body: 
               application/json:
                  example: |
                     [
                        {&quot;author&quot;:&quot;@ironic&quot;,&quot;content&quot;:&quot;Nothing interesting&quot;,&quot;id&quot;:1,&quot;title&quot;:&quot;First post&quot;},
                        {&quot;author&quot;:&quot;@ironic&quot;,&quot;content&quot;:&quot;Again nothing interesting&quot;,&quot;id&quot;:2,&quot;title&quot;:&quot;Second post&quot;}
                    ]
   post:
      description: Creates a post
      body: 
         application/json:
            example: |
               {&quot;author&quot;:&quot;@ironic&quot;,&quot;content&quot;:&quot;Nothing interesting&quot;, &quot;title&quot;:&quot;Test post&quot;}
   /{id}:
      get:
         description: View of a post
         responses:
            200:
               body: 
                  application/json:
                     example: |
                        {&quot;author&quot;:&quot;@ironic&quot;,&quot;content&quot;:&quot;Nothing interesting&quot;,&quot;id&quot;:1,&quot;title&quot;:&quot;First post&quot;}                     
      delete:  
         description: Deletes a post
&lt;/textarea&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;h3&gt;
Using Hazlecast in Payara&lt;/h3&gt;
&lt;/div&gt;
&lt;div&gt;
Even if Payara comes with an embedded Hazelcast, I will not use it by letting Payara start it, and the reason is what I found when playing around with &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;EntryListener&lt;/span&gt;. I will however use the Hazelcast that is provided, but will not activate it as written here:&amp;nbsp;&lt;a href=&quot;https://github.com/payara/Payara/wiki/Hazelcast-%28Payara-4.1.153%29&quot;&gt;https://github.com/payara/Payara/wiki/Hazelcast-%28Payara-4.1.153%29&lt;/a&gt;&amp;nbsp;but more with ideas as written here:&amp;nbsp;&lt;a href=&quot;http://blog.modernjava.info/2014/10/using-hazelcast-as-jcache-provider-with.html&quot;&gt;http://blog.modernjava.info/2014/10/using-hazelcast-as-jcache-provider-with.html&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
To start with, this is what we will need in the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;pom.xml&lt;/span&gt;,&lt;/div&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;&lt;dependencies&gt;
   &lt;dependency&gt;
      &lt;groupid&gt;javax&lt;/groupId&gt;
      &lt;artifactid&gt;javaee-web-api&lt;/artifactId&gt;
      &lt;version&gt;7.0&lt;/version&gt;
      &lt;scope&gt;provided&lt;/scope&gt;
   &lt;/dependency&gt;
   &lt;dependency&gt;
      &lt;groupid&gt;com.hazelcast&lt;/groupId&gt;
      &lt;artifactid&gt;hazelcast&lt;/artifactId&gt;
      &lt;version&gt;3.5&lt;/version&gt;
      &lt;scope&gt;provided&lt;/scope&gt;
   &lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;/textarea&gt;
&lt;br /&gt;
&lt;div&gt;
I am using Hazelcast 3.5 since that is the one that comes with Payara 4.153.
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
To fire up Hazelcast we will use an annotation and a provider so we can use CDI where we want to use stuff from Hazelcast.&lt;br /&gt;
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package se.ironic.hazelblog;

import static java.lang.annotation.ElementType.*;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
import javax.inject.Qualifier;

@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Hazelcast {

}

&lt;/textarea&gt;
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package se.ironic.hazelblog;

import com.hazelcast.config.Config;
import com.hazelcast.config.MapStoreConfig;
import com.hazelcast.core.HazelcastInstance;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.inject.Singleton;

@ApplicationScoped
public class HazelcastProvider {

    @Produces
    @Singleton
    @Hazelcast
    public HazelcastInstance create() {
        System.out.println(&quot;Creating Hazelcast Instance&quot;);
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        Config config = new Config();

        MapStoreConfig storeConfig = new MapStoreConfig();
        storeConfig.setEnabled(true);
        storeConfig.setClassName(&quot;se.ironic.hazelblog.PostLoader&quot;);
        config.getMapConfig(&quot;posts&quot;).setMapStoreConfig(storeConfig);
        HazelcastInstance newInst = com.hazelcast.core.Hazelcast.newHazelcastInstance(config);

        return newInst;
    }

    public void close(@Disposes @Hazelcast HazelcastInstance instance) {
        System.out.println(&quot;Shutting down Hazelcast....&quot;);
        instance.shutdown();
    }
}
&lt;/textarea&gt;
&lt;br /&gt;
&lt;br /&gt;
The reason for doing like this is that I noticed by playing around with &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;EntryListener&lt;/span&gt; that by letting Payara firing up Hazelcast I cannot really add listeners, since Hazelcast then know nothing about my classes (resulting in &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;ClassNotFoundException&lt;/span&gt;), so to resolve this we need to provide the class loader from our web-application to Hazelcast. To do this we need to start it &quot;manually&quot; and provide the class loader so Hazelcast knows about them. You can also see we configure Hazelcast with a &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MapLoader&lt;/span&gt;, more on that later.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
REST-resource&lt;/h3&gt;
I will not share the full code since you can find it on Bitbucket. In PostResource we use CDI to get hold of the Hazelcast, it will initialise on first use, so if no pre-warming occurs (like using a startup bean) it will take 5-10 seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;    @Inject
    @Hazelcast
    private HazelcastInstance hazelcastInstance;
&lt;/textarea&gt;
&lt;br /&gt;
And use it 

&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path(&quot;{id}&quot;)
    public Post get(@PathParam(&quot;id&quot;) Long id) {
        IMap&lt;Long, Post&gt; map = hazelcastInstance.getMap(&quot;posts&quot;);
        Post post = map.get(id);
        if(post == null) {
            throw new WebApplicationException(&quot;No post found!&quot;, Response.Status.NOT_FOUND);
        }
        return post;
    }
&lt;/textarea&gt;
&lt;br /&gt;
For the creation of a Post we can use a trick to load it in the map by trying to get it after the save. That is we don&#39;t put it in the map directly and use a MapStore to save it (we don&#39;t know the id until after the persist). But since this is about using MapLoader, we will use that and not put it (as indicated in the comments)
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public void post(Post post) {
        postRepository.persist(post);
        // need to &quot;touch&quot; it to load it to the map.
        // could also have use put since we have id after persist.
        IMap&lt;Long, Post&gt; map = hazelcastInstance.getMap(&quot;posts&quot;);
        map.get(post.getId());
    }
&lt;/textarea&gt;&lt;br /&gt;
&lt;h3&gt;
MapLoader using JPA&lt;/h3&gt;
Actually, I am not using it directly from the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MapLoader&lt;/span&gt;, but injecting a &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;@Statless&lt;/span&gt; bean from it, that does the actual JPA stuff.&lt;br /&gt;
As the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MapLoader&lt;/span&gt; lives in Hazelcast and is created by it, we cannot use &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;@Inject&lt;/span&gt; or even make it a managed bean (well we can, but it will not help since it is not using the jave ee container to handle it). But since CDI 1.1 we can inject using the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;CDI&lt;/span&gt;-class.&lt;br /&gt;
&lt;br /&gt;
This is how the map loader I create looks like:&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package se.ironic.hazelblog;

import com.hazelcast.core.MapLoader;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.enterprise.inject.spi.CDI;

public class PostLoader implements MapLoader&lt;Long, Post&gt; {

    @Override
    public Post load(Long id) {
        PostRepository repo = CDI.current().select(PostRepository.class).get();
        Post post = repo.find(id);
        return post;
    }

    @Override
    public Map&lt;Long, Post&gt; loadAll(Collection&lt;long&gt; ids) {
        Map&lt;Long, Post&gt; all = new HashMap&lt;&gt;();
        PostRepository repo = CDI.current().select(PostRepository.class).get();
        Map&lt;String, Object&gt; params = new HashMap&lt;&gt;();
        params.put(&quot;ids&quot;, ids);
        List&lt;post&gt; posts = repo.findByQuery(&quot;SELECT p FROM Post p WHERE p.id in :ids&quot;, params);
        for (Post post : posts) {
            all.put(post.getId(), post);
            System.out.println(&quot;Post: &quot; + post);
        }
        return all;
    }

    @Override
    public Iterable&lt;long&gt; loadAllKeys() {
        PostRepository repo = CDI.current().select(PostRepository.class).get();
        List&lt;long&gt; ids = repo.findByQuery(&quot;SELECT p.id FROM Post p&quot;, Collections.EMPTY_MAP);
        return ids;
    }

}
&lt;/textarea&gt;
&lt;br /&gt;
Notice the code to inject the PostRepository (which is the bean using JPA with an EntityManager). This will work since Hazelcast is loaded from the container with our classes.&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;PostRepository repo = CDI.current().select(PostRepository.class).get();
&lt;/textarea&gt;&lt;br /&gt;
&lt;h3&gt;
Some notes&lt;/h3&gt;
I have implemented&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;loadAllKeys()&lt;/span&gt; and&amp;nbsp;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;loadAll(...)&lt;/span&gt;, this is probably fine since I do not have so many posts, but for a huge database and if you do not want them all in memory, you may leave them empty and return null for keys or you will end up waiting for a while. I played with a criteria search on the map&lt;br /&gt;
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Collection&lt;post&gt; list() {
        String author = uriInfo.getQueryParameters().getFirst(&quot;author&quot;);
        if(author != null) {
            System.out.println(&quot;Searching on map... author:&quot; + author);
            IMap&lt;Long, Post&gt; map = hazelcastInstance.getMap(&quot;posts&quot;);
            EntryObject entryObject = new PredicateBuilder().getEntryObject();
            PredicateBuilder predicate = entryObject.get(&quot;author&quot;).equal(author);
            Collection&lt;post&gt; values = map.values(predicate);
            return values;
        }
        return Collections.EMPTY_LIST;
    }
&lt;/textarea&gt;
&lt;br /&gt;
and found out that by doing that, Hazelcast will try to load all keys from the database before it searcher memory.&lt;br /&gt;
However, this is done only once, if you add items to the database, it will not get loaded if you do not do anything to tell the map, as you have seen in the &quot;@POST&quot; or put it there yourself, subsequent searches on the map will not try to load items not there from the first loadAll.&lt;br /&gt;
&lt;br /&gt;
Payara does not really matter in the context, other than having a Hazelcast and being a Java EE container. But I also use it since it have a default datasource for Derby, so I kind of used that to avoid setting up a database, and load a few posts to get started.If you use another container, you may have to change the hazelnuts dependency to be &quot;compile&quot; instead of &quot;provided&quot; if that container donate have it. You may also need to set up a datasource.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The code can be found here: [&lt;a href=&quot;https://bitbucket.org/pejomstd/hazelblog&quot;&gt;https://bitbucket.org/pejomstd/hazelblog&lt;/a&gt;]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/5901708391109101165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2015/10/playing-with-hazelcast-on-payara.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/5901708391109101165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/5901708391109101165'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2015/10/playing-with-hazelcast-on-payara.html' title='Playing with Hazelcast on Payara'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-144958828908865467</id><published>2015-05-19T20:51:00.002+02:00</published><updated>2015-05-19T20:51:57.540+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Payara"/><title type='text'>Payara Micro, even easier</title><content type='html'>Just saw this post. [&lt;a href=&quot;http://java.dzone.com/articles/java-ee-embedded-and-micro&quot;&gt;http://java.dzone.com/articles/java-ee-embedded-and-micro&lt;/a&gt;]. It is not even nescessary to build a runner, using Payara Micro, it is as easy as this:&lt;br /&gt;
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;java -jar payara-micro-4.1.152.1.jar --deploy task-web-1.0-SNAPSHOT.war
&lt;/textarea&gt;

&lt;br /&gt;
More here:&lt;a href=&quot;http://www.payara.co.uk/introducing_payara_micro&quot;&gt;http://www.payara.co.uk/introducing_payara_micro&lt;/a&gt; </content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/144958828908865467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2015/05/payara-micro-even-easier.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/144958828908865467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/144958828908865467'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2015/05/payara-micro-even-easier.html' title='Payara Micro, even easier'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-78381675333952191</id><published>2015-05-19T18:52:00.001+02:00</published><updated>2015-05-19T18:54:32.688+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="glassfish"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java EE"/><category scheme="http://www.blogger.com/atom/ns#" term="Microservice"/><category scheme="http://www.blogger.com/atom/ns#" term="Payara"/><category scheme="http://www.blogger.com/atom/ns#" term="REST"/><category scheme="http://www.blogger.com/atom/ns#" term="RESTful"/><category scheme="http://www.blogger.com/atom/ns#" term="Webservice"/><title type='text'>RESTful Service on an embedded Glassfish/Payara</title><content type='html'>&lt;br /&gt;
Last posts were about making a RESTFul service and run it on Jersey with an embedded Jetty.&lt;br /&gt;
This time I will set up a more Java EE like solution with the same REST Resource, but instead run it on an embedded Glassfish (actually, I will go for Payara). I will take the same model as before. Next part I will also add a JSF 2.2 client to use the RESTful service.&lt;br /&gt;
&lt;br /&gt;
I will create this as a maven multi module with a parent project and two subprojects. One will be a web-project and the other will be a &quot;runner&quot; for the embedded Glassfish. I will not use maven to run, but will create a class that will run the embedded Glassfish with the war-file from the other project.&lt;br /&gt;
&lt;br /&gt;
As it is pretty easy I use NetBeans to create maven projects for me.&lt;br /&gt;
&lt;br /&gt;
The structure will be like this:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;embgf&lt;/span&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;task-web&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;gf-runner&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;pack-dist&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h3&gt;
task-web&lt;/h3&gt;
&lt;/div&gt;
&lt;div&gt;
To start with, instead of having to set up a Servlet on &quot;/api&quot; path, we will create a configuration class that extends JAX_RSs &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Application&lt;/span&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package se.ironic.task.boundary;

import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath(&quot;api&quot;)
public class JAXRSConfiguration extends Application {

    @Override
    public Set&lt;Class&lt;?&gt;&gt; getClasses() {
        HashSet&lt;Class&lt;?&gt;&gt; classes = new HashSet&lt;&gt;();
        classes.add(TaskResource.class);
        return classes;
    }
    
}

&lt;/textarea&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
And this will be the class for the Task service.&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package se.ironic.task.boundary;

import java.net.URI;
import java.util.List;
import java.util.Optional;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import se.ironic.task.model.Task;

/**
 *
 * @author Ironic
 */
@Path(&quot;tasks&quot;)
public class TaskResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List&lt;task&gt; getAll() {
        return TaskCache.INST.getTasks();
    }
    
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response create(Task task) {
        TaskCache.INST.putTask(task);
        URI id = URI.create(&quot;tasks/&quot; + task.getId());
        Response resp = Response.created(id).build();
        return resp;
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path(&quot;{id}&quot;)
    public Response getTask(@PathParam(&quot;id&quot;) String id) {
        Optional&lt;task&gt; task = TaskCache.INST.getTask(id);
        Response resp = null;
        if (task.isPresent()) {
            resp = Response.ok(task.get()).build();
        } else {
            resp = Response.noContent().build();
        }
        return resp;
    }
    
    @PUT @Consumes(MediaType.APPLICATION_JSON)
    @Path(&quot;{id}&quot;)
    public Response update(Task task) {
        // Just replace the one there
        TaskCache.INST.putTask(task);
        return Response.ok().build();
    }
    
    @DELETE
    @Path(&quot;{id}&quot;)
    public Response delete(@PathParam(&quot;id&quot;) String id) {
        System.out.println(&quot;Deleting task: &quot; + id);
        TaskCache.INST.removeTask(id);
        return Response.ok().build();
    }
}

&lt;/textarea&gt;
&lt;br /&gt;
&lt;br /&gt;
The service will be available at [&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;http://localhost:2001/&lt;i&gt;task-web&lt;/i&gt;/api/tasks&lt;/span&gt;] (depending what you use as &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;port &lt;/span&gt;and &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;contextRoot&lt;/span&gt;)&lt;br /&gt;
Just to have some Tasks to start with since we have a simple cache in a HashMap, we create a startup bean to create some.&lt;br /&gt;
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package se.ironic.task.control;

import java.util.Calendar;
import java.util.Date;
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import se.ironic.task.boundary.TaskCache;
import se.ironic.task.model.Task;

@Singleton @Startup
public class BootTasks {
    @PostConstruct
    public void initTasks() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.DATE, 3);
        TaskCache.INST.putTask(Task.of(&quot;Add JAXRSConfiguration&quot;, &quot;Add a class for JAXRS configuration&quot;, cal.getTime()));
        TaskCache.INST.putTask(Task.of(&quot;Add TaskResource&quot;, &quot;Add a class for Task service&quot;, cal.getTime()));
        TaskCache.INST.putTask(Task.of(&quot;Add BootTasks&quot;, &quot;Add a bean for bootstrap&quot;, cal.getTime()));
    }
}
&lt;/textarea&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
gf-runner&lt;/h3&gt;
&lt;h4&gt;
Embedded Payara&lt;/h4&gt;
Trying to follow [&lt;a href=&quot;http://www.payara.co.uk/using_payara_embedded_and_payara_micro_with_mav&quot;&gt;http://www.payara.co.uk/using_payara_embedded_and_payara_micro_with_mav&lt;/a&gt;] I ran in to some issues. The dependency on that page does not really work, it end up with the following message:&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;[ERROR] Failed to execute goal on project gf-runner: Could not resolve dependencies for project se.ironic:gf-runner:jar:1.0-SNAPSHOT: Failed to collect dependencies at fish.payara.extras:payara-embedded-web:jar:4.1.152.1: Failed to read artifact descriptor for fish.payara.extras:payara-embedded-web:jar:4.1.152.1: Could not find artifact org.glassfish.main.extras:extras:pom:4.1.152.1 in central (http://repo.maven.apache.org/maven2) -&gt; [Help 1]
&lt;/textarea&gt;
&lt;br /&gt;
&lt;br /&gt;
There is a bug-report on this. But to get on, I will download the jar and do a &quot;quickie&quot; and add it as a system dependency and get on.&lt;br /&gt;
&lt;textarea class=&quot;xml&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;&lt;dependency&gt;
   &lt;groupid&gt;fish.payara.extras&lt;/groupId&gt;
   &lt;artifactid&gt;payara-embedded-all&lt;/artifactId&gt;
   &lt;version&gt;4.1.152.1&lt;/version&gt;
   &lt;!--&lt;type&gt;jar&lt;/type&gt;--&gt;
   &lt;!-- fix until maven repor for payara fixed --&gt;
   &lt;scope&gt;system&lt;/scope&gt;
   &lt;systempath&gt;${basedir}/lib/payara-embedded-all-4.1.152.1.jar&lt;/systemPath&gt;
&lt;/dependency&gt;
&lt;/textarea&gt;
&lt;br /&gt;
The code to get up and running with the war-file from task-web on an embedded Payara is just a few lines:&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package se.ironic.gfrunner;

import java.io.File;
import org.glassfish.embeddable.BootstrapProperties;
import org.glassfish.embeddable.GlassFish;
import org.glassfish.embeddable.GlassFishException;
import org.glassfish.embeddable.GlassFishProperties;
import org.glassfish.embeddable.GlassFishRuntime;

public class EmbeddedGFRunner {

    public static void main(String[] args) throws GlassFishException {
        if(args.length != 3) {
            System.out.println(&quot;Usage &gt; EmbeddedGFRunner \&quot;port\&quot; \&quot;deployable.war\&quot; \&quot;contextRoot\&quot;&quot;);
            System.exit(1);
        }
        int port = Integer.parseInt(args[0]);
        BootstrapProperties bootstrap = new BootstrapProperties();
        GlassFishRuntime runtime = GlassFishRuntime.bootstrap();
        GlassFishProperties glassfishProperties = new GlassFishProperties();
        glassfishProperties.setPort(&quot;http-listener&quot;, port);
        GlassFish glassfish = runtime.newGlassFish(glassfishProperties);
        glassfish.start();
        glassfish.getDeployer().deploy(new File(args[1]), &quot;--contextroot&quot;, args[2]);
    }
}

&lt;/textarea&gt;

&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
pack-dist&lt;/h3&gt;
As I am a bit lazy and want to avoid copy jars manually I created a pom-project just to copy dependencies. The needed jar file will end up in the root folders under &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;./dist/&lt;/span&gt;, I also added a bat file to start the embedded Payara with the following content:&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;java -cp dist/gf-runner-1.0-SNAPSHOT.jar;dist/payara-embedded-all-4.1.152.1.jar se.ironic.gfrunner.EmbeddedGFRunner 2001 dist/task-web-1.0-SNAPSHOT.war task-web
&lt;/textarea&gt;
&lt;br /&gt;
&lt;br /&gt;
I also tried the jersey-client from the previous post with s slight modification for the context-path and it still works. (or you can start the payara with &quot;/&quot; as context path)&lt;br /&gt;
&lt;br /&gt;
In next part I will add a JSF client on top of this service to show some nice stuff in Java EE 7 and JSF 2.2.&lt;br /&gt;
&lt;br /&gt;
[The full project can be found at: &lt;a href=&quot;https://bitbucket.org/pejomstd/embedded-gf-payara&quot;&gt;https://bitbucket.org/pejomstd/embedded-gf-payara&lt;/a&gt;]&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/78381675333952191/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2015/05/restful-service-on-embedded.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/78381675333952191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/78381675333952191'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2015/05/restful-service-on-embedded.html' title='RESTful Service on an embedded Glassfish/Payara'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-8018074595122809037</id><published>2015-05-02T15:00:00.001+02:00</published><updated>2015-05-02T15:01:22.077+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Jersey"/><category scheme="http://www.blogger.com/atom/ns#" term="Jetty"/><category scheme="http://www.blogger.com/atom/ns#" term="Microservice"/><category scheme="http://www.blogger.com/atom/ns#" term="REST"/><category scheme="http://www.blogger.com/atom/ns#" term="Webservice"/><title type='text'>REST with Jersey and Jetty part 3</title><content type='html'>&lt;h2&gt;
REST with Jersey and Jetty part 3&lt;/h2&gt;
&lt;h3&gt;
Adding JSON support.&lt;/h3&gt;
The first two parts &amp;nbsp;in this small series of posts were about setting up the server and be able to run it with Jersey. [&lt;a href=&quot;http://ironicprogrammer.blogspot.com/2015/04/rest-with-jersey-and-jetty-part-1.html&quot;&gt;REST with Jersey and Jetty part 1&lt;/a&gt;, &lt;a href=&quot;http://ironicprogrammer.blogspot.com/2015/05/rest-with-jersey-and-jetty-part-2.html&quot;&gt;REST with Jersey and Jetty part 2&lt;/a&gt;].&lt;br /&gt;
&lt;br /&gt;
This time there will be a bit more work. And I will take it step by step.&lt;br /&gt;
&lt;br /&gt;
The service we will implement will handle tasks. To start with, there will only be one task list where all tasks will go.&lt;br /&gt;
&lt;br /&gt;
The api will be the following.&lt;br /&gt;
Task class:&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package model;

import java.util.Date;
import java.util.UUID;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Task {
    private String id;
    private String title;
    private String description;
    private Date dueDate;

    public Task() {
    }
    
    public static Task of(String title, String description, Date dueDate) {
        UUID randomUUID = UUID.randomUUID();
        return new Task(randomUUID.toString(), title, description, dueDate);
    }

    private Task(String id, String title, String description, Date dueDate) {
        this.id = id;
        this.title = title;
        this.description = description;
        this.dueDate = dueDate;
    }

    // getters/setters

    @Override
    public String toString() {
        return &quot;Task{&quot; + &quot;id=&quot; + id + &quot;, title=&quot; + title + &quot;, description=&quot; + description + &quot;, dueDate=&quot; + dueDate + &#39;}&#39;;
    }
    
    
    
}

&lt;/textarea&gt;
&lt;br /&gt;
&lt;br /&gt;
To start with we add support for getting the list, there will be some hardcoding until we have the working JSON support, since the first thing we want is a working Jersey with JSON support, not to complicate things further. When we have that, we can start adding functionality. But in the end, we will try to support:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;list all&lt;/li&gt;
&lt;li&gt;show a single task&lt;/li&gt;
&lt;li&gt;create a task&lt;/li&gt;
&lt;li&gt;update a task&lt;/li&gt;
&lt;li&gt;remove a task&lt;/li&gt;
&lt;li&gt;show range of tasks&lt;/li&gt;
&lt;li&gt;get task count&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
But starting with some hardcoded stuff, to get the server running with JSON, this will be the stating point for the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;TaskResource&lt;/span&gt;&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package rest;

import java.util.Date;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import model.Task;

@Path(&quot;tasks&quot;)
public class TaskResource {
    @GET @Produces(MediaType.APPLICATION_JSON)
    public List&lt;task&gt; getAll() {
        List&lt;task&gt; all = new ArrayList&lt;&gt;();
        all.add(Task.of(&quot;Testtask&quot;, &quot;Task to test&quot;, new Date()));
        return all;
    }
}

&lt;/textarea&gt;
&lt;br /&gt;
&lt;br /&gt;
If you start the server and try to surf to this [http://localhost:2001/api/tasks] will yield the following in the log.&lt;br /&gt;
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;maj 02, 2015 11:02:34 FM org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor aroundWriteTo
SEVERE: MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=java.util.List&lt;model.Task&gt;.
&lt;/textarea&gt;
&lt;br /&gt;
so we need to add some stuff to have JSON support.&lt;br /&gt;
&lt;br /&gt;
Well, just a shor Googling, and it was pretty easy to add. [http://stackoverflow.com/questions/25474223/jersey-rest-messagebodywriter-not-found-for-media-type-application-jso] gives a hint. Just added moxy and it works to get JSON with the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;@GET&lt;/span&gt;.&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;&lt;dependency&gt;
   &lt;groupid&gt;org.glassfish.jersey.media&lt;/groupId&gt;
   &lt;artifactid&gt;jersey-media-moxy&lt;/artifactId&gt;
   &lt;version&gt;2.17&lt;/version&gt;
&lt;/dependency&gt;
&lt;/textarea&gt;
&lt;br /&gt;
So lets go for some real coding. We will add a simple cache, To avoid having a database for this simple example it will only contain a map with the tasks.&lt;br /&gt;
&lt;br /&gt;
Lets start with some simple support of the cache:&lt;br /&gt;
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package rest;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import model.Task;

public enum TaskCache {
    INST;
    
    private Map&lt;String, Task&gt; tasks;

    private TaskCache() {
        tasks = new HashMap&lt;&gt;();
    }
    
    public Optional&lt;task&gt; getTask(String id) {
        return Optional.ofNullable(tasks.get(id));
    }
    
    public void putTask(Task task) {
        tasks.put(task.getId(), task);
    }
    
    public void removeTask(Task task) {
        tasks.remove(task.getId());
    }
    
    public List&lt;task&gt; getTasks() {
        return new ArrayList(tasks.values());
    }
    
}
&lt;/textarea&gt;
&lt;br /&gt;
Lets first add a method to create a task and one for getting a specific task.&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response create(Task task) {
        TaskCache.INST.addTask(task);
        URI id = URI.create(&quot;tasks/&quot; + task.getId());
        Response resp = Response.created(id).build();
        return resp;
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path(&quot;{id}&quot;)
    public Response getTask(@PathParam(&quot;id&quot;) String id) {
        Optional&lt;task&gt; task = TaskCache.INST.getTask(id);
        Response resp = null;
        if (task.isPresent()) {
            resp = Response.ok(task.get()).build();
        } else {
            resp = Response.noContent().build();
        }
        return resp;
    }
&lt;/textarea&gt;
&lt;br /&gt;
To test this, we will need to also add a method to get a single task and a client to test it.&lt;br /&gt;
&lt;br /&gt;
First, the client.&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package app;

import java.net.URI;
import java.util.Date;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import model.Task;

public class JerseyClient {

    public static void main(String[] args) {
        Client client = ClientBuilder.newClient();
        WebTarget postTarget = client.target(&quot;http://localhost:2001&quot;).path(&quot;api&quot;).path(&quot;tasks&quot;);
        Response postResponse = postTarget.request(MediaType.APPLICATION_JSON)
                .post(Entity.json(Task.of(&quot;Testclient&quot;, &quot;Using test client to create&quot;, new Date())));
        
        System.out.println(postResponse.getStatus());
        URI location = postResponse.getLocation();
        
        System.out.println(location);
        
        WebTarget getTarget = client.target(location);
        Response getResponse = getTarget.request(MediaType.APPLICATION_JSON).get();
        
        System.out.println(getResponse.getStatus());
        System.out.println(getResponse.readEntity(Task.class));
    }
}

&lt;/textarea&gt;
&lt;br /&gt;
&lt;br /&gt;
So far the client just adds a Task, gets the URI to the created Task and then gets it using the @GET for the methods added above.&lt;br /&gt;
&lt;br /&gt;
Next step, fix the getAll().&lt;br /&gt;
The client cannot handle a List without wrapping it in a GenericType, but that is really all there is too it, we can still return List&lt;type&gt; from the method.&lt;/type&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;// TaskResource.java
@GET
@Produces(MediaType.APPLICATION_JSON)
public List&lt;task&gt; getAll() {
    return TaskCache.INST.getTasks();
}

// JerseyClient.java
 WebTarget allTarget = client.target(&quot;http://localhost:2001&quot;).path(&quot;api&quot;).path(&quot;tasks&quot;);
        
 GenericType&lt;List&lt;task&gt;&gt; genericType = new GenericType&lt;List&lt;task&gt;&gt;() {};
        
 List&lt;task&gt; all = allTarget.request(MediaType.APPLICATION_JSON).get(genericType);
 for (Task task : all) {
    System.out.println(task);
 }
&lt;/textarea&gt;
&lt;br /&gt;
The only thing we need to add now is update and delete. We will also add some code to test it in the client.
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;@PUT @Consumes(MediaType.APPLICATION_JSON)
    @Path(&quot;{id}&quot;)
    public Response update(Task task) {
        // Just replace the one there
        System.out.println(&quot;Updating task: &quot; + task);
        TaskCache.INST.putTask(task);
        return Response.ok().build();
    }
    
    @DELETE
    @Path(&quot;{id}&quot;)
    public Response delete(@PathParam(&quot;id&quot;) String id) {
        System.out.println(&quot;Deleting task: &quot; + id);
        TaskCache.INST.removeTask(id);
        return Response.ok().build();
    }
&lt;/textarea&gt;
&lt;br /&gt;
I also made some changes in the client:
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;public static void main(String[] args) {
    Client client = ClientBuilder.newClient();
    List&lt;uri&gt; locations = new ArrayList&lt;&gt;();
        
    WebTarget target = client.target(&quot;http://localhost:2001&quot;).path(&quot;api&quot;).path(&quot;tasks&quot;);
        
    Response postResponse = target.request(MediaType.APPLICATION_JSON)
            .post(Entity.json(Task.of(&quot;Testclient1&quot;, &quot;Using test client to create&quot;, new Date())));
    locations.add(postResponse.getLocation());
        
    postResponse = target.request(MediaType.APPLICATION_JSON)
            .post(Entity.json(Task.of(&quot;Testclient2&quot;, &quot;Using test client to create&quot;, new Date())));
    locations.add(postResponse.getLocation());
        
    postResponse = target.request(MediaType.APPLICATION_JSON)
            .post(Entity.json(Task.of(&quot;Testclient3&quot;, &quot;Using test client to create&quot;, new Date())));
    locations.add(postResponse.getLocation());
        
        
    // Get first one
    WebTarget getTarget = client.target(locations.get(0));
    Response getResponse = getTarget.request(MediaType.APPLICATION_JSON).get();
    
    System.out.println(getResponse.getStatus());
    System.out.println(getResponse.readEntity(Task.class));
       
    // Change second one
    getTarget = client.target(locations.get(1));
    getResponse = getTarget.request(MediaType.APPLICATION_JSON).get();
    Task aTask = getResponse.readEntity(Task.class);
    aTask.setTitle(&quot;This title is changed&quot;);
    client.target(locations.get(1)).request(MediaType.APPLICATION_JSON).put(Entity.json(aTask));
        
    // Delete thirs one
    client.target(locations.get(2)).request().delete();
        
    WebTarget allTarget = client.target(&quot;http://localhost:2001&quot;).path(&quot;api&quot;).path(&quot;tasks&quot;);
        
    GenericType&lt;List&lt;task&gt;&gt; genericType = new GenericType&lt;List&lt;task&gt;&gt;() {};
        
    List&lt;task&gt; all = allTarget.request(MediaType.APPLICATION_JSON).get(genericType);
    for (Task task : all) {
        System.out.println(task);
    }
 }
&lt;/textarea&gt;
&lt;br /&gt;
Enjoy your Task microservice in REST using embedded Jetty with Jersey.&lt;br /&gt;
&lt;br /&gt;
Read more about Jersey [&lt;a href=&quot;https://jersey.java.net/documentation/latest/index.html&quot;&gt;https://jersey.java.net/documentation/latest/index.html&lt;/a&gt;]&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/8018074595122809037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2015/05/rest-with-jersey-and-jetty-part-3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/8018074595122809037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/8018074595122809037'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2015/05/rest-with-jersey-and-jetty-part-3.html' title='REST with Jersey and Jetty part 3'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-233138927237313584</id><published>2015-05-01T12:00:00.000+02:00</published><updated>2015-05-01T12:01:05.557+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Jersey"/><category scheme="http://www.blogger.com/atom/ns#" term="Jetty"/><category scheme="http://www.blogger.com/atom/ns#" term="Microservice"/><category scheme="http://www.blogger.com/atom/ns#" term="REST"/><category scheme="http://www.blogger.com/atom/ns#" term="Webservice"/><title type='text'>REST with Jersey and Jetty part 2</title><content type='html'>&lt;h2&gt;
REST with Jersey and Jetty part 2&lt;/h2&gt;
&lt;div&gt;
&lt;h3&gt;
Getting Jersey into play&lt;/h3&gt;
In this part, we will introduce Jetty as serving with rest. We will att a class serving a &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;@GET&lt;/span&gt; request.&lt;br /&gt;
&lt;br /&gt;
We will need an extra dependency for Jersey to work, and after getting a strange error under startup I ended up changing the dependency on Jetty from the previous post [&lt;a href=&quot;http://ironicprogrammer.blogspot.se/2015/04/rest-with-jersey-and-jetty-part-1.html&quot;&gt;http://ironicprogrammer.blogspot.se/2015/04/rest-with-jersey-and-jetty-part-1.html&lt;/a&gt;]. I got the following error:&lt;br /&gt;
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;2015-05-01 11:37:38.214:INFO:oejs.Server:main: jetty-9.1.1.v20140108
2015-05-01 11:37:38.224:WARN:oejuc.AbstractLifeCycle:main: FAILED org.eclipse.jetty.server.Server@7637f22: java.lang.NoSuchMethodError: org.eclipse.jetty.util.DateCache.setTimeZone(Ljava/util/TimeZone;)V
java.lang.NoSuchMethodError: org.eclipse.jetty.util.DateCache.setTimeZone(Ljava/util/TimeZone;)V
&lt;/textarea&gt;
&lt;br /&gt;
When adding the dependency for Jersey 2.17 after th Jetty dependency. Actually I got it to work by moving the Jetty dependency to after the Jersey dependency. But reading the log you can see that 2.17 if Jersey used Jetty 9.1.1 so, updating Jetty dependency to 9.1.1.v20140108, the order does not matter.&lt;br /&gt;
This is the dependencies for this part.
&lt;br /&gt;
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;&lt;dependencies&gt;
   &lt;dependency&gt;
      &lt;groupid&gt;org.glassfish.jersey.containers&lt;/groupId&gt;
      &lt;artifactid&gt;jersey-container-jetty-servlet&lt;/artifactId&gt;
      &lt;version&gt;2.17&lt;/version&gt;
   &lt;/dependency&gt;
   &lt;dependency&gt;
      &lt;groupid&gt;org.eclipse.jetty&lt;/groupId&gt;
      &lt;artifactid&gt;jetty-servlet&lt;/artifactId&gt;
      &lt;version&gt;9.1.1.v20140108&lt;/version&gt;
   &lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;/textarea&gt;
&lt;br /&gt;
&lt;br /&gt;
We will also create a new statup-class, It will not be much more code than the one in the previous part, but some extra stuff is needed to get Jersey into play.&lt;br /&gt;
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package app;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

public class JerseyServer {
    public static void main(String[] args) {
        int port = 2001;
        if(args.length == 1) {
            port = Integer.parseInt(args[0]);
        }
        Server server = new Server(port);
        
        ServletHolder servletHolder = new ServletHolder(org.glassfish.jersey.servlet.ServletContainer.class);
        servletHolder.setInitParameter(&quot;com.sun.jersey.config.property.resourceConfigClass&quot;, &quot;com.sun.jersey.api.core.PackagesResourceConfig&quot;);
        servletHolder.setInitParameter(&quot;jersey.config.server.provider.packages&quot;, &quot;rest&quot;);//Set the package where the services reside
        servletHolder.setInitParameter(&quot;com.sun.jersey.api.json.POJOMappingFeature&quot;, &quot;true&quot;);
        ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        server.setHandler(contextHandler);
        contextHandler.addServlet(servletHolder, &quot;/api/*&quot;);
        
        try {
            server.start();
            server.join();
        } catch (Exception ex) {
            Logger.getLogger(JerseyServer.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(1);
        }
    }
}
&lt;/textarea&gt;
&lt;br /&gt;
The difference here is that we use a ServletHolder with some init parameters to set Jersey up. We also set the path to serve to &quot;/api/*&quot; instead of plain root &quot;/&quot;.

&lt;br /&gt;
That brings us to REST, we need something to show that it works. To do this we have a class under &quot;rest&quot; package called HelloResource.
&lt;br /&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path(&quot;hello&quot;)
public class HelloResource {
    @GET @Produces(&quot;text/plain&quot;)
    public String sayHello() {
        return &quot;Hello from HelloResource!&quot;;
    }
}

&lt;/textarea&gt;
&lt;br /&gt;
&lt;br /&gt;
So now the only thing you have to do is to start upp &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;JerseyServer&lt;/span&gt; and surf into [&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;http://localhost:2001/api/hello&lt;/span&gt;] and you should see the hello message. And there you have your first little Microservice ;)&lt;br /&gt;
&lt;br /&gt;
In future post will explore how to use more than &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;@GET&lt;/span&gt; and also how to add JSON support to this.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/233138927237313584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2015/05/rest-with-jersey-and-jetty-part-2.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/233138927237313584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/233138927237313584'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2015/05/rest-with-jersey-and-jetty-part-2.html' title='REST with Jersey and Jetty part 2'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-9113025173278858745</id><published>2015-04-30T21:17:00.001+02:00</published><updated>2015-05-05T21:52:31.420+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Jersey"/><category scheme="http://www.blogger.com/atom/ns#" term="Jetty"/><category scheme="http://www.blogger.com/atom/ns#" term="REST"/><category scheme="http://www.blogger.com/atom/ns#" term="Webservice"/><title type='text'>REST with Jersey and Jetty part 1</title><content type='html'>&lt;h2&gt;
REST with Jersey and Jetty part 1&lt;/h2&gt;
&lt;h3&gt;
Running Jersy standalone with a Servlet.&lt;/h3&gt;
&lt;div&gt;
A few days ago I started to look into how to run a REST service with an embedded container. Now a friend of Springframework will say, that is easy with Spring, but after looking at a tutorial [&lt;a href=&quot;http://spring.io/guides/tutorials/bookmarks/&quot;&gt;http://spring.io/guides/tutorials/bookmarks/&lt;/a&gt;] I notice a couple of things. The annotations are not the standard JSR 331/339 ones, and there is a lot of other things from spring framework coming into play. Well, sorry Spring-guys, I don’t want that. I want to go with standard JSR annotations, and no specialities from Spring.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;line-height: 22.0799999237061px;&quot;&gt;So my ide is to use Jersey which is the reference implementation och JSR 311/339 and run it on a server that can be embedded. What I want to do is to have the following support.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;line-height: 22.0799999237061px;&quot;&gt;Ability to run with an embedded server (my choise: “jetty”)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;line-height: 22.0799999237061px;&quot;&gt;Ability to serve REST calls (my choise: “Jersey”)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;line-height: 22.0799999237061px;&quot;&gt;Ability to communicate wiht JSON.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
After some research I noticed that it is not easy to find any good resource on how to run Jersey with an embedded server. the bes I could find was [&lt;a href=&quot;http://jlunaquiroga.blogspot.se/2014/01/restful-web-services-with-jetty-and.html&quot;&gt;http://jlunaquiroga.blogspot.se/2014/01/restful-web-services-with-jetty-and.html&lt;/a&gt;] , but I don’t like blogs saying “you only need to include the jars necessary or use maven” but leaving out the information of which the necessary jars are or the specific maven dependencies needed.. the documentation over Jersey is scarce in examples.&lt;br /&gt;
&lt;br /&gt;
I will start this “journey” by building it up step by step. In this part, I will do only what is necessary to start an embedded server.&lt;br /&gt;
&lt;br /&gt;
I used the above blog as a starting point. First step I will show is how to run a servlet in an embedded Jetty.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is to have a dependency to Netty.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;&lt;dependency&gt;
      &lt;groupid&gt;org.eclipse.jetty&lt;/groupId&gt;
      &lt;artifactid&gt;jetty-servlet&lt;/artifactId&gt;
      &lt;version&gt;9.1.1.v20140108&lt;/version&gt;
   &lt;/dependency&gt;
&lt;/textarea&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
The server will be started in a class with a main method,&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package app;

import servlet.HelloServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;

public class MiniServer {
    public static void main(String[] args) throws Exception {
        int port = 2001;
        if(args.length == 1) {
            port = Integer.parseInt(args[0]);
        }
        Server server = new Server(port);
        ServletHandler handler = new ServletHandler();
        handler.addServletWithMapping(HelloServlet.class, &quot;/hello&quot;);
        server.setHandler(handler);
        
        server.start();
        server.join();
    }
}

&lt;/textarea&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
There will also be a simple servlet to run in it.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;textarea class=&quot;java&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;package servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType(&quot;text/html&quot;);
        response.setStatus(HttpServletResponse.SC_OK);
        response.getWriter().println(&quot;Hello from Sevlet&quot;);
    }
}

&lt;/textarea&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
Next post is about how to create a REST service based on Jersey and run it in Jetty.&lt;br /&gt;
(Update: changed the version of Jetty dependency, since I in next post use Jersey 2.17 and there was some issues running with Jetty 9.0.2)&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/9113025173278858745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2015/04/rest-with-jersey-and-jetty-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/9113025173278858745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/9113025173278858745'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2015/04/rest-with-jersey-and-jetty-part-1.html' title='REST with Jersey and Jetty part 1'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-6320582065063512161</id><published>2013-12-29T12:13:00.001+01:00</published><updated>2013-12-29T12:15:11.847+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JSF"/><category scheme="http://www.blogger.com/atom/ns#" term="JSF2"/><category scheme="http://www.blogger.com/atom/ns#" term="Primefaces"/><category scheme="http://www.blogger.com/atom/ns#" term="RichFaces"/><title type='text'>Why I plan to leave RichFaces</title><content type='html'>Having recently worked with upgrading RichFaces 3.3 to 4.3.1 I have come to the conlusion.... &quot;It basically s*cks&quot;. I will give some reasons why:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Huge makeover of tags&lt;/li&gt;
&lt;li&gt;Removal of tags&lt;/li&gt;
&lt;li&gt;Changes in attibutes&lt;/li&gt;
&lt;li&gt;Too many attributes.&lt;/li&gt;
&lt;/ul&gt;
Maybe RF was good when it came, because there was not so much else. But the makeover from 3 to 4 made an upgrade a real pain in the a**.&lt;br /&gt;
&lt;br /&gt;
Googling help for RF in most cases gives result for 3.3.x solutions. I have found it hard to find any useful information about 4 or later. This makes an upgrade hard since it is not easy to find the proper information how things are done with 4.3.x, specially how to replace stuff that is removed from 3.3.x since there is not a decent upgrade guide to be found either. Maybe I have missed some place where all this is written, but weeks of Googling without finding anything is another problem, the documentation s*cks when there is not easy to find what you need.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Makeover of Tags&lt;/h3&gt;
&lt;div&gt;
Some examples:&amp;nbsp;&lt;/div&gt;
&lt;textarea class=&quot;xml&quot; cols=&quot;60&quot; name=&quot;code&quot; rows=&quot;10&quot;&gt;List&lt;string&gt;
&lt;rich:tooTip/&gt;
became 
&lt;rich:tootip/&gt;
...
&lt;rich:tooBar/&gt;
became 
&lt;rich:toobar/&gt;
&lt;/textarea&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Removal of tags&lt;/h3&gt;
&lt;i&gt;rich:modalPanel&lt;/i&gt; dissapeared. Well WHY? I think a lot of people used it, now all that code have to be totally rewritten.&lt;br /&gt;
&lt;div&gt;
&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;&lt;i&gt;rich:layoutPanel&lt;/i&gt; was removed. Well now I have found nothing obvious to replace it so back to postitioning by div and css.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=3815776380138759375&quot;&gt;&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;Changes in attributes&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;Take&lt;i&gt; rich:dataTable&lt;/i&gt; as an example: some attributes removed, some new, and also changes from camel-case to all lower case attributes but not all. WTF? do you really want someone to use the framework after an upgrade, do not change EVERYTHING. All event-attributes was changed to lowercase (&quot;onRowClick&quot; to &quot;onrowclick&quot;), but not things like &quot;rowClass&quot;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=3815776380138759375&quot;&gt;&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;
&lt;i&gt;rich:panel&lt;/i&gt;: attribute &quot;header&quot;changed meaning from label to space-separated list of styles (???)&lt;br /&gt;
&lt;h3&gt;
&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;Too many attributes&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;a4j:commandButton: 32 attributes&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;a4j:commandLing: 37 attributes&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;rich:dataTable: 34 attributes&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;This is just a few examples, there is a lot of headache upgrading from 3.3.x to 4.3.x, not only on the surface, if you are using classes in your backing code, be aware, the package structure is also changed, classes have dissapeared and things just stop working. Changing the tags may look hard enough, but when new ones are in place you still probably have strange bugs that need fixing since things that worked before does not work any more.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;bold&quot;&gt;&lt;span class=&quot;property&quot;&gt;If I would choose next upgrade, I would not choose RF 5, but go for PrimeFaces instead.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/6320582065063512161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2013/12/why-i-plan-to-leave-richfaces.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/6320582065063512161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/6320582065063512161'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2013/12/why-i-plan-to-leave-richfaces.html' title='Why I plan to leave RichFaces'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-4380258047531897482</id><published>2013-11-13T18:45:00.000+01:00</published><updated>2013-11-13T20:51:13.653+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CDI"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java EE"/><category scheme="http://www.blogger.com/atom/ns#" term="JEE"/><category scheme="http://www.blogger.com/atom/ns#" term="JSF2"/><category scheme="http://www.blogger.com/atom/ns#" term="Primefaces"/><title type='text'>Designing a “modular” web application</title><content type='html'>&lt;h2&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 21px; font-weight: normal; vertical-align: baseline;&quot;&gt;Background&lt;/span&gt;&lt;/h2&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;I would like to separate functionality for a web application into separate jar-modules and include these in a war project. &lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;The purpose for this is to separate development and deployment, that is, to develop functionality separately and include it in the war-packaging and it should automatically be usable with templates, menues etc.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;Sorry if the code don&#39;t display so well. But putting codes with Generics is not so well handled by Bloggers editor, so until I have time to fix it you will have to live with it ;) and I will use [] instead of &amp;lt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;/span&gt;

&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 21px; font-weight: normal; vertical-align: baseline;&quot;&gt;Structure&lt;/span&gt;&lt;/h2&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;To make it modular it is nescessary to have some common code (placed in “common-web”). The structure for this is basically:&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://yuml.me/55c4759f&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;232&quot; src=&quot;http://yuml.me/55c4759f&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;ul id=&quot;docs-internal-guid-46648021-527c-31e9-755e-f92d89ff0c6b&quot; style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-weight: bold; vertical-align: baseline;&quot;&gt;common-web&lt;/span&gt;&lt;span style=&quot;vertical-align: baseline;&quot;&gt;: will contain code common to modules and web-applications. &lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-style: italic; vertical-align: baseline;&quot;&gt;templates&lt;/span&gt;&lt;span style=&quot;vertical-align: baseline;&quot;&gt;: for reuse in different modules, basic templates is put in a common module.&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-style: italic; vertical-align: baseline;&quot;&gt;login&lt;/span&gt;&lt;span style=&quot;vertical-align: baseline;&quot;&gt;: (out of scope, will not implement login in this example) for reuse of login-form etc. i.e. the same files and functionality applies to all web-applications that uses login.&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-style: italic; vertical-align: baseline;&quot;&gt;resources&lt;/span&gt;&lt;span style=&quot;vertical-align: baseline;&quot;&gt;: common css and images is placed to be reused.&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-style: italic; vertical-align: baseline;&quot;&gt;menu&lt;/span&gt;&lt;span style=&quot;vertical-align: baseline;&quot;&gt;: functionality to assemble &lt;/span&gt;&lt;span style=&quot;font-style: italic; vertical-align: baseline;&quot;&gt;n&lt;/span&gt;&lt;span style=&quot;vertical-align: baseline;&quot;&gt; menu(es) from &lt;/span&gt;&lt;span style=&quot;font-style: italic; vertical-align: baseline;&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;vertical-align: baseline;&quot;&gt; modules so they will present in web-applications no matter in what module a page is used.&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-style: italic; vertical-align: baseline;&quot;&gt;common code&lt;/span&gt;&lt;span style=&quot;vertical-align: baseline;&quot;&gt;: code for hoding and generating menu(es), common utility code for JSF, ManagedBeans etc.&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-weight: bold; vertical-align: baseline;&quot;&gt;war&lt;/span&gt;&lt;span style=&quot;vertical-align: baseline;&quot;&gt;: web-project with war-packaging that will use modules.&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;webmoduleA..X: functional parts that implement a function or group af functions that logically belong together.&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;as an example I will implement at “&lt;/span&gt;&lt;span style=&quot;font-style: italic; font-weight: bold; vertical-align: baseline;&quot;&gt;todo-webmodule&lt;/span&gt;&lt;span style=&quot;vertical-align: baseline;&quot;&gt;” in a PoC to show the functionality.&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;h3&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 21px; font-weight: normal; vertical-align: baseline;&quot;&gt;Menu&lt;/span&gt;&lt;/h3&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;Basic functionality for menu is placed in &lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline;&quot;&gt;common-web&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;h4&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;What am I trying to solve here?&lt;/span&gt;&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;A module can have different kind of needs, to access parts of its functionality we need a &lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline;&quot;&gt;menu with 1 or more items&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt; (even if a module can be without menu, for example common-web may not need one, even if it is also a kind of a module).&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;b&gt;&lt;i&gt;Requirements&lt;/i&gt;&lt;/b&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;A menu sholud be able to present itself as a top-menu in a menubar&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;A menu should be able to present itself as a part of another menu (i.e. not on toplevel) but in another menu.&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;Should be able to order children of a node.&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;Support to up to 4 levels of menues (more level will not be displayed)&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;b&gt;&lt;i&gt;Assumptions&lt;/i&gt;&lt;/b&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;If a menu has no children it should have an action attached (=no expression needed)&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;If a menu has children, it has no action attatched to it.(=no expression needed)&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;Only SubMenus can be placed, not single menues (MenuItem). And they can only be placed in other SubMenus.&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline;&quot;&gt;Placement&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;“/” is root, putting menues under “/” would put them in top menubar.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;Take as an example; you have 3 top menus (Admin, Project, Help). These should all be placed under “/”&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;Further, say we want to capture this endresult for menues.&lt;/span&gt;&lt;/div&gt;
&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;/&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;admin&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: square; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;add user&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: square; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;list users&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;project&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: square; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;add project&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: square; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;list projects&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; font-style: italic; font-weight: bold; list-style-type: square; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;issues&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;add issue&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;list issues&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;help&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; list-style-type: square; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;about&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;/admin&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;/admin/add user&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;/admin/list users&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;/project&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;/project/add project&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;/project/list projects&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;/project/&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline;&quot;&gt;issues&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;/help&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;/help/about&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;We have Issues under its own grouping and this should be inserted under project. (The reason behind this is that it may be developed in another module and we want to insert it under project in this application)&lt;/span&gt;&lt;/div&gt;
&lt;h4&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline;&quot;&gt;Ordering&lt;/span&gt;&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;When it comes to ordering, I want to speify an order on all levels. The purpose of this is that when adding top menues dynamically I do not know which order they will appear, hence it is usefull to be able to define it on top-level. &lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;Another purpose is, that since it is possible to insert a menu into another, this may disturb the order or we want the inserted menu group to in another position than it gets inserted to.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;This solution for this is to sort all items alphabetically and then resort according to supplied ordering (which is allowed to just use the ones it wants to sort in from start)&lt;/span&gt;&lt;/div&gt;
&lt;h2&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 21px; font-weight: normal; vertical-align: baseline;&quot;&gt;Solution&lt;/span&gt;&lt;/h2&gt;
&lt;h3&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;Model&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://yuml.me/535fd003&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;http://yuml.me/535fd003&quot; width=&quot;171&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;h3&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;font-size: 17px; vertical-align: baseline;&quot;&gt;Description&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;I will describe the solution by taking my example project on bitbucket as an example.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;The example project (on bitbucket) have the following structure:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://yuml.me/0fcc2391&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;http://yuml.me/0fcc2391&quot; width=&quot;191&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; id=&quot;docs-internal-guid-46648021-5287-e378-62a5-e5fe8cc9eb8e&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;In this example the only “working” code for a MenuGroup that I will implement is the TODO-functionality, and of course the supporting code to have it modular. As goes for the concept of menus I will add a couple of MenuGroups undermodule-web itself. (Do not be surprised if the code here differs from the one on bitbucket, because there may be improvements done in the real code.). There is also mockup code to add the menues as described above to get more than one menu.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;To have a menu for “Todo”, the following code will give me that as a “MenuGroup”&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot;&gt;
&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
public class TodoMenuGroup extends MenuGroup {

    @Override
    public Menu getRootMenu() {
        return Menu.Builder.submenu(&quot;Todo&quot;, &quot;todo&quot;)
                .addChild(Menu.Builder.item(&quot;View lists&quot;, &quot;view_lists&quot;)
                       .withExpression(&quot;/todo/todolists&quot;).build())
                .addChild(Menu.Builder.item(&quot;Create list&quot;, &quot;create_list&quot;)
                       .withExpression(&quot;/todo/create-list&quot;).build())
                .build();
    }
    
}
&lt;/textarea&gt;
&lt;table style=&quot;border-collapse: collapse; border: none; width: 624px;&quot;&gt;&lt;colgroup&gt;&lt;col width=&quot;*&quot;&gt;&lt;/col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;To have it modular and generate modules, this is done by having the menu.xhtml and supporting classes in common-web. The most important are MenuBean (that assemble the menu for the view), MenuAssembler (that assembles a menu for MenuBean from the groups it is provided)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;To get menu groups aswell as config of orderings and placement from other modules, a bit of CDI is used.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot;&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
@Named
@ApplicationScoped
public class MenuBean extends BaseBean implements Serializable {

    List&lt;Menu&gt; menus = Collections.emptyList();

    @Inject
    @Any
    private Instance&lt;MenuGroup&gt; mnuGrpInst;

    @Inject @Any
    private Instance&lt;WebMenuConfig&gt; menuConfInst;
    
    
    public List&lt;Menu&gt; getMenus() {
        if (menus.isEmpty()) {
            assembleMenus();
        }
        return menus;
    }

    private void assembleMenus() {

        MenuAssembler ma = new MenuAssembler();
        for (MenuGroup menuGrp : mnuGrpInst) {
            ma.addGroup(menuGrp);
        }

        for (Iterator&lt;WebMenuConfig&gt; it = menuConfInst.iterator(); it.hasNext();) {
            WebMenuConfig webMenuConfig = it.next();
            for (Map.Entry&lt;String,String&gt; entry : webMenuConfig.getOrderings().entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                ma.addOrdering(key, value);
            }
            for (Map.Entry&lt;String,String&gt; entry : webMenuConfig.getPlacements().entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                ma.addPlacement(key, value);
            }
        }

        menus = ma.assemble();
    }

}
&lt;/textarea&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;Since we do not know which MenuGroups will exist when developing common code, we inject any type in an Instance&lt;menugroup&gt;. The view will call getMenus() tha if empty will try to assemble the menu. The placement and ordering should be provided from outside aswell, not hardcoded as in this case.&lt;/menugroup&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: bold; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;The order we do this is:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;ol style=&quot;font-weight: bold; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; list-style-type: decimal; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;add MenuGroups&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; list-style-type: decimal; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;add rules &lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;ol style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; list-style-type: lower-alpha; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;placement and/or ordering (defined in a WebMenuConfig implementation)&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;li dir=&quot;ltr&quot; style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; list-style-type: decimal; vertical-align: baseline;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;vertical-align: baseline;&quot;&gt;call assemble()&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/ol&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: bold; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;The last call will assemble the menu and return a list of the top menus. These menus will after returning be rendered in the view.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: bold; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;The implementation of the WebMenuConfig in this case is defined like this:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot;&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
public class ModwebMenuConfig extends WebMenuConfig {

   @Override
   public Map&lt;String,String&gt;  getOrderings() {
      HashMap&lt;String,String&gt; orderings = new HashMap&amp;lt;&amp;gt;();     
      orderings.put(MenuAssembler.TOP_ORDER, &quot;admin,todo,projects,help&quot;);
      orderings.put(&quot;project&quot;, &quot;add_project,list_projects,issues&quot;);
      return orderings;
   }

   @Override
   public Map&lt;String,String&gt; getPlacements() {
      HashMap&lt;String,String&gt; placements = new HashMap&amp;lt;&amp;gt;();
      placements.put(&quot;issues&quot;, &quot;project&quot;);
      return placements;
   }
}
&lt;/textarea&gt;
&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div style=&quot;font-weight: bold;&quot;&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; vertical-align: baseline;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;This will give a menu that looks like:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8y1gWtHpowH8f98e9SX69-0mgtHMKGcTRDVbU9ktLSpOAtRfZoAZmrQrIlLsp_vKjx70Gz1abHR2p7Uj9VFyTGKPnvm0DgBZBTOVAuMxInAqelmhmwBhGAh5809otVYMvY-loaulgnSs/s1600/menu.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;102&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8y1gWtHpowH8f98e9SX69-0mgtHMKGcTRDVbU9ktLSpOAtRfZoAZmrQrIlLsp_vKjx70Gz1abHR2p7Uj9VFyTGKPnvm0DgBZBTOVAuMxInAqelmhmwBhGAh5809otVYMvY-loaulgnSs/s400/menu.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline;&quot;&gt;Code can be found at: &lt;/span&gt;&lt;a href=&quot;https://bitbucket.org/pejomstd/modweb&quot; style=&quot;text-decoration: none;&quot;&gt;&lt;span style=&quot;color: #1155cc; font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: underline; vertical-align: baseline;&quot;&gt;https://bitbucket.org/pejomstd/modweb&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;; font-size: 17px; font-weight: bold; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/4380258047531897482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2013/11/designing-modular-web-application.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/4380258047531897482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/4380258047531897482'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2013/11/designing-modular-web-application.html' title='Designing a “modular” web application'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8y1gWtHpowH8f98e9SX69-0mgtHMKGcTRDVbU9ktLSpOAtRfZoAZmrQrIlLsp_vKjx70Gz1abHR2p7Uj9VFyTGKPnvm0DgBZBTOVAuMxInAqelmhmwBhGAh5809otVYMvY-loaulgnSs/s72-c/menu.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-5489644450779345290</id><published>2012-07-12T09:46:00.001+02:00</published><updated>2012-07-12T09:46:07.162+02:00</updated><title type='text'>&quot;plz give codez...&quot;</title><content type='html'>or &lt;b&gt;&lt;i&gt;&quot;How to try to get the work done by posting questions&quot;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Hold your hat because this may have some ironic content.&lt;br /&gt;
&lt;br /&gt;
Well this post is going to be mostly about discussions in groups on LinkedIn. And specifically about questions asked in the groups. It seams to be a tendency for freshers from certain countries to try to get the work done by asking help from others. Seriously, LinkedIn is a professional networks site, but that does not mean that the professionals there are suppose to do your work for you.&lt;br /&gt;
&lt;br /&gt;
It is almost amazing to see that some does not have the capability to think just 2 seconds before posting a question or the capability to search either the group in hand or to use a search engine (&lt;b&gt;like &lt;a href=&quot;http://www.google.com/&quot;&gt;Google&lt;/a&gt;!&lt;/b&gt;) to try to find an answer.&lt;br /&gt;
&lt;br /&gt;
Well lets narrow down to Java because that is my field at the moment. Lets be honest. Getting to know the basics for Java, it is not hard to find resources online. For crying out loud, I think Oracle&#39;s (Sun&#39;s) documentation &amp;nbsp;and tutorial online is far better then what can be found for C# (Not that I looked recently). Despite of this, groups on LinkedIn is filled with basic questions, why?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Some examples&lt;/b&gt;:&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Give me codez (or I do not know anything, but please do the job for me)&lt;/i&gt;&lt;/b&gt;:&lt;br /&gt;
&lt;div style=&quot;font-style: italic; padding: 20px;&quot;&gt;
&quot;Hi All, I want to learn Collection framework. Will you please tell me the sources where I can get the &quot;Easy to Understand&quot; and &quot;With Examples&quot; and &quot;Real Time Scenarios&quot; ? Need Your Help !!! &quot;&lt;/div&gt;
Well, the short answer is, &quot;&lt;b&gt;Google it!!!&lt;/b&gt;&quot;. To search for this will give more answers than someone is willing to spend time explaining in a group discussion. To answer this I would probably Google for the sources as I do not bookmark these kind of things. I will not give you examples. And certainly to give real time scenarios will make me write a lot, which I am not willing to do for the effort put in in asking the question.&lt;br /&gt;
&lt;div style=&quot;font-style: italic; padding: 20px;&quot;&gt;
How can we create array of vector or array of arrayList,please reply
&lt;/div&gt;
Actually a student. But come on, aren&#39;t LinkedIn a network site for professionals. Should a question really be a question where the obvious answer is, &quot;See the API documentation&quot; or &quot;We are not doing your homework here!&quot;.
&lt;br /&gt;
&lt;br /&gt;
Another one:&lt;br /&gt;
&lt;div style=&quot;font-style: italic; padding: 20px;&quot;&gt;
i am a java fresher...can u suggest how the interfaces given to developers to program...? if possible give some real time examples.....@thanks in advance
&lt;/div&gt;
How should I give you an example of how this is done? Should I make a movie out of how to check in into SVN created interfaces and show how a newbie check it out and start working?&lt;br /&gt;
&lt;br /&gt;
Here is a different one, but requesting the docs instead of code:&lt;br /&gt;
&lt;div style=&quot;font-style: italic; padding: 20px;&quot;&gt;
can anyone explain me ,what id maven?also provide me docs.thanks in advance
&lt;/div&gt;
Or some links and docs:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;font-style: italic; padding: 20px;&quot;&gt;
Please send me best javafx links and pdf. Thanks in advance.
&lt;/div&gt;
Some Basic Java and API questions:&lt;br /&gt;
&lt;div style=&quot;font-style: italic; padding: 20px;&quot;&gt;
What is the difference between String Buffer and String Builder? 
&lt;br /&gt;
&lt;br /&gt;
Abstract classes and interfaces
&lt;br /&gt;
&lt;br /&gt;
What is synchronize keyword? Why we use synchronize keyword in java?
&lt;br /&gt;
&lt;br /&gt;
what is system , out and println in system.out.println()?and how it works? 
&lt;br /&gt;
&lt;br /&gt;
What is the difference between HashTable and HashMap?
&lt;/div&gt;
&lt;b&gt;Ok, here it is:&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;a href=&quot;http://docs.oracle.com/javase/6/docs/api/&quot;&gt;Java™ Platform, Standard Edition 6 API Specification&lt;/a&gt;,&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;a href=&quot;http://docs.oracle.com/javase/tutorial/java/index.html&quot;&gt;Trail: Learning the Java Language&lt;/a&gt;&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Language difficulties (or do you think you are in a chat for kids?):&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Proper English seam to be some kind of standard. Look at this reply in a thread about an exception in Struts-1&lt;br /&gt;
&lt;div style=&quot;font-style: italic; padding: 20px;&quot;&gt;
hello &quot;---&quot; wt prob in struts2 ur nw in struts2 ok no problem
wt u use eclipse or net bean i hav nt much knowledge in struts1 bu i m working in struts2
&lt;br /&gt;
&lt;br /&gt;
plz frnds, tell me.....&lt;/div&gt;
Again, in a networking site for professionals, should you really write in a way that teenagers do in a chat?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;About interviews:
&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div style=&quot;font-style: italic; padding: 20px;&quot;&gt;
Hello, In an interview i faced the question &quot;What is your project architecture?&quot;can u plz help me the correct answer &lt;/div&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;Well, maybe if you do not know what you have done the last couple of years, maybe you should not have that job. One thing that I can tell you is that I have no clue how you worked during those two years.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;And people posting jobs under discussion? I do not even want to go there...&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/5489644450779345290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2012/07/plz-give-codez.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/5489644450779345290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/5489644450779345290'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2012/07/plz-give-codez.html' title='&quot;plz give codez...&quot;'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-5054716124942269818</id><published>2012-01-31T10:49:00.000+01:00</published><updated>2012-01-31T10:56:02.435+01:00</updated><title type='text'>My experience with Binero 2.0 (so far...)</title><content type='html'>Well, for those who do not know, Binero is a Swedish Webhotel, which I use for a small site, and also administer another.&lt;br /&gt;
&lt;br /&gt;
They brag about being &quot;Best in Test&quot; and having an awesome support all days a week through phone and email.&lt;br /&gt;
&lt;br /&gt;
Well according to me, if they are best in test, how bad are the other ones? If the support are awesome, why is it impossible to reach them by phone, (if you do not want to be in a phone queue listening to some stupid 80&#39;s computer game melody forever)? And why does it take a full day to get an answer on a mail you send?&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;

OneClick&lt;/h2&gt;
They also lifts out their &quot;OneClick&quot; solution as you avoid sitting with long installations. However, it does not really work. And then you have to wait to get an answer from the support that does not really help.&lt;br /&gt;
&lt;br /&gt;
In my example, I wanted to migrate my small site to 2.0 to be able to test Umbraco for the other site. Well to not think of the headache to migrate, which I will describe later, when finally migrated I tried to install it. Well did it work?&lt;br /&gt;
&lt;br /&gt;
Not really. Trying to install Umbraco on the Windows platform, you have to choose domain and then application to install. Guess what! The only thing I can do, is to read the message that the chosen platform does not support this. Well, creating a subdomain for Linux instead, Umbraco is not an option anymore.&lt;br /&gt;
&lt;br /&gt;
What does the support say, that I have to create the subdomain on Linux!&lt;br /&gt;
&lt;br /&gt;
Ok, I did not actually write that it was Umbraco I was trying to install and since that should be on Windows. But after replying to the mail 21 hours ago, I still have not got any answer to why this does not work.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;

Migrating&lt;/h2&gt;
Ok, back to the migration, which is a story it self.&lt;br /&gt;
&lt;br /&gt;
I started it early myself, since this is an option. then it says, migration will start 24th at 10:49, then nothing happens, this is what I see when I log in. Then I sent a mail about this, and what I wrote and when I can not tell, because of later problems. Anyway, the support took their time to answer, like 6-8 hours. (Because calling is not an option &quot;There is many calling right now....&quot;).&lt;br /&gt;
&lt;br /&gt;
Reply was something like &quot;We are sorry about this, but we can not give any estimations of how long it will take, but no longer then the end of next week&quot;...&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What!,&lt;/b&gt; can it take more than one week to move a -NET site with not that many pages? After a long time, at friday, I get a message that a technician will reply to me with a better answer. He did, monday, with the short note that it was stuck in a state that did not tell them it did not work.&lt;br /&gt;
&lt;br /&gt;
Then the actual migration. For the site there was no problems actually. There was just ONE inconvenience. My mail address&amp;nbsp;disappeared. I wrote the support about it (from another address), No reply at all, then I wrote after 6 hours, that this is bad, and maybe I should blog about it....Well when I got home, there was an account again. But all my old mails were missing, and still are. And Binero is all quiet, no reply at all on the task.&lt;br /&gt;
&lt;br /&gt;
The ironi in this is that they are trying to take the customers from another webhotel, that had mail problems a while ago.&lt;br /&gt;
&lt;br /&gt;
On top of it, in the migration an invoice that was already paid was copied as not paid to the new account.&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/5054716124942269818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2012/01/my-experience-with-binero-20-so-far.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/5054716124942269818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/5054716124942269818'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2012/01/my-experience-with-binero-20-so-far.html' title='My experience with Binero 2.0 (so far...)'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-1543112594158550116</id><published>2011-10-19T11:02:00.001+02:00</published><updated>2013-11-13T20:58:23.289+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Scala"/><category scheme="http://www.blogger.com/atom/ns#" term="Scala swing"/><category scheme="http://www.blogger.com/atom/ns#" term="SSC (Scala Stock Charts)"/><category scheme="http://www.blogger.com/atom/ns#" term="stocks"/><title type='text'>Scala Stock Charts - part 6 some GUI things</title><content type='html'>I got a bit caught up in all the programming and finished up a few diagrams, then some refactoring and was able to remove a couple of hundred lines of code. The program now looks like this:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1CBylOnO_rDu8BiLvahtNuqWolaYCnUcMo3Suu99y0bc5hs3_kDIcizV8l9SPHJ73_rqNBovXnYhXO8u3cF30W0md48nMzI5aEPhQ5v_agfI6K-UJguVBG5Z377NjoOnuxA1jKKQg1yg/s1600/Screen+Shot+2011-10-18+at+9.24.18+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;172&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1CBylOnO_rDu8BiLvahtNuqWolaYCnUcMo3Suu99y0bc5hs3_kDIcizV8l9SPHJ73_rqNBovXnYhXO8u3cF30W0md48nMzI5aEPhQ5v_agfI6K-UJguVBG5Z377NjoOnuxA1jKKQg1yg/s320/Screen+Shot+2011-10-18+at+9.24.18+PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see a lot have happened since the last pictures of the application. So here is some things.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;









Main part&lt;/h2&gt;
The applications is build up around a main frame that contains the bar chart and some overlays. As you can see there is also some text fields and buttons. The upper part is to search stocks/indexes and also handle the overlays in the bar char. These fields and buttons are:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Search field to enter a search criteria to filter the instruments to search for.&lt;/li&gt;
&lt;li&gt;Search button, to apply the search&lt;/li&gt;
&lt;li&gt;A combo box, to show the filtered search result, and also choose the stock to view. This combo box listen to changes and updates the bar chart with the selected stock&lt;/li&gt;
&lt;li&gt;Next there is a box to limit the range of the data. I have not introduced recalculation for splits and emissions so to have a possibility to handle to not show before these events, I added a box to filter away prices before this date part.&lt;/li&gt;
&lt;li&gt;Next there is the intervals for the moving averages in the chart, default they are set to 5,20,50 but can be changed but have as most 3 different, but also as few as one. Default they are Simple Moving Average (SMA),&lt;/li&gt;
&lt;li&gt;to change to Exponential Moving Average (EMA) there is a checkbox&lt;/li&gt;
&lt;li&gt;to update changed settings for Moving averages there is a button &quot;Update averages&quot;&lt;/li&gt;
&lt;li&gt;finally on the top there is a check box to switch on/off viewing of &quot;Bollinger Bands&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
In the bottom part there is buttons for additional chart types. these are the ones I picked as most interesting for me and they show some different aspect of the prices.&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Stocastics (show how a stocks price is doing in relation to past movements)&lt;/li&gt;
&lt;li&gt;RSI (shows how strong a stock is moving in the current direction)&lt;/li&gt;
&lt;li&gt;Aroon (shows if a stock is trending or oscillating)&lt;/li&gt;
&lt;li&gt;MACD (and also MACD-histogram) (a momentum oscillator)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
As I mentioned the main part is a Bar chart diagram. It contains some overlays like volume, moving average and optional Bollinger bands. These help to get a basic overview of a stocks movement and trend. It is made up of a specialized panel for the bar chart to handle the drawing of the chart.&lt;br /&gt;
&lt;br /&gt;
The main application implements a method named top that is used in wrapped Swing features used in Scala. I have an object representing my starting point of the application, the first lines looks like:&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
object ScaBorsApp extends SimpleSwingApplication with Logging{
    def top = new MainFrame {
      title = &quot;Technical Analysis for Stocks&quot;
      val COL_GREEN = new Color(0,150,0)
      val searchField = new TextField {
          text = &quot;a&quot;
          columns = 10
        }
&lt;/textarea&gt;
As you can see I provide a title and also here is the search field where to put a search string. The most important thing to note here is the inheritance of SimpleSwingApplication which makes this object a Swing application&lt;br /&gt;
&lt;br /&gt;
The next part looks like this&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;/*
       * Search button, will get the pricelist and do filter and sort to present in combo box
       */
      val searchBtn = new Button(&quot;Search&quot;) {
          action = Action(&quot;Search&quot;){ 
            val pricelists = PriceService.getPriceLists map { kv =&amp;gt; kv.instruments } flatMap { 
                case i: Instrument =&amp;gt; i 
                case x =&amp;gt; x
              } filter {
                i: Instrument =&amp;gt; i.name.toLowerCase().startsWith(searchField.text.toLowerCase)
              }
            
            val items = pricelists.toList sortWith {(i1,i2) =&amp;gt; i1.name.toLowerCase &amp;lt; i2.name.toLowerCase}
            combo.peer.setModel(
              ComboBox.newConstantModel(
                  for{p &amp;lt;- items} yield p.ticker + &quot;: &quot; + p.name
              )
            )
          }
        }
        
      /*
       * ComboBox to present filtered search for stocks, see searchButton action code how search is performed
       */
      import event._
      val combo = new ComboBox(List(&quot;-- Search to be able to select --&quot;)) {
        preferredSize = new Dimension(300,20)
        listenTo(selection)
        reactions += {
          case SelectionChanged(c) =&amp;gt; 
            curInstrument = new Instrument(selection.item.split(&quot;:&quot;)(0),selection.item.split(&quot;:&quot;)(1).trim,&quot;&quot;)
            curPriceList = PriceService.getInstrumentData(curInstrument).filter(p =&amp;gt; p.date.substring(0,fromTextBox.text.length).toInt &amp;gt;= fromTextBox.text.toInt)
            barchartPanel.updateList(curPriceList)
          case e =&amp;gt; info(e.toString)
        }
      }
...
val chkBollinger = new CheckBox {
        text = &quot;Bollinger bands&quot;
        reactions += {
          case x =&amp;gt; barchartPanel.setBollinger(this.selected) 
        }
      }
&lt;/textarea&gt;
Here you can see some on the fly declaration and reactions to events on the components. &amp;nbsp;The following code shows how to add these to the contents of other panels. you can also see the creation at the click of the button, creation of a generic diagram for &quot;stochastics&quot; mixed in with a DrawListener to make it drawable. Also how the series of stochastics is added to a generic diagram can be seen here.&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
     /*
       * Top menu panel.
       */
      val menu = new FlowPanel {
        contents += new Label(&quot;Stock&quot;)
        contents += searchField
        contents += searchBtn
        contents += combo
        contents += fromTextBox
        contents += avgSettings
        contents += chkExpAverage
        contents += btnUpdateAvg
        contents += chkBollinger
      }
....
val bottomPanel = new FlowPanel{
        contents += new Button(){
          text = &quot;Stochastics&quot;
          reactions += {
            case bc: ButtonClicked =&amp;gt; val stD = new Frame {
                title=&quot;Stochastics &quot; + curInstrument.name
              }
              stD.open()
              val panel = new GenericDiagram with DrawListener
              val scrPan = new ScrollPane{
                preferredSize = new Dimension(1180,220)
                contents = panel
              }
              stD.contents = scrPan
              val stoList = PriceUtil.stochastics(curPriceList, 14)
              panel.addSerie(ChartSerie(stoList,Color.blue))
              panel.addSerie(ChartSerie(PriceUtil.slidingAvg(stoList, 3),Color.red))
              panel.addDateSerie(curPriceList.map{p=&amp;gt;p.date})
              panel.setLabelLevels(List(20d,50d,80d))
              // need to force set max, it is not always 100 ??
              panel.maxVal = 100d
          }
        }
....
contents = new BorderPanel() {
        add(menu, BorderPanel.Position.North) 
        add(scrollPane, BorderPanel.Position.Center)
        add(bottomPanel, BorderPanel.Position.South)
      }
&lt;/textarea&gt;
This last part of the code adds the actual panels containing the fields, bar chart and buttons to the Swing application.&lt;br /&gt;
&lt;h2&gt;





Additional panels&lt;/h2&gt;
To add some extra check to the main part there is some diagrams that first was their own specialized panel, but after some refactoring they now all except MACD uses a generalized panel called &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;GenericDiagram&lt;/span&gt; and here is a part of that code:&lt;br /&gt;
&lt;br /&gt;
And here is addition of some of the buttons into menu panel (top panel) followed by some example of the bottom panel with addition of button and reactions to its event. You see here that here is where the panel frame is set up inside the reaction to show the GenericDiagram with &quot;stochastic&quot; data.&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
 val chkBollinger = new CheckBox {
        text = &quot;Bollinger bands&quot;
        reactions += {
          case x =&amp;gt; barchartPanel.setBollinger(this.selected) 
        }
      }

...

trait BasicChartProps {
  val PAD_TOP,PAD_BOTTOM = 20
  val PREF_H = 200
  val PREF_W = 1180
  var maxVal = Double.MinValue
  var minVal = Double.MaxValue
  var startX = 50
}
/**
 * Generic panel for simple series
 */
class GenericDiagram extends Panel with BasicChartProps with Logging{
  private var series = List[ChartSerie]()
  private var dateSerie = List[String]()
  
...
&lt;/textarea&gt;
Not so much to mention really except that as you see I extend with a trait with basic chart properties. this is intended to have common properties for this and other diagrams. The var&#39;s is to be able to add series and date series to the diagram. So this panel is only responsible to draw the things that are sent to it.



&lt;br /&gt;
&lt;h2&gt;








Ability to draw&lt;/h2&gt;
No bar chart is complete if it is not possible to draw some help lines. This is managed by adding a trait for this, that can be mixed in wherever I want it. The code for that trais is:

&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;...
/**
 * Trait to use for Panels that should have line drawin possibilities
 */
trait DrawListener extends Panel {
  val pointZero = new Point(0,0)
  
  var curStart = pointZero//new Point(0,0)
  var curEnd = new Point(0,0)
  listenTo(mouse.clicks, mouse.moves, keys)
  reactions += {
    case e: MousePressed  =&amp;gt; 
                curStart = e.point
         //moveTo(e.point)
         requestFocusInWindow()
       case e: MouseDragged  =&amp;gt; curEnd = e.point; repaint() //lineTo(e.point)
       case e: MouseReleased =&amp;gt; moveTo(curStart);lineTo(e.point);curStart=pointZero;curEnd=pointZero
       case KeyTyped(_,&#39;c&#39;,_,_) =&amp;gt; 
         path = new geom.GeneralPath
         repaint()
       case _ =&amp;gt; repaint()
  }
  /* records the dragging */
  var path = new geom.GeneralPath

  def lineTo(p: Point) { path.lineTo(p.x, p.y); repaint() }
  def moveTo(p: Point) { path.moveTo(p.x, p.y); repaint() }
  
  override def paintComponent(g: Graphics2D) = {
    super.paintComponent(g)
    g.setColor(Color.black)
    if(curStart.x != 0 &amp;amp;&amp;amp; curEnd.y != 0){
      g.drawLine(curStart.x,curStart.y,curEnd.x,curEnd.y)
    }
    g.draw(path)
  }
}
...
&lt;/textarea&gt;
An example of this functionality is to draw help lines in a MACD diagram. (or any really)



&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEib7MwQAXey7SJyJGoG5gyrXpus5aS14KneIZW0ssZ67HxddEBbeyD1y8wZpaDifkhq587MuZ7YCKs2yaCN0pHm6RiJ73miyoyNtVDbOkhWBya-UdwTmcA-c0mWO9p-br9O3QXcIGM2b1M/s1600/Screen+Shot+2011-10-18+at+10.04.13+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;64&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEib7MwQAXey7SJyJGoG5gyrXpus5aS14KneIZW0ssZ67HxddEBbeyD1y8wZpaDifkhq587MuZ7YCKs2yaCN0pHm6RiJ73miyoyNtVDbOkhWBya-UdwTmcA-c0mWO9p-br9O3QXcIGM2b1M/s320/Screen+Shot+2011-10-18+at+10.04.13+PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
This can be mixed in like in this case:


&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
val panel = new MACDPanel(Nil) with DrawListener
&lt;/textarea&gt;
And then it is possible to draw on that panel.</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/1543112594158550116/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/10/scala-stock-charts-part-6-some-gui.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/1543112594158550116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/1543112594158550116'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/10/scala-stock-charts-part-6-some-gui.html' title='Scala Stock Charts - part 6 some GUI things'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1CBylOnO_rDu8BiLvahtNuqWolaYCnUcMo3Suu99y0bc5hs3_kDIcizV8l9SPHJ73_rqNBovXnYhXO8u3cF30W0md48nMzI5aEPhQ5v_agfI6K-UJguVBG5Z377NjoOnuxA1jKKQg1yg/s72-c/Screen+Shot+2011-10-18+at+9.24.18+PM.png" height="72" width="72"/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-1163694067784890491</id><published>2011-10-01T18:39:00.000+02:00</published><updated>2013-11-13T21:05:26.215+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Scala"/><category scheme="http://www.blogger.com/atom/ns#" term="Scala swing"/><category scheme="http://www.blogger.com/atom/ns#" term="SSC (Scala Stock Charts)"/><category scheme="http://www.blogger.com/atom/ns#" term="stocks"/><title type='text'>Scala stocks part 5 - Refactoring, big time</title><content type='html'>There is soooo much stuff that I would like to look in to. Alfresco, Liferay, GWT, Spring, Scrum, Agile etc. Right now though, I continue with my Scala project doing a Technical analysis tool for stocks using a Swing gui, also that with Scalas Swing libraries.&lt;br /&gt;
&lt;br /&gt;
After working with the GUI, I started to get annoyed on myself mixing things up here and there, so I decided to refactor a bit. Actually, since I wrote the last post, I got a bit further then just plain refactoring. Simultaneously with the refactoring I worked on the GUI and also restructured code to finish up the loading of prices, enhancement of that loading and in that work I also managed to introduce some &quot;Actors&quot;.&lt;br /&gt;
&lt;br /&gt;
I will now also start to explain a little bit more what the code does.&lt;br /&gt;
&lt;br /&gt;
I will split the refactoring and explanation in more than this post, otherwise I may get too long.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Refactoring of the FileHandler.&lt;/b&gt;&lt;br /&gt;
The new file is now much shorter, and includes only stuff to handle files. The extraction and transformation to the model is removed from the file handling. that messy code can be seen here&amp;nbsp;&lt;a href=&quot;http://ironicprogrammer.blogspot.com/2011/08/scala-stock-charts-part-3-saving-quotes.html&quot;&gt;http://ironicprogrammer.blogspot.com/2011/08/scala-stock-charts-part-3-saving-quotes.html&lt;/a&gt;&amp;nbsp;if you have not already read it.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;codebox-header&quot;&gt;
FileHandler.scala
&lt;/div&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;/*
 @author Peter Johansson / Ironic programmer 
 */

package me.ironic.scabors.file
import me.ironic.scabors.model._
import me.ironic.scabors.util.Logging

object FileHandler{
  def apply() = { new FileHandler() }
}

class FileHandler extends Logging {
  import java.io.{File,BufferedWriter,FileWriter,IOException}
  import scala.collection.mutable.{ HashMap =&amp;gt; MutableHashMap}
  import scala.collection.immutable.{ HashMap }
  import scala.io.Source
  
  val rootDir = { scala.util.Properties.userDir }
  val filesDir = { rootDir + &quot;/files&quot;}
  val logFile = { rootDir + &quot;/&quot; + &quot;sBors.log&quot;}
  val pricelistsFile = { rootDir + &quot;/files/pricelists.txt&quot;}
      
  def checkDir(dirName: String){
     val f = new File(dirName)
     if(!f.exists){
       f.mkdirs
       info(&quot;!! Created dir at : &quot; + dirName)
     }
  }
  
  def writeToFile(fileName: String, append: Boolean, rows: List[String]){
    // Check that dir exista or creat if not
    checkDir(filesDir)
    
    val bw = new BufferedWriter(new FileWriter(fileName,append))
    
    rows foreach { row =&amp;gt;
      bw.write(row + &quot;\n&quot;)
    }
    
    bw.close()
  }
  
  def priceFile(ticker: String) = {
    rootDir + &quot;/files/&quot; + ticker.replace(&quot; &quot;,&quot;_&quot;) + &quot;.txt&quot;
  }
  
  def loadFile(fileName: String)  = {
    val fc = Source.fromFile(fileName)
    fc.getLines.toList
  }
  
}
&lt;/textarea&gt;
&lt;br /&gt;
In the start of the file, you see:
&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
object FileHandler{
  def apply() = { new FileHandler() }
}
&lt;/textarea&gt;
This is a &lt;i&gt;companion object&lt;/i&gt; I use it to have a factory method. Maybe not really nescessary but at least I get away with not having to write&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;new FileHandler()&lt;/span&gt;&lt;br /&gt;
every time I need it and can use the shorter version&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;FileHandler()&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The rest of the FileHandler should be quite easy to figure out. I have only one write-method where I send in the filename, if I want to append and a list of strings to write to the file. With this I can do all the saving I need.&lt;br /&gt;
&lt;br /&gt;
There is also only one method for getting the file content (loadFile), this returns a list of strings which I later can traverse and to all the logic with.&lt;br /&gt;
&lt;br /&gt;
I also have a method to have a format for how a price file is named. I do not want any blanks in the filename so this method is replacing that with &quot;_&quot; instead.&lt;br /&gt;
&lt;br /&gt;
As you can see the FileHandler extends &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Logging&lt;/span&gt;. I do not need that here since no logging is going on in this class as it is now, but I can add it if I want. More about the &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Logging&lt;/span&gt; later.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Introducing PriceDAO.&lt;/b&gt;&lt;br /&gt;
To hide FileHandler from the rest of the system, and also to the mapping between files and model that was before done in the FileHandler, I introduced a DAO object to do the work. Doing this I can always change the way I persist later without too much impact on the code.&lt;br /&gt;
&lt;br /&gt;
There is still some refactoring to do in this one since I have not changed the fact that I use mutable lists.&lt;br /&gt;
&lt;div class=&quot;codebox-header&quot;&gt;
PriceDAO.scala&lt;/div&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
/*
 @author Peter Johansson / Ironic programmer 
 */
package me.ironic.scabors.dao

/**
 * Provides service methods and communicate with underlaying storage
 */
import me.ironic.scabors.util.Logging
import me.ironic.scabors.model._
import me.ironic.scabors.file.FileHandler
import scala.collection.mutable.{ HashMap =&amp;gt; MutableHashMap}
import scala.collection.immutable.{ HashMap }
  
object PriceDAO extends Logging{
  
  def saveDailyPrices(prices: List[PriceItem]) = {
    info(&quot;## Saving daily prices&quot;)
       
    var lists = new MutableHashMap[String,List[Price]]
    var curList = &quot;?&quot;
    
    prices foreach { price =&amp;gt;
      price match { 
        case q: Price =&amp;gt; { 
                            savePriceToFile(q);
                            lists(curList) = List(q) ::: lists(curList)
                          }
        case qList: PriceList =&amp;gt; {
                                    curList = qList.name;
                                    lists += qList.name -&amp;gt; List()
                                 }
        case _ =&amp;gt; warn(price.toString)
      }
    }
    
    // Save current lists to file...
    saveStockPriceList(lists)
  }
  
  /**
   * Method for saving a price to file
   */
  protected def savePriceToFile(price: Price) = {
    val fileHandler = FileHandler()
    val fName = fileHandler.priceFile(price.ticker)
    fileHandler.writeToFile(fName, true, List(price.toString))
  }
  
  /**
   * Method for saving an updated pricelist map to file.
   */
  protected def saveStockPriceList(pricelist: MutableHashMap[String,List[Price]]){
    info(&quot;## Saving pricelists&quot;)
    
    val sb = new StringBuffer
    sb.append(&quot;{ \&quot;pricelists\&quot;: [\n&quot;)
    for{ (listname,prices) &amp;lt;- pricelist } {
      sb.append(&quot;\t{ \n\t\t\&quot;listname\&quot;: \&quot;&quot; + listname + &quot;\&quot;,\n&quot;)
      sb.append(&quot;\t\t\&quot;stocks\&quot;: [\n&quot;)
      for{ price &amp;lt;- prices } {
        sb.append(&quot;\t\t\t{ \&quot;ticker\&quot;: \&quot;&quot;+price.ticker + &quot;\&quot;, \&quot;aktie\&quot;: \&quot;&quot; + price.aktie + &quot;\&quot;},\n&quot;)
      }
      sb.append(&quot;\t\t],\n&quot;)
      sb.append(&quot;\t},\n&quot;)
    }
    sb.append(&quot;}\n&quot;)
    
    val fileHandler = FileHandler()
    val fName = fileHandler.pricelistsFile
    fileHandler.writeToFile(fName, false, List(sb.toString))
  }
  
  /**
   * Method for loading price lists to a HashMap, 
   * each entry in the map is a list of Instruments
   */
  def loadPriceLists  : MutableHashMap[String, List[Instrument]] = {
    info(&quot;## Loading pricelists&quot;)
    var pricelists = new MutableHashMap[String, List[Instrument]]
    val ListExtractorRE = &quot;&quot;&quot;.*&quot;listname&quot;: &quot;(.+)&quot;,.*\s*&quot;&quot;&quot;.r
    val InstExtractorRE = &quot;&quot;&quot;.*&quot;ticker&quot;: &quot;(.+)&quot;, &quot;aktie&quot;: &quot;(.+)&quot;.*\s*&quot;&quot;&quot;.r
   
    /*
     * When hitting a PriceList, a new list begins
     */
    var curList = &quot;?&quot;
    val fileHandler = FileHandler()
    val fName = fileHandler.pricelistsFile
    val rows = fileHandler.loadFile(fName)
    rows foreach { line =&amp;gt;
      line match {
        case ListExtractorRE(listname) =&amp;gt; val pList = new PriceList(listname)
          curList = pList.name
          pricelists += pList.name -&amp;gt; List()
        case InstExtractorRE(ticker, aktie) =&amp;gt; val inst = new Instrument(ticker, aktie) 
          pricelists(curList) = List(inst) ::: pricelists(curList)
        case _ =&amp;gt; None
      }
      
    } 
    pricelists
  }
  
  /**
   * Method for loading all prices for a specific instrument.
   */
  def loadInstrumentData(inst: Instrument) : List[Price] = {
    val fileHandler = FileHandler()
    info(&quot;Loading instrument &quot; + inst)
    val fName = fileHandler.priceFile(inst.ticker)
    
    val PriceExtractorRE = &quot;&quot;&quot;Price\(([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*).*\)&quot;&quot;&quot;.r
    val pricelines = fileHandler.loadFile(fName)
    val prices = pricelines map { line =&amp;gt;
      line match {
        case PriceExtractorRE(date,ticker,aktie,diffKr,diffPerc,buy,sell,last,high,low,returnNo,returnKr) =&amp;gt; 
          Price(date,ticker,aktie,diffKr.toDouble,diffPerc.toDouble,buy.toDouble,sell.toDouble,last.toDouble,high.toDouble,low.toDouble,returnNo.toDouble,returnKr.toDouble)
        
      } 
    } 
    prices.toList
  }
  
}

&lt;/textarea&gt;
&lt;br /&gt;
&lt;b&gt;Some explanation maybe?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Well, I am not going into every line. I choose some parts that I think is interesting parts of Scala.&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;  
def saveDailyPrices(prices: List[PriceItem]) = {
/*....*/
     var lists = new MutableHashMap[String,List[Price]]
    var curList = &quot;?&quot;

      prices foreach { price =&amp;gt;
      price match { 
        case q: Price =&amp;gt; { 
                            savePriceToFile(q);
                            lists(curList) = List(q) ::: lists(curList)
                          }
        case qList: PriceList =&amp;gt; {
                                    curList = qList.name;
                                    lists += qList.name -&amp;gt; List()
                                 }
        case _ =&amp;gt; warn(price.toString)
      }
    }
&lt;/textarea&gt;
&lt;br /&gt;
This code it possibly a good&amp;nbsp;candidate to do some further refactoring on to try to make it immutable, but this is what is going on.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;lists&lt;/span&gt; is mutable, because I need to add things in it, and I assume that I do not know what lists are coming in. (Even if they are pretty known from the file)&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;prices&lt;/span&gt; is a list of type &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;List[PriceItem]&lt;/span&gt;, this means that everything in that list is of something under type &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;PriceItem&lt;/span&gt; but right now I am only interested in the types &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Price&lt;/span&gt; and &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;PriceList&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;If it is a &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;PriceList&lt;/span&gt; I know that a new price list is starting, I add this as a map key with an empty list as the map value.&lt;/li&gt;
&lt;li&gt;The flow goes on and for every &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Price&lt;/span&gt; that comes up this is added in the current list.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
The next chunk of interest...&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
  val ListExtractorRE = &quot;&quot;&quot;.*&quot;listname&quot;: &quot;(.+)&quot;,.*\s*&quot;&quot;&quot;.r
    val InstExtractorRE = &quot;&quot;&quot;.*&quot;ticker&quot;: &quot;(.+)&quot;, &quot;aktie&quot;: &quot;(.+)&quot;.*\s*&quot;&quot;&quot;.r
    /*....*/
    val rows = fileHandler.loadFile(fName)
    rows foreach { line =&amp;gt;
      line match {
        case ListExtractorRE(listname) =&amp;gt; val pList = new PriceList(listname)
          curList = pList.name
          pricelists += pList.name -&amp;gt; List()
        case InstExtractorRE(ticker, aktie) =&amp;gt; val inst = new Instrument(ticker, aktie) 
          pricelists(curList) = List(inst) ::: pricelists(curList)
        case _ =&amp;gt; None
      }
      
    } 
&lt;/textarea&gt;
&lt;br /&gt;
Here is the loading of the price lists. I will sow you part of the file so you know what we are dealing with.
&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
{ &quot;pricelists&quot;: [
        { 
                &quot;listname&quot;: &quot;OMX Stockholm Mid Cap&quot;,
                &quot;stocks&quot;: [
                        { &quot;ticker&quot;: &quot;ORES&quot;, &quot;aktie&quot;: &quot;&lt;d6&gt;resund&quot;},
                        { &quot;ticker&quot;: &quot;AF B&quot;, &quot;aktie&quot;: &quot;&lt;c5&gt;F B&quot;},
                        { &quot;ticker&quot;: &quot;VNIL SDB&quot;, &quot;aktie&quot;: &quot;Vostok Nafta Investment&quot;},
                        { &quot;ticker&quot;: &quot;WIHL&quot;, &quot;aktie&quot;: &quot;Wihlborgs&quot;},
                        { &quot;ticker&quot;: &quot;WALL B&quot;, &quot;aktie&quot;: &quot;Wallenstam B&quot;},
&lt;/textarea&gt;
&lt;/div&gt;
That is how it is saved. So seeinging that makes it easier to explain what the above code does.
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;first there is 2 &quot;extractors&quot;, these are regular expressions. In Scala you can use the 3-qouted strings to make a regular expression just by putting &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;.r&lt;/span&gt; after it. This expressions can then be used as types cases in pattern matching and is very powerful way to extract thing.&lt;/li&gt;
&lt;li&gt;(&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: pre;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&quot;&quot;&quot;.*&quot;listname&quot;: &quot;(.+)&quot;,.*\s*&quot;&quot;&quot;.r&lt;/span&gt;&lt;/span&gt;) is for extracting the name of a list. This matches on the line in the file beginning with any character and then &quot;listname&quot;:&lt;/li&gt;
&lt;li&gt;the next &quot;extractor&quot; is for matching an instrument. for&amp;nbsp;convenience I write the file with a &quot;ticker&quot;&amp;nbsp;on a new line to avoid complex regexps. So I only need to parse the file and match on these.&lt;/li&gt;
&lt;li&gt;When matching a new list I put a new map entry with an empty list, and when hitting a &quot;ticker&quot; I just add that instrument in the current list. Similar to what is going on when saving them.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;b&gt;Major restruction of PriceLoad.&lt;/b&gt;&lt;/div&gt;
I more or less totally reworked the loading of the prices from the site they are available from&lt;br /&gt;
&lt;br /&gt;
One thing I wanted to do was to use actors. Here is were I got loose on doing that. Well, thats a bit exaggerating since there is only one Actor involved here (and another one in the Logging) so not so big fuzz. Here is the code, and I get into some details after it.&lt;br /&gt;
&lt;div class=&quot;codebox-header&quot;&gt;
PriceLoad.scala&lt;/div&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;/*
 @author Peter Johansson / Ironic programmer 
 */

package me.ironic.scabors.dao
import me.ironic.scabors.model._
import me.ironic.scabors.util._
// Singleton to handle loading of Prices
object PriceFetcher extends Logging {
  import java.util.Calendar
  
  import java.text.SimpleDateFormat
    val fmt = new SimpleDateFormat(&quot;yyyyMMdd&quot;)
      
    def stringDateList(c: Calendar,bDate:String) : List[String] ={
      if(fmt.format(c.getTime()) == bDate) {
        List(fmt.format(c.getTime()))
      } else {
        val c2 = c.clone().asInstanceOf[Calendar]
        c2.add(Calendar.DATE,1)
        fmt.format(c.getTime()) :: stringDateList(c2,bDate)
      }
    }
      
   def main(args: Array[String]) = {
      if(args.length &amp;lt; 1  || args.length &amp;gt; 2){
        println(&quot;Usage: PriceFetcher YYYYMMDD # for single day&quot;)
        println(&quot;Usage: PriceFetcher YYYYMMDD YYYYMMDD # for batch mode&quot;)
        sys.exit(1)
      }
          
      val list = {
        if(args.length == 1){
          List(args(0))
        } else {
          require(args(1).compareTo(args(0)) &amp;gt; 0)
          val dFrom = fmt.parse(args(0))
          val cal = Calendar.getInstance()
          cal.setTime(dFrom)
          stringDateList(cal, args(1))
        }
      }
      
      info(&quot;Will run fetching for list &quot; + list)
      val fetcher = new PriceFetchActor
      fetcher.start
      list foreach { s =&amp;gt;
        fetcher ! Daily(s)
      }
      fetcher ! Stop
      // Need to stop the logger, otherwise there is a hanging thread
      import scala.actors.Actor.State
      while(fetcher.getState != State.Terminated){
        // to wait until all work is done
      }
      stopLogger
      sys.exit(0)    
   }
}

import scala.actors.Actor
import scala.actors.Actor._
import me.ironic.scabors.util.Logging
class PriceFetchActor extends Actor with Logging{
  import scala.io.Source
      
  val baseUrl = &quot;http://thesite/&quot;
  def act(){
    loop{
      react {
        case d: Daily =&amp;gt; 
          info(&quot;Fetching prices for &quot; + d)
          val uri = baseUrl + d.date + &quot;k.txt&quot;
          try{
            val lines = readUrl(uri)
            val handledLines = processLines(lines,d.date)
            info(&quot;Did lines : &quot; + handledLines.size)
            PriceDAO.saveDailyPrices(handledLines)
          } catch {
            case x =&amp;gt; warn(x.toString)
          }
        case Stop =&amp;gt; 
          info(&quot;Stopping PriceFetchActor&quot;)
          exit()
        case _ =&amp;gt;
      }
    }
  }
  
  def readUrl(url: String) : List[String] = {
    val fc = Source.fromURL(url).getLines().toList 
    fc
  }
  
  val PriceExtractorRE = &quot;&quot;&quot;([[^Ticker]^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t.*&quot;&quot;&quot;.r
  val ListExtractorRE = &quot;&quot;&quot;(OMX[^\t]+)\t+&quot;&quot;&quot;.r
  
  // Should go through the lines from the file and make a list with jSon-like format. 
  def processLines(lines: List[String],date: String) : List[PriceItem] = {
    info(&quot;-&amp;gt; Processing lines&quot;)
    val instruments = lines takeWhile(s=&amp;gt; ! s.startsWith(&quot;Externa listan&quot;)) 
    instruments map { inst =&amp;gt;  
       inst match {
        case ListExtractorRE(list) =&amp;gt; PriceList(list)//&quot;{\&quot;instrumentList\&quot;: \&quot;&quot; + list + &quot;\&quot;}&quot;
        case PriceExtractorRE(ticker,aktie,diffKr,diffPerc,buy,sell,last,high,low,returnNo,returnKr) 
          =&amp;gt; Price(date,ticker,aktie,diffKr.replace(&quot;,&quot;,&quot;.&quot;).toDouble,diffPerc.replace(&quot;,&quot;,&quot;.&quot;).toDouble,buy.replace(&quot;,&quot;,&quot;.&quot;).toDouble,sell.replace(&quot;,&quot;,&quot;.&quot;).toDouble,last.replace(&quot;,&quot;,&quot;.&quot;).toDouble,high.replace(&quot;,&quot;,&quot;.&quot;).toDouble,low.replace(&quot;,&quot;,&quot;.&quot;).toDouble,returnNo.replace(&quot;,&quot;,&quot;.&quot;).toDouble,returnKr.replace(&quot;,&quot;,&quot;.&quot;).toDouble) 
        case _ =&amp;gt; InvalidPrice(date,inst.replace(&quot;\t&quot;,&quot;[tab]&quot;))
      } 
    }
  } 
}&lt;/textarea&gt;
&lt;br /&gt;
This is an application object with a main method so it is available to run from the command line. What it does is to check if you enter with one or two arguments. Entering with one argument will load for one day. Entering with two arguments will run for a date span. I do not really car if there is days that does not have any prices, the only thing that will happen is that a FileNotFoundException will be logged.&lt;br /&gt;
&lt;br /&gt;
The date span wil be&amp;nbsp;recursively&amp;nbsp;calculated to a list of strings with the method stringDateList.&lt;br /&gt;
&lt;br /&gt;
After getting the list with dates, whether it is one item or more, I am traversing that list and sending a Daily object to an actor to do the loading and saving of that day. When all dates are handled I send a Stop message so the actor can exit itself.&lt;br /&gt;
&lt;br /&gt;
Since I am sending to actors the flow of the program just passes to the end of the main method so I have to check the state of the actor before I do the exit. (There is a hang otherwise, because there is a thread that is still running somewhere.) and I do not want to do a sys.exit() before since that kills the thread that is loading.&lt;br /&gt;
&lt;br /&gt;
The messages that is sent is case object/class that is defined like:&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
case object Stop
case class Daily(date: String)
&lt;/textarea&gt;
&lt;br /&gt;
Other than the actor logic, the load and save is more or less the same as before. Just that now it is threaded and runs by an actor by sending messages to it.&lt;br /&gt;
&lt;br /&gt;
Well, that was enough for this time. The GUI is more evolved also, but that is another story, another day. But a teaser to show how it looks so far:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh45-4cide3isDeSQ5pp7kQuvb8hPMJSRgAWZu8qMS9mB6S2Ggkn6cUD7h2WKv3bx-5J6CTR6ahuISP9vhXcBPAaluWRuoSOjlSlfi1LjJkgTXx_UnTm7jphheEYZG14Z8UXEIDiODTQVc/s1600/Screen+Shot+2011-10-01+at+6.38.02+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;206&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh45-4cide3isDeSQ5pp7kQuvb8hPMJSRgAWZu8qMS9mB6S2Ggkn6cUD7h2WKv3bx-5J6CTR6ahuISP9vhXcBPAaluWRuoSOjlSlfi1LjJkgTXx_UnTm7jphheEYZG14Z8UXEIDiODTQVc/s320/Screen+Shot+2011-10-01+at+6.38.02+PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/1163694067784890491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/10/scala-stocks-part-5-refactoring-big.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/1163694067784890491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/1163694067784890491'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/10/scala-stocks-part-5-refactoring-big.html' title='Scala stocks part 5 - Refactoring, big time'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh45-4cide3isDeSQ5pp7kQuvb8hPMJSRgAWZu8qMS9mB6S2Ggkn6cUD7h2WKv3bx-5J6CTR6ahuISP9vhXcBPAaluWRuoSOjlSlfi1LjJkgTXx_UnTm7jphheEYZG14Z8UXEIDiODTQVc/s72-c/Screen+Shot+2011-10-01+at+6.38.02+PM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-5326722610858241792</id><published>2011-09-24T23:49:00.003+02:00</published><updated>2013-11-13T21:07:36.614+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="gradle"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Scala"/><category scheme="http://www.blogger.com/atom/ns#" term="Scala swing"/><category scheme="http://www.blogger.com/atom/ns#" term="SSC (Scala Stock Charts)"/><category scheme="http://www.blogger.com/atom/ns#" term="stocks"/><title type='text'>Scala stock charts, part 4 - Woking with the GUI - 1</title><content type='html'>I have been busy the last couple of weeks, or better saying, too lazy to sit home with my Scala Technical Analysis tool. Anyway, this weekend I decided to continue and this time to start from the GUI and start using the functionality done so far from a GUI.&lt;br /&gt;
&lt;br /&gt;
I have also done som restructuring in the packages which now is:&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;package me.ironic.scabors.app&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;package me.ironic.scabors.service&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;package me.ironic.scabors.model&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;package me.ironic.scabors.file&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
even if I have not reworked the messy file-package. I will do that later. however, I finished up with loading the price list, and that code now look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
def loadPriceLists : MutableHashMap[String, List[Instrument]] = {
    log(&quot;## Loading pricelists&quot;)
    var pricelists = new MutableHashMap[String, List[Instrument]]
    val fc = Source.fromFile(pricelistsFile)
    val ListExtractorRE = &quot;&quot;&quot;.*&quot;listname&quot;: &quot;(.+)&quot;,.*\s*&quot;&quot;&quot;.r
    val InstExtractorRE = &quot;&quot;&quot;.*&quot;ticker&quot;: &quot;(.+)&quot;, &quot;aktie&quot;: &quot;(.+)&quot;.*\s*&quot;&quot;&quot;.r
   
    /*
     * When hitting a PriceList, a new list begins
     */
    var curList = &quot;?&quot;
    fc.getLines foreach { line =&amp;gt;
      line match {
        case ListExtractorRE(listname) =&amp;gt; val pList = new PriceList(listname)
          curList = pList.name
          pricelists += pList.name -&amp;gt; List()
        case InstExtractorRE(ticker, aktie) =&amp;gt; val inst = new Instrument(ticker, aktie) 
          pricelists(curList) = List(inst) ::: pricelists(curList)
        case _ =&amp;gt; None
      }
      
    } 
    return pricelists
  }
&lt;/textarea&gt;
&lt;br /&gt;
I also broke out the model classes from the file package, and put it in another file called PriceModel.scala, you can also see that I am now using &quot;Price&quot; which is a better name than &quot;Quote&quot; so all references to Quote is now replaced with Price. The content of that file is:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;codebox-header&quot;&gt;
PriceModel.scala
&lt;/div&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
package me.ironic.scabors.model

// To be able to handle Iterator[PriceItem]
trait PriceItem 

case class InvalidPrice(date: String, content:String) extends PriceItem
case class PriceList(name:String) extends PriceItem
case class Price(date: String, ticker :String, aktie : String,
    diffKr : Double, diffPerc : Double, buy : Double,
    sell : Double, last : Double, high : Double,
    low : Double, returnNo : Double, returnKr : Double
  ) extends PriceItem
case class Instrument(ticker:String, aktie: String)  
&lt;/textarea&gt;
&lt;br /&gt;
&lt;br /&gt;
I also made a Service object so that the GUI does not need to know or depend on anything from the file package. So far as I have gotten with the GUI it just contains two methods, one to get all price lists and one to get the data for a chosen stock. Here is the code:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;codebox-header&quot;&gt;
PriceService.scala
&lt;/div&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
package me.ironic.scabors.service

object PriceService {
  import me.ironic.scabors.file.FileHandler
  val pricelists = {
    println(&quot;# loading pricelists&quot;)
    FileHandler.loadPriceLists
  }
  
  def getPriceLists = {
     // using already loaded pricelists, i.e loading is done in val...
     pricelists
  }
  
  def getInstrument(inst: String) = {
    FileHandler.loadInstrument(inst)
  }
}
&lt;/textarea&gt;
&lt;br /&gt;
&lt;h2&gt;

GUI programming done in Scala&lt;/h2&gt;
&lt;div&gt;
I decided to leave the idea of using Java FX that I had from the beginning and that I wrote in the beginning post. Instead I decided to use Scala Swing. Not so easy as it turned out, because first of all, it has been a couple of years since I last did any Java Swing programming and second of all, it was not very similar and not easy to transform Java Swing thinking to Scala Swing thinking. Well, it is less code, but surly, at this stage it looks really messy. Maybe it takes a while for my brain to melt Scala Swing programming and the fact that google got warm from all searching and few good examples does not help.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I am to tired to explain most of the code, maybe in a later post, but here is what the purpose if the GUI is so far.&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Provide a text field to filter search for stocks &quot;Instrument&quot;&lt;/li&gt;
&lt;li&gt;Provide a button to perform the search&lt;/li&gt;
&lt;li&gt;Provide a ComboBox to present the filtered result from the search and to select stock to draw&lt;/li&gt;
&lt;li&gt;Provide Panel for drawing a Bar Chart of selected stock&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH5qevPQTD7fu3BJ72e9TfhabORmR9uJK8KKa02HSWkSpxDuFgBv4WyfkTL7vXDuoTh2k1SMc_xwb0ETL5lKT4a51Z9V8wg30reVVsp2OC0mihuDFFKO8ZolicsBrI6nEkd_GOjdR41pg/s1600/Screen+Shot+2011-09-24+at+11.34.19+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;76&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH5qevPQTD7fu3BJ72e9TfhabORmR9uJK8KKa02HSWkSpxDuFgBv4WyfkTL7vXDuoTh2k1SMc_xwb0ETL5lKT4a51Z9V8wg30reVVsp2OC0mihuDFFKO8ZolicsBrI6nEkd_GOjdR41pg/s320/Screen+Shot+2011-09-24+at+11.34.19+PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
I have implemented and it works as I wand, except that the tedious job to provide the functionality to draw a bar chart is not done. Thea is a later&amp;nbsp;exercise&amp;nbsp;and a future post to describe. I let you see the messy code for this.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;codebox-header&quot;&gt;
ScaBorsApp.scala
&lt;/div&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
package me.ironic.scabors.app

import swing._
import java.awt.Dimension
import me.ironic.scabors.service._
import me.ironic.scabors.model._
object ScaBorsApp extends SimpleSwingApplication{
      
    def top = new MainFrame {
      title = &quot;Technical Analysis for Stocks&quot;
      val searchField = new TextField {
          text = &quot;a&quot;
          columns = 20
        }
       /*
       * Search button, will get the pricelist and do filter and sort to present in combo box
       */
      val searchBtn = new Button(&quot;Search&quot;) {
          action = Action(&quot;Search&quot;){ 
            val pricelists = PriceService.getPriceLists map { kv =&amp;gt; kv._2 } flatMap { 
                case i: Instrument =&amp;gt; i 
                case x =&amp;gt; x
              } filter {
                i: Instrument =&amp;gt; i.aktie.toLowerCase().startsWith(searchField.text.toLowerCase)
              }
            
            val items = pricelists.toList sortWith {(i1,i2) =&amp;gt; i1.aktie.toLowerCase &amp;lt; i2.aktie.toLowerCase}
            combo.peer.setModel(
              ComboBox.newConstantModel(
                  for{p &amp;lt;- items} yield p.ticker + &quot;: &quot; + p.aktie
              )
            )
          }
        }
    
      /*
       * ComboBox to present filtered search for stocks, see searchButton action code how search is performed
       */
      import event._
      val combo = new ComboBox(List(&quot;-- Search to be able to select --&quot;)) {
        preferredSize = new Dimension(300,20)
        listenTo(selection)
        reactions += {
          case SelectionChanged(c) =&amp;gt;
            curInstrument = new Instrument(selection.item.split(&quot;:&quot;)(0),selection.item.split(&quot;:&quot;)(1).trim)
            curPriceList = PriceService.getInstrument(curInstrument.ticker)
            barchartPanel.updateList(curPriceList)

        }
      }
      
      var curInstrument: Instrument = Instrument(&quot;---&quot;,&quot;Not choosen&quot;)
      var curPriceList: List[PriceItem] = Nil
      
      /*
       * Top menu panel.
       */
      val menu = new FlowPanel {
        contents += new Label(&quot;Stock&quot;)
        contents += searchField
        contents += searchBtn
        contents += combo
      }
      
    val barchartPanel = new BarChartPanel(curPriceList)
      val scrollPane = new ScrollPane {
        preferredSize = new Dimension(1180,700)
        contents = barchartPanel
      }
      

      contents = new BorderPanel() {
        add(menu, BorderPanel.Position.North) 
        add(scrollPane, BorderPanel.Position.Center)
      }
     
      preferredSize = new Dimension(1200,800)
    }
}

class BarChartPanel(var list: List[PriceItem]) extends Panel {
  import java.awt.Color
  background = Color.white
  preferredSize = new Dimension(1180,680)
  override protected def paintComponent(g: Graphics2D) {
    super.paintComponent(g)
    
  } 
  
  def updateList(newList: List[PriceItem]) = {
    list = newList
    println(&quot;Updating list : &quot; + list)
  }
}

&lt;/textarea&gt;
&lt;br /&gt;
Yeah, thats right, I also gave up SBT, I am now using gradle to build. here is the code for that.
build.gradle
&lt;br /&gt;
&lt;div class=&quot;codebox-header&quot;&gt;
build.gradle
&lt;/div&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
apply plugin: &#39;scala&#39;

repositories {
    mavenCentral()
}

dependencies {
    // Libraries needed to run the scala tools
    scalaTools &#39;org.scala-lang:scala-compiler:2.9.1&#39;
    scalaTools &#39;org.scala-lang:scala-library:2.9.1&#39;

    // Libraries needed for scala api
    compile &#39;org.scala-lang:scala-library:2.9.1&#39;

    // Libraries needed for scala.swing
//    scalaTools &#39;org.scala-lang:scala-swing:2.9.1&#39;
    compile &#39;org.scala-lang:scala-swing:2.9.1&#39;
}


task createSourceDirs &amp;lt;&amp;lt; {
  println &quot;# Creating source dirs&quot;
  [&#39;src/main/scala&#39;,&#39;src/test/scala&#39;,&#39;src/main/java&#39;,&#39;src/test/java&#39;].each { 
    println &quot; - $it&quot;
    new File(it).mkdirs()
  }
}
&lt;/textarea&gt;
&lt;br /&gt;
Until later..... ciao!</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/5326722610858241792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/09/scala-stock-charts-part-4-woking-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/5326722610858241792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/5326722610858241792'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/09/scala-stock-charts-part-4-woking-with.html' title='Scala stock charts, part 4 - Woking with the GUI - 1'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH5qevPQTD7fu3BJ72e9TfhabORmR9uJK8KKa02HSWkSpxDuFgBv4WyfkTL7vXDuoTh2k1SMc_xwb0ETL5lKT4a51Z9V8wg30reVVsp2OC0mihuDFFKO8ZolicsBrI6nEkd_GOjdR41pg/s72-c/Screen+Shot+2011-09-24+at+11.34.19+PM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-7527538976287752762</id><published>2011-09-13T21:41:00.000+02:00</published><updated>2013-11-13T21:02:03.592+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="sbt"/><category scheme="http://www.blogger.com/atom/ns#" term="Scala"/><category scheme="http://www.blogger.com/atom/ns#" term="Servlet"/><category scheme="http://www.blogger.com/atom/ns#" term="web-fragments"/><title type='text'>Web Fragment using Scala</title><content type='html'>Do you want to use Scala in a Java web environment, or write web fragment using scala. Or maybe you would ask: why do it at all? The answer is, because you can!&lt;br /&gt;
&lt;br /&gt;
Well my little spike succeeded without any severe headache, actually so well that I did not got any at all and there was never any risk to get one.&lt;br /&gt;
&lt;br /&gt;
I used SBT to build my Scala code, probably I could use it to make the full application, but I used Netbeans to create a web projet for my spike.&lt;br /&gt;
&lt;br /&gt;
Setting up for SBT.&lt;br /&gt;
&lt;br /&gt;
create folder for the project, for example:&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;gt;mkdir webfrag&lt;/span&gt;&lt;br /&gt;
enter the directory and create and edit build.sbt for servlet programming&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;gt;touch build.sbt&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Put the following in the build-sbt file
&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
name := &quot;WebFrag&quot;
 
version := &quot;1.0&quot;
 
organization := &quot;me.ironic&quot;
 
scalaVersion := &quot;2.9.1&quot;
 
scalaSource in Compile &amp;lt;&amp;lt;= baseDirectory(_ / &quot;src&quot;)
 
scalaSource in Test &amp;lt;&amp;lt;= baseDirectory(_ / &quot;test&quot;)
 
libraryDependencies += &quot;javax&quot; % &quot;javaee-api&quot; % &quot;6.0&quot; % &quot;provided&quot;
 
libraryDependencies += &quot;log4j&quot; % &quot;log4j&quot; % &quot;1.2.16&quot; % &quot;provided&quot;
 
libraryDependencies += &quot;junit&quot; % &quot;junit&quot; % &quot;4.8.2&quot; % &quot;test&quot;
&lt;/textarea&gt;
&lt;br /&gt;
Create a Servlet in Scala in this way.&lt;br /&gt;
create &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;src/&lt;/span&gt; folder and create and edit a file for the servlet, for example &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;src/WebFragHello.scala&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
You can write what you want, but to make a form of HelloWorld-like example fill it with for example:&lt;br /&gt;
&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
package me.ironic

import javax.servlet.annotation._
import java.io._
import javax.servlet._
import http._

@WebServlet(name = &quot;WebFragHelloServlet&quot;, urlPatterns = {Array(&quot;/hello&quot;)})
class WebFragHelloServlet extends HttpServlet {
        override def doGet(req: HttpServletRequest, res: HttpServletResponse) : Unit = {
           val user = req.getParameter(&quot;user&quot;) match {
                case s: String =&amp;gt; s
                case _ =&amp;gt; &quot;John Doe&quot;
                }
           val out = res.getWriter()
           out.println(toHtml(user).toString())
        }
        def toHtml(user: String) = 
        &lt;html&gt;
          &lt;body&gt;
            &lt;h1&gt;Hello {user}&lt;/h1&gt;
          &lt;/body&gt;
        &lt;/html&gt;

}

&lt;/textarea&gt;
&lt;br /&gt;
This code also &quot;catches&quot; the case that user parameter is not sent.A special feature seams to be that the scala code does not understand urlPattern as used in Java in the annotation, that is why I use {Array(&quot;/hello&quot;)} instead of {&quot;/hello&quot;}&lt;br /&gt;
&lt;br /&gt;
Compile and package the code with SBT&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;gt;sbt compile&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;gt;sbt package&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
To make it work as a web-fragment: Put the compiled jar in WEB-INF/lib folder in a Servlet 3.0 server, you also need to put scala-library.jar in the server to be able to use scala objects. In netbeans you just need to add that jar-file to &quot;libraries&quot; folder in the test web project&lt;br /&gt;
&lt;br /&gt;
Surf to .../context-root/hello or&amp;nbsp;/context-root/hello?user=Ironic&lt;br /&gt;
&lt;br /&gt;
Neet isn&#39;t it?&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/7527538976287752762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/09/web-fragment-using-scala.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/7527538976287752762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/7527538976287752762'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/09/web-fragment-using-scala.html' title='Web Fragment using Scala'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-6152341331317964843</id><published>2011-08-22T22:51:00.001+02:00</published><updated>2013-11-13T22:28:24.609+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SSC (Scala Stock Charts)"/><title type='text'>Scala stock charts, part 3 - Saving the quotes</title><content type='html'>Going further in programming the functionality behind the technical analysis tool for stocks made in Scala we are going to save the daily quotes to separate file, we are also going to supply functionality to load the data for a stock, and save and read a price list divided in 3 lists.&lt;br /&gt;
&lt;br /&gt;
The format of the files is a bitt different, the Quotes I will save and read as they are, but the price list will have a different format that will look as jSon and is saved in a way that will be easy to read with pattern matching. For the matter of fact also the Stock-quotes for a single instrument will be read and transformed to a list of Quote&#39;s with pattern matching.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;codebox-header&quot;&gt;FileHandler.scala&lt;/div&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;/*
 @author Peter Johansson / Ironic programmer 
 */

package scala.ironic.file

object FileHandler {
  import java.io.{File,BufferedWriter,FileWriter,IOException}
  import scala.collection.mutable.{ HashMap =&amp;gt; MutableHashMap}
  import scala.collection.immutable.{ HashMap }
  import scala.io.Source
  
  val rootDir = { scala.util.Properties.userDir }
  val filesDir = { rootDir + &quot;/files&quot;}
  val logFile = { rootDir + &quot;/&quot; + &quot;sBors.log&quot;}
  val pricelistsFile = { rootDir + &quot;/files/pricelists.txt&quot;}
    
  def saveDailyQuotes(quotes: Iterator[QuoteItem]) = {
    log(&quot;## Saving daily qoutes&quot;)
    log(&quot;--- rootDir : &quot; + rootDir)
    log(&quot;--- filesDir : &quot; + filesDir)
    // Check that dir exista or creat if not
    checkDir(filesDir)
    
    var lists = new MutableHashMap[String,List[Quote]]
    var curList = &quot;?&quot;
    
    quotes foreach { quote =&amp;gt;
      quote match { 
        case q: Quote =&amp;gt; { 
                            saveQuoteToFile(q);
                            lists(curList) = List(q) ::: lists(curList)
                          }
        case qList: QuoteList =&amp;gt; {
                                    curList = qList.name;
                                    lists += qList.name -&amp;gt; List()
                                 }
        case _ =&amp;gt; log(&quot;! &quot; + quote)
      }
    }
    
    // Save current lists to file...
    saveStockPriceList(lists)
    
  }
  
  def checkDir(dirName: String){
     val f = new File(dirName)
     if(!f.exists){
       f.mkdirs
       log(&quot;!! Created dir at : &quot; + dirName)
     }
  }
  
  def saveQuoteToFile(quote: Quote) = {
    val fileName = scala.util.Properties.userDir + &quot;/files/&quot; + quote.ticker.replace(&quot; &quot;,&quot;_&quot;) + &quot;.txt&quot;
    val bw = new BufferedWriter(new FileWriter(fileName,true))
    bw.write(quote + &quot;\n&quot;)
    bw.close()
  }
  
  def saveStockPriceList(pricelist: MutableHashMap[String,List[Quote]]){
    log(&quot;## Saving pricelists&quot;)
    val bw = new BufferedWriter(new FileWriter(pricelistsFile,false))
    val sb = new StringBuffer
    sb.append(&quot;{ \&quot;pricelists\&quot;: [\n&quot;)
    for{ (listname,quotes) &amp;lt;- pricelist } {
      sb.append(&quot;\t{ \n\t\t\&quot;listname\&quot;: \&quot;&quot; + listname + &quot;\&quot;,\n&quot;)
      sb.append(&quot;\t\t\&quot;stocks\&quot;: [\n&quot;)
      for{ quote &amp;lt;- quotes } {
        sb.append(&quot;\t\t\t{ \&quot;ticker\&quot;: \&quot;&quot;+quote.ticker + &quot;\&quot;, \&quot;aktie\&quot;: \&quot;&quot; + quote.aktie + &quot;\&quot;},\n&quot;)
      }
      sb.append(&quot;\t\t],\n&quot;)
      sb.append(&quot;\t},\n&quot;)
    }
    sb.append(&quot;}\n&quot;)
    
    bw.write(sb.toString)
    bw.close()
  }
  
  def log(msg: String){
    println(msg)
    val bw = new BufferedWriter(new FileWriter(logFile,true))
    bw.write(msg + &quot;\n&quot;)
    bw.close()
    
  }
  
  def loadPriceLists : HashMap[String, List[Instrument]] = {
    log(&quot;## Loading pricelists&quot;)
    val pricelists = new HashMap[String, List[Instrument]]
    val fc = Source.fromFile(pricelistsFile)
    val ListExtractorRE = &quot;&quot;&quot;.*&quot;listname&quot;: &quot;(.+)&quot;,.*\s*&quot;&quot;&quot;.r
    val InstExtractorRE = &quot;&quot;&quot;.*&quot;ticker&quot;: &quot;(.+)&quot;, &quot;aktie&quot;: &quot;(.+)&quot;.*\s*&quot;&quot;&quot;.r
   
    fc.getLines foreach { line =&amp;gt;
      line match {
        case ListExtractorRE(listname) =&amp;gt; println(&quot;#### got listname : &quot; + new QuoteList(listname))
        case InstExtractorRE(ticker, aktie) =&amp;gt; 
          println(&quot;# got instrument : &quot; + new Instrument(ticker, aktie))
        case _ =&amp;gt; 
      }
      
    }
    return pricelists
  }
  
  def loadInstrument(ticker: String): List[QuoteItem] = {
    val fn = rootDir + &quot;/files/&quot; + ticker.replace(&quot; &quot;,&quot;_&quot;) + &quot;.txt&quot;
    val fc = Source.fromFile(fn)
    val QuoteExtractorRE = &quot;&quot;&quot;Quote\(([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*),([^\,]*).*\)&quot;&quot;&quot;.r
    println(QuoteExtractorRE)
    val quotelines = fc.getLines// filter( s=&amp;gt; ! s.startsWith(&quot;Quote&quot;)) 
    val quotes = quotelines map { line =&amp;gt;
      line match {
        case QuoteExtractorRE(date,ticker,aktie,diffKr,diffPerc,buy,sell,last,high,low,returnNo,returnKr) =&amp;gt; 
          Quote(date,ticker,aktie,diffKr.toDouble,diffPerc.toDouble,buy.toDouble,sell.toDouble,last.toDouble,high.toDouble,low.toDouble,returnNo.toDouble,returnKr.toDouble)
        case _ =&amp;gt; InvalidQuote(&quot;?&quot;, line)
      } 
    } 
    return quotes.toList
  }
  
  
}

&lt;/textarea&gt;That is a lot of code that I wrote on the fly, but not as much as it would have been to do the same thing in Java. the nice thing is the pattern matching, that saves a lot pain that Java code would bring, for example reading every line in the file would not be more code, but also creating and getting the values to objects would give a lot of more code.&lt;br /&gt;
&lt;br /&gt;
[coming... Java code to do it as a comparison]&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;checkDir&lt;/span&gt;: is a method to create directory structure if it does not exist. Actually the first time loading the quotes there is no /files dir if it is not created manually, to avoid crashing, and open upp for the&amp;nbsp;possibility&amp;nbsp;to later use some config to have the data files in a directory of choice this is to ensure that the supplied configured dir will be created.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;saveDailyQuotes&lt;/span&gt;: traverse the content of a daily quote file and calls to save single quote and collect the price lists and calls to save these.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;saveStockPriceList&lt;/span&gt;: saves the current instruments divided in their lists to a file.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;saveQuoteToFile&lt;/span&gt;: append a single quote to its data file.&lt;br /&gt;
&lt;br /&gt;
Finally the methods for loading price lists and a single instrument&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;loadPriceLists&lt;/span&gt;: loads the pice lists back to a map with a list name and a list of Instruments. (Actually it is note yet finished, since I want to think out a way to avoid having a mutable HashMap, now it only prints out what it gets.)&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;loadInstrument&lt;/span&gt;: loads the file of a single stock to a list of Quote&#39;s&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I am not completely happy with it, there is some duplication of code, for example I create new Writers in every method that save things. There is certainly things that can improve here. However, refactoring is a later issue, and this does what I want it to do, so for now it will have to do.&lt;br /&gt;
&lt;br /&gt;
Now the interesting part is beginning to appear, next thing is to make functionality to take car of the technical stuff for the charts to be drawn.</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/6152341331317964843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/08/scala-stock-charts-part-3-saving-quotes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/6152341331317964843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/6152341331317964843'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/08/scala-stock-charts-part-3-saving-quotes.html' title='Scala stock charts, part 3 - Saving the quotes'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-8282761050037410567</id><published>2011-08-19T16:46:00.001+02:00</published><updated>2013-11-13T22:32:21.979+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Scala"/><category scheme="http://www.blogger.com/atom/ns#" term="SSC (Scala Stock Charts)"/><category scheme="http://www.blogger.com/atom/ns#" term="stocks"/><title type='text'>Scala stock charts, part 2 - Getting the quotes</title><content type='html'>I am Swedish so I am for the moment only interested in the Swedish stock market. I have found a site where to get the quotes, it is in text format and I intend to read this information and save it in in other files, one file for each instrument (I call on single stock instrument since it is a form of financial instrument).&lt;br /&gt;
&lt;br /&gt;
The format of the daily file is: (There is an example file to work with at : &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;http://sites.google.com/site/ironicprogrammer/files/20110817k.txt&lt;/span&gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;codebox-content&quot;&gt;Slutkurser från OMX 2011-08-17                Slutkurser från Burgundy 2011-08-17    &lt;br /&gt;
Ticker Aktie +/- +/-% Köp Sälj Senast Högst Lägst Oms (antal) Oms (SEK)      Senast Högst Lägst Oms (antal) Oms (SEK)&lt;br /&gt;
OMX Stockholm Large Cap                    &lt;br /&gt;
ABB ABB Ltd -2,30 -1,66 136,40 136,50 136,40 139,40 136,40 3299500 453921900      136,6 139,4 136,6 183000 25240000&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;It is hard to see in that little box, however. first row is title information of the file.&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Slutkurser från OMX 2011-08-17[6 tabs]Slutkurser från Burgundy 2011-08-17 &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
That is not really&amp;nbsp;necessary&amp;nbsp;and can be skipped as the next line, but the next line is interesting to see the structure of the quotes:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;p1&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #6fa8dc;&quot;&gt;Ticker&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;Aktie&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;+/-&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;+/-%&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;Köp&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;Sälj&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;Senast&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;Högst&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;Lägst&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;Oms (antal)&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;Oms (SEK)&lt;/span&gt;[6 tabs]Senast&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;Högst&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;Lägst&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;Oms (antal)&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;Oms (SEK)&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;p1&quot;&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;When reading the file I will only be interested in the quotes from OMX, the Burgundy I do not want so when saving the quotes to different files I will not&amp;nbsp;consider&amp;nbsp;these, so it is the blue marked fileds that would be used.&lt;br /&gt;
&lt;br /&gt;
The third row &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;p1&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;OMX Stockholm Large Cap&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
is the name of the first list of quotes. It continues like this in the file;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Listname&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Ticker Aktie ...&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;...&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Listname ...&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Ticker Aktie ...&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;...&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;I am only interested in the first three lists, the forth is named &quot;Externa listan&quot;, and I will use this name to break the read.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;So lets start write som code (finally!!)&lt;/b&gt;&lt;/div&gt;&lt;div&gt;I use the REPL for a little bit trial before I put in in classes/objects.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;To test to read the file:&lt;/div&gt;
&lt;textarea name=&quot;code&quot; class=&quot;scala&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
scala&gt; val url = &quot;http://sites.google.com/site/ironicprogrammer/files/&quot;            
url: java.lang.String = http://sites.google.com/site/ironicprogrammer/files/

scala&amp;gt; val file = &quot;20110817k.txt&quot;                             
file: java.lang.String = 20110817k.txt

scala&gt; import scala.io.Source
import scala.io.Source

scala&gt; val fc = Source.fromURL(url+file)
fc: scala.io.BufferedSource = non-empty iterator

scala&gt;; fc.getLines foreach { println }
Slutkurser fr?n OMX 2011-08-17                Slutkurser fr?n Burgundy 2011-08-17    
Ticker Aktie +/- +/-% K?p S?lj Senast H?gst L?gst Oms (antal) Oms (SEK)      Senast H?gst L?gsOms (antal) Oms (SEK)&lt;br /&gt;
OMX Stockholm Large Cap                   
ABB ABB Ltd -2,30 -1,66 136,40 136,50 136,40 139,40 136,40 3299500 453921900      136,6 139,4 136,6 183000 25240000&lt;br /&gt;
ALFA Alfa Laval -0,80 -0,68 117,50 117,60 117,50 119,10 114,80 1121500 131304100      117,6 118,9 114,49223 5760000&lt;/textarea&gt;
&lt;div&gt;Ok, everything seams to work so this need to be taken car of in some other way.&lt;br /&gt;
&lt;br /&gt;
Lets put it in a bit more organized way:&lt;br /&gt;
&lt;br /&gt;
I put a file in src/main/scala/ironic that is named &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;QuoteLoad.scala&lt;/span&gt; with the following content:&lt;/div&gt;&lt;div class=&quot;codebox-header&quot;&gt;QuoteLoad.scala&lt;/div&gt;&lt;pre&gt;&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
/*
 @author Peter Johansson / Ironic programmer 
 */

package scala.ironic

// To be able to handle Iterator[QuoteItem]
trait QuoteItem 

case class InvalidQuote(date: String, content:String) extends QuoteItem
case class QuoteList(name:String) extends QuoteItem
case class Quote(date: String, ticker :String, aktie : String,
    diffKr : Double, diffPerc : Double, buy : Double,
    sell : Double, last : Double, high : Double,
    low : Double, returnNo : Double, returnKr : Double
  ) extends QuoteItem

// Singleton to handle loading of quotes
object QuoteLoad {
   def main(args: Array[String]) = {
      
      loadQuotes(&quot;http://sites.google.com/site/ironicprogrammer/files/&quot;,&quot;20110817&quot;)
   }
   
   val QuoteExtractorRE = &quot;&quot;&quot;([[^Ticker]^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t.*&quot;&quot;&quot;.r
   val ListExtractorRE = &quot;&quot;&quot;(OMX[^\t]+)\t+&quot;&quot;&quot;.r
  
   def loadQuotes(url: String, date: String){
      import scala.io.Source
      
      val uri = url + date + &quot;k.txt&quot;
      val fc = Source.fromURL(uri) 

      val instruments = processLines(fc.getLines(),date)
      println (instruments)
      instruments foreach { inst =&amp;gt; inst match {
        case ilist: QuoteList =&amp;gt; 
            println(ilist)
        case q: Quote =&amp;gt;
            println(q)
        case _ =&amp;gt; println(inst)//
        }
      }
   }
  
    // Should go through the lines from the file and make a iterable with QuoteItem&#39;s. 
    def processLines(lines: Iterator[String],date: String) : Iterator[QuoteItem] = {
      val instruments = lines takeWhile(s=&amp;gt; ! s.startsWith(&quot;Externa listan&quot;)) 
      instruments map { inst =&amp;gt;  
         inst match {
          case ListExtractorRE(list) =&amp;gt; QuoteList(list)//&quot;{\&quot;instrumentList\&quot;: \&quot;&quot; + list + &quot;\&quot;}&quot;
   case QuoteExtractorRE(ticker,aktie,diffKr,diffPerc,buy,sell,last,high,low,returnNo,returnKr) 
            =&amp;gt; Quote(date,ticker,aktie,diffKr.replace(&quot;,&quot;,&quot;.&quot;).toDouble,diffPerc.replace(&quot;,&quot;,&quot;.&quot;).toDouble,buy.replace(&quot;,&quot;,&quot;.&quot;).toDouble,sell.replace(&quot;,&quot;,&quot;.&quot;).toDouble,last.replace(&quot;,&quot;,&quot;.&quot;).toDouble,high.replace(&quot;,&quot;,&quot;.&quot;).toDouble,low.replace(&quot;,&quot;,&quot;.&quot;).toDouble,returnNo.replace(&quot;,&quot;,&quot;.&quot;).toDouble,returnKr.replace(&quot;,&quot;,&quot;.&quot;).toDouble) 
          case _ =&amp;gt; InvalidQuote(date,inst.replace(&quot;\t&quot;,&quot;[tab]&quot;))
        } 
      } 
    }
    
}
&lt;/textarea&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Ok there may be some features to explain here.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
First of all, I make use of an singleton object here so I will be able to call from a terminal window. So it has a main method, but I also extract the functionality so the future client will be able to use the same methods to load quotes.&lt;br /&gt;
&lt;br /&gt;
There is a &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;trait&lt;/span&gt; so I can avoid getting &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Iterator[Any]&lt;/span&gt; and instead getting &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Iterator[QuoteItem]&lt;/span&gt; to be able to handle the &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;case class&lt;/span&gt; objects only, when I later will save the quotes to different files.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;QuoteList&lt;/span&gt;: is for holding the name of a list (there is different list of quotes according to its category, that is more or less the amount of trading that is done and the size of the companies)&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Quote&lt;/span&gt;: is for holding the quote for the day for a specific share&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;InvalidQuote&lt;/span&gt;: is for holding (and logging for error checking) an invalid row from the file.&lt;br /&gt;
&lt;br /&gt;
There is two regexp&#39;s that is handled later in pattern matching to extract the lists and quotes from the file. They look for the structure in the file for valid quotes and the simpler one is for extracting the list name that is only one text.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;def loadQuotes(url: String, date: String)&lt;/span&gt;: handles the load from the URL and calls a helper method to extract the valid quotes and lists.&lt;br /&gt;
&lt;br /&gt;
This will have to do for a first version, later I will save these quotes to different files.&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/8282761050037410567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/08/scala-stock-charts-part-2-getting.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/8282761050037410567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/8282761050037410567'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/08/scala-stock-charts-part-2-getting.html' title='Scala stock charts, part 2 - Getting the quotes'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-3475329119887182527</id><published>2011-07-31T14:41:00.000+02:00</published><updated>2011-10-19T09:34:23.953+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Scala"/><category scheme="http://www.blogger.com/atom/ns#" term="SSC (Scala Stock Charts)"/><category scheme="http://www.blogger.com/atom/ns#" term="stocks"/><title type='text'>Scala stock charts, part 1 - Thoughts about structure</title><content type='html'>Having read through almost halfway, and not even coming to the functional part, in the online book &quot;Programming Scala&quot; by Alex Payne (&lt;a href=&quot;http://ofps.oreilly.com/titles/9780596155957&quot;&gt;http://ofps.oreilly.com/titles/9780596155957&lt;/a&gt;), I am starting to get some ideas of what I want to try out in my new Technical Analysis program for stocks. &amp;nbsp;For sure I would like to use SBT (&lt;a href=&quot;https://github.com/harrah/xsbt/wiki&quot;&gt;https://github.com/harrah/xsbt/wiki&lt;/a&gt;) as a building tool and try to use &quot;Specs&quot; for tests (&lt;a href=&quot;http://ofps.oreilly.com/titles/9780596155957/ScalaToolsLibs.html#ScalaSpecs&quot;&gt;http://ofps.oreilly.com/titles/9780596155957/ScalaToolsLibs.html#ScalaSpecs&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
To start with I want to build my program using either common classes or &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;case classes&lt;/span&gt;, haven´t clearly figured that out, at least I want to use &lt;i&gt;companion objects&lt;/i&gt;. Anyway, I want to get in touch with different features in Scala so there probably will be some file handling with regexp in Scalas pattern matching. At the same way as I want to get in touch with as many features as possible, I also want to keep it as simple as possible so there probably will be som rewrites during the course of my little project as I learn more. If possible I will use trait also, but probably after a rework. I will start more &quot;java-like&quot; with more OO-structure and then try to &quot;functionalize&quot; it.&lt;br /&gt;
&lt;br /&gt;
I haven´t really figured out if I want o use JavaFX either. So I will try to build a library in Scala that ccan be used by client of choice, may be JavaFX but maybe also Flex or Swing. That I will figure out later.&lt;br /&gt;
&lt;br /&gt;
More about this later....&lt;br /&gt;
and then probably with some code :)</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/3475329119887182527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/3475329119887182527'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/07/scala-stock-charts-part-1-thoughts.html' title='Scala stock charts, part 1 - Thoughts about structure'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-2976589558796088422</id><published>2011-07-11T14:36:00.001+02:00</published><updated>2011-07-31T14:42:17.258+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Scala"/><title type='text'>Long time no see</title><content type='html'>It has been a while since last post. Sorry about that! It has been a period of organizational problems (not as fun as programming problems that needs to be solved) that could have been written about, but to sit in the middle of a stormy change takes the energy away.&lt;br /&gt;
&lt;br /&gt;
Anyway, this is what I have been doing:&lt;br /&gt;
I started looking at Scala. For me it looks really interesting and I think it is something that is worth looking in to since it joins well with Java and runs on the JVM. You also need to write less code to do the same thing as with Java.&lt;br /&gt;
To learn Scala I have small idea that I should take my old Java-Swing tool for technical analysis of stocks on the Swedish stock market, set it up to use Scala with a JavaFX-client for the GUI. In this way I intend to get into Scala and at the same time JavaFX a little bit. this little tool of mine I have had as a project to learn new programming languages for over 10 years now. From the first version in an Excel spreadsheet it has taken the way over Turbo-pascal, Visual C++, maybe I also had a C#-client for a while until I returned to the Java Swing client.&lt;br /&gt;
&lt;br /&gt;
I also started to read a lot of agile books about modelling and developing and also a bit about Neuro Linguistic Programming but that is a completely different subject but may be good if you want to take a leading role and/or how to handle the users and other team members and just get better at asking questions as one area of self development.&lt;br /&gt;
&lt;br /&gt;
I will go on, so maybe there will soon be a posting about Scala or JavaFX or both. Or something completely different.&lt;br /&gt;
&lt;br /&gt;
Ciao</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/2976589558796088422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/2976589558796088422'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2011/07/long-time-no-see.html' title='Long time no see'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-6196533781838253752</id><published>2010-10-06T12:59:00.001+02:00</published><updated>2011-07-31T14:42:46.540+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Glassfish v3"/><category scheme="http://www.blogger.com/atom/ns#" term="grails"/><title type='text'>Problem with Grails on Glassfish v3?</title><content type='html'>I almost gave up trying to run grails applications on Glassfish v3. Today I stumbled on a solution that was so easy that I should be ashamed I did not investigate a bit further. The problem is with some OSGi headers and is documented &lt;a href=&quot;http://jira.codehaus.org/browse/GRAILS-6096&quot;&gt;here&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
Others have had the problem and the solution I found on nabble was pretty simple:&lt;br /&gt;
Add the following line in BuildConfig.groovy in your project that should run on a Glassfish v3.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;grails.project.war.osgi.headers=false&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This helps with the problem not being able to deploy a grails app on Glassfish v3 when you experience the following hints in the log on GF:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;SEVERE: Module type not recognized&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;SEVERE: There is no installed container capable of handling this application com.sun.enterprise.deploy.shared.FileArchive@68237947&lt;/span&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/6196533781838253752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/6196533781838253752'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2010/10/problem-with-grails-on-glassfish-v3.html' title='Problem with Grails on Glassfish v3?'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-8025160944292746791</id><published>2010-08-20T12:21:00.002+02:00</published><updated>2010-08-20T13:44:03.680+02:00</updated><title type='text'>Mountain climbing as analogy to programming.</title><content type='html'>I just had vacation and I do not know why, but suddenly I got to think that walking/climbing a mountain (as that is one of my favorite things to do at vacation) could be used as an analogy for programming and learning programming.&lt;br /&gt;
&lt;br /&gt;
As a starting point we have a geek that have no physical ability to talk about (because geeks seldom do sports or go outside the house).&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Start with easy tracks&lt;/h2&gt;To be able to climb a mountain you need to be fit. If you start with a very steep path without being fit, you will get exhausted or fall down and die.&lt;br /&gt;
&lt;br /&gt;
Also keep the distance short so you do not overuse your muscles. you may want to take a hike to morrow as well and with aching limbs it will not be that easy or fun. &lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;That is to programming: start learning an easy programming language, do a little bit of learning every day, and eventually you will get it. Doing to much makes your brain tired and you may be so bored with the stuff that you may quit and do something else.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Increase the difficulty gradually&lt;/h2&gt;Having started the tracking experience, it may be boring to do the same path every time and after a while your fitness will tend to stagnate and adapt to what you are doing. That is, walk longer paths, and also more steep paths, the body tends to adapt to be able to handle the demands, but not more than necessary. We need to increase the work load to be able to handle more and more.When we are fitter, we can handle more difficult paths. However, even if it is good to challenge yourself a bit, do not overdo it (you may fall down and die). When you climb the mountain higher you will get a more panoramic view, it is beautiful and you can also start to see the path you took, and maybe also see different paths you can take to get to the same place.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;That is to programming&lt;/i&gt;: &lt;i&gt;Do not just learn the basics, they are good to have but can not help you in the long run, specially not if you want to have it as a profession. do the basics, repeat them, but when you feel comfortable with them, increase the amount of code you write, and also the difficulty of the code: that is, start doing design work, object oriented programming etc. Knowing the basics may help you write simple routines, but climbing higher will give you a better view of the surroundings and starting to put things together or how to do different designs to get to the same result.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Walk different mountains&lt;/h2&gt;No we may not have made it to the top of the first one yet, but does that really matter? Not really, the last part of getting to the top of a mountain may be easy, but it is usually not. Take Matterhorn, or Mount Everest for example. A lot of people climb them, but not all of them go for the top. you can go to the mountain and go as far as you have the time to do, or as high as you have the strength to do. this does not mean that you do not have a meaningful experience or doing a bad work. You doing as much as you can do or are willing to do, and even if its it not to the top, you may reach much higher than most people will do in their lifetime.&lt;br /&gt;
&lt;br /&gt;
If you think that you did a mountain as good as you can or that you did it long enough to get bored. Try another one, it will give you another view, different tracks. It may have paths that is easier then the first mountain, but also paths that is harder. Maybe it will get you higher quicker and let you see more, maybe the paths are harder but the view is more rewarding than the first one.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;That is to programming: Learn different programming languages, the first one you learn may not be a very good one to use professionally, but it may be a good language for learning basic programming. The new language may give you more opportunities to solve things quicker than the first one you learned. It may also be harder to do stuff in it, but when they are done, it may be better, quicker to do what you want it to do. for example Java may be easier to learn and use than C++ but performance wise, some C++ programs do better. On the other hand Java is more platform independent than C++, so it may be a better option for some companies.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;Different language can solve things easier than in other languages, or have better performance. the choice of language depends of the application you want to make. Learn more than one to widen your options and you will be better at your work.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;So when do I get to the top?&lt;/h2&gt;Ok, lets be realistic. You may never get to the top. It depends on the mountain you decide to climb. Take Mount everest for example, it is the highest mountain we have, only a few made it to the top, and even fewer without injuries.&lt;br /&gt;
&lt;br /&gt;
Take most mountains that is not a walk in the park, you may never reach the top, but you can get far enough to be satisfied with the experience and the rewards it give.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;For programmers: not all programmers learn absolutely everything about one single programming language. they leave the top part for experts, that are fit to do the advanced stuff.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;Anyway programming is not really about doing the most advanced stuff or the most dangerous stuff. It is about doing stuff that other can follow. someone is coming after you and may have to maintain stuff you did. If it is to difficult they may not be able to go all the way, or understand how the heck you were able to get up to that cliff. programming is about leading the way for other to follow, you take a path that is fairly easy, sometimes not so easy but still manageable, you draw a map so that other can take the same path and continue from there.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;So what are you waiting for, go out and climb a new mountain today!&lt;/b&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/8025160944292746791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/8025160944292746791'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2010/08/mountain-climbing-as-analogy-to.html' title='Mountain climbing as analogy to programming.'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-4430501402788374362</id><published>2010-05-04T19:05:00.002+02:00</published><updated>2011-07-31T14:42:32.619+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Glassfish v3"/><title type='text'>Struts2 on Glassfish v3</title><content type='html'>OMG. It was not that trivial to get it going, at least not using Netbeans.&lt;br /&gt;
&lt;br /&gt;
First trying to use maven since I need to have some EJBs, but I gave up after not being able to get the archetype for Struts2 do any project for me, first complaining about no commons-collections-3.2.1, downloading it and got a little bit longer, but then could not find anything for struts2.1.6.&lt;br /&gt;
&lt;br /&gt;
So I went on creating a Struts2 project and got it to work by pointing out the jar files needed in Netbeans JavaEE webproject for Glassfish, YES there is a lot of jarfiles depending on each other since I also want to use TILES. Anyway, when I wanted the use the EJBs I had to create a EAR-project to hold everything together, what happens then?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Struts2 stops working&lt;/b&gt;, complaining of a lot of classes not loaded or cannot find. I spent almost all the afternoon before finally finding the problem.&lt;br /&gt;
&lt;br /&gt;
Netbeans ant-script wants to copy every f...ing jar file that is not a TLD to the lib of the EAR, NOT into the Web applications WEB-INF/lib, which then makes sence for the errors in the log: when loading from that EAR/lib folder, it can not find struts-core classes since that jar file is in the Web-app because it includes TLDs,&lt;br /&gt;
&lt;br /&gt;
So finally solved, hack the build-impl.xml and copy &lt;b&gt;ALL &lt;/b&gt;jar files to the web-app so it works.Why Netbeans do this way I do not know, maybe someone can inform me?</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/4430501402788374362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/4430501402788374362'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2010/05/struts2-on-glassfish-v3.html' title='Struts2 on Glassfish v3'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-270973587530818781</id><published>2010-03-26T16:01:00.000+01:00</published><updated>2010-03-26T16:01:18.347+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><category scheme="http://www.blogger.com/atom/ns#" term="tutorial"/><title type='text'>Tutorials</title><content type='html'>I have started a Java tutorial for starting up with Java. It can be found at my Google-site. The tutorial is basic Java.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://sites.google.com/site/ironicprogrammer/tutorials/ironic-programmer-java-tutorial&quot;&gt;http://sites.google.com/site/ironicprogrammer/tutorials/ironic-programmer-java-tutorial&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I will continuosly add more stuff to the site. Even if the first lessons may be a bit text to read. I will try to do programming by examples.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/270973587530818781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/270973587530818781'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2010/03/tutorials.html' title='Tutorials'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-3989786309363551166</id><published>2010-03-07T16:04:00.003+01:00</published><updated>2013-11-13T22:35:51.169+01:00</updated><title type='text'>Scary, but maybe true</title><content type='html'>A week ago I read the blogpost &quot;&lt;a href=&quot;http://www.codinghorror.com/blog/2010/02/the-nonprogramming-programmer.html&quot;&gt;The Non-Programming Programmer&lt;/a&gt;&quot; by Jeff Atwood at Coding horror about that many applicants for programming work can not program at all.&lt;br /&gt;
&lt;br /&gt;
During my 10 years in the business I experienced a few myself. I wish I then had the examples to give and exclude some that can not program.&lt;br /&gt;
&lt;br /&gt;
Some examples:&lt;br /&gt;
&lt;h4&gt;What you can see as a teacher&lt;/h4&gt;At my first job as a teacher at university, part of my job was to lecture Pascal and C. Included was laborations in the language learned. Here I could see some serious laziness or lack of logic. One of the first tasks used to be to print out a matrix of the numbers 1..100 in a table of size 10x10. Of course this task is to learn some basic structures in the language learned like iterations as for-loop and conditionals like if. This should be a fairly simple task, but one guy actually just did a&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
writeln(&quot;1 2 3 4 5 6 7 8 9 10&quot;);
writeln(&quot;11 12 13 14 15 16 17 18 19 20&quot;);
&lt;/textarea&gt;
and so on.&lt;br /&gt;
Another example is the laziness of students. Some did not want to put in some work to learn the language, they just wanted to pass the class. There is different ways to do this. One is to try to get a group to add your name to the report, another way is to copy someone elses work. Now the stupid part of this, a teacher notice more than you may think. Someone that is not able to manage simple task and then all of a sudden turn up with a solution that looks pretty similar to the brightest student or that of someone that the teacher helped and put in some pattern of text that was put there as an example but is failry recognizable since it was a value you do not just put in.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;About applying programmers&lt;/h4&gt;Here we have programmers(? or not) that actually have a bigger mouth then ability to program. They do good at an interview and get the job. Later it turn out.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;that they do not at all know anything about Java, and the excuse is that they hoped that they soon shuould catch up and learn.&lt;/li&gt;
&lt;li&gt;the one I heard from the boss that applied (this was early 2000 when the market was hot). That they heard that the company was looking and maybe this person could be a candidate because he did som Basic 10 years ago and was thinking maybe he could do some programming.&lt;/li&gt;
&lt;li&gt;I have noticed, at an interview, think really carefull when people start to talk about project they have been in and saying: &quot;In this project WE used this and that language/database.&quot; or &quot;The application I worked is build in this and that technique and this database&quot;. The problem with this is that some uses the knowledge of others in their CV, just because they were in a project that had a very nice arhitechture does not mean they did anything of it.&lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt;Programmers at work&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;One consultant I met at a task where we came in to look at why the clients web build in asp was so slow. Well the consultant they had there that have been working on the web did not know any SQL so in 4 different frames in a framset did a full lookup on the resultset of a table looped until the key was found and then used anothere key to do the same on another table.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;A programmer I worked with got the task to do some of the work when we were dividing an existing Session EJB into 3-4 smaller ones and at the same time change the medthods to return Collection of objects instead of a ResultSet. He actually did that, that is moved the code from the old one to the new one. What he missed was that the work is actually not finishe just because you move code, there is actually placed were you use the code, like a client that ALSO needs to be changed if you change the contract and move the methods it need. WHOOPS!&lt;/li&gt;
&lt;li&gt;Another man I worked with said he knew Java EE after he went throug a book, downloading the examples and compiled and run throug them once. But, when he did some actual coding, he did not reuse the methods I already had done, he made new ones with other names.&lt;/li&gt;
&lt;li&gt;Some programers seam to have the philosophy. &quot;&lt;i&gt;If it compiles and run it must be right&lt;/i&gt;&quot;. NO it is not. Making the compiler happy is easy, making the application work is not the same as keeping the compiler happy, it is logic not syntax.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;So that post was very welcomed and will be used in the future.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;While we are at it, try to solve&amp;nbsp;this one with recursion&lt;/b&gt;:&lt;/div&gt;&lt;div&gt;You have a class called Org to represent a organization. The root organization is the starting point and every instance of the class holds its own suborganizations and a reference to its parent.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqRWBGZ514HZnD3vmORBXoW0a6JOp-yE31MfljvPJjrHy_ZuulquiludnQNfL06X4dvkA5d5RGo26R1xh4GUCzFtqdXBzzPxrGs1MTPMktlO8UcH5eiDpBZz60icsjC79YXbnERQZOLbk/s1600-h/org_class.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqRWBGZ514HZnD3vmORBXoW0a6JOp-yE31MfljvPJjrHy_ZuulquiludnQNfL06X4dvkA5d5RGo26R1xh4GUCzFtqdXBzzPxrGs1MTPMktlO8UcH5eiDpBZz60icsjC79YXbnERQZOLbk/s200/org_class.png&quot; width=&quot;198&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;pre class=&quot;codebox-header&quot;&gt;Org.java
&lt;/pre&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
public class Org{
    private long id;
    private Org parent;
    private List&lt;org&gt; children;
    private String name;

    public Org(long id, String name){
     ...
    }

    // getters / setters
    ....
}
&lt;/textarea&gt;&lt;div&gt;Your task is to print the organization tree starting from the root.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: x-large;&quot;&gt;Please share your own stories in the comments&lt;/span&gt;&lt;/b&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/3989786309363551166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2010/03/scary-but-maybe-true.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/3989786309363551166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/3989786309363551166'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2010/03/scary-but-maybe-true.html' title='Scary, but maybe true'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqRWBGZ514HZnD3vmORBXoW0a6JOp-yE31MfljvPJjrHy_ZuulquiludnQNfL06X4dvkA5d5RGo26R1xh4GUCzFtqdXBzzPxrGs1MTPMktlO8UcH5eiDpBZz60icsjC79YXbnERQZOLbk/s72-c/org_class.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-7881005513157649045</id><published>2010-03-05T18:48:00.008+01:00</published><updated>2013-11-13T22:47:09.466+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="JSF2"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><title type='text'>File upload in JSF2 using base class</title><content type='html'>Surfing the net for JSF2 resources can be a tedious task. Actually for file upload I actually found a couple of blogs describing how to do it the firs I found actually only (&lt;a href=&quot;http://dominikdorn.com/?p=169&quot;&gt;FileUpload with JSF 2 and Servlet 3.0&lt;/a&gt;) made a taglib based on the second one. And it includes maven which I do not use.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;I had to remake the example a bit since I got question to provide a sample application. When extracting the code I noticed it did not work anymore. The reason is probably the one mentioned at this blog: &lt;a href=&quot;http://mcatr.blogspot.com/2010/01/multipart-requests-and-jsf.html&quot;&gt;http://mcatr.blogspot.com/2010/01/multipart-requests-and-jsf.html&lt;/a&gt;&lt;/b&gt;.To make it work again, I did a solution that I am not happy with but it works. It takes the idea from this blog, joined with some from the other blogs mentioned. The former blog states that a multipart request to JSF 2 do not work, because it can not extract parameters from that kind of request.&lt;br /&gt;
&lt;br /&gt;
The problem is that for what I actually wanted it was not right and one was a little bit overkill. So as usual I took another approach. I got some helf from&amp;nbsp;&lt;a href=&quot;http://balusc.blogspot.com/2009/12/uploading-files-with-jsf-20-and-servlet.html&quot;&gt;Uploading files with JSF 2.0 and Servlet 3.0&lt;/a&gt;&amp;nbsp;but that solution includes making a custom component and renderer, and is dependant on classes found in&amp;nbsp;&lt;a href=&quot;http://balusc.blogspot.com/2009/12/uploading-files-in-servlet-30.html&quot;&gt;Uploading files in Servlet 3.0&lt;/a&gt;. I actually copied all the code and tried it...but I got a failure when loading the page. So I wanted something with less code. and simpler to use, and I have a case when I am going to store vCards in a database so a solution to save the file on disk means I have to modify code anyway.&lt;br /&gt;
&lt;br /&gt;
I took the following approach:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Use standard html &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;,Courier,monospace;&quot;&gt;&amp;lt;input type=&quot;file&quot; /&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Use @ManagedBean&lt;/li&gt;
&lt;li&gt;I first had a base class to handle the file and extended the Managed bean with this one, but since this stopped working I had to add:&lt;/li&gt;

&lt;ul&gt;&lt;li&gt;A Wrapper to wrap multipart requests&lt;/li&gt;
&lt;li&gt;A Filter to catch multipart request and transform them to the Wrapper type.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;I also have a FacesUtil class to simplify getting request and parameters&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Here is the code:&lt;/div&gt;&lt;h3&gt;In the view (vCardForm.xhtml)&lt;/h3&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
&amp;lt;h:form enctype=&quot;multipart/form-data&quot;&amp;gt;
 &amp;lt;input type=&quot;file&quot; name=&quot;vcardFile&quot;/&amp;gt;
 &amp;lt;h:commandButton action=&quot;#{vcardBean.uploadVCard}&quot; value=&quot;Upload&quot;/&amp;gt;
&amp;lt;/h:form&amp;gt;
&lt;/textarea&gt;&lt;h3&gt;Class to represent the uploaded file (UploadFile.java)&lt;/h3&gt;I created a class to store some information about the file being upload, I can later choose if I want to store to disk or in a database, for example sending this to an EJB and the EJB descides what to do.&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
package theironicprogrammer.model;

public class UploadFile {
 private String fileName;
 private String contentType;
 privte byte[] fileData;
 
 public UploadFile(String fileName, String contentType, byte[] fileData){
  this.fileName = fileName;
  this.contentType = contentType;
  this.fileData = fileData;
 }
 
 public String getFileName(){
  return fileName;
 }
 public String getContentType(){
  return contentType;
 }
 public byte[] getFileData(){
  return fileData;
 }
 
 public void setFileName(String fileName){
  this.fileName = fileName;
 }
 public void getContentType(String contentType){
  this.contentType = contentType;
 }
 public void setFileData(byte[] fileData){
  this.fileData = fileData;
 }
}
&lt;/textarea&gt;&lt;h3&gt;The managed bean (VCardBean.java)&lt;/h3&gt;The interesting thing going on here is that i initialize the base class with the request for use of the request. Probably I could have done this in the constructor of the baseclass, but something you have to have to refactor.&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
package theironicprogrammer.model;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.servlet.ServletOutputStream;
import theironicprogrammer.session.PersonUpdaterLocal;
import theironicprogrammer.http.MultiPart;

/**
 *
 * @author theironicprogrammer@gmail.com
 */
@ManagedBean(name=&quot;vcardBean&quot;)
@RequestScoped
public class VCardBean implements Serializable{
    @EJB PersonBean personBean;

    public String uploadVCard(){
        System.out.println(&quot;uploadVCard...&quot;);
        HttpServletRequest req = FacesUtil.getRequest();
        if(req instanceof MultipartRequestWrapper){
            MultipartRequestWrapper multi = (MultipartRequestWrapper)req;

            UploadFile uf = multi.findFile(&quot;vcardFile&quot;);
            if(uf != null){
                String fileExt = uf.getFileName().substring(uf.getFileName().lastIndexOf(&quot;.&quot;));
                System.out.println(&quot;Extension&quot; + fileExt);
                // should actually check the extension, but no big deal for example
                personBean.saveVCard(uf, &quot;testuser&quot;);

                FacesUtil.getFlash().put(&quot;messageCode&quot;, &quot;vcard.upload.ok&quot;);
                FacesUtil.getFlash().put(&quot;fileName&quot;, uf.getFileName());
            }

        }
        return &quot;vCardForm&quot;;
    }

    public String findVCard(){
        UploadFile uf = personBean.findVCard(&quot;testuser&quot;);
        if(uf == null) {
            FacesUtil.getFlash().put(&quot;messageCode&quot;, &quot;vcard.upload.err.load&quot;);
            FacesUtil.getFlash().put(&quot;messageType&quot;, &quot;errors&quot;);

        } else {
            ServletOutputStream output = null;
            try {
                output = FacesUtil.getResponse().getOutputStream();
                FacesUtil.getResponse().setHeader(&quot;Content-disposition&quot;, &quot;attachment; filename=&quot; + uf.getFileName());
                FacesUtil.getResponse().setContentType(uf.getContentType());
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                baos.write(uf.getFileData());
                FacesUtil.getResponse().setCharacterEncoding(&quot;UTF-8&quot;);
                FacesUtil.getResponse().setContentLength(baos.size());
                baos.writeTo(output);
                output.flush();
            } catch (IOException ex) {
                FacesUtil.getFlash().put(&quot;messageCode&quot;, &quot;vcard.upload.err.load&quot;);
                FacesUtil.getFlash().put(&quot;messageType&quot;, &quot;errors&quot;);
                Logger.getLogger(VCardBean.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    output.close();
                } catch (IOException ex) {
                    FacesUtil.getFlash().put(&quot;messageCode&quot;, &quot;vcard.upload.err.load&quot;);
                    FacesUtil.getFlash().put(&quot;messageType&quot;, &quot;errors&quot;);
                    Logger.getLogger(VCardBean.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return &quot;vCardForm&quot;;
    }

    public String removeVCard(){
        personBean.removeVCard(&quot;testuser&quot;);
        FacesUtil.getFlash().put(&quot;messageCode&quot;, &quot;vcard.remove.ok&quot;);
        FacesUtil.getFlash().put(&quot;messageType&quot;, &quot;messages&quot;);
        return &quot;vCardForm&quot;;
    }

}

&lt;/textarea&gt;&lt;br /&gt;
&lt;h3&gt;MultipartRequestWrapper&lt;/h3&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
package ironicprogrammer.http;

import ironicprogrammer.model.UploadFile;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.Part;

/**
 *
 * @author theironicprogrammer@gmail.com
 */
public class MultipartRequestWrapper extends HttpServletRequestWrapper {
    private static final String CONTENT_DISPOSITION = &quot;content-disposition&quot;;
    private static final String CONTENT_DISPOSITION_FILENAME = &quot;filename&quot;;

    private Hashtable&lt;String, String&gt; params = new Hashtable&lt;String, String&gt;();

    public MultipartRequestWrapper(HttpServletRequest request) {
        super(request);
        System.out.println(&quot;Created multipart wrapper....&quot;);
        try {
            System.out.println(&quot;Looping parts&quot;);            
            for (Part p : request.getParts()) {
                System.out.println(String.format(&quot;Part name: %1$s, contentType : %2$s&quot;, p.getName(), p.getContentType()));
                for(String header : p.getHeaderNames()){
                    System.out.println(&quot;Header name : &quot; + header + &quot;, value : &quot; + p.getHeader(header));
                }
                byte[] b = new byte[(int) p.getSize()];
                p.getInputStream().read(b);
                params.put(p.getName(), new String[]{new String(b)});
            }
        } catch (IOException ex) {
            Logger.getLogger(MultipartRequestWrapper.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ServletException ex) {
            Logger.getLogger(MultipartRequestWrapper.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public UploadFile findFile(String attrName){
        UploadFile uf = null;
        try {

            Part p = findPart(attrName);
            if(p != null){
                String fileName = getFilename(p);
                System.out.println(&quot;Filename : &quot; + fileName + &quot;, contentType &quot; + p.getContentType());
                byte[] b = new byte[(int) p.getSize()];
                p.getInputStream().read(b);
                params.put(p.getName(), new String[]{new String(b)});
                uf = new UploadFile(fileName, p.getContentType(), b);
            }

        } catch (IOException ex) {
            Logger.getLogger(MultiPart.class.getName()).log(Level.SEVERE, null, ex);
        }
        return uf;
    }

    private Part findPart(String name){
        HttpServletRequest request = (HttpServletRequest)getRequest();
        Part p = null;
        try {
            for (Part part : request.getParts()) {
                if(part.getName().equals(name)){
                    p = part;
                    break;
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(MultiPart.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ServletException ex) {
            Logger.getLogger(MultiPart.class.getName()).log(Level.SEVERE, null, ex);
        }

        return p;
    }

    private String getFilename(Part part) {
        for (String cd : part.getHeader(CONTENT_DISPOSITION).split(&quot;;&quot;)) {
            if (cd.trim().startsWith(CONTENT_DISPOSITION_FILENAME)) {
                return cd.substring(cd.indexOf(&#39;=&#39;) + 1).trim().replace(&quot;\&quot;&quot;, &quot;&quot;);
            }
        }
        return null;
    }

    @Override
    public String getParameter(String name) {
      String [] values = getParameterValues(name);
      if(values == null || values.length == 0) {
        return null;
      }

      return values[0];
    }

    @Override
    public Map&lt;String, String&gt; getParameterMap() {
      return params;
    }

    @Override
    public Enumeration&lt;String&gt; getParameterNames() {
      return params.keys();
    }

    @Override
    public String[] getParameterValues(String name) {
      return params.get(name);
    }

}

&lt;/textarea&gt;&lt;br /&gt;
&lt;h3&gt;MultipartRequestFilter&lt;/h3&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
package ironicprogrammer.http;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * @author theironicprogrammer@gmail.com
 */
@WebFilter(urlPatterns=&quot;/*&quot;)
public class MultipartRequestFilter implements  Filter{
    private static final String REQUEST_METHOD_POST = &quot;POST&quot;;
    private static final String CONTENT_TYPE_MULTIPART = &quot;multipart/&quot;;


    public void init(FilterConfig filterConfig) throws ServletException {
        
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        if(isMultipartRequest(httpRequest)){
            System.out.println(&quot;Is multipart request.... wrapping it.&quot;);
            request = new MultipartRequestWrapper(httpRequest);
        }
        chain.doFilter(request, response);
    }

    public void destroy() {
        
    }

    public static final boolean isMultipartRequest(HttpServletRequest request) {
        return REQUEST_METHOD_POST.equalsIgnoreCase(request.getMethod())
            &amp;amp;&amp;amp; request.getContentType() != null
            &amp;amp;&amp;amp; request.getContentType().toLowerCase().startsWith(CONTENT_TYPE_MULTIPART);
    }

}

&lt;/textarea&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Session bean for handling the storage.&lt;/h3&gt;For the example this only stores it in the session.&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
package ironicprogrammer.session;

import ironicprogrammer.model.UploadFile;
import ironicprogrammer.utils.FacesUtil;
import java.util.HashMap;
import java.util.Map;
import javax.ejb.Stateless;

/**
 *
* @author theironicprogrammer@gmail.com
 */
@Stateless
public class PersonBean {

    /**
     * Saves a vcard for the person with supplied username
     */
    public void saveVCard(UploadFile file, String username){
        // Make use of session for example. No need to complicate with connection to filesystem or database
        System.out.println(&quot;Saving vcard for &quot; + username);
        getVcards().put(username, file);
    }


    public UploadFile findVCard(String username){
        System.out.println(&quot;Getting vcard for&quot; + username);
        return getVcards().get(username);
    }

    public void removeVCard(String username){
        System.out.println(&quot;Removing vcard for&quot; + username);
        getVcards().remove(username);
    }

    private Map&lt;String, UploadFile&gt; getVcards(){
        Map&lt;String, UploadFile&gt; vcards = (Map&lt;String, UploadFile&gt;)FacesUtil.getRequest().getSession().getAttribute(&quot;vcards&quot;);
        if(vcards == null){
            vcards = new HashMap&lt;String, UploadFile&gt;();
            FacesUtil.getRequest().getSession().setAttribute(&quot;vcards&quot;, vcards);
        }
        return vcards;
    }
 
}
&lt;/textarea&gt;&lt;br /&gt;
&lt;h3&gt;Finally the class to inherit to make it all work&lt;/h3&gt;This is now obsolete, but I keep it in case JSF will handle the mutlipart form in the future. But even then it may not be needed.&lt;br /&gt;
&lt;textarea name=&quot;code&quot; class=&quot;java&quot; cols=&quot;60&quot; rows=&quot;10&quot;&gt;
package theironicprogrammer.http;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import theironicprogrammer.model.UploadFile;

/**
 *
 * @author theironicprogrammer@gmail.com
 */
public class MultiPart {
    private static final String CONTENT_DISPOSITION = &quot;content-disposition&quot;;
    private static final String CONTENT_DISPOSITION_FILENAME = &quot;filename&quot;;
   
    private HttpServletRequest request;
    
    protected MultiPart(){
        
    }

    public UploadFile findFile(String attrName){
        UploadFile uf = null;
        try {
            
            Part p = findPart(attrName);
            if(p != null){
                String fileName = getFilename(p);
                System.out.println(&quot;Filename : &quot; + fileName + &quot;, contentType &quot; + p.getContentType());
                byte[] b = new byte[(int) p.getSize()];
                p.getInputStream().read(b);
                uf = new UploadFile(fileName, p.getContentType(), b);
            }
            
        } catch (IOException ex) {
            Logger.getLogger(MultiPart.class.getName()).log(Level.SEVERE, null, ex);
        }
        return uf;
    }


    public HttpServletRequest getRequest() {
        return request;
    }

    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    private Part findPart(String name){
        Part p = null;
        try {
            for (Part part : request.getParts()) {
                if(part.getName().equals(name)){
                    p = part;
                    break;
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(MultiPart.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ServletException ex) {
            Logger.getLogger(MultiPart.class.getName()).log(Level.SEVERE, null, ex);
        }

        return p;
    }

    private String getFilename(Part part) {
        for (String cd : part.getHeader(CONTENT_DISPOSITION).split(&quot;;&quot;)) {
            if (cd.trim().startsWith(CONTENT_DISPOSITION_FILENAME)) {
                return cd.substring(cd.indexOf(&#39;=&#39;) + 1).trim().replace(&quot;\&quot;&quot;, &quot;&quot;);
            }
        }
        return null;
    }
    
}

&lt;/textarea&gt;
&lt;br /&gt;
The only thing needed in the Managed bean is to call findFile(&quot;vcardFile&quot;) on the multipart request to get the file that is being uploaded and take action on that.&lt;br /&gt;
&lt;br /&gt;
A sample project (for netbeans) can be found here:&amp;nbsp;&lt;a href=&quot;http://sites.google.com/site/ironicprogrammer/home/jsf-file-upload-example&quot;&gt;http://sites.google.com/site/ironicprogrammer/home/jsf-file-upload-example&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/7881005513157649045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2010/03/file-upload-in-jsf2.html#comment-form' title='29 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/7881005513157649045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/7881005513157649045'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2010/03/file-upload-in-jsf2.html' title='File upload in JSF2 using base class'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>29</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815776380138759375.post-3891457870232644622</id><published>2010-01-10T18:45:00.000+01:00</published><updated>2010-03-10T17:28:51.572+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="database"/><category scheme="http://www.blogger.com/atom/ns#" term="Glassfish v3"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="JSF"/><category scheme="http://www.blogger.com/atom/ns#" term="JSF2"/><category scheme="http://www.blogger.com/atom/ns#" term="Netbeans 6.8"/><title type='text'>Netbeans tutorial &quot;Generating a JavaServer Faces 2.0 CRUD Application from a Database&quot;</title><content type='html'>I went through&lt;a href=&quot;http://netbeans.org/kb/docs/web/jsf20-crud.html&quot;&gt; this tutorial&lt;/a&gt; today. Nice example, but there was something I did not like. As a geek I sit on a sunday and try out a tutorial on my home computer. Lazy as I am I do not want to start my MySql instance, since adding more running components tend to slow down my almost four year old Toshiba laptop.&lt;br /&gt;
&lt;br /&gt;
Since I was going to run Glassfish v3 anyway I was thinking a better idea is to have the database in the form of JavaDB, so I tweaked the script to fit into Derby instead, not much tweaking to do actually and doing it made me happy to not be forced to start MySql (My mysql is by the way a bit old and installed the same time as I installed InstantRails long time ago, and probably needs to be updated). The insert script in the tutorial work more or less as it is in JavaDB just remove the 3 SET-clauses in the top and the COMMIT in the end and it should work.&lt;br /&gt;
&lt;br /&gt;
The script can be found at my google-site &lt;a href=&quot;http://sites.google.com/site/ironicprogrammer/home/jsf-2-0-tutorial-db-script&quot;&gt;http://sites.google.com/site/ironicprogrammer/home/jsf-2-0-tutorial-db-script&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://ironicprogrammer.blogspot.com/feeds/3891457870232644622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ironicprogrammer.blogspot.com/2010/01/netbeans-tutorial-generating-javaserver.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/3891457870232644622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815776380138759375/posts/default/3891457870232644622'/><link rel='alternate' type='text/html' href='http://ironicprogrammer.blogspot.com/2010/01/netbeans-tutorial-generating-javaserver.html' title='Netbeans tutorial &quot;Generating a JavaServer Faces 2.0 CRUD Application from a Database&quot;'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>