Wednesday, 5 August 2015

Wednesday, 3 June 2015

Road Testing

The Blog Platform is now in a state of a minimum viable product. I am guinea pigging it on my own website www.geoffhayward.eu. This guinea pigging is helping me find UI defects and bugs. Most importantly the guinea pigging is helping me improve the spec before the next iteration starts.

In the next iteration I intend to crate a web-service API so that each front-end can be a client of the platform. This will mean each front-end client is language and template engine independent from the Blog Platform.

I will be sure to add updates about the Blog Platform's progress here soon.

Monday, 25 May 2015

Comments are Implemented

The video below proudly demonstrates the commenting functionality I have been implementing this weekend for the blog platform.

Comments have a one to many relationship with posts.



I have used cascade on delete so that a post can be deleted without the need to delete each of its comments first. The JPA withing the Java looks like this:

Commnet.java
    [...]
    @NotNull
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="POST_ID")
    private Post post;
    [...]

I cannot wait to start using the new blog platform now it is almost finished.

Saturday, 23 May 2015

Tags

The tags are hooked up. Please find a video of the end result below:



Each blog post can have n many tags. Tags are embedded into the 'Post' class.
    @ElementCollection
    @CollectionTable(name="POST_TAGS", joinColumns = @JoinColumn(name="POST_ID"))
    @Column(name="TAGS")
    private List<tag> tags = new ArrayList<>();

I experimented with tags as entities in order to query them in a more JPA way. However, after several hours of making it complicated I decided to go with embedding them. After all: Why complicate the entities for the sake of a JPQL query?

Tuesday, 19 May 2015

JSF Buttons Nested in a Repaintable Elements

There was a little bug in posts where any unsaved fields would be lost when removing a tag from the tag list. This happened because each tag element had <f:ajax render="@form" /> set.

Setting the JSF <f:ajax render="tags-output" /> had not facilitated the repainting of  the tag list. This was a problem and I thought <f:ajax render="@form" /> was the solution.

Armed with new knowledge about JSF  I have prefix the panelGroup's id with the form's id.

Now the bug has gone and the problem is solved.
    <ui:repeat var="t" value="#{postWriter.post.tags}">
        <h:commandButton
            value="#{t}"
            action="#{postWriter.removeTag(t)}"
        >
            <f:ajax
                render="posts:tags-output posts:tags"
            />
        </h:commandButton>
    </ui:repeat>

Friday, 15 May 2015

A Cleaner Entity Count

Using TypedQuery<T> I got a cleaner entity count with JPA's JPQL.

Here is the cleaner way:

    public int countAllMessages(){
        return em.createQuery("SELECT count(m) FROM Message m", Number.class).getSingleResult().intValue();
    }

Instead of:

    public int countAllMessages(){
        Query q = em.createQuery("SELECT count(m) FROM Message m");
        Number result = (Number) q.getSingleResult();
        return result.intValue();
    }

Where q.getSingleResult() is cast to Number.

Thursday, 14 May 2015

General Settings

The general settings items are odd to model compared with the other entities that have been modeled within the blog platform.  The other entities created for the blog platform, such as 'Post' entities, can have n many instances persisted. If modeled this same way all settings would become one entity. Would it be better in this instance to persist each setting item individually?

I decided to try out modeling each setting individually for now. Here is what I have implemented.

JSF
     <label for="blog-desc">Blog Name</label>
    <h:inputText
        id="blog-name"
        value="#{configurationWriter.blogName}"
    >
        <f:ajax event="blur" />
    </h:inputText>

    <label for="blog-desc">Blog Description</label>
    <h:inputText
        id="blog-desc"
        value="#{configurationWriter.blogDescription}"
    >
        <f:ajax event="blur" />
    </h:inputText>



ConfigurationWriter.java
@Named("configurationWriter")
@ViewScoped
public class ConfigurationWriter implements Serializable {
    
    @Inject
    private ConfigurationDAOBean ps;
    private String blogName;
    private String blogDescription;
    
    @PostConstruct
    private void setup(){
        blogName = ps.fetch("blog-name").getValue();
        blogDescription = ps.fetch("blog-description").getValue();
    }
    
    public void save(){
        saveHelper("blog-name", blogName);
        saveHelper("blog-description", blogDescription);
    }
    
    private void saveHelper(String field, String value){
        Configuration c = ps.fetch(field);
        c.setValue(value);
        ps.store(c);
    }

    public String getBlogName() {
        return blogName;
    }

    public void setBlogName(String blogName) {
        this.blogName = blogName;
    }

    public String getBlogDescription() {
        return blogDescription;
    }

    public void setBlogDescription(String blogDescription) {
        this.blogDescription = blogDescription;
    }
}
   

ConfigurationDAOBean.java
@Stateless
public class ConfigurationDAOBean {

    @PersistenceContext
    private EntityManager em;

    public Configuration fetch(String item) {
        List<Configuration> results = em.createQuery("SELECT c FROM Configuration c WHERE c.name = :name", Configuration.class)
                .setParameter("name", item)
                .getResultList();
        
        if (results.isEmpty()) {
            Configuration c = new Configuration();
            c.setName(item);
            em.persist(c);
            return c;
        }
        
        return results.get(0);
    }

    public void store(Configuration c) {
        em.merge(c);
    }
}

I am open to ideas!