/*
GanttProject is an opensource project management tool. License: GPL3
Copyright (C) 2012 GanttProject Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package net.sourceforge.ganttproject.document.webdav;
import io.milton.httpclient.Host;
import io.milton.httpclient.ProxyDetails;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.logging.Level;
import net.sourceforge.ganttproject.GPLogger;
import biz.ganttproject.core.option.DefaultStringOption;
import biz.ganttproject.core.option.StringOption;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
/**
* Caching factory of WebDavResource instances.
*
* @author dbarashev (Dmitry Barashev)
*/
class MiltonResourceFactory {
private static final int TIMEOUT_MS = 30000;
private static class Key {
String url;
String username;
String password;
Key(String url, String username, String password) {
this.url = url;
this.username = username;
this.password = password;
}
@Override
public int hashCode() {
return Objects.hashCode(url, username, password);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Key == false) {
return false;
}
Key that = (Key) obj;
return Objects.equal(this.url, that.url) && Objects.equal(this.username, that.username) && Objects.equal(this.password, that.password);
}
}
private final Map<String, Host> myHostCache = Maps.newHashMap();
private final Map<Key, MiltonResourceImpl> myResourceCache = Maps.newHashMap();
private String myUsername;
private String myPassword;
private final StringOption myProxy;
public MiltonResourceFactory() {
myProxy = new DefaultStringOption("");
}
public MiltonResourceFactory(String username, String password, StringOption proxyOption) {
myUsername = username;
myPassword = password;
myProxy = proxyOption;
}
MiltonResourceImpl createResource(WebDavUri uri) {
Key key = new Key(uri.buildUrl(), myUsername, myPassword);
MiltonResourceImpl result = myResourceCache.get(key);
if (result == null) {
result = new MiltonResourceImpl(uri, getHost(uri), this);
myResourceCache.put(key, result);
}
return result;
}
void clearCache() {
myResourceCache.clear();
}
public void setCredentials(String username, String password) {
myUsername = username;
myPassword = password;
}
private Host getHost(WebDavUri uri) {
String hostKey = uri.buildRootUrl();
Host result = myHostCache.get(hostKey);
if (result== null) {
result = new Host(uri.hostUrl, uri.rootPath, uri.port, myUsername, myPassword, getProxyDetails(myProxy), TIMEOUT_MS, null, null);
result.setSecure(uri.isSecure);
// myHostCache.put(hostKey, result);
}
return result;
}
static ProxyDetails getProxyDetails(StringOption proxyOption) {
if (Strings.isNullOrEmpty(proxyOption.getValue())) {
return null;
}
String url = proxyOption.getValue().trim();
ProxyDetails result = new ProxyDetails();
if ("system".equalsIgnoreCase(url)) {
result.setUseSystemProxy(true);
} else {
result.setUseSystemProxy(false);
if (!url.startsWith("http://") && !url.startsWith("https://")) {
url = "http://" + url;
}
try {
URL parsedUrl = new URL(url);
if (parsedUrl.getUserInfo() != null) {
String userInfo = parsedUrl.getUserInfo().replace("%40", "@");
int posColon = userInfo.indexOf(':');
String username = null;
String password = null;
if (posColon >= 0) {
username = userInfo.substring(0, posColon);
password = (posColon + 1) > userInfo.length() ? null : userInfo.substring(posColon + 1);
} else {
username = userInfo;
}
result.setUserName(username.replace("%3A", ":"));
result.setPassword(password == null ? null : password.replace("%3A", ":"));
}
result.setProxyHost(parsedUrl.getHost());
if (parsedUrl.getPort() != -1 && parsedUrl.getPort() != parsedUrl.getDefaultPort()) {
result.setProxyPort(parsedUrl.getPort());
}
} catch (MalformedURLException e) {
GPLogger.getLogger(MiltonResourceFactory.class).log(Level.WARNING, String.format("Failed to parse proxy settings: %s", url), e);
return null;
}
}
return result;
}
}