/** * 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.domain.channel; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.log4j.Logger; import com.redhat.rhn.domain.BaseDomainHelper; import com.redhat.rhn.domain.common.ChecksumType; import com.redhat.rhn.domain.errata.Errata; import com.redhat.rhn.domain.org.Org; import com.redhat.rhn.domain.rhnpackage.Package; import com.redhat.rhn.domain.server.Server; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.manager.channel.ChannelManager; import com.redhat.rhn.manager.system.IncompatibleArchException; import com.redhat.rhn.manager.system.SystemManager; /** * Channel * @version $Rev$ */ public class Channel extends BaseDomainHelper implements Comparable<Channel> { /** * Logger for this class */ private static Logger log = Logger.getLogger(Channel.class); public static final String PUBLIC = "public"; public static final String PROTECTED = "protected"; public static final String PRIVATE = "private"; private static List<String> archesToSkipRepodata = new ArrayList<String>(Arrays .asList("channel-sparc-sun-solaris", "channel-i386-sun-solaris", "channel-sparc")); private String baseDir; private ChannelArch channelArch; private ChecksumType checksumType; private String description; private Date endOfLife; private String GPGKeyUrl; private String GPGKeyId; private String GPGKeyFp; private Long id; private String label; private Date lastModified; private Date lastSynced; private String name; private String access = PRIVATE; private Org org; private Channel parentChannel; private ChannelProduct product; private ProductName productName; private Comps comps; private String summary; private Set<Errata> erratas = new HashSet<Errata>(); private Set<Package> packages = new HashSet<Package>(); private Set<ContentSource> sources = new HashSet<ContentSource>(); private Set<ChannelFamily> channelFamilies = new HashSet<ChannelFamily>(); private Set<DistChannelMap> distChannelMaps = new HashSet<DistChannelMap>(); private Set<Org> trustedOrgs = new HashSet<Org>(); private String maintainerName; private String maintainerEmail; private String maintainerPhone; private String supportPolicy; /** * @param orgIn what org you want to know if it is globally subscribable in * @return Returns whether or not this channel is globally subscribable. */ public boolean isGloballySubscribable(Org orgIn) { return ChannelFactory.isGloballySubscribable(orgIn, this); } /** * Sets the globally subscribable attribute for this channel * @param orgIn what org you want to set if it is globally subscribable in * @param value True if you want the channel to be globally subscribable, * false if not. */ public void setGloballySubscribable(boolean value, Org orgIn) { ChannelFactory.setGloballySubscribable(orgIn, this, value); } /** * Returns true if this Channel is a satellite channel. * @return true if this Channel is a satellite channel. */ public boolean isSatellite() { return getChannelFamily().getLabel().startsWith( ChannelFamilyFactory.SATELLITE_CHANNEL_FAMILY_LABEL); } /** * Returns true if this Channel is a Proxy channel. * @return true if this Channel is a Proxy channel. */ public boolean isProxy() { ChannelFamily cfam = getChannelFamily(); if (cfam != null) { return cfam.getLabel().startsWith( ChannelFamilyFactory.PROXY_CHANNEL_FAMILY_LABEL); } return false; } /** * Returns true if this Channel is a Rhel channel. * @return true if this Channel is a Rhel channel. */ public boolean isRhelChannel() { return org == null; } /** * Returns true if this channel is of specified release (f.e. RHEL6) * @param ver release version * @return true if this channel is of specified release */ public boolean isReleaseXChannel(Integer ver) { if (getDistChannelMaps() != null) { for (DistChannelMap map : getDistChannelMaps()) { if (map.getRelease().contains(ver.toString())) { return true; } } } return false; } /** * @return Returns the baseDir. */ public String getBaseDir() { return baseDir; } /** * @param b The baseDir to set. */ public void setBaseDir(String b) { this.baseDir = b; } /** * @return Returns the channelArch. */ public ChannelArch getChannelArch() { return channelArch; } /** * @param c The channelArch to set. */ public void setChannelArch(ChannelArch c) { this.channelArch = c; } /** * @return Returns the channelChecksum. */ public ChecksumType getChecksumType() { return checksumType; } /** * @param checksumTypeIn The checksum to set. */ public void setChecksumType(ChecksumType checksumTypeIn) { this.checksumType = checksumTypeIn; } /** * @param compsIn The Comps to set. */ public void setComps(Comps compsIn) { this.comps = compsIn; } /** * @return Returns the Comps. */ public Comps getComps() { return comps; } /** * @return Returns the description. */ public String getDescription() { return description; } /** * @param d The description to set. */ public void setDescription(String d) { this.description = d; } /** * @return Returns the endOfLife. */ public Date getEndOfLife() { return endOfLife; } /** * @param e The endOfLife to set. */ public void setEndOfLife(Date e) { this.endOfLife = e; } /** * @return Returns the gPGKeyFp. */ public String getGPGKeyFp() { return GPGKeyFp; } /** * @param k The gPGKeyFP to set. */ public void setGPGKeyFp(String k) { GPGKeyFp = k; } /** * @return Returns the gPGKeyId. */ public String getGPGKeyId() { return GPGKeyId; } /** * @param k The gPGKeyId to set. */ public void setGPGKeyId(String k) { GPGKeyId = k; } /** * @return Returns the gPGKeyUrl. */ public String getGPGKeyUrl() { return GPGKeyUrl; } /** * @param k The gPGKeyUrl to set. */ public void setGPGKeyUrl(String k) { GPGKeyUrl = k; } /** * @return Returns the id. */ public Long getId() { return id; } /** * @param i The id to set. */ public void setId(Long i) { this.id = i; } /** * @return Returns the label. */ public String getLabel() { return label; } /** * @param l The label to set. */ public void setLabel(String l) { this.label = l; } /** * @return Returns the lastModified. */ public Date getLastModified() { return lastModified; } /** * @param l The lastModified to set. */ public void setLastModified(Date l) { this.lastModified = l; } /** * @return Returns the lastSynced. */ public Date getLastSynced() { return lastSynced; } /** * @param lastSyncedIn The lastSynced to set. */ public void setLastSynced(Date lastSyncedIn) { this.lastSynced = lastSyncedIn; } /** * @return Returns the name. */ public String getName() { return name; } /** * @param n The name to set. */ public void setName(String n) { this.name = n; } /** * @return Returns the org. */ public Org getOrg() { return org; } /** * @param o The org to set. */ public void setOrg(Org o) { this.org = o; } /** * @return Returns the parentChannel. */ public Channel getParentChannel() { return parentChannel; } /** * @param p The parentChannel to set. */ public void setParentChannel(Channel p) { this.parentChannel = p; } /** * @return Returns the summary. */ public String getSummary() { return summary; } /** * @param s The summary to set. */ public void setSummary(String s) { this.summary = s; } /** * @return Returns the set of erratas for this channel. */ public Set<Errata> getErratas() { return erratas; } /** * Sets the erratas set for this channel * @param erratasIn The set of erratas */ public void setErratas(Set<Errata> erratasIn) { this.erratas = erratasIn; } /** * Adds a single errata to the channel * @param errataIn The errata to add */ public void addErrata(Errata errataIn) { erratas.add(errataIn); } /** * @deprecated Do not use this method * @return Returns the set of packages for this channel. */ @Deprecated public Set<Package> getPackages() { return packages; } /** * @return Returns the size of the package set for this channel. */ public int getPackageCount() { // we don;t want to use packages.size() // this could be a lot (we don't want to load all the packages // in Rhn-server to get a single number) ... // So we are better off using a hibernate query for the count... return ChannelFactory.getPackageCount(this); } /** * @return Returns the size of the package set for this channel. */ public int getErrataCount() { return ChannelFactory.getErrataCount(this); } /** * Sets the packages set for this channel * @param packagesIn The set of erratas */ public void setPackages(Set<Package> packagesIn) { this.packages = packagesIn; } /** * * @param sourcesIn The set of yum repo sources */ public void setSources(Set<ContentSource> sourcesIn) { this.sources = sourcesIn; } /** * * @return set of yum repos for this channel */ public Set<ContentSource> getSources() { return sources; } /** * Adds a single package to the channel * @param packageIn The package to add * @deprecated Do not use this method. */ @Deprecated public void addPackage(Package packageIn) { if (!getChannelArch().isCompatible(packageIn.getPackageArch())) { throw new IncompatibleArchException(packageIn.getPackageArch(), getChannelArch()); } packages.add(packageIn); } /** * Removes a single package from the channel * @param user the user doing the remove * @param packageIn The package to remove */ public void removePackage(Package packageIn, User user) { List<Long> list = new ArrayList<Long>(); list.add(packageIn.getId()); ChannelManager.removePackages(this, list, user); } /** * Some methods for hibernate to get and set channel families. However, * there should be only one channel family per channel. */ /** * @return Returns the set of channelFamiliess for this channel. */ public Set<ChannelFamily> getChannelFamilies() { return channelFamilies; } /** * Sets the channelFamilies set for this channel * @param channelFamiliesIn The set of channelFamilies */ public void setChannelFamilies(Set<ChannelFamily> channelFamiliesIn) { if (channelFamiliesIn.size() > 1) { throw new TooManyChannelFamiliesException(this.getId(), "A channel can only have one channel family"); } this.channelFamilies = channelFamiliesIn; } /** * * @param trustedOrgsIn set of trusted orgs for this channel */ public void setTrustedOrgs(Set<Org> trustedOrgsIn) { this.trustedOrgs = trustedOrgsIn; } /** * * @return set of trusted orgs for this channel */ public Set<Org> getTrustedOrgs() { return this.trustedOrgs; } /** * @return number of trusted organizations that have access to this channel */ public int getTrustedOrgsCount() { if (trustedOrgs != null) { return trustedOrgs.size(); } return 0; } /** * Adds a single channelFamily to the channel * @param channelFamilyIn The channelFamily to add */ public void addChannelFamily(ChannelFamily channelFamilyIn) { if (this.getChannelFamilies().size() > 0) { throw new TooManyChannelFamiliesException(this.getId(), "A channel can only have one channel family"); } channelFamilies.add(channelFamilyIn); } /** * Set the channel family for this channel. * @param channelFamilyIn The channelFamily to add */ public void setChannelFamily(ChannelFamily channelFamilyIn) { channelFamilies.clear(); this.addChannelFamily(channelFamilyIn); } /** * Get the channel family for this channel. * @return the channel's family, or null if none found */ public ChannelFamily getChannelFamily() { if (this.getChannelFamilies().size() == 1) { Object[] cfams = this.getChannelFamilies().toArray(); return (ChannelFamily) cfams[0]; } return null; } /** * Returns true if this channel is considered a base channel. * @return true if this channel is considered a base channel. */ public boolean isBaseChannel() { return (getParentChannel() == null); } /** * Returns true if this channel is a cloned channel. * @return whether the channel is cloned or not */ public boolean isCloned() { return false; } /** * {@inheritDoc} */ public boolean equals(final Object other) { if (other instanceof SelectableChannel) { return this.equals(((SelectableChannel)other).getChannel()); } if (!(other instanceof Channel)) { return false; } Channel castOther = (Channel) other; return new EqualsBuilder().append(getId(), castOther.getId()).isEquals(); } /** * {@inheritDoc} */ public int hashCode() { return new HashCodeBuilder().append(getId()).toHashCode(); } /** * @return Returns the product. */ public ChannelProduct getProduct() { return product; } /** * @param productIn The product to set. */ public void setProduct(ChannelProduct productIn) { this.product = productIn; } /** * @return Returns the distChannelMaps. */ public Set<DistChannelMap> getDistChannelMaps() { return distChannelMaps; } /** * @param distChannelMapsIn The distChannelMaps to set. */ public void setDistChannelMaps(Set<DistChannelMap> distChannelMapsIn) { this.distChannelMaps = distChannelMapsIn; } /** * Check if this channel is subscribable by the Org passed in. Checks: * * 1) If channel is a Proxy or Spacewalk channel == false 2) If channel has * 0 (or less) available subscriptions == false. * * @param orgIn to check available subs * @param server to check if subscribable * @return boolean if subscribable or not */ public boolean isSubscribable(Org orgIn, Server server) { if (log.isDebugEnabled()) { log.debug("isSubscribable.archComp: " + SystemManager.verifyArchCompatibility(server, this)); log.debug("isProxy: " + this.isProxy()); log.debug("isSatellite: " + this.isSatellite()); } return (SystemManager.verifyArchCompatibility(server, this) && !this.isProxy() && !this .isSatellite()); } /** * {@inheritDoc} */ public String toString() { return new ToStringBuilder(this).append("id", id).append("label", label).toString(); } /** * @return the productName */ public ProductName getProductName() { return productName; } /** * @param productNameIn the productName to set */ public void setProductName(ProductName productNameIn) { this.productName = productNameIn; } /** * Returns true if the access provided is a valid value. * @param acc the access value being checked * @return true if the access provided is valid */ public boolean isValidAccess(String acc) { if (acc.equals(Channel.PUBLIC) || acc.equals(Channel.PRIVATE) || acc.equals(Channel.PROTECTED)) { return true; } return false; } /** *@param acc public, protected, or private */ public void setAccess(String acc) { access = acc; } /** * @return public, protected, or private */ public String getAccess() { return access; } /** * * @return wheter channel is protected */ public boolean isProtected() { return this.getAccess().equals(Channel.PROTECTED); } /** * Returns the child channels associated to a base channel * @param user the User needed for accessibility issues * @return a list of child channels or empty list if there are none. */ public List<Channel> getAccessibleChildrenFor(User user) { if (isBaseChannel()) { return ChannelFactory.getAccessibleChildChannels(this, user); } return new ArrayList<Channel>(); } /** * {@inheritDoc} */ public int compareTo(Channel o) { return this.getName().compareTo(o.getName()); } /** * @return maintainer's name */ public String getMaintainerName() { return maintainerName; } /** * @return maintainer's email */ public String getMaintainerEmail() { return maintainerEmail; } /** * @return maintainer's phone number */ public String getMaintainerPhone() { return maintainerPhone; } /** * @return channel's support policy */ public String getSupportPolicy() { return supportPolicy; } /** * @param mname maintainer's name */ public void setMaintainerName(String mname) { maintainerName = mname; } /** * @param email maintainer's email */ public void setMaintainerEmail(String email) { maintainerEmail = email; } /** * @param phone maintainer's phone number (string) */ public void setMaintainerPhone(String phone) { maintainerPhone = phone; } /** * @param policy channel support policy */ public void setSupportPolicy(String policy) { supportPolicy = policy; } /** * Created for taskomatic -- probably shouldn't be called from the webui * @return returns if custom channel */ public boolean isCustom() { return getOrg() != null; } /** * Does this channel need repodata generated * @return Returns a boolean if repodata generation Required */ public boolean isChannelRepodataRequired() { // generate repodata for all channels having channel checksum set except solaris if (archesToSkipRepodata.contains(this.channelArch.getLabel())) { return true; } return checksumType != null; } /** * true if the channel contains any kickstartstartable distros * @return true if the channel contains any distros. */ public boolean containsDistributions() { return ChannelFactory.containsDistributions(this); } /** * get the compatible checksum type to be used for repomd.xml * based on channel release. * If its a custom channel use the checksum_type_id from db set at creation time * If its RHEL-5 we use sha1 anything newer will be sha256. * @return checksumType */ public String getChecksumTypeLabel() { if ((checksumType == null) || (checksumType.getLabel() == null)) { // each channel shall have set checksumType return null; } return checksumType.getLabel(); } /** * @return the original Channel the channel was cloned from */ public Channel getOriginal() { throw new UnsupportedOperationException(); } }