/**
* Copyright (c) 2009--2012 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.taskomatic.task.repomd;
import com.redhat.rhn.domain.channel.Channel;
import com.redhat.rhn.domain.rhnpackage.Package;
import com.redhat.rhn.frontend.dto.PackageDto;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
/**
*
* @version $Rev $
*
*/
public abstract class RepomdWriter {
protected SimpleContentHandler handler;
private static final String CONTROL_CHARS;
private static final String CONTROL_CHARS_REPLACEMENT;
static {
CONTROL_CHARS = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008" +
"\u000B\u000C\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015" +
"\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F";
CONTROL_CHARS_REPLACEMENT = StringUtils.repeat(" ", CONTROL_CHARS.length());
}
private static Logger log = Logger.getLogger(RepomdWriter.class);
/**
* Constructor takes in a writer
* @param writer content writer
* @param shouldEscape says whether write output shall be escaped
*/
public RepomdWriter(Writer writer, boolean shouldEscape) {
OutputFormat of = new OutputFormat();
of.setPreserveSpace(true);
XMLSerializer serializer = null;
if (shouldEscape) {
// XMLSerializer used to escape chars like < >
serializer = new XMLSerializer(writer, of);
}
else {
// UnescapingXmlSerializer doesn't escape anything,
// input shall already be escaped
serializer = new UnescapingXmlSerializer(writer, of);
}
try {
handler = new SimpleContentHandler(serializer.asContentHandler());
}
catch (IOException e) {
// XXX fatal error
}
try {
handler.startDocument();
}
catch (SAXException e) {
// XXX fatal error
}
}
protected SimpleContentHandler getTemporaryHandler(OutputStream st) {
OutputFormat of = new OutputFormat();
of.setPreserveSpace(true);
of.setOmitXMLDeclaration(true);
XMLSerializer tmpSerial = new XMLSerializer(st, of);
SimpleContentHandler tmpHandler = new SimpleContentHandler(tmpSerial);
return tmpHandler;
}
/**
*
* @param handler content handler
* @param pkgDto package info dto object
* @throws SAXException
*/
protected static void addPackageBoilerplate(SimpleContentHandler handler,
PackageDto pkgDto) throws SAXException {
long pkgId = pkgDto.getId().longValue();
SimpleAttributesImpl attr = new SimpleAttributesImpl();
attr.addAttribute("pkgid", sanitize(pkgId, pkgDto.getChecksum()));
attr.addAttribute("name", sanitize(pkgId, pkgDto.getName()));
attr.addAttribute("arch", sanitize(pkgId, pkgDto.getArchLabel()));
handler.startElement("package", attr);
attr.clear();
attr.addAttribute("ver", sanitize(pkgId, pkgDto.getVersion()));
attr.addAttribute("rel", sanitize(pkgId, pkgDto.getRelease()));
attr.addAttribute("epoch", sanitize(pkgId,
getPackageEpoch(pkgDto.getEpoch())));
handler.startElement("version", attr);
handler.endElement("version");
}
/**
*
* @param pkg package object
* @return package epoch string
*/
protected static String getPackageEpoch(Package pkg) {
return getPackageEpoch(pkg.getPackageEvr().getEpoch());
}
/**
*
* @param epoch package epoch string
* @return modified epoch string
*/
protected static String getPackageEpoch(String epoch) {
if (epoch == null || epoch.length() == 0) {
epoch = "0";
}
return epoch;
}
/**
* Removes all control characters from passed in String.
* @param pkgId package id
* @param input char input
*/
protected static String sanitize(Long pkgId, String input) {
if (StringUtils.containsNone(input, CONTROL_CHARS)) {
return input;
}
if (log.isDebugEnabled()) {
log.debug("Package " + pkgId +
" metadata contains control chars, cleanup required: " + input);
}
return StringUtils.replaceChars(input, CONTROL_CHARS, CONTROL_CHARS_REPLACEMENT);
}
/**
*
* @param channel channel info
*/
public abstract void begin(Channel channel);
/**
* writer end call
*/
public abstract void end();
}