Directory

← Back

Ilves

Ilves is a feature packed seed for responsive web apps. If JEE portal feels too heavy for you then Ilves may be a better fit for your project.

Author

Rating

Popularity

<100

Ilves enables lean development and deployment of responsive web apps:

  • minimizing Zero Sprint length (embedded jetty and WAR seed projects),
  • accelerating development cycles (embedded web server),
  • catering for common functionality (built-in features),
  • minimizing web UI code complexity (Vaadin framework) and
  • enabling one step cloud deployment (Heroku) or
  • easy setup to other cloud environments like Amazon AWS.

Features and architecture details are available at Ilves Wiki which you can find from Links section of this page.

Feature highlight: FIDO U2F login support. Feature highlight: GitHub OAuth login support. Feature highlight: Google Authenticator two factor login support.

Please take look at "5 minute tutorial" for detailed description about development cycle.

Sample code

package org.bubblecloud.ilves.comment;

import com.vaadin.server.VaadinService;
import com.vaadin.ui.*;
import org.apache.commons.lang3.StringUtils;
import org.vaadin.addons.sitekit.model.Company;
import org.vaadin.addons.sitekit.model.User;
import org.vaadin.addons.sitekit.site.DefaultSiteUI;
import org.vaadin.addons.sitekit.site.Site;

import javax.persistence.EntityManager;

/**
 * Example comment component implementation.
 */
public class CommentAddComponent extends CustomComponent {

    private CommentListComponent commentListComponent;

    /**
     * The default constructor which instantiates Vaadin
     * component hierarchy.
     */
    public CommentAddComponent() {

        final User user = DefaultSiteUI.getSecurityProvider().getUserFromSession();

        final String contextPath = VaadinService.getCurrentRequest().getContextPath();
        final Site site = Site.getCurrent();

        final Company company = site.getSiteContext().getObject(Company.class);
        final EntityManager entityManager = site.getSiteContext().getObject(EntityManager.class);

        final Panel panel = new Panel(site.localize("panel-add-comment"));
        setCompositionRoot(panel);

        final VerticalLayout mainLayout = new VerticalLayout();
        panel.setContent(mainLayout);
        mainLayout.setMargin(true);
        mainLayout.setSpacing(true);

        final TextArea commentMessageField = new TextArea(site.localize("field-comment-message"));
        mainLayout.addComponent(commentMessageField);
        commentMessageField.setWidth(100, Unit.PERCENTAGE);
        commentMessageField.setRows(3);
        commentMessageField.setMaxLength(255);

        final Button addCommentButton = new Button(site.localize("button-add-comment"));
        mainLayout.addComponent(addCommentButton);
        if (user == null) {
            commentMessageField.setEnabled(false);
            commentMessageField.setInputPrompt(site.localize("message-please-login-to-comment"));
            addCommentButton.setEnabled(false);
        }

        addCommentButton.addClickListener(new Button.ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                final String commentMessage = commentMessageField.getValue();
                if (StringUtils.isEmpty(commentMessage)) {
                    return;
                }
                final Comment comment = new Comment(company, user, contextPath, commentMessage);
                entityManager.getTransaction().begin();
                try {
                    entityManager.persist(comment);
                    entityManager.getTransaction().commit();
                    commentMessageField.setValue("");
                    if (commentListComponent != null) {
                        commentListComponent.refresh();
                    }
                } finally {
                    if (entityManager.getTransaction().isActive()) {
                        entityManager.getTransaction().rollback();
                    }
                }
            }
        });

    }

    /**
     * @return the comment list component
     */
    public CommentListComponent getCommentListComponent() {
        return commentListComponent;
    }

    /**
     * @param commentListComponent the comment list component to set
     */
    public void setCommentListComponent(final CommentListComponent commentListComponent) {
        this.commentListComponent = commentListComponent;
    }
}
package org.bubblecloud.ilves.comment;

import com.vaadin.server.VaadinService;
import com.vaadin.ui.*;
import com.vaadin.ui.themes.ValoTheme;
import org.vaadin.addons.sitekit.model.Company;
import org.vaadin.addons.sitekit.site.Site;
import org.vaadin.addons.sitekit.util.GravatarUtil;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.List;

/**
 * Example comment list component implementation.
 */
public class CommentListComponent extends CustomComponent {

    public CommentListComponent() {
    }

    @Override
    public void attach() {
        super.attach();

        refresh();
    }

    public void refresh() {

        final String contextPath = VaadinService.getCurrentRequest().getContextPath();
        final Site site = Site.getCurrent();

        final Company company = site.getSiteContext().getObject(Company.class);
        final EntityManager entityManager = site.getSiteContext().getObject(EntityManager.class);

        final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        final CriteriaQuery<Comment> commentCriteriaQuery = builder.createQuery(Comment.class);
        final Root<Comment> commentRoot = commentCriteriaQuery.from(Comment.class);
        commentCriteriaQuery.where(builder.and(
                builder.equal(commentRoot.get("owner"), company),
                builder.equal(commentRoot.get("dataId"), contextPath)
        ));
        commentCriteriaQuery.orderBy(builder.asc(commentRoot.get("created")));

        final TypedQuery<Comment> commentTypedQuery = entityManager.createQuery(commentCriteriaQuery);
        final List<Comment> commentList = commentTypedQuery.getResultList();

        final Panel panel = new Panel(site.localize("panel-comments"));
        setCompositionRoot(panel);

        final GridLayout gridLayout = new GridLayout(3, commentList.size() + 1);
        panel.setContent(gridLayout);
        gridLayout.setSpacing(true);
        gridLayout.setMargin(true);
        gridLayout.setColumnExpandRatio(0, 0.0f);
        gridLayout.setColumnExpandRatio(1, 0.1f);
        gridLayout.setColumnExpandRatio(2, 0.9f);

        final Label authorHeaderLabel = new Label();
        authorHeaderLabel.setStyleName(ValoTheme.LABEL_BOLD);
        authorHeaderLabel.setValue(site.localize("column-header-author"));
        gridLayout.addComponent(authorHeaderLabel, 0, 0, 1, 0);

        final Label commentHeaderLabel = new Label();
        commentHeaderLabel.setStyleName(ValoTheme.LABEL_BOLD);
        commentHeaderLabel.setValue(site.localize("column-header-comment"));
        gridLayout.addComponent(commentHeaderLabel, 2, 0);

        for (int i = 0; i < commentList.size(); i++) {
            final Comment comment = commentList.get(i);

            final Link authorImageLink = GravatarUtil.getGravatarImageLink(comment.getAuthor().getEmailAddress());
            gridLayout.addComponent(authorImageLink, 0, i + 1);

            final Label authorLabel = new Label();
            final String authorName = comment.getAuthor().getFirstName();
            authorLabel.setValue(authorName);
            gridLayout.addComponent(authorLabel, 1, i + 1);

            final Label messageLabel = new Label();
            messageLabel.setValue(comment.getMessage());
            gridLayout.addComponent(messageLabel, 2, i + 1);
        }

    }
}

Compatibility

(Loading compatibility data...)

Was this helpful? Need more help?
Leave a comment or a question below. You can also join the chat on Discord or ask questions on StackOverflow.

Version

  • Added security layer audit trail.
  • Refactored package structures.
  • Refactored theme.
  • Improved wiki on page editing.
  • Added HTML escaping to Wiki markup.
  • Added WAR project seed.
  • Added on demand command line SASS compiler to seed projects.
  • Added command line generator for generating liquibase change XML from JPA model changes.
Released
2014-12-21
Maturity
STABLE
License
Apache License 2.0

Compatibility

Framework
Vaadin 7.3+
Vaadin 7.4+ in 4.0.6
Vaadin 7.6+ in 4.1.6
Browser
Browser Independent

Vaadin Add-on Directory

Find open-source widgets, add-ons, themes, and integrations for your Vaadin application. Vaadin Add-on Directory
The channel for finding, promoting, and distributing Vaadin add-ons.
Online