package org.jfrog.hudson.util.converters;
import com.google.common.collect.Lists;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import hudson.util.XStream2;
import org.apache.commons.lang.StringUtils;
import org.jfrog.hudson.RepositoryConf;
import org.jfrog.hudson.ServerDetails;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
/**
* @author Lior Hasson
*/
public class ServerDetailsConverter extends XStream2.PassthruConverter<ServerDetails> {
Logger logger = Logger.getLogger(ServerDetailsConverter.class.getName());
List<String> converterErrors = Lists.newArrayList();
// mapping of the old ServerDetails field to the corresponding new field
private static final Map<String, String> newToOldFields;
static {
newToOldFields = new HashMap<String, String>();
newToOldFields.put("repositoryKey", "deployReleaseRepository");
newToOldFields.put("snapshotsRepositoryKey", "deploySnapshotRepository");
newToOldFields.put("downloadSnapshotRepositoryKey", "resolveSnapshotRepository");
newToOldFields.put("downloadReleaseRepositoryKey", "resolveReleaseRepository");
}
public ServerDetailsConverter(XStream2 xstream) {
super(xstream);
}
public void convertToReleaseAndSnapshotRepository(ServerDetails server) {
Class<? extends ServerDetails> overrideClass = server.getClass();
try {
Field oldReleaseRepositoryField = overrideClass.getDeclaredField("downloadRepositoryKey");
oldReleaseRepositoryField.setAccessible(true);
Object oldReleaseRepositoryValue = oldReleaseRepositoryField.get(server);
if (oldReleaseRepositoryValue != null && StringUtils.isNotBlank((String) oldReleaseRepositoryValue)) {
Field newReleaseRepositoryField = overrideClass.getDeclaredField("downloadReleaseRepositoryKey");
newReleaseRepositoryField.setAccessible(true);
newReleaseRepositoryField.set(server, oldReleaseRepositoryValue);
Field newSnapshotRepositoryField = overrideClass.getDeclaredField("downloadSnapshotRepositoryKey");
newSnapshotRepositoryField.setAccessible(true);
newSnapshotRepositoryField.set(server, oldReleaseRepositoryValue);
}
} catch (NoSuchFieldException e) {
converterErrors.add(getConversionErrorMessage(server, e));
} catch (IllegalAccessException e) {
converterErrors.add(getConversionErrorMessage(server, e));
}
}
public void convertToDynamicReposSelection(ServerDetails server) {
Class<? extends ServerDetails> overrideClass = server.getClass();
for (Map.Entry<String, String> e : newToOldFields.entrySet()) {
setNewReposFieldFromOld(server, overrideClass, e.getKey(), e.getValue());
}
}
private void setNewReposFieldFromOld(ServerDetails reflectedObject, Class classToChange, String oldFieldName,
String newFieldName) {
try {
Field oldField = classToChange.getDeclaredField(oldFieldName);
oldField.setAccessible(true);
String oldValue = (String) oldField.get(reflectedObject);
if (StringUtils.isNotBlank(oldValue)) {
Field newField = classToChange.getDeclaredField(newFieldName);
RepositoryConf newValue = new RepositoryConf(oldValue, oldValue, false);
newField.setAccessible(true);
newField.set(reflectedObject, newValue);
}
} catch (NoSuchFieldException e) {
converterErrors.add(getConversionErrorMessage(reflectedObject, e));
} catch (IllegalAccessException e) {
converterErrors.add(getConversionErrorMessage(reflectedObject, e));
}
}
@Override
protected void callback(ServerDetails server, UnmarshallingContext context) {
convertToReleaseAndSnapshotRepository(server);
convertToDynamicReposSelection(server);
if (!converterErrors.isEmpty()) {
logger.info(converterErrors.toString());
}
}
private String getConversionErrorMessage(ServerDetails serverDetails, Exception e) {
return String.format("Could not convert the class '%s' to use the new overriding Resolve repositories." +
" Cause: %s", serverDetails.getClass().getName(), e.getCause());
}
}