nl.strohalm.cyclos.entities.ads.AdCategory.java Source code

Java tutorial

Introduction

Here is the source code for nl.strohalm.cyclos.entities.ads.AdCategory.java

Source

/*
This file is part of Cyclos (www.cyclos.org).
A project of the Social Trade Organisation (www.socialtrade.org).
    
Cyclos is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
    
Cyclos is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with Cyclos; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    
 */
package nl.strohalm.cyclos.entities.ads;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import nl.strohalm.cyclos.entities.Entity;
import nl.strohalm.cyclos.entities.Relationship;

import org.apache.commons.collections.CollectionUtils;

/**
 * A hierarchical ad category
 * @author luis
 */
public class AdCategory extends Entity implements Comparable<AdCategory> {

    public static enum Relationships implements Relationship {
        PARENT("parent"), CHILDREN("children");
        private final String name;

        private Relationships(final String name) {
            this.name = name;
        }

        @Override
        public String getName() {
            return name;
        }
    }

    /**
     * The maximum level for nesting categories<br>
     * Note: take into account the calculations in getGlobalOrder when increasing MAX_LEVEL. MAX_LEVEL cannot be increased infinitely.
     */
    public static final int MAX_LEVEL = 3;

    private static final long serialVersionUID = -4371587757348684782L;
    private String name;
    private AdCategory parent;
    private Collection<AdCategory> children;
    private boolean active;
    private Integer order = 0;
    private BigInteger globalOrder;

    @Override
    public int compareTo(final AdCategory other) {
        return getFullName().compareTo(other.getFullName());
    }

    public Collection<AdCategory> getChildren() {
        return children;
    }

    public String getFullName() {
        if (parent == null) {
            return name;
        } else {
            return parent.getFullName() + ": " + name;
        }
    }

    public String getFullNameButRoot() {
        if (getLevel() <= 2) {
            return name;
        } else {
            return parent.getFullNameButRoot() + ": " + name;
        }
    }

    /**
     * returns a BigInteger indicating the global order index of the category. In the global order, whenever an item with children is encountered, all
     * child nodes are first handled before going on with the next item/node on the same level.<br>
     * Note that this method only works correctly with a maximum of 999 subcategories for a certain category.
     * @author rinke
     */
    public BigInteger getGlobalOrder() {
        if (globalOrder == null) {
            final int correctedLevel = AdCategory.MAX_LEVEL - getLevel();
            final BigInteger levelFactor = new BigInteger("1000").pow(correctedLevel);
            // specified indexes are always > 0. Unspecified indexes of 0 mess up the calculation, so...
            final Integer index = (getOrder() == 0) ? 1 : getOrder();
            final BigInteger parentGlobalOrder = (getParent() == null) ? BigInteger.ZERO
                    : getParent().getGlobalOrder();
            globalOrder = parentGlobalOrder.add(levelFactor.multiply(new BigInteger(index.toString())));
        }
        return globalOrder;
    }

    public int getLevel() {
        if (parent == null) {
            return 1;
        }
        return 1 + parent.getLevel();
    }

    @Override
    public String getName() {
        return name;
    }

    public Integer getOrder() {
        return order;
    }

    public AdCategory getParent() {
        return parent;
    }

    /**
     * Returns a list, beggining of the level 1 category to this one
     */
    public List<AdCategory> getPathFromRoot() {
        final List<AdCategory> path = new ArrayList<AdCategory>();
        AdCategory current = this;
        while (current != null) {
            path.add(current);
            current = current.getParent();
        }
        Collections.reverse(path);
        return path;
    }

    public AdCategory getRootCategory() {
        if (parent == null) {
            return this;
        }
        return parent.getRootCategory();
    }

    /**
     * tests if the category is disabled or not. Note that it does not test this for parent categories. If any parent category is disabled, then
     * logically the child categories are also disabled, even if this is not always updated to these child categories. For this reason, in particular
     * cases it's better to use {@link #isEnabled()}.
     * @return true if the category is not disabled.
     */
    public boolean isActive() {
        return active;
    }

    /**
     * tests if this category or any of its parents is active. If a parent category is disabled, then logically the child categories are also
     * disabled, even though these might not be updated. For this reason, this method might be more appropriate than {@link #isActive()}.
     * @return true if and only if this category and all of it's parents in line are active.
     */
    public boolean isEnabled() {
        AdCategory current = this;
        while (current != null) {
            if (!current.isActive()) {
                return false;
            }
            current = current.getParent();
        }
        return true;
    }

    public boolean isLeaf() {
        return CollectionUtils.isEmpty(children);
    }

    public boolean isRoot() {
        return parent == null;
    }

    public void setActive(final boolean active) {
        this.active = active;
        globalOrder = null;
    }

    public void setChildren(final Collection<AdCategory> children) {
        this.children = children;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public void setOrder(final Integer orderIndex) {
        order = orderIndex;
        globalOrder = null;
    }

    public void setParent(final AdCategory parent) {
        this.parent = parent;
        globalOrder = null;
    }

    @Override
    public String toString() {
        return getId() + " - " + name;
    }
}