/**
* Copyright (c) 2009--2015 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.
*/
/*
* Copyright (c) 2010 SUSE LLC
*/
package com.redhat.rhn.domain.errata;
import com.redhat.rhn.common.db.DatabaseException;
import com.redhat.rhn.common.db.datasource.DataResult;
import com.redhat.rhn.common.db.datasource.ModeFactory;
import com.redhat.rhn.common.db.datasource.SelectMode;
import com.redhat.rhn.common.db.datasource.WriteMode;
import com.redhat.rhn.common.hibernate.HibernateFactory;
import com.redhat.rhn.common.hibernate.HibernateRuntimeException;
import com.redhat.rhn.domain.channel.Channel;
import com.redhat.rhn.domain.channel.ChannelFactory;
import com.redhat.rhn.domain.common.ChecksumFactory;
import com.redhat.rhn.domain.errata.impl.PublishedBug;
import com.redhat.rhn.domain.errata.impl.PublishedClonedErrata;
import com.redhat.rhn.domain.errata.impl.PublishedErrata;
import com.redhat.rhn.domain.errata.impl.PublishedErrataFile;
import com.redhat.rhn.domain.errata.impl.UnpublishedBug;
import com.redhat.rhn.domain.errata.impl.UnpublishedClonedErrata;
import com.redhat.rhn.domain.errata.impl.UnpublishedErrata;
import com.redhat.rhn.domain.errata.impl.UnpublishedErrataFile;
import com.redhat.rhn.domain.org.Org;
import com.redhat.rhn.domain.rhnpackage.Package;
import com.redhat.rhn.domain.rhnpackage.PackageFactory;
import com.redhat.rhn.domain.user.User;
import com.redhat.rhn.frontend.action.channel.manage.PublishErrataHelper;
import com.redhat.rhn.frontend.dto.ErrataOverview;
import com.redhat.rhn.frontend.dto.ErrataPackageFile;
import com.redhat.rhn.frontend.dto.OwnedErrata;
import com.redhat.rhn.frontend.dto.PackageOverview;
import com.redhat.rhn.frontend.xmlrpc.InvalidChannelException;
import com.redhat.rhn.manager.channel.ChannelManager;
import com.redhat.rhn.manager.errata.ErrataManager;
import com.redhat.rhn.manager.errata.cache.ErrataCacheManager;
import org.apache.commons.collections.IteratorUtils;
import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
/**
* ErrataFactory - the singleton class used to fetch and store
* com.redhat.rhn.domain.errata.Errata objects from the
* database.
* @version $Rev$
*/
public class ErrataFactory extends HibernateFactory {
private static ErrataFactory singleton = new ErrataFactory();
private static Logger log = Logger.getLogger(ErrataFactory.class);
public static final String ERRATA_TYPE_BUG = "Bug Fix Advisory";
public static final String ERRATA_TYPE_ENHANCEMENT = "Product Enhancement Advisory";
public static final String ERRATA_TYPE_SECURITY = "Security Advisory";
private ErrataFactory() {
super();
}
/**
* Get the Logger for the derived class so log messages
* show up on the correct class
*/
@Override
protected Logger getLogger() {
return log;
}
/**
* List the package ids that were pushed to a channel because of an errata
* @param cid the channel id
* @param eid the errata id
* @return List of package ids
*/
public static List<Long> listErrataChannelPackages(Long cid, Long eid) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("channel_id", cid);
params.put("errata_id", eid);
DataResult<ErrataPackageFile> dr = executeSelectMode(
"ErrataCache_queries",
"package_associated_to_errata_and_channel", params);
List toReturn = new ArrayList<Long>();
for (ErrataPackageFile file : dr) {
toReturn.add(file.getPackageId());
}
return toReturn;
}
/**
* Tries to locate errata based on either the errataum's id or the
* CVE/CAN identifier string.
* @param identifier erratum id or CVE/CAN id string
* @return list of erratas found
*/
public static List lookupByIdentifier(String identifier) {
Long eid = null;
List retval = new LinkedList();
Errata errata = null;
try {
eid = new Long(Long.parseLong(identifier));
}
catch (NumberFormatException e) {
eid = null;
}
if (eid != null) {
errata = ErrataFactory.lookupPublishedErrataById(eid);
if (errata != null) {
retval.add(errata);
}
}
else if (identifier.length() > 4) {
String prefix = null;
errata = ErrataFactory.lookupByAdvisoryId(identifier);
if (errata != null) {
retval.add(errata);
}
else {
errata = ErrataFactory.lookupByAdvisory(identifier);
if (errata != null) {
retval.add(errata);
}
}
if (errata == null) {
prefix = identifier.substring(0, 4);
if (prefix.matches("RH.A")) {
StringTokenizer strtok = new StringTokenizer(identifier, "-");
StringBuilder buf = new StringBuilder();
boolean foundFirst = false;
while (strtok.hasMoreTokens()) {
buf.append(strtok.nextToken());
if (!foundFirst) {
buf.append("-");
foundFirst = true;
}
else {
if (strtok.hasMoreTokens()) {
buf.append(":");
}
}
}
identifier = buf.toString();
errata = ErrataFactory.lookupByAdvisoryId(identifier);
}
if (errata != null) {
retval.add(errata);
}
}
if (errata == null) {
prefix = identifier.substring(0, 3);
if ((prefix.equals("CVE") || prefix.equals("CAN")) &&
identifier.length() > 7 && identifier.indexOf('-') == -1) {
identifier = identifier.substring(0, 3) + "-" +
identifier.substring(3, 7) + "-" +
identifier.substring(7);
}
List erratas = ErrataFactory.lookupByCVE(identifier);
retval.addAll(erratas);
}
}
return retval;
}
/**
* publish takes an unpublished errata and copies its contents into a Published Errata
* object (and then returns this object). This method also handles removing the old
* Unpublished Errata object and child elements from the db.
* @param unpublished The Errata to publish
* @return Returns a published errata.
*/
public static Errata publish(Errata unpublished) {
//Make sure the errata we're publishing is unpublished
if (unpublished.isPublished()) {
return unpublished; //there is nothing we can do here
}
//Create a published errata using unpublished
Errata published;
if (unpublished.isCloned()) {
published = new PublishedClonedErrata();
((PublishedClonedErrata)published).setOriginal(
((UnpublishedClonedErrata)unpublished).getOriginal());
}
else {
published = ErrataFactory.createPublishedErrata();
}
copyDetails(published, unpublished, false);
//Save the published Errata
save(published);
//Remove the unpublished Errata from db
try {
Session session = HibernateFactory.getSession();
session.delete(unpublished);
}
catch (HibernateException e) {
throw new HibernateRuntimeException(
"Errors occurred while publishing errata", e);
}
//return the published errata
return published;
}
/**
* Takes a published or unpublished errata and publishes to a channel, creating
* all of the correct ErrataFile* entries. This method does push packages to
* the appropriate channel. (Appropriate as defined as the channel previously
* having a package with the same name).
* @param errataList list of errata to publish
* @param chan channel to publish it into.
* @param user the user doing the pushing
* @param inheritPackages include only original channel packages
* @return the published errata
*/
public static List<Errata> publishToChannel(List<Errata> errataList, Channel chan,
User user, boolean inheritPackages) {
return publishToChannel(errataList, chan, user, inheritPackages, true);
}
/**
* Takes a published or unpublished errata and publishes to a channel, creating
* all of the correct ErrataFile* entries. This method does push packages to
* the appropriate channel. (Appropriate as defined as the channel previously
* having a package with the same name).
* @param errataList list of errata to publish
* @param chan channel to publish it into.
* @param user the user doing the pushing
* @param inheritPackages include only original channel packages
* @param performPostActions true (default) if you want to refresh newest package
* cache and schedule repomd regeneration. False only if you're going to do those
* things yourself.
* @return the published errata
*/
public static List<Errata> publishToChannel(List<Errata> errataList, Channel chan,
User user, boolean inheritPackages, boolean performPostActions) {
List<com.redhat.rhn.domain.errata.Errata> toReturn = new ArrayList<Errata>();
for (Errata errata : errataList) {
if (!errata.isPublished()) {
errata = publish(errata);
}
errata.addChannel(chan);
errata.addChannelNotification(chan, new Date());
Set<Package> packagesToPush = new HashSet<Package>();
DataResult<PackageOverview> packs;
if (inheritPackages) {
if (!chan.isCloned()) {
throw new InvalidChannelException("Cloned channel expected: " +
chan.getLabel());
}
Channel original = chan.getOriginal();
// see BZ 805714, if we are a clone of a clone the 1st clone
// may not have the errata we want
Set<Channel> associatedChannels = errata.getChannels();
while (original.isCloned() &&
!associatedChannels.contains(original)) {
original = ChannelFactory.lookupOriginalChannel(original);
}
packs = ErrataManager.listErrataChannelPacks(original, errata, user);
}
else {
packs = ErrataManager.lookupPacksFromErrataForChannel(chan, errata, user);
}
for (PackageOverview packOver : packs) {
//lookup the Package object
Package pack = PackageFactory.lookupByIdAndUser(
packOver.getId().longValue(), user);
packagesToPush.add(pack);
}
Errata e = publishErrataPackagesToChannel(errata, chan, user, packagesToPush);
toReturn.add(e);
}
if (performPostActions) {
postPublishActions(chan, user);
}
return toReturn;
}
/**
* Publish an errata to a channel but only push a small set of packages
* along with it
*
* @param errata errata to publish
* @param chan channel to publish it into.
* @param user the user doing the pushing
* @param packages the packages to push
* @return the published errata
*/
public static Errata publishToChannel(Errata errata, Channel chan, User user,
Set<Package> packages) {
if (!errata.isPublished()) {
errata = publish(errata);
}
errata.addChannel(chan);
errata = publishErrataPackagesToChannel(errata, chan, user, packages);
postPublishActions(chan, user);
return errata;
}
private static void postPublishActions(Channel chan, User user) {
ChannelManager.refreshWithNewestPackages(chan,
"java::publishErrataPackagesToChannel");
}
/**
* Private helper method that pushes errata packages to a channel
*/
private static Errata publishErrataPackagesToChannel(Errata errata,
Channel chan, User user, Set<Package> packages) {
// Much quicker to push all packages at once
List<Long> pids = new ArrayList<Long>();
for (Package pack : packages) {
pids.add(pack.getId());
}
ChannelManager.addPackages(chan, pids, user);
for (Package pack : packages) {
List<ErrataFile> publishedFiles = ErrataFactory.lookupErrataFile(
errata, pack);
Map<String, ErrataFile> toAdd = new HashMap();
if (publishedFiles.size() == 0) {
// Now create the appropriate ErrataFile object
String path = pack.getPath();
if (path == null) {
throw new DatabaseException("Package " + pack.getId() +
" has NULL path, please run spacewalk-data-fsck");
}
ErrataFile publishedFile = ErrataFactory
.createPublishedErrataFile(ErrataFactory
.lookupErrataFileType("RPM"), pack
.getChecksum().getChecksum(), path);
publishedFile.addPackage(pack);
publishedFile.setErrata(errata);
publishedFile.setModified(new Date());
((PublishedErrataFile) publishedFile).addChannel(chan);
singleton.saveObject(publishedFile);
}
else {
for (ErrataFile publishedFile : publishedFiles) {
String fileName = publishedFile.getFileName().substring(
publishedFile.getFileName().lastIndexOf("/") + 1);
if (!toAdd.containsKey(fileName)) {
toAdd.put(fileName, publishedFile);
((PublishedErrataFile) publishedFile).addChannel(chan);
singleton.saveObject(publishedFile);
}
}
}
}
ChannelFactory.save(chan);
List chanList = new ArrayList();
chanList.add(chan.getId());
ErrataCacheManager.insertCacheForChannelErrataAsync(chanList, errata);
return errata;
}
/**
* @param org Org performing the cloning
* @param e Errata to be cloned
* @return clone of e
*/
public static Errata createClone(Org org, Errata e) {
UnpublishedClonedErrata clone = new UnpublishedClonedErrata();
copyDetails(clone, e, true);
PublishErrataHelper.setUniqueAdvisoryCloneName(e, clone);
clone.setOriginal(e);
clone.setOrg(org);
save(clone);
return clone;
}
/**
* Helper method to copy the details for.
* @param copy The object to copy into.
* @param original The object to copy from.
* @param clone set to true if this is a cloned errata, and thus
* things like org or advisory name shouldn't be set
*/
private static void copyDetails(Errata copy, Errata original, boolean clone) {
//Set the easy things first ;)
if (!clone) {
copy.setAdvisory(original.getAdvisory());
copy.setAdvisoryName(original.getAdvisoryName());
copy.setOrg(original.getOrg());
}
copy.setAdvisoryType(original.getAdvisoryType());
copy.setProduct(original.getProduct());
copy.setErrataFrom(original.getErrataFrom());
copy.setDescription(original.getDescription());
copy.setSynopsis(original.getSynopsis());
copy.setTopic(original.getTopic());
copy.setSolution(original.getSolution());
copy.setIssueDate(original.getIssueDate());
copy.setUpdateDate(original.getUpdateDate());
copy.setNotes(original.getNotes());
copy.setRefersTo(original.getRefersTo());
copy.setAdvisoryRel(original.getAdvisoryRel());
copy.setLocallyModified(original.getLocallyModified());
copy.setLastModified(original.getLastModified());
/*
* Copy the packages
* packages aren't published or unpublished exactly... that is determined
* by the status of the errata...
*/
copy.setPackages(new HashSet(original.getPackages()));
/*
* Copy the keywords
* if we use the string version of addKeyword, we don't have to worry about
* whether or not the keyword is published.
*/
Iterator keysItr = IteratorUtils.getIterator(original.getKeywords());
while (keysItr.hasNext()) {
Keyword k = (Keyword) keysItr.next();
copy.addKeyword(k.getKeyword());
}
/*
* Copy the bugs. If copy is published, then the bugs should be published as well.
* If not, then we want unpublished bugs.
*/
Iterator bugsItr = IteratorUtils.getIterator(original.getBugs());
while (bugsItr.hasNext()) {
Bug bugIn = (Bug) bugsItr.next();
Bug cloneB;
if (copy.isPublished()) { //we want published bugs
cloneB = ErrataManager.createNewPublishedBug(bugIn.getId(),
bugIn.getSummary(),
bugIn.getUrl());
}
else { //we want unpublished bugs
cloneB = ErrataManager.createNewUnpublishedBug(bugIn.getId(),
bugIn.getSummary(),
bugIn.getUrl());
}
copy.addBug(cloneB);
}
}
/**
* Create a new PublishedErrata from scratch
* @return the PublishedErrata created
*/
public static Errata createPublishedErrata() {
return new PublishedErrata();
}
/**
* Create a new UnpublishedErrata
* @return the UnpublishedErrata created
*/
public static Errata createUnpublishedErrata() {
return new UnpublishedErrata();
}
/**
* Creates a new Unpublished Bug object with the given id and summary.
* @param id The id for the new bug
* @param summary The summary for the new bug
* @param url The bug URL
* @return The new unpublished bug.
*/
public static Bug createUnpublishedBug(Long id, String summary, String url) {
Bug bug = new UnpublishedBug();
bug.setId(id);
bug.setSummary(summary);
bug.setUrl(url);
return bug;
}
/**
* Creates a new Published Bug object with the given id and summary.
* @param id The id for the new bug
* @param summary The summary for the new bug
* @param url The bug URL
* @return The new published bug.
*/
public static Bug createPublishedBug(Long id, String summary, String url) {
Bug bug = new PublishedBug();
bug.setId(id);
bug.setSummary(summary);
bug.setUrl(url);
return bug;
}
/**
* Creates a new Unpublished Errata file with given ErrataFileType, checksum, and name
* @param ft ErrataFileType for the new ErrataFile
* @param cs MD5 Checksum for the new Errata File
* @param name name for the file
* @param packages Packages associated with this errata file.
* @return new Unpublished Errata File
*/
public static ErrataFile createUnpublishedErrataFile(ErrataFileType ft,
String cs,
String name,
Set packages) {
ErrataFile file = new UnpublishedErrataFile();
file.setFileType(ft);
file.setChecksum(ChecksumFactory.safeCreate(cs, "md5"));
file.setFileName(name);
file.setPackages(packages);
return file;
}
/**
* Creates a new Published Errata file with given ErrataFileType, checksum, and name
* @param ft ErrataFileType for the new ErrataFile
* @param cs MD5 Checksum for the new Errata File
* @param name name for the file
* @return new Published Errata File
*/
public static ErrataFile createPublishedErrataFile(ErrataFileType ft,
String cs,
String name) {
return createPublishedErrataFile(ft, cs, name, new HashSet());
}
/**
* Creates a new Published Errata file with given ErrataFileType, checksum, and name
* @param ft ErrataFileType for the new ErrataFile
* @param cs MD5 Checksum for the new Errata File
* @param name name for the file
* @param packages Packages associated with this errata file.
* @return new Published Errata File
*/
public static ErrataFile createPublishedErrataFile(ErrataFileType ft,
String cs,
String name,
Set packages) {
ErrataFile file = new PublishedErrataFile();
file.setFileType(ft);
file.setChecksum(ChecksumFactory.safeCreate(cs, "md5"));
file.setFileName(name);
file.setPackages(packages);
return file;
}
/**
* Lookup a ErrataFileType based on a label
* @param label file type label (RPM, IMG, etc)
* @return ErrataFileType instance
*/
public static ErrataFileType lookupErrataFileType(String label) {
Session session = null;
ErrataFileType retval = null;
try {
session = HibernateFactory.getSession();
retval = (ErrataFileType) session.getNamedQuery("ErrataFileType.findByLabel")
.setString("label", label).setCacheable(true).uniqueResult();
}
catch (HibernateException e) {
throw new HibernateRuntimeException(e.getMessage(), e);
}
return retval;
}
/**
* Lookup ErrataFiles by errata and file type
* @param errataId errata id
* @param fileType file type label
* @return list of ErrataFile instances
*/
public static List lookupErrataFilesByErrataAndFileType(Long errataId,
String fileType) {
Session session = null;
List retval = null;
try {
session = HibernateFactory.getSession();
Query q = session.getNamedQuery("PublishedErrataFile.listByErrataAndFileType");
q.setLong("errata_id", errataId.longValue());
q.setString("file_type", fileType.toUpperCase());
retval = q.list();
if (retval == null) {
q = session.getNamedQuery("UnpublishedErrataFile.listByErrataAndFileType");
q.setLong("errata_id", errataId.longValue());
q.setString("file_type", fileType.toUpperCase());
retval = q.list();
}
}
catch (HibernateException e) {
throw new HibernateRuntimeException(e.getMessage(), e);
}
return retval;
}
/**
* Lookup a Errata by their id
* @param id the id to search for
* @return the Errata found
*/
public static Errata lookupById(Long id) {
//Look for published Errata first
Session session = HibernateFactory.getSession();
Errata errata = (Errata) session.get(PublishedErrata.class, id);
//If we nothing was found, look for it in the Unpublished Errata table...
if (errata == null) {
errata = (Errata) session.get(UnpublishedErrata.class, id);
}
return errata;
}
/**
* Lookup a Errata by the advisoryType string
* @param advisoryType to search for
* @return the Errata found
*/
public static List lookupErratasByAdvisoryType(String advisoryType) {
Session session = null;
List retval = null;
try {
session = HibernateFactory.getSession();
retval = session.getNamedQuery("PublishedErrata.findByAdvisoryType")
.setString("type", advisoryType)
//Retrieve from cache if there
.setCacheable(true).list();
}
catch (HibernateException he) {
log.error("Error loading ActionArchTypes from DB", he);
throw new
HibernateRuntimeException("Error loading ActionArchTypes from db");
}
return retval;
}
/**
* Finds published errata by id
* @param id errata id
* @return Errata if found, otherwise null
*/
public static Errata lookupPublishedErrataById(Long id) {
Session session = null;
Errata retval = null;
try {
session = HibernateFactory.getSession();
retval = (Errata) session.getNamedQuery("PublishedErrata.findById")
.setLong("id", id.longValue()).uniqueResult();
}
catch (HibernateException he) {
log.error("Error loading ActionArchTypes from DB", he);
throw new
HibernateRuntimeException("Error loading ActionArchTypes from db");
}
return retval;
}
/**
* Look up an errata by the advisory name. This is a unique field in the db and this
* method is needed to help us see if a created/edited advisoryName is unique.
* @param advisory The advisory to lookup
* @return Returns the errata corresponding to the passed in advisory name.
*/
public static Errata lookupByAdvisory(String advisory) {
Session session = null;
Errata retval = null;
// try {
//look for a published errata first
session = HibernateFactory.getSession();
retval = (Errata) session.getNamedQuery("PublishedErrata.findByAdvisoryName")
.setString("advisory", advisory)
.uniqueResult();
//if nothing was found, check the unpublished errata table
if (retval == null) {
retval = (Errata)
session.getNamedQuery("UnpublishedErrata.findByAdvisoryName")
.setString("advisory", advisory)
.uniqueResult();
}
// }
// catch (HibernateException e) {
// throw new
// HibernateRuntimeException("Error looking up errata by advisory name");
// }
return retval;
}
/**
* Finds errata based on advisory id
* @param advisoryId errata advisory id
* @return Errata if found, otherwise null
*/
public static Errata lookupByAdvisoryId(String advisoryId) {
Session session = null;
Errata retval = null;
try {
//look for a published errata first
session = HibernateFactory.getSession();
retval = (Errata) session.getNamedQuery("PublishedErrata.findByAdvisory")
.setString("advisory", advisoryId)
.uniqueResult();
if (retval == null) {
retval = (Errata)
session.getNamedQuery("UnpublishedErrata.findByAdvisory")
.setString("advisory", advisoryId)
.uniqueResult();
}
}
catch (HibernateException e) {
throw new
HibernateRuntimeException("Error looking up errata by advisory name");
}
return retval;
}
/**
* Finds errata based on CVE string
* @param cve cve text
* @return Errata if found, otherwise null
*/
public static List lookupByCVE(String cve) {
List retval = new LinkedList();
SelectMode mode = ModeFactory.getMode("Errata_queries", "erratas_for_cve");
Map<String, Object> params = new HashMap<String, Object>();
params.put("cve", cve);
List result = mode.execute(params);
Session session = HibernateFactory.getSession();
for (Iterator iter = result.iterator(); iter.hasNext();) {
Map row = (Map) iter.next();
Long rawId = (Long) row.get("id");
retval.add(session.load(PublishedErrata.class, rawId));
}
return retval;
}
/**
* Lookup all the clones of a particular errata
* @param org Org that the clones belongs to
* @param original Original errata that the clones are clones of
* @return list of clones of the errata
*/
public static List lookupByOriginal(Org org, Errata original) {
Session session = null;
List retval = null;
try {
session = HibernateFactory.getSession();
retval = session.
getNamedQuery("UnpublishedClonedErrata.findByOriginal")
.setParameter("original", original)
.setParameter("org", org).list();
if (retval == null) {
retval = lookupPublishedByOriginal(org, original);
}
}
catch (HibernateException e) {
throw new
HibernateRuntimeException("Error looking up errata by original errata");
}
return retval;
}
/**
* Lookup all the clones of a particular errata
* @param org Org that the clones belongs to
* @param original Original errata that the clones are clones of
* @return list of clones of the errata
*/
public static List lookupPublishedByOriginal(Org org, Errata original) {
Session session = null;
List retval = null;
try {
session = HibernateFactory.getSession();
retval = session.getNamedQuery("PublishedClonedErrata.findByOriginal")
.setParameter("original", original)
.setParameter("org", org).list();
}
catch (HibernateException e) {
throw new
HibernateRuntimeException("Error looking up errata by original errata");
}
return retval;
}
/**
* Lists errata present in both channels
* @param org orgaznization
* @param channelFrom channel1
* @param channelTo channel2
* @return list of errata
*/
public static List listSamePublishedInChannels(Org org, Channel channelFrom,
Channel channelTo) {
Session session = null;
List retval = null;
try {
session = HibernateFactory.getSession();
retval = session.getNamedQuery("PublishedErrata.findSameInChannels")
.setParameter("channel_from", channelFrom)
.setParameter("channel_to", channelTo).list();
}
catch (HibernateException e) {
throw new
HibernateRuntimeException("Error looking up errata by original errata");
}
return retval;
}
/**
* Lists errata from channelFrom, that are cloned from the same original
* as errata in channelTo
* @param org orgaznization
* @param channelFrom channel1
* @param channelTo channel2
* @return list of errata
*/
public static List listPublishedBrothersInChannels(Org org, Channel channelFrom,
Channel channelTo) {
Session session = null;
List retval = null;
try {
session = HibernateFactory.getSession();
retval = session.getNamedQuery("PublishedClonedErrata.findBrothersInChannel")
.setParameter("channel_from", channelFrom)
.setParameter("channel_to", channelTo).list();
}
catch (HibernateException e) {
throw new
HibernateRuntimeException("Error looking up errata by original errata");
}
return retval;
}
/**
* Lists errata from channelFrom, that have clones in channelTo
* @param org orgaznization
* @param channelFrom channel1
* @param channelTo channel2
* @return list of errata
*/
public static List listPublishedClonesInChannels(Org org, Channel channelFrom,
Channel channelTo) {
Session session = null;
List retval = null;
try {
session = HibernateFactory.getSession();
retval = session.getNamedQuery("PublishedErrata.findClonesInChannel")
.setParameter("channel_from", channelFrom)
.setParameter("channel_to", channelTo)
.list();
}
catch (HibernateException e) {
throw new
HibernateRuntimeException("Error looking up errata by original errata");
}
return retval;
}
/**
* Insert or Update a Errata.
* @param errataIn Errata to be stored in database.
*/
public static void save(Errata errataIn) {
singleton.saveObject(errataIn);
}
/**
* Delete a bug
* @param deleteme Bug to delete
*/
public static void removeBug(Bug deleteme) {
singleton.removeObject(deleteme);
}
/**
* Delete a Keyword
* @param deleteme Keyword to delete
*/
public static void remove(Keyword deleteme) {
singleton.removeObject(deleteme);
}
/**
* Remove a file.
* @param deleteme ErrataFile to delete
*/
public static void removeFile(ErrataFile deleteme) {
singleton.removeObject(deleteme);
}
/**
* Lists errata assigned to a particular channel,
* sorted by date (from oldest to newest)
* @param org the Org in question
* @param channel the channel you want to get the errata for
* @return A list of Errata objects
*/
public static List lookupByChannelSorted(Org org, Channel channel) {
return HibernateFactory.getSession().
getNamedQuery("PublishedErrata.lookupSortedByChannel")
.setParameter("org", org)
.setParameter("channel", channel)
.list();
}
/**
* Lists errata assigned to a particular channel between
* the given start and end date. The list is sorted by date
* (from oldest to newest).
* @param org the Org in question
* @param channel the channel you want to get the errata for
* @param startDate the start date
* @param endDate the end date
* @return A list of Errata objects
*/
public static List<Errata> lookupByChannelBetweenDates(Org org, Channel channel,
String startDate, String endDate) {
return HibernateFactory.getSession().
getNamedQuery("PublishedErrata.lookupByChannelBetweenDates")
.setParameter("org", org)
.setParameter("channel", channel)
.setParameter("start_date", startDate)
.setParameter("end_date", endDate)
.list();
}
/**
* Lookup an errataFile object by it's errata and package
* @param errata the errata associated
* @param pack the package associated
* @return the requested errata file object
*/
public static List<ErrataFile> lookupErrataFile(Errata errata, Package pack) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("errata", errata);
params.put("package", pack);
return singleton.listObjectsByNamedQuery(
"PublishedErrataFile.lookupByErrataAndPackage", params);
}
/**
* Returns a list of ErrataOverview that match the given errata ids.
* @param eids Errata ids.
* @param org Organization to match results with
* @return a list of ErrataOverview that match the given errata ids.
*/
public static List<ErrataOverview> search(List eids, Org org) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("eids", eids);
params.put("org_id", org.getId());
List results = singleton.listObjectsByNamedQuery(
"PublishedErrata.searchById", params);
List<ErrataOverview> errata = new ArrayList<ErrataOverview>();
for (Object result : results) {
Object[] values = (Object[]) result;
ErrataOverview eo = new ErrataOverview();
// e.id, e.advisory, e.advisoryName, e.advisoryType, e.synopsis, e.updateDate
eo.setId((Long)values[0]);
eo.setAdvisory((String)values[1]);
eo.setAdvisoryName((String)values[2]);
eo.setAdvisoryType((String)values[3]);
eo.setAdvisorySynopsis((String)values[4]);
eo.setUpdateDate((Date)values[5]);
eo.setIssueDate((Date)values[6]);
errata.add(eo);
}
return errata;
}
/**
* Returns a list of ErrataOverview of Errata that match the given Package
* ids.
* @param pids Package ids whose Errata are being sought.
* @return a list of ErrataOverview of Errata that match the given Package
* ids.
*/
public static List<ErrataOverview> searchByPackageIds(List pids) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("pids", pids);
if (log.isDebugEnabled()) {
log.debug("pids = " + pids);
}
List results = singleton.listObjectsByNamedQuery(
"PublishedErrata.searchByPackageIds", params);
if (log.isDebugEnabled()) {
log.debug("Query 'PublishedErrata.searchByPackageIds' returned " +
results.size() + " entries");
}
List<ErrataOverview> errata = new ArrayList<ErrataOverview>();
Long lastId = null;
ErrataOverview eo = null;
for (Object result : results) {
Object[] values = (Object[]) result;
// e.id, e.advisory, e.advisoryName, e.advisoryType, e.synopsis, e.updateDate
Long curId = (Long)values[0];
if (!curId.equals(lastId)) {
eo = new ErrataOverview();
}
eo.setId((Long)values[0]);
eo.setAdvisory((String)values[1]);
eo.setAdvisoryName((String)values[2]);
eo.setAdvisoryType((String)values[3]);
eo.setAdvisorySynopsis((String)values[4]);
eo.setUpdateDate((Date)values[5]);
eo.setIssueDate((Date)values[6]);
eo.addPackageName((String)values[7]);
if (!curId.equals(lastId)) {
errata.add(eo);
lastId = curId;
}
if (log.isDebugEnabled()) {
log.debug("curId = " + curId + ", lastId = " + lastId);
log.debug("ErrataOverview formed: " + eo.getAdvisoryName() + " for " +
eo.getPackageNames());
}
}
return errata;
}
/**
* Returns a list of ErrataOverview of Errata that match the given Package
* ids.
* @param pids Package ids whose Errata are being sought.
* @param org Organization to match results with
* @return a list of ErrataOverview of Errata that match the given Package
* ids.
*/
public static List<ErrataOverview> searchByPackageIdsWithOrg(List pids, Org org) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("pids", pids);
params.put("org_id", org.getId());
if (log.isDebugEnabled()) {
log.debug("org_id = " + org.getId());
log.debug("pids = " + pids);
}
List results = singleton.listObjectsByNamedQuery(
"PublishedErrata.searchByPackageIdsWithOrg", params);
if (log.isDebugEnabled()) {
log.debug("Query 'PublishedErrata.searchByPackageIdsWithOrg' returned " +
results.size() + " entries");
}
List<ErrataOverview> errata = new ArrayList<ErrataOverview>();
Long lastId = null;
ErrataOverview eo = null;
for (Object result : results) {
Object[] values = (Object[]) result;
// e.id, e.advisory, e.advisoryName, e.advisoryType, e.synopsis, e.updateDate
Long curId = (Long)values[0];
if (!curId.equals(lastId)) {
eo = new ErrataOverview();
}
eo.setId((Long)values[0]);
eo.setAdvisory((String)values[1]);
eo.setAdvisoryName((String)values[2]);
eo.setAdvisoryType((String)values[3]);
eo.setAdvisorySynopsis((String)values[4]);
eo.setUpdateDate((Date)values[5]);
eo.setIssueDate((Date)values[6]);
eo.addPackageName((String)values[7]);
if (!curId.equals(lastId)) {
errata.add(eo);
lastId = curId;
}
if (log.isDebugEnabled()) {
log.debug("curId = " + curId + ", lastId = " + lastId);
log.debug("ErrataOverview formed: " + eo.getAdvisoryName() + " for " +
eo.getPackageNames());
}
}
return errata;
}
/**
* Sync all the errata details from one errata to another
* @param cloned the cloned errata that needs syncing
*/
public static void syncErrataDetails(PublishedClonedErrata cloned) {
copyDetails(cloned, cloned.getOriginal(), true);
}
/**
* List errata objects by ID
* @param ids list of ids
* @return List of Errata Objects
*/
public static List<Errata> listErrata(Collection<Long> ids) {
return singleton.listObjectsByNamedQuery("PublishedErrata.listByIds",
new HashMap(), ids, "list");
}
/**
* Get list of errata ids that are in one channel but not another
* @param fromCid errata are in this channel
* @param toCid but not in this one
* @return list of errata overviews
*/
public static DataResult<ErrataOverview> relevantToOneChannelButNotAnother(
Long fromCid, Long toCid) {
SelectMode mode = ModeFactory.getMode("Errata_queries",
"relevant_to_one_channel_but_not_another");
Map<String, Object> params = new HashMap<String, Object>();
params.put("from_cid", fromCid);
params.put("to_cid", toCid);
DataResult<ErrataOverview> results = mode.execute(params);
return results;
}
/**
* List all owned, published, unmodified, cloned errata in an org. Useful when cloning
* channels.
* @param orgId Org id to look for
* @return List of OwnedErrata
*/
public static DataResult<OwnedErrata> listPublishedOwnedUnmodifiedClonedErrata(
Long orgId) {
SelectMode mode = ModeFactory.getMode("Errata_queries",
"published_owned_unmodified_cloned_errata");
Map<String, Object> params = new HashMap<String, Object>();
params.put("org_id", orgId);
DataResult<OwnedErrata> results = mode.execute(params);
return results;
}
/**
* Get all advisory strings (published or unpublished) that end in the given string.
* Useful when cloning errata.
* @param ending String ending of the advisory
* @return Set of existing advisories
*/
public static Set<String> listAdvisoriesEndingWith(String ending) {
SelectMode mode = ModeFactory.getMode("Errata_queries", "advisories_ending_with");
Map<String, Object> params = new HashMap<String, Object>();
params.put("ending", "%" + ending);
List<Map<String, Object>> results = mode.execute(params);
Set<String> ret = new HashSet<String>();
for (Map<String, Object> result : results) {
ret.add((String) result.get("advisory"));
}
return ret;
}
/**
* Get all advisory names (published or unpublished) that end in the given string.
* Useful when cloning errata.
* @param ending String ending of the advisory
* @return Set of existing advisory names
*/
public static Set<String> listAdvisoryNamesEndingWith(String ending) {
SelectMode mode = ModeFactory.getMode("Errata_queries",
"advisory_names_ending_with");
Map<String, Object> params = new HashMap<String, Object>();
params.put("ending", "%" + ending);
List<Map<String, Object>> results = mode.execute(params);
Set<String> ret = new HashSet<String>();
for (Map<String, Object> result : results) {
ret.add((String) result.get("advisory_name"));
}
return ret;
}
/**
* Get ErrataOverview by errata id
* @param eid errata id
* @return ErrataOverview object
*/
public static ErrataOverview getOverviewById(Long eid) {
SelectMode mode = ModeFactory.getMode("Errata_queries", "overview_by_id");
Map<String, Object> params = new HashMap<String, Object>();
params.put("eid", eid);
DataResult<ErrataOverview> results = mode.execute(params);
if (results.size() == 0) {
return null;
}
results.elaborate();
return results.get(0);
}
/**
* Get ErrataOverview by advisory
* @param advisory the advisory
* @return ErrataOverview object
*/
public static ErrataOverview getOverviewByAdvisory(String advisory) {
SelectMode mode = ModeFactory.getMode("Errata_queries", "overview_by_advisory");
Map<String, Object> params = new HashMap<String, Object>();
params.put("advisory", advisory);
DataResult<ErrataOverview> results = mode.execute(params);
if (results.size() == 0) {
return null;
}
results.elaborate();
return results.get(0);
}
/**
* Clone an erratum in the db. Will fill contents of rhnErrata, rhnErrataCloned,
* rhnErrataBugList, rhnErrataPackage, rhnErrataKeyword, and rhnErrataCVE. Basically
* do everything that PublishErrataHelper.cloneErrataFast does, but much, much faster.
* @param originalEid erratum id to clone from
* @param advisory unique advisory
* @param advisoryName unique name
* @param orgId org id to clone into
* @return ErrataOverview for the cloned erratum
*/
public static ErrataOverview cloneErratum(Long originalEid, String advisory,
String advisoryName, Long orgId) {
WriteMode m = ModeFactory.getWriteMode("Errata_queries", "clone_erratum");
Map<String, Object> params = new HashMap<String, Object>();
params.put("eid", originalEid);
params.put("advisory", advisory);
params.put("name", advisoryName);
params.put("org_id", orgId);
m.executeUpdate(params);
ErrataOverview clone = getOverviewByAdvisory(advisory);
// set original
m = ModeFactory.getWriteMode("Errata_queries", "set_original");
params = new HashMap<String, Object>();
params.put("original_id", originalEid);
params.put("clone_id", clone.getId());
m.executeUpdate(params);
// clone bugs
m = ModeFactory.getWriteMode("Errata_queries", "clone_bugs");
m.executeUpdate(params);
// clone keywords
m = ModeFactory.getWriteMode("Errata_queries", "clone_keywords");
m.executeUpdate(params);
// clone packages
m = ModeFactory.getWriteMode("Errata_queries", "clone_packages");
m.executeUpdate(params);
// clone cves
m = ModeFactory.getWriteMode("Errata_queries", "clone_cves");
m.executeUpdate(params);
// clone files
m = ModeFactory.getWriteMode("Errata_queries", "clone_files");
m.executeUpdate(params);
return clone;
}
}