/**
* Copyright (c) 2009--2014 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package com.redhat.rhn.frontend.dto;
import java.util.ArrayList;
import java.util.List;
import com.redhat.rhn.common.db.datasource.DataResult;
import com.redhat.rhn.common.localization.LocalizationService;
import com.redhat.rhn.domain.channel.Channel;
import com.redhat.rhn.domain.channel.ChannelFactory;
import com.redhat.rhn.frontend.filter.DepthAware;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* ChannelTreeNode
* @version $Rev$
*/
public class ChannelTreeNode extends BaseDto implements BaseListDto,
DepthAware,
Comparable<ChannelTreeNode> {
private Long id;
private String name;
private Long channelArchId;
private Long packageCount;
private Long systemCount;
private Long errataCount;
private String channelLabel;
private Long channelFamilyId;
private Long channelFamilySearchedFor;
private boolean accessible = true;
private Long parentId;
private Long orgId;
private String orgName;
private String archName;
/**
* Handle the orphan'd child channels by adding a "fake" node
* This is done because a child can be viewable when the parent is not
* @param result list of nodes to solve
*/
public static void processList(DataResult<ChannelTreeNode> result) {
DataResult<ChannelTreeNode> toReturn =
new DataResult<ChannelTreeNode>(new ArrayList());
toReturn.setFilter(true);
toReturn.setFilterData(result.getFilterData());
//We want the orphans to be at the end of the list, so lets add them here
// and then add them to the whole list later
List<ChannelTreeNode> orphans = new ArrayList<ChannelTreeNode>();
ChannelTreeNode lastParent = null;
ChannelTreeNode lastOrphan = null;
for (ChannelTreeNode node : result) {
//if the node is a parent, mark it as last and move on
if (node.isParent()) {
lastParent = node;
toReturn.add(node);
} //if the node is a child of previous parent, move on
else if (lastParent != null && node.getParentId().
equals(lastParent.getId())) {
toReturn.add(node);
} //else we couldn't find the previous parent (so it's probably not here :{)
else {
//If this is the first orphan or the parent of the last orphan doesn't
// match this orphan's parent, then we need to add a node for the
// restriciton
if (lastOrphan == null ||
!lastOrphan.getParentId().equals(node.getParentId())) {
orphans.add(newRestrictedParent(node));
orphans.add(node);
}
//this orphan has the same parent as the last, so no new dummy node
else {
orphans.add(node);
}
lastOrphan = node;
}
}
toReturn.addAll(orphans);
result.clear();
result.addAll(toReturn);
result.setTotalSize(toReturn.size());
}
private static ChannelTreeNode newRestrictedParent(ChannelTreeNode child) {
ChannelTreeNode parent = new ChannelTreeNode();
parent.setAccessible(false);
parent.setName(LocalizationService.getInstance().getMessage("channel.unavailable"));
parent.setId(child.getParentId());
parent.setParentId(null);
return parent;
}
/**
* @return Returns the parentId.
*/
public Long getParentId() {
return parentId;
}
/**
* @param parentIdIn The parentId to set.
*/
public void setParentId(Long parentIdIn) {
this.parentId = parentIdIn;
}
/**
* @return Returns the channelFamilySearchedFor.
*/
public Long getChannelFamilySearchedFor() {
return channelFamilySearchedFor;
}
/**
* @param channelFamilySearchedForIn The channelFamilySearchedFor to set.
*/
public void setChannelFamilySearchedFor(Long channelFamilySearchedForIn) {
this.channelFamilySearchedFor = channelFamilySearchedForIn;
}
/**
* {@inheritDoc}
*/
public Long getId() {
return id;
}
/**
* @param idIn channel id
*/
public void setId(Long idIn) {
id = idIn;
}
/**
* retrieves the name of the channel
* @return name
*/
public String getName() {
return name;
}
/**
* retrieves the name of the channel
* @return name
*/
public String getUpperName() {
return this.getName().toUpperCase();
}
/**
* @return Returns the channelArchId.
*/
public Long getChannelArchId() {
return channelArchId;
}
/**
* @param channelArchIdIn The channelArchId to set.
*/
public void setChannelArchId(Long channelArchIdIn) {
this.channelArchId = channelArchIdIn;
}
/**
* @return Returns the channelLabel.
*/
public String getChannelLabel() {
return channelLabel;
}
/**
* @param channelLabelIn The channelLabel to set.
*/
public void setChannelLabel(String channelLabelIn) {
this.channelLabel = channelLabelIn;
}
/**
* @return Returns the depth.
*/
public Long getDepth() {
//if it's a parent, the depth is 1
if (parentId == null) {
return 1L;
} //if it's a child the depth is 2
return 2L;
}
/**
* @return Returns the packageCount.
*/
public Long getPackageCount() {
return packageCount;
}
/**
* @param packageCountIn The packageCount to set.
*/
public void setPackageCount(Long packageCountIn) {
this.packageCount = packageCountIn;
}
/**
* @param nameIn The name to set.
*/
public void setName(String nameIn) {
this.name = nameIn;
}
/**
* @return Returns the systemCount.
*/
public Long getSystemCount() {
return systemCount;
}
/**
* @param systemCountIn The systemCount to set.
*/
public void setSystemCount(Long systemCountIn) {
this.systemCount = systemCountIn;
}
/**
* {@inheritDoc}
*/
public boolean changeRowColor() {
return !(this.getDepth() > 1);
}
/**
* {@inheritDoc}
*/
public boolean greyOutRow() {
if (channelFamilyId == null || channelFamilySearchedFor == null) {
return false;
}
return !channelFamilyId.equals(channelFamilySearchedFor);
}
/**
* {@inheritDoc}
*/
public String getNodeIdString() {
if (parentId != null) {
return "c" + id;
}
return "p" + id;
}
/**
* @return Returns the channelFamilyId.
*/
public Long getChannelFamilyId() {
return channelFamilyId;
}
/**
* @param channelFamilyIdIn The channelFamilyId to set.
*/
public void setChannelFamilyId(Long channelFamilyIdIn) {
this.channelFamilyId = channelFamilyIdIn;
}
/**
* @return Returns the parentOrSelfId.
*/
public Long getParentOrSelfId() {
if (isParent()) {
return id;
}
return parentId;
}
/**
* {@inheritDoc}
*/
public String toString() {
return new ToStringBuilder(this).
append("id", id).append("name", name).toString();
}
/**
* If we want to allow users to view this channel or not.
* @param accessibleIn or not.
*/
public void setAccessible(boolean accessibleIn) {
this.accessible = accessibleIn;
}
/**
* Get if we should let the user see this channel or not. Defaults
* to true.
* @return if accessible
*/
public boolean getAccessible() {
return this.accessible;
}
/**
* Returns <code>true</code> if this node is a parent channel node, <code>false</code>
* otherwise. A node is considered a parent if its <code>depth</code> is 1 and its
* <code>id</code> and <code>parentOrSelfId</code> properties have the same value.
*
* @return <code>true</code> if this node is a parent node, <code>false</code>
* otherwise.
*/
public boolean isParent() {
return parentId == null;
}
/**
*
* {@inheritDoc}
*/
public boolean equals(Object object) {
if (object == null || !getClass().equals(object.getClass())) {
return false;
}
ChannelTreeNode that = (ChannelTreeNode)object;
return new EqualsBuilder().append(this.id, that.id).isEquals();
}
/**
*
* {@inheritDoc}
*/
public int hashCode() {
return new HashCodeBuilder().append(this.id).toHashCode();
}
/**
*
* {@inheritDoc}
*/
public long depth() {
return getDepth().longValue();
}
/**
* Used mainly for sorting so it is in a nice order.
*
* {@inheritDoc}
*/
public int compareTo(ChannelTreeNode arg0) {
//if they are both parents, just sort by name
if (this.isParent() && arg0.isParent()) {
return this.getUpperName().compareTo(arg0.getUpperName());
}
//if none of them are parents
if (!this.isParent() && !arg0.isParent()) {
//if they have the same parent
if (this.getParentOrSelfId().equals(arg0.getParentOrSelfId())) {
return this.getUpperName().compareTo(arg0.getUpperName());
}
Channel one = ChannelFactory.lookupById(this.getParentOrSelfId());
Channel two = ChannelFactory.lookupById(arg0.getParentOrSelfId());
return one.getName().toUpperCase().compareTo(two.getName().toUpperCase());
}
//If the first one is a parent, but the 2nd one isn't
if (this.isParent() && !arg0.isParent()) {
//if a is a parent of b
if (this.getId().equals(arg0.getParentOrSelfId())) {
return -1;
}
Channel two = ChannelFactory.lookupById(arg0.getParentOrSelfId());
return this.getUpperName().compareTo(two.getName().toUpperCase());
}
if (!this.isParent() && arg0.isParent()) {
//is b a parent of a
if (this.getParentOrSelfId().equals(arg0.getId())) {
return 1;
} //else if this is just some random child
Channel two = ChannelFactory.lookupById(parentId);
return two.getName().toUpperCase().compareTo(arg0.getUpperName());
}
return 0;
}
/**
* Get the channel's org id.
* @return The channel's org id.
*/
public Long getOrgId() {
return orgId;
}
/**
* Set the channel's org id.
* @param orgid The channel's org id.
*/
public void setOrgId(Long orgid) {
orgId = orgid;
}
/**
* Get the channel's org name.
* @return The channel's org name.
*/
public String getOrgName() {
return orgName;
}
/**
* Set the channel's org name.
* @param orgname An channel's org name.
*/
public void setOrgName(String orgname) {
orgName = orgname;
}
/**
* @return Returns the archName.
*/
public String getArchName() {
return archName;
}
/**
* @param archNameIn The archName to set.
*/
public void setArchName(String archNameIn) {
this.archName = archNameIn;
}
/**
* @return errata count for channel
*/
public Long getErrataCount() {
return errataCount;
}
/**
* @param errataCountIn errata count to set
*/
public void setErrataCount(Long errataCountIn) {
this.errataCount = errataCountIn;
}
}