| /******************************************************************************* |
| * Copyright (c) 2009 Tasktop Technologies and others. |
| * 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: |
| * Tasktop Technologies - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.mylyn.internal.oslc.core.client; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.apache.commons.httpclient.HostConfiguration; |
| import org.apache.commons.httpclient.HttpClient; |
| import org.apache.commons.httpclient.HttpMethodBase; |
| import org.apache.commons.httpclient.URIException; |
| import org.apache.commons.httpclient.cookie.CookiePolicy; |
| import org.apache.commons.httpclient.methods.GetMethod; |
| import org.apache.commons.httpclient.methods.PostMethod; |
| import org.apache.commons.httpclient.methods.PutMethod; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.mylyn.commons.net.AbstractWebLocation; |
| import org.eclipse.mylyn.commons.net.Policy; |
| import org.eclipse.mylyn.commons.net.WebUtil; |
| import org.eclipse.mylyn.internal.oslc.core.IOslcCoreConstants; |
| import org.eclipse.mylyn.internal.oslc.core.OslcCreationDialogDescriptor; |
| import org.eclipse.mylyn.internal.oslc.core.OslcSelectionDialogDescriptor; |
| import org.eclipse.mylyn.internal.oslc.core.OslcServiceDescriptor; |
| import org.eclipse.mylyn.internal.oslc.core.OslcServiceFactory; |
| import org.eclipse.mylyn.internal.oslc.core.OslcServiceProvider; |
| import org.eclipse.mylyn.internal.oslc.core.OslcServiceProviderCatalog; |
| import org.eclipse.mylyn.internal.oslc.core.ServiceHome; |
| import org.eclipse.mylyn.internal.oslc.core.cm.AbstractChangeRequest; |
| import org.eclipse.mylyn.tasks.core.RepositoryResponse; |
| import org.eclipse.mylyn.tasks.core.data.TaskAttribute; |
| import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper; |
| import org.eclipse.mylyn.tasks.core.data.TaskData; |
| import org.jdom.Attribute; |
| import org.jdom.Document; |
| import org.jdom.Element; |
| import org.jdom.JDOMException; |
| import org.jdom.filter.ElementFilter; |
| import org.jdom.input.SAXBuilder; |
| |
| /** |
| * Base class from which to implement an OSLC client |
| * |
| * @author Robert Elves |
| */ |
| public abstract class AbstractOslcClient { |
| |
| protected final AbstractWebLocation location; |
| |
| protected final HttpClient httpClient; |
| |
| protected final OslcServiceDescriptor configuration; |
| |
| public AbstractOslcClient(AbstractWebLocation location, OslcServiceDescriptor data) { |
| this.location = location; |
| this.httpClient = createHttpClient(); |
| this.configuration = data; |
| } |
| |
| protected HttpClient createHttpClient() { |
| HttpClient httpClient = new HttpClient(); |
| httpClient.setHttpConnectionManager(WebUtil.getConnectionManager()); |
| httpClient.getParams().setCookiePolicy(CookiePolicy.RFC_2109); |
| |
| // See: https://jazz.net/jazz/web/projects/Rational%20Team%20Concert#action=com.ibm.team.workitem.viewWorkItem&id=85127\ |
| // Added to support fix session cookie issue when talking to tomcat |
| httpClient.getParams().setParameter("http.protocol.single-cookie-header", true); //$NON-NLS-1$ |
| |
| WebUtil.configureHttpClient(httpClient, getUserAgent()); |
| return httpClient; |
| } |
| |
| /** |
| * Return your unique connector identifier i.e. com.mycompany.myconnector |
| */ |
| public abstract String getUserAgent(); |
| |
| /** |
| * Exposed at connector level via IOslcCoreConnector.getAvailableServices() |
| */ |
| public List<OslcServiceProvider> getAvailableServices(String url, IProgressMonitor monitor) throws CoreException { |
| |
| RequestHandler<List<OslcServiceProvider>> handler = new RequestHandler<List<OslcServiceProvider>>( |
| "Requesting Available Services") { //$NON-NLS-1$ |
| |
| @Override |
| public List<OslcServiceProvider> run(HttpMethodBase method, IProgressMonitor monitor) throws CoreException { |
| try { |
| final List<OslcServiceProvider> result = new ArrayList<OslcServiceProvider>(); |
| parseServices(method.getResponseBodyAsStream(), result, monitor); |
| return result; |
| } catch (IOException e) { |
| throw new CoreException(new Status(IStatus.ERROR, IOslcCoreConstants.ID_PLUGIN, |
| "Network error occurred retrieving available services: " + e.getMessage(), e)); //$NON-NLS-1$ |
| } |
| } |
| }; |
| |
| return executeMethod(createGetMethod(url), handler, monitor); |
| } |
| |
| protected Document getDocumentFromMethod(HttpMethodBase method) throws CoreException { |
| try { |
| return getDocumentFromStream(method.getResponseBodyAsStream()); |
| } catch (IOException e) { |
| throw new CoreException(new Status(IStatus.ERROR, IOslcCoreConstants.ID_PLUGIN, |
| "Network error obtaining response from server: " + e.getMessage(), e)); //$NON-NLS-1$ |
| } |
| } |
| |
| protected Document getDocumentFromStream(InputStream inStream) throws CoreException { |
| SAXBuilder builder = new SAXBuilder(); |
| builder.setExpandEntities(false); |
| try { |
| return builder.build(inStream); |
| } catch (JDOMException e) { |
| throw new CoreException(new Status(IStatus.ERROR, IOslcCoreConstants.ID_PLUGIN, |
| "Error parsing response: " + e.getMessage(), e)); //$NON-NLS-1$ |
| } catch (IOException e) { |
| throw new CoreException(new Status(IStatus.ERROR, IOslcCoreConstants.ID_PLUGIN, |
| "Network error parsing response: " + e.getMessage(), e)); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * public for testing |
| */ |
| public void parseServices(InputStream inStream, Collection<OslcServiceProvider> providers, IProgressMonitor monitor) |
| throws CoreException { |
| |
| Document doc = getDocumentFromStream(inStream); |
| |
| Iterator<?> itr = doc.getDescendants(new ElementFilter(IOslcCoreConstants.ELEMENT_SERVICE_PROVIDER_CATALOG)); |
| while (itr.hasNext()) { |
| Element element = (Element) itr.next(); |
| if (element != doc.getRootElement()) { |
| Attribute attrAbout = element.getAttribute(IOslcCoreConstants.ATTRIBUTE_ABOUT, |
| IOslcCoreConstants.NAMESPACE_RDF); |
| String title = element.getChild(IOslcCoreConstants.ELEMENT_TITLE, IOslcCoreConstants.NAMESPACE_DC) |
| .getText(); |
| if (attrAbout != null && attrAbout.getValue().length() > 0) { |
| providers.add(new OslcServiceProviderCatalog(title, attrAbout.getValue())); |
| } |
| } |
| } |
| itr = doc.getDescendants(new ElementFilter(IOslcCoreConstants.ELEMENT_SERVICE_PROVIDER)); |
| while (itr.hasNext()) { |
| Element element = (Element) itr.next(); |
| String title = element.getChild(IOslcCoreConstants.ELEMENT_TITLE, IOslcCoreConstants.NAMESPACE_DC) |
| .getText(); |
| Element service = element.getChild(IOslcCoreConstants.ELEMENT_SERVICES, |
| IOslcCoreConstants.NAMESPACE_OSLC_DISCOVERY_1_0); |
| if (service != null) { |
| String resource = service.getAttributeValue(IOslcCoreConstants.ATTRIBUTE_RESOURCE, |
| IOslcCoreConstants.NAMESPACE_RDF); |
| providers.add(new OslcServiceProvider(title, resource)); |
| } |
| } |
| } |
| |
| /** |
| * Retrieve a service descriptor for the given service provider. Exposed at connector level by |
| * IOslcConnector.getServiceDescriptor() |
| * |
| * @throws CoreException |
| */ |
| public OslcServiceDescriptor getServiceDescriptor(OslcServiceProvider provider, IProgressMonitor monitor) |
| throws CoreException { |
| OslcServiceDescriptor configuration = new OslcServiceDescriptor(provider.getUrl()); |
| downloadServiceDescriptor(configuration, monitor); |
| return configuration; |
| } |
| |
| /** |
| * Populate the provided configuration with new data from the remote repository. |
| */ |
| protected void downloadServiceDescriptor(final OslcServiceDescriptor config, IProgressMonitor monitor) |
| throws CoreException { |
| |
| RequestHandler<OslcServiceDescriptor> handler = new RequestHandler<OslcServiceDescriptor>( |
| "Retrieving Service Descriptor") { //$NON-NLS-1$ |
| |
| @Override |
| public OslcServiceDescriptor run(HttpMethodBase method, IProgressMonitor monitor) throws CoreException, |
| IOException { |
| config.clear(); |
| parseServiceDescriptor(method.getResponseBodyAsStream(), config, monitor); |
| return config; |
| } |
| }; |
| |
| executeMethod(createGetMethod(config.getAboutUrl()), handler, monitor); |
| |
| } |
| |
| /** |
| * public for testing |
| */ |
| public void parseServiceDescriptor(InputStream inStream, OslcServiceDescriptor config, IProgressMonitor monitor) |
| throws CoreException { |
| Document doc = getDocumentFromStream(inStream); |
| |
| Iterator<?> itr = doc.getDescendants(new ElementFilter(IOslcCoreConstants.ELEMENT_TITLE, |
| IOslcCoreConstants.NAMESPACE_DC)); |
| if (itr.hasNext()) { |
| Element element = (Element) itr.next(); |
| config.setTitle(element.getText()); |
| } |
| |
| itr = doc.getDescendants(new ElementFilter(IOslcCoreConstants.ELEMENT_DESCRIPTION, |
| IOslcCoreConstants.NAMESPACE_DC)); |
| if (itr.hasNext()) { |
| Element element = (Element) itr.next(); |
| config.setDescription(element.getText()); |
| } |
| |
| itr = doc.getDescendants(new ElementFilter(IOslcCoreConstants.ELEMENT_CREATIONDIALOG, |
| IOslcCoreConstants.NAMESPACE_OSLC_CM_1_0)); |
| while (itr.hasNext()) { |
| boolean isDefault = false; |
| Element element = (Element) itr.next(); |
| String label = element.getChild(IOslcCoreConstants.ELEMENT_TITLE, IOslcCoreConstants.NAMESPACE_DC) |
| .getText(); |
| String url = element.getChild(IOslcCoreConstants.ELEMENT_URL, IOslcCoreConstants.NAMESPACE_OSLC_CM_1_0) |
| .getText(); |
| Attribute attrDefault = element.getAttribute(IOslcCoreConstants.ATTRIBUTE_DEFAULT, |
| IOslcCoreConstants.NAMESPACE_OSLC_CM_1_0); |
| if (attrDefault != null && attrDefault.getValue().equals("true")) { //$NON-NLS-1$ |
| isDefault = true; |
| } |
| OslcCreationDialogDescriptor recordType = new OslcCreationDialogDescriptor(label, url); |
| config.addCreationDialog(recordType); |
| if (isDefault) { |
| config.setDefaultCreationDialog(recordType); |
| } |
| } |
| |
| itr = doc.getDescendants(new ElementFilter(IOslcCoreConstants.ELEMENT_SIMPLEQUERY)); |
| if (itr.hasNext()) { |
| Element element = (Element) itr.next(); |
| String url = element.getChild(IOslcCoreConstants.ELEMENT_URL, IOslcCoreConstants.NAMESPACE_OSLC_CM_1_0) |
| .getText(); |
| if (url != null) { |
| config.setSimpleQueryUrl(url); |
| } |
| } |
| |
| itr = doc.getDescendants(new ElementFilter(IOslcCoreConstants.ELEMENT_FACTORY)); |
| while (itr.hasNext()) { |
| boolean isDefault = false; |
| Element element = (Element) itr.next(); |
| String title = element.getChild(IOslcCoreConstants.ELEMENT_TITLE, IOslcCoreConstants.NAMESPACE_DC) |
| .getText(); |
| String url = element.getChild(IOslcCoreConstants.ELEMENT_URL, IOslcCoreConstants.NAMESPACE_OSLC_CM_1_0) |
| .getText(); |
| if (element.getAttribute(IOslcCoreConstants.ATTRIBUTE_DEFAULT) != null |
| && element.getAttribute(IOslcCoreConstants.ATTRIBUTE_DEFAULT).getValue().equals("true")) { //$NON-NLS-1$ |
| isDefault = true; |
| } |
| OslcServiceFactory factory = new OslcServiceFactory(title, url); |
| if (isDefault) { |
| config.setDefaultFactory(factory); |
| } |
| config.addServiceFactory(factory); |
| } |
| |
| itr = doc.getDescendants(new ElementFilter(IOslcCoreConstants.ELEMENT_HOME)); |
| if (itr.hasNext()) { |
| Element element = (Element) itr.next(); |
| Element childTitle = element.getChild(IOslcCoreConstants.ELEMENT_TITLE, IOslcCoreConstants.NAMESPACE_DC); |
| Element childUrl = element.getChild(IOslcCoreConstants.ELEMENT_URL, |
| IOslcCoreConstants.NAMESPACE_OSLC_CM_1_0); |
| if (childTitle != null && childTitle.getText().length() > 0 && childUrl != null |
| && childUrl.getText().length() > 0) { |
| ServiceHome home = new ServiceHome(childTitle.getText(), childUrl.getText()); |
| config.setHome(home); |
| } |
| } |
| |
| itr = doc.getDescendants(new ElementFilter(IOslcCoreConstants.ELEMENT_SELECTIONDIALOG)); |
| if (itr.hasNext()) { |
| Element element = (Element) itr.next(); |
| Element childTitle = element.getChild(IOslcCoreConstants.ELEMENT_TITLE, IOslcCoreConstants.NAMESPACE_DC); |
| Element childUrl = element.getChild(IOslcCoreConstants.ELEMENT_URL, |
| IOslcCoreConstants.NAMESPACE_OSLC_CM_1_0); |
| if (childTitle != null && childTitle.getText().length() > 0 && childUrl != null |
| && childUrl.getText().length() > 0) { |
| |
| OslcSelectionDialogDescriptor selection = new OslcSelectionDialogDescriptor(childTitle.getText(), |
| childUrl.getText()); |
| |
| String isDefault = element.getAttributeValue(IOslcCoreConstants.ATTRIBUTE_DEFAULT, |
| IOslcCoreConstants.NAMESPACE_OSLC_CM_1_0); |
| if (isDefault != null) { |
| selection.setDefault(isDefault.equals("true")); //$NON-NLS-1$ |
| } |
| |
| String hintHeight = element.getAttributeValue(IOslcCoreConstants.ATTRIBUTE_HINTHEIGHT, |
| IOslcCoreConstants.NAMESPACE_OSLC_CM_1_0); |
| if (hintHeight != null) { |
| selection.setHintHeight(hintHeight); |
| } |
| |
| String hintWidth = element.getAttributeValue(IOslcCoreConstants.ATTRIBUTE_HINTWIDTH, |
| IOslcCoreConstants.NAMESPACE_OSLC_CM_1_0); |
| if (hintWidth != null) { |
| selection.setHintWidth(hintWidth); |
| } |
| |
| String label = element.getChildText(IOslcCoreConstants.ELEMENT_LABEL, |
| IOslcCoreConstants.NAMESPACE_OSLC_CM_1_0); |
| if (label != null) { |
| selection.setLabel(label); |
| } |
| |
| config.addSelectionDialog(selection); |
| } |
| } |
| |
| } |
| |
| public Collection<AbstractChangeRequest> performQuery(String queryUrl, IProgressMonitor monitor) |
| throws CoreException { |
| |
| RequestHandler<Collection<AbstractChangeRequest>> handler = new RequestHandler<Collection<AbstractChangeRequest>>( |
| "Performing Query") { //$NON-NLS-1$ |
| |
| @Override |
| public Collection<AbstractChangeRequest> run(HttpMethodBase method, IProgressMonitor monitor) |
| throws CoreException, IOException { |
| Collection<AbstractChangeRequest> result = new ArrayList<AbstractChangeRequest>(); |
| parseQueryResponse(method.getResponseBodyAsStream(), result, monitor); |
| return result; |
| } |
| }; |
| |
| return executeMethod(createGetMethod(queryUrl), handler, monitor); |
| |
| } |
| |
| // TODO: Handle pagination |
| public void parseQueryResponse(InputStream inStream, Collection<AbstractChangeRequest> requests, |
| IProgressMonitor monitor) throws CoreException { |
| Document doc = getDocumentFromStream(inStream); |
| |
| Iterator<?> itr = doc.getDescendants(new ElementFilter(IOslcCoreConstants.ELEMENT_CHANGEREQUEST, |
| IOslcCoreConstants.NAMESPACE_OSLC_CM_1_0)); |
| while (itr.hasNext()) { |
| Element element = (Element) itr.next(); |
| String title = element.getChildText(IOslcCoreConstants.ELEMENT_TITLE, IOslcCoreConstants.NAMESPACE_DC); |
| String id = element.getChildText(IOslcCoreConstants.ELEMENT_IDENTIFIER, IOslcCoreConstants.NAMESPACE_DC); |
| |
| if (title != null && id != null) { |
| AbstractChangeRequest request = createChangeRequest(id, title); |
| request.setType(element.getChildText(IOslcCoreConstants.ELEMENT_TYPE, IOslcCoreConstants.NAMESPACE_DC)); |
| request.setDescription(element.getChildText(IOslcCoreConstants.ELEMENT_DESCRIPTION, |
| IOslcCoreConstants.NAMESPACE_DC)); |
| request.setSubject(element.getChildText(IOslcCoreConstants.ELEMENT_SUBJECT, |
| IOslcCoreConstants.NAMESPACE_DC)); |
| request.setCreator(element.getChildText(IOslcCoreConstants.ELEMENT_CREATOR, |
| IOslcCoreConstants.NAMESPACE_DC)); |
| request.setModified(element.getChildText(IOslcCoreConstants.ELEMENT_MODIFIED, |
| IOslcCoreConstants.NAMESPACE_DC)); |
| requests.add(request); |
| } |
| |
| } |
| } |
| |
| protected abstract AbstractChangeRequest createChangeRequest(String id, String title); |
| |
| /** |
| * Updates this clients 'repository configuration'. If old types were in use (locally cached) and still exist they |
| * are re-read from repository. |
| */ |
| public void updateRepositoryConfiguration(IProgressMonitor monitor) throws CoreException { |
| configuration.clear(); |
| downloadServiceDescriptor(configuration, monitor); |
| } |
| |
| public abstract TaskData getTaskData(final String encodedTaskId, TaskAttributeMapper mapper, |
| IProgressMonitor monitor) throws CoreException; |
| |
| public abstract RepositoryResponse putTaskData(TaskData taskData, Set<TaskAttribute> oldValues, |
| IProgressMonitor monitor) throws CoreException; |
| |
| protected GetMethod createGetMethod(String requestPath) { |
| GetMethod method = new GetMethod(getRequestPath(requestPath)); |
| method.setFollowRedirects(true); |
| method.setDoAuthentication(true); |
| // application/xml is returned by oslc servers by default |
| //method.setRequestHeader("Accept", "application/xml"); |
| return method; |
| } |
| |
| protected PostMethod createPostMethod(String requestPath) { |
| PostMethod method = new PostMethod(getRequestPath(requestPath)); |
| method.setFollowRedirects(false); |
| method.setDoAuthentication(true); |
| // this.entity = getRequestEntity(method); |
| // if (pairs != null) { |
| // method.setRequestBody(pairs); |
| // } else if (entity != null) { |
| // method.setRequestEntity(entity); |
| // } else { |
| // StatusHandler.log(new Status(IStatus.WARNING, IOslcCoreConstants.ID_PLUGIN, |
| // "Request body or entity missing upon post.")); //$NON-NLS-1$ |
| // } |
| return method; |
| } |
| |
| protected PutMethod createPutMethod(String requestPath) { |
| PutMethod method = new PutMethod(getRequestPath(requestPath)); |
| method.setFollowRedirects(false); |
| method.setDoAuthentication(true); |
| return method; |
| } |
| |
| protected <T> T executeMethod(HttpMethodBase method, RequestHandler<T> handler, IProgressMonitor monitor) |
| throws CoreException { |
| monitor = Policy.monitorFor(monitor); |
| try { |
| monitor.beginTask(handler.getRequestName(), IProgressMonitor.UNKNOWN); |
| |
| HostConfiguration hostConfiguration = WebUtil.createHostConfiguration(httpClient, location, monitor); |
| int code = WebUtil.execute(httpClient, hostConfiguration, method, monitor); |
| |
| handler.handleReturnCode(code, method); |
| |
| return handler.run(method, monitor); |
| } catch (IOException e) { |
| throw new CoreException(new Status(IStatus.WARNING, IOslcCoreConstants.ID_PLUGIN, |
| "An unexpected network error has occurred: " + e.getMessage(), e)); //$NON-NLS-1$ |
| } finally { |
| if (method != null) { |
| method.releaseConnection(); |
| } |
| monitor.done(); |
| } |
| |
| } |
| |
| public String getRequestPath(String repositoryUrl) { |
| if (repositoryUrl.startsWith("./")) { //$NON-NLS-1$ |
| return WebUtil.getRequestPath(location.getUrl()) + repositoryUrl.substring(1); |
| } else if (repositoryUrl.startsWith("/")) { //$NON-NLS-1$ |
| return WebUtil.getRequestPath(location.getUrl()) + repositoryUrl; |
| } |
| return WebUtil.getRequestPath(repositoryUrl); |
| } |
| |
| public abstract class RequestHandler<T> { |
| |
| private final String requestName; |
| |
| public RequestHandler(String requestName) { |
| this.requestName = requestName; |
| } |
| |
| public abstract T run(HttpMethodBase method, IProgressMonitor monitor) throws CoreException, IOException; |
| |
| public String getRequestName() { |
| return requestName; |
| } |
| |
| protected void handleReturnCode(int code, HttpMethodBase method) throws CoreException { |
| try { |
| if (code == java.net.HttpURLConnection.HTTP_OK) { |
| return;// Status.OK_STATUS; |
| } else if (code == java.net.HttpURLConnection.HTTP_MOVED_TEMP |
| || code == java.net.HttpURLConnection.HTTP_CREATED) { |
| // A new resource created... |
| return;// Status.OK_STATUS; |
| } else if (code == java.net.HttpURLConnection.HTTP_UNAUTHORIZED |
| || code == java.net.HttpURLConnection.HTTP_FORBIDDEN) { |
| throw new CoreException(new Status(IStatus.ERROR, IOslcCoreConstants.ID_PLUGIN, |
| "Unable to log into server, ensure repository credentials are correct.")); //$NON-NLS-1$ |
| } else if (code == java.net.HttpURLConnection.HTTP_PRECON_FAILED) { |
| // Mid-air collision |
| throw new CoreException(new Status(IStatus.ERROR, IOslcCoreConstants.ID_PLUGIN, |
| "Mid-air collision occurred.")); //$NON-NLS-1$ |
| } else if (code == java.net.HttpURLConnection.HTTP_CONFLICT) { |
| throw new CoreException(new Status(IStatus.ERROR, IOslcCoreConstants.ID_PLUGIN, |
| "A conflict occurred.")); //$NON-NLS-1$ |
| } else { |
| throw new CoreException( |
| new Status( |
| IStatus.ERROR, |
| IOslcCoreConstants.ID_PLUGIN, |
| "Unknown error occurred. Http Code: " + code + " Request: " + method.getURI() + " Response: " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| + method.getResponseBodyAsString())); |
| } |
| } catch (URIException e) { |
| throw new CoreException(new Status(IStatus.ERROR, IOslcCoreConstants.ID_PLUGIN, "Network Error: " //$NON-NLS-1$ |
| + e.getMessage())); |
| } catch (IOException e) { |
| throw new CoreException(new Status(IStatus.ERROR, IOslcCoreConstants.ID_PLUGIN, "Network Error: " //$NON-NLS-1$ |
| + e.getMessage())); |
| } |
| } |
| |
| } |
| } |