/**
* Copyright (c) 2009--2016 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.xmlrpc.serializer;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.text.DecimalFormat;
import org.apache.commons.codec.binary.Base64;
import redstone.xmlrpc.XmlRpcException;
import redstone.xmlrpc.XmlRpcSerializer;
import com.redhat.rhn.FaultException;
import com.redhat.rhn.common.util.StringUtil;
import com.redhat.rhn.domain.config.ConfigRevision;
import com.redhat.rhn.domain.config.EncodedConfigRevision;
import com.redhat.rhn.frontend.xmlrpc.serializer.util.SerializerHelper;
/**
* ConfigRevisionSerializer
* @version $Rev$
*
* @xmlrpc.doc
* #struct("Configuration Revision information")
* #prop("string", "type")
* #options()
* #item("file")
* #item("directory")
* #item("symlink")
* #options_end()
* #prop_desc("string", "path","File Path")
* #prop_desc("string", "target_path","Symbolic link Target File Path.
* Present for Symbolic links only.")
* #prop_desc("string", "channel","Channel Name")
* #prop_desc("string", "contents","File contents (base64 encoded according
to the contents_enc64 attribute)")
* #prop_desc("boolean", "contents_enc64"," Identifies base64 encoded content")
* #prop_desc("int", "revision","File Revision")
* #prop_desc($date, "creation","Creation Date")
* #prop_desc($date, "modified","Last Modified Date")
* #prop_desc("string", "owner","File Owner. Present for files or directories only.")
* #prop_desc("string", "group","File Group. Present for files or directories only.")
* #prop_desc("int", "permissions","File Permissions (Deprecated).
* Present for files or directories only.")
* #prop_desc("string", "permissions_mode", "File Permissions.
* Present for files or directories only.")
* #prop_desc("string", "selinux_ctx", "SELinux Context (optional).")
* #prop_desc("boolean", "binary", "true/false , Present for files only.")
* #prop_desc("string", "sha256", "File's sha256 signature. Present for files only.")
* #prop_desc("string", "macro-start-delimiter",
* "Macro start delimiter for a config file. Present for text files only.")
* #prop_desc("string", "macro-end-delimiter",
* "Macro end delimiter for a config file. Present for text files only.")
* #struct_end()
*/
public class ConfigRevisionSerializer extends RhnXmlRpcCustomSerializer {
public static final String CONTENTS = "contents";
public static final String CONTENTS_ENC64 = "contents_enc64";
public static final String PATH = "path";
public static final String TARGET_PATH = "target_path";
public static final String OWNER = "owner";
public static final String GROUP = "group";
public static final String SELINUX_CTX = "selinux_ctx";
public static final String PERMISSIONS = "permissions";
public static final String PERMISSIONS_MODE = "permissions_mode";
public static final String MACRO_START = "macro-start-delimiter";
public static final String MACRO_END = "macro-end-delimiter";
public static final String BINARY = "binary";
public static final String TYPE = "type";
public static final String REVISION = "revision";
/**
* {@inheritDoc}
*/
public Class getSupportedClass() {
return ConfigRevision.class;
}
/**
* {@inheritDoc}
*/
protected void doSerialize(Object value, Writer output, XmlRpcSerializer serializer)
throws XmlRpcException, IOException {
ConfigRevision rev = (ConfigRevision) value;
SerializerHelper helper = new SerializerHelper(serializer);
if (rev.getConfigFileType() != null) {
helper.add(TYPE, rev.getConfigFileType().getLabel());
}
helper.add(PATH, rev.getConfigFile().getConfigFileName().getPath());
helper.add(REVISION, rev.getRevision());
helper.add("creation", rev.getCreated());
helper.add("modified", rev.getModified());
helper.add(SELINUX_CTX, rev.getConfigInfo().getSelinuxCtx());
if (!rev.isSymlink()) {
helper.add(OWNER, rev.getConfigInfo().getUsername());
helper.add(GROUP, rev.getConfigInfo().getGroupname());
helper.add(PERMISSIONS, rev.getConfigInfo().getFilemode());
helper.add(PERMISSIONS_MODE, new DecimalFormat("000").format(
rev.getConfigInfo().getFilemode().longValue()));
}
else {
helper.add(TARGET_PATH, rev.getConfigInfo().getTargetFileName().getPath());
}
if (rev.isFile()) {
helper.add(BINARY, rev.getConfigContent().isBinary());
helper.add("sha256", rev.getConfigContent().getChecksum().getChecksum());
if (rev instanceof EncodedConfigRevision || rev.getConfigContent().isBinary()) {
addEncodedFileContent(rev, helper);
}
else {
addFileContent(rev, helper);
}
}
helper.add("channel", rev.getConfigFile().getConfigChannel().getName());
helper.writeTo(output);
}
protected void addFileContent(ConfigRevision rev, SerializerHelper helper) {
if (!rev.getConfigContent().isBinary()) {
String content = rev.getConfigContent().getContentsString();
if (!StringUtil.containsInvalidXmlChars2(content)) {
helper.add(CONTENTS, content);
helper.add(CONTENTS_ENC64, Boolean.FALSE);
}
helper.add(MACRO_START, rev.getConfigContent().getDelimStart());
helper.add(MACRO_END, rev.getConfigContent().getDelimEnd());
}
}
protected void addEncodedFileContent(ConfigRevision rev, SerializerHelper helper) {
try {
helper.add(CONTENTS, new String(Base64.encodeBase64(
rev.getConfigContent().getContents()), "UTF-8"));
}
catch (UnsupportedEncodingException e) {
String msg = "Following errors were encountered " +
"when creating the config file.\n" + e.getMessage();
throw new FaultException(1023, "ConfgFileError", msg);
}
helper.add(CONTENTS_ENC64, Boolean.TRUE);
if (!rev.getConfigContent().isBinary()) {
helper.add(MACRO_START, rev.getConfigContent().getDelimStart());
helper.add(MACRO_END, rev.getConfigContent().getDelimEnd());
}
}
}