/* vim: set ts=2 et sw=2 cindent fo=qroca: */ package com.globant.katari.gadgetcontainer.domain; import org.apache.commons.lang.Validate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashSet; import java.util.Set; import java.util.Collections; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.JoinColumn; import javax.persistence.Table; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorType; import com.globant.katari.shindig.domain.Application; /** Represents a group of gadgets that can be displayed on a web page. * * Gadgets are intended to be shown in a page in a column layout. Each gadget * defines the column and the position (order) in that column. * * This is an abstract base class. Subclasses implements specific behaviour for * gadget groups, like templates and customization. */ @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "group_type", discriminatorType = DiscriminatorType.STRING) @Table(name = "gadget_groups") public abstract class GadgetGroup { /** The class logger. */ private static Logger log = LoggerFactory.getLogger(GadgetGroup.class); /** The id of the gadget group, 0 for a newly created gadget group. */ @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; /** The name of the group. * * This is never null. */ @Column(nullable = false) private String name; /** The view of this gadget group. * * This will only hold gadgtes that support this view or the default view. It * is never null. */ @Column(name = "view_name", nullable = false) private String view; /** The gadgets in this group. * * It is never null. */ @OneToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL }) @JoinColumn(name = "gadget_group_id") private Set<GadgetInstance> gadgets = new HashSet<GadgetInstance>(); /** The number of columns of the gadget group. */ @Column(name = "number_of_columns", nullable = false) private int numberOfColumns = 1; /** Hibernate constructor. */ GadgetGroup() { } /** Constructor. * * @param groupName name of the group. It cannot be null * * @param viewName name of the view. This gadget will only contain gadgets * that support this view or the default view. It cannot be null * * @param columns the number of columns in the group. It must be 1 or * greater. */ public GadgetGroup(final String groupName, final String viewName, final int columns) { Validate.notEmpty(groupName, "Group name can not be null nor empty."); Validate.notEmpty(viewName, "View name can not be null nor empty."); Validate.isTrue(columns >= 1, "Number of columns must be 1 or greater."); name = groupName; view = viewName; numberOfColumns = columns; } /** Obtains the group id. * * @return the id, 0 for a newly created object. */ public long getId() { return id; } /** Obtains the group name. * * @return the group name, never null. */ public String getName() { return name; } /** Returns the name of the view. * * This gadget will only contain gadgets that support this view or the * default view. * * @return the view name, never null. */ public String getView() { return view; } /** Returns an unmodifiable view of the gadget instances of this group. * * @return the gadgets. It never returns null. */ public Set<GadgetInstance> getGadgets() { return Collections.unmodifiableSet(gadgets); } /** Returns the number of columns. * * @return the number of columns, 1 or greater. */ public int getNumberOfColumns() { return numberOfColumns; } /** Finds if there is a gadget in the group for the application. * * @param application The application to look for in the gadget group. It * cannot be null. * * @return true if the application was found in the group, false otherwise. */ public boolean contains(final Application application) { log.trace("Entering contains"); Validate.notNull(application, "The application cannot be null."); for (GadgetInstance instance: getGadgets()) { if (application.getUrl().equals(instance.getApplication().getUrl())) { // The application is already in the group. log.trace("Leaving contains with true"); return true; } } log.trace("Leaving contains with false"); return false; } /** Adds a gadget to the group. * * @param instance the gadget instance to add to the group. It cannot be * null. The gadget must support the groups view. */ protected void add(final GadgetInstance instance) { Validate.notNull(instance, "The instance cannot be null"); Validate.isTrue(instance.getApplication().isViewSupported(view), "The gadget " + instance.getApplication().getUrl() + " does not support group " + name + "'s view."); gadgets.add(instance); } /** Removes a gadget from the group. * * @param instance the gadget instance to remove from the group. It cannot be * null. */ protected void remove(final GadgetInstance instance) { Validate.notNull(instance, "The instance cannot be null"); gadgets.remove(instance); } /** Tells if this gadget group is customizable. * * A customizable gadget group allows the user to move, add and remove * gadgets. * * @return true if the gadget group is customizable, false otherwise. */ public abstract boolean isCustomizable(); }