/*******************************************************************************
* Copyright (c) 2009, 2010 Innovation Gate GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innovation Gate GmbH - initial API and implementation
******************************************************************************/
package de.innovationgate.eclipse.editors.helpers;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.eclipse.core.net.proxy.IProxyChangeEvent;
import org.eclipse.core.net.proxy.IProxyChangeListener;
import org.eclipse.core.net.proxy.IProxyService;
import org.eclipse.core.resources.IFile;
import de.innovationgate.eclipse.editors.Plugin;
import de.innovationgate.eclipse.editors.config.TMLTag;
import de.innovationgate.eclipse.editors.config.TMLTagAttribute;
import de.innovationgate.eclipse.editors.config.TMLTagDefinitions;
import de.innovationgate.eclipse.utils.Activator;
import de.innovationgate.eclipse.utils.DefaultHttpClient;
import de.innovationgate.eclipse.utils.wga.WGADesignStructureHelper;
import de.innovationgate.wga.common.beans.csconfig.v1.Version;
import de.innovationgate.wga.model.VersionCompliance;
/**
* provides context information based on the IG online help
* HTTP-Connection necessary
*/
public class HTTPContextInformationProvider implements ContextInformationProvider, IProxyChangeListener {
private static final String BASE_URL = "http://doc.openwga.com";
private static final String TAG_INFO_URL = BASE_URL + "/doc/eclipse/displayHelp?type=tag";
private static final String ATTRIBUTE_INFO_URL = BASE_URL + "/doc/eclipse/displayHelp?type=attribute";
private static final String BROWSE_DOCUMENTATION_URL = BASE_URL + "/doc/eclipse/openDocumentation";
private Map<String, String> _cache = new HashMap<String,String>();
private HttpClient _httpClient;
private int _connectionErrors = 0;
private static final int MAX_CONNECTION_ERRORS = 5;
public class HTTPContextInformation implements ContextInformation {
private String _tagname;
private String _attribute;
private String _value;
private IFile _tmlFile;
private VersionCompliance _versionCompliance;
public HTTPContextInformation(String tagname, String attribute, String value, IFile tmlFile) {
_tagname = tagname;
_attribute = attribute;
_value = value;
_tmlFile = tmlFile;
_versionCompliance = retrieveVersionCompliance(_tmlFile);
}
public URL getDocLocation() {
try {
String tagname = rewriteTagName(_tagname);
StringBuffer url = new StringBuffer();
url.append(BROWSE_DOCUMENTATION_URL);
url.append("?tag=" + tagname);
if (_attribute != null) {
url.append("&attribute=" + _attribute);
}
Version version = VersionCompliance.toWGAVersion(_versionCompliance);
if (version != null) {
url.append("&version=" + Integer.toString(version.getMajorVersion()) + Integer.toString(version.getMinorVersion()));
}
return new URL(url.toString());
} catch (Exception e) {
return null;
}
}
public String getInformation() {
String result = _cache.get(createCacheKey(_tagname, _attribute, _value, _versionCompliance));
if (result != null) {
return result;
} else {
if (_attribute != null) {
return retrieveAttributeHelp();
} else {
return retrieveTagHelp();
}
}
}
private String retrieveTagHelp() {
if (_connectionErrors < MAX_CONNECTION_ERRORS) {
StringBuffer information = new StringBuffer();
try {
// build online help url
GetMethod getMethod = new GetMethod(retrieveTagInfoURL(_tagname, _versionCompliance));
int returnCode = _httpClient.executeMethod(getMethod);
if (returnCode == HttpsURLConnection.HTTP_OK) {
information.append(getMethod.getResponseBodyAsString());
}
} catch (Exception e) {
Plugin.getDefault().logError("Unable to retrieve online help data.", e);
_connectionErrors ++;
}
String result = information.toString().trim();
if (result.length() > 0) {
_cache.put(createCacheKey(_tagname, _versionCompliance), result);
return result;
} else {
return null;
}
} else {
// too many connection errors
return null;
}
}
private String retrieveAttributeHelp() {
if (_connectionErrors < MAX_CONNECTION_ERRORS) {
StringBuffer information = new StringBuffer();
try {
// build online help url
GetMethod getMethod = null;
if (_attribute != null) {
getMethod = new GetMethod(retrieveAttributeInfoURL(_tagname, _attribute, _value, _versionCompliance));
}
if (getMethod != null) {
int returnCode = _httpClient.executeMethod(getMethod);
if (returnCode == HttpsURLConnection.HTTP_OK) {
information.append(getMethod.getResponseBodyAsString());
}
}
} catch (Exception e) {
Plugin.getDefault().logError("Unable to retrieve online help data.", e);
_connectionErrors++;
}
String result = information.toString().trim();
if (result.length() > 0) {
_cache.put(createCacheKey(_tagname, _attribute, _value, _versionCompliance), result);
return result;
} else {
return null;
}
} else {
// too many connection errors
return null;
}
}
}
public HTTPContextInformationProvider() {
IProxyService proxyService = Plugin.getDefault().getProxyService();
try {
_httpClient = new DefaultHttpClient(proxyService, new URI(BASE_URL));
} catch (URISyntaxException e) {
// should not happen
}
proxyService.addProxyChangeListener(this);
}
public ContextInformation getAttributeInformation(String tagname, String attribute, IFile file) {
return getAttributeInformation(tagname, attribute, null,file);
}
public ContextInformation getAttributeInformation(String tagname, String attribute, String value, IFile tmlFile) {
VersionCompliance versionCompliance = retrieveVersionCompliance(tmlFile);
if (value != null) {
// check if attribute value help is available - otherwise disable value lookup (set value to null)
TMLTag tag = TMLTagDefinitions.getInstance(versionCompliance).getTagByName(tagname);
if (tag != null) {
TMLTagAttribute tagAttribute = tag.getAttribute(attribute);
if (tagAttribute != null) {
if (!tagAttribute.isValueHelpEnabled()) {
value = null;
}
}
}
}
tagname = rewriteTagName(tagname);
return new HTTPContextInformation(tagname, attribute, value, tmlFile);
}
public ContextInformation getTagInformation(String tagname, IFile tmlFile) {
tagname = rewriteTagName(tagname);
return new HTTPContextInformation(tagname, null, null, tmlFile);
}
private String rewriteTagName(String tagname) {
// #00000116
if (tagname != null && tagname.matches("\\[.*\\]")) {
// dynamic tag -> show help of <tml:include> tag
tagname = "include";
}
return tagname;
}
private static String retrieveTagInfoURL(String tagname, VersionCompliance versionCompliance) {
StringBuffer url = new StringBuffer();
url.append(TAG_INFO_URL);
url.append("&tag=" + tagname);
Version version = VersionCompliance.toWGAVersion(versionCompliance);
if (version != null) {
url.append("&version=" + Integer.toString(version.getMajorVersion()) + Integer.toString(version.getMinorVersion()));
}
return url.toString();
}
private static String retrieveAttributeInfoURL(String tagname, String attribute, String value, VersionCompliance versionCompliance) {
StringBuffer url = new StringBuffer();
url.append(ATTRIBUTE_INFO_URL);
url.append("&tag=" + tagname);
url.append("&attribute=" + attribute);
if (value != null) {
url.append("&value=" + value);
}
Version version = VersionCompliance.toWGAVersion(versionCompliance);
if (version != null) {
url.append("&version=" + Integer.toString(version.getMajorVersion()) + Integer.toString(version.getMinorVersion()));
}
return url.toString();
}
private static String createCacheKey(String tagname, VersionCompliance compliance) {
return createCacheKey(tagname, null, null, compliance);
}
private static String createCacheKey(String tagname, String attribute, String value, VersionCompliance compliance) {
StringBuffer key = new StringBuffer();
if (tagname != null) {
key.append(tagname);
} else {
key.append("#NULL#");
}
if (attribute != null) {
key.append(attribute);
} else {
key.append("#NULL#");
}
if (value != null) {
key.append(value);
} else {
key.append("#NULL#");
}
if (compliance != null) {
key.append(compliance.getKey());
} else {
key.append("#NULL#");
}
return key.toString();
}
public void proxyInfoChanged(IProxyChangeEvent event) {
reset();
}
public void reset() {
// reset connection errors
_connectionErrors = 0;
}
private static VersionCompliance retrieveVersionCompliance(IFile tmlFile) {
if (tmlFile != null && tmlFile.exists()) {
return WGADesignStructureHelper.getWGAVersionCompliance(tmlFile);
} else {
return Activator.DEFAULT_VERSION_COMPLIANCE;
}
}
}