package it.altecspace.mylyn.redmine.client;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import javax.sql.rowset.spi.XmlWriter;
import javax.xml.bind.Binder;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.apache.xmlrpc.serializer.XmlWriterFactory;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.mylyn.commons.net.AuthenticationCredentials;
import org.eclipse.mylyn.commons.net.AuthenticationType;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import com.taskadapter.redmineapi.RedmineException;
public class RedmineClientManager implements IRedmineClientManager
{
private final IPath stateLocationPath;
public RedmineClientManager(IPath stateLocationPath)
{
this.stateLocationPath = stateLocationPath;
}
Map<String,RedmineClient> clientsByUrl = new HashMap<String, RedmineClient>();
@Override
public IRedmineClient getClient(TaskRepository repository) throws RedmineException
{
RedmineClient client = clientsByUrl.get(repository.getUrl());
if(client!=null)
{
return client;
}
if(configurationFileExists(repository.getUrl()))
{
CachedRepositoryConfiguration configuration = loadConfigurationFromCache(repository.getUrl());
client = createClientFromTaskRepository(repository, configuration);
}
else
{
CachedRepositoryConfiguration configuration = new CachedRepositoryConfiguration();
client = createClientFromTaskRepository(repository, configuration);
client.loadConfiguration();
saveConfigurationToCache(repository.getUrl(),configuration);
}
clientsByUrl.put(repository.getUrl(), client);
return client;
}
@Override
public void validateConnection(TaskRepository repository) throws RedmineException
{
RedmineClient client = createClientFromTaskRepository(repository, new CachedRepositoryConfiguration());
try
{
client.validateConnection();
}
catch (RedmineException e)
{
throw e;
}
finally
{
client.shutdown();
}
}
private RedmineClient createClientFromTaskRepository(TaskRepository repository, CachedRepositoryConfiguration configuration)
{
String url = repository.getUrl();
AuthenticationCredentials credentials = repository.getCredentials(AuthenticationType.REPOSITORY);
String username = credentials.getUserName();
String password = credentials.getPassword();
return new RedmineClient(url, username, password, configuration);
}
private boolean configurationFileExists(String repositoryUrl)
{
String encodedFilename = null;
try
{
encodedFilename = URLEncoder.encode(repositoryUrl,"UTF-8");
}
catch (UnsupportedEncodingException e)
{
return false;
}
File destinationFile = stateLocationPath.append(encodedFilename).toFile();
return destinationFile.exists();
}
private CachedRepositoryConfiguration loadConfigurationFromCache(String repositoryUrl) throws RedmineException
{
File configurationFile = getConfigurationFileForUrl(repositoryUrl);
BufferedReader reader=null;
try
{
reader = new BufferedReader(new FileReader(configurationFile));
}
catch (IOException e)
{
throw new RedmineException("Failed to open configuration file",e);
}
try
{
JAXBContext context = JAXBContext.newInstance(CachedRepositoryConfiguration.class);
Unmarshaller u = context.createUnmarshaller();
return (CachedRepositoryConfiguration)u.unmarshal(reader);
}
catch (JAXBException e)
{
throw new RedmineException("Failed to serialize configuration to configuration file",e);
}
finally
{
try
{
reader.close();
}
catch (IOException e)
{
}
}
}
private void saveConfigurationToCache(String repositoryUrl, CachedRepositoryConfiguration configuration) throws RedmineException
{
File configurationFile = getConfigurationFileForUrl(repositoryUrl);
BufferedWriter writer=null;
try
{
writer = new BufferedWriter(new FileWriter(configurationFile));
}
catch (IOException e)
{
throw new RedmineException("Failed to open configuration file",e);
}
try
{
JAXBContext context = JAXBContext.newInstance(CachedRepositoryConfiguration.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(configuration, writer);
}
catch (JAXBException e)
{
throw new RedmineException("Failed to serialize configuration to configuration file",e);
}
finally
{
try
{
writer.close();
}
catch (IOException e)
{
}
}
}
private File getConfigurationFileForUrl(String repositoryUrl) throws RedmineException
{
String encodedFilename = null;
try
{
encodedFilename = URLEncoder.encode(repositoryUrl,"UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new RedmineException("Failed to encode repository url as filename",e);
}
File destinationFile = stateLocationPath.append(encodedFilename).toFile();
return destinationFile;
}
}