diff options
author | Sam Davis | 2016-07-20 03:53:53 +0000 |
---|---|---|
committer | Sam Davis | 2016-07-20 21:21:59 +0000 |
commit | b7621a8cb6f0306a65499b3802640a23f01c9ac0 (patch) | |
tree | 6ee20d5b65e830ac19b7eb457ef75bbeddbb1b12 /connector-bugzilla-rest | |
parent | 7305015c049e295171c6ebb3930f001eea16c9e0 (diff) | |
download | org.eclipse.mylyn.tasks-b7621a8cb6f0306a65499b3802640a23f01c9ac0.tar.gz org.eclipse.mylyn.tasks-b7621a8cb6f0306a65499b3802640a23f01c9ac0.tar.xz org.eclipse.mylyn.tasks-b7621a8cb6f0306a65499b3802640a23f01c9ac0.zip |
495085: Bugzilla REST connector should use proxy information from
TaskRepository
Change-Id: I1b8734a3080c4c777e427017e6d53dca960fb043
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=495085
Diffstat (limited to 'connector-bugzilla-rest')
-rw-r--r-- | connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConnector.java | 943 |
1 files changed, 482 insertions, 461 deletions
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConnector.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConnector.java index bc6092738..4c1375b5e 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConnector.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConnector.java @@ -1,461 +1,482 @@ -/******************************************************************************* - * Copyright (c) 2013 Frank Becker 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: - * Frank Becker - initial API and implementation - *******************************************************************************/ - -package org.eclipse.mylyn.internal.bugzilla.rest.core; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.Date; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -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.jdt.annotation.Nullable; -import org.eclipse.mylyn.commons.core.StatusHandler; -import org.eclipse.mylyn.commons.core.operations.IOperationMonitor; -import org.eclipse.mylyn.commons.core.operations.OperationUtil; -import org.eclipse.mylyn.commons.net.AuthenticationCredentials; -import org.eclipse.mylyn.commons.net.Policy; -import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation; -import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationType; -import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials; -import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Field; -import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.FieldValues; -import org.eclipse.mylyn.internal.commons.core.operations.NullOperationMonitor; -import org.eclipse.mylyn.internal.tasks.core.IRepositoryConstants; -import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector; -import org.eclipse.mylyn.tasks.core.IRepositoryQuery; -import org.eclipse.mylyn.tasks.core.ITask; -import org.eclipse.mylyn.tasks.core.RepositoryInfo; -import org.eclipse.mylyn.tasks.core.RepositoryVersion; -import org.eclipse.mylyn.tasks.core.TaskRepository; -import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentHandler; -import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler; -import org.eclipse.mylyn.tasks.core.data.TaskAttribute; -import org.eclipse.mylyn.tasks.core.data.TaskData; -import org.eclipse.mylyn.tasks.core.data.TaskDataCollector; -import org.eclipse.mylyn.tasks.core.data.TaskMapper; -import org.eclipse.mylyn.tasks.core.sync.ISynchronizationSession; - -import com.google.common.base.Optional; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.UncheckedExecutionException; - -public class BugzillaRestConnector extends AbstractRepositoryConnector { - - public static final Duration CLIENT_CACHE_DURATION = new Duration(24, TimeUnit.HOURS); - - public static final Duration CONFIGURATION_CACHE_EXPIRE_DURATION = new Duration(7, TimeUnit.DAYS); - - public static final Duration CONFIGURATION_CACHE_REFRESH_AFTER_WRITE_DURATION = new Duration(1, TimeUnit.DAYS); - - private static final ThreadLocal<IOperationMonitor> context = new ThreadLocal<IOperationMonitor>(); - - private BugzillaRestTaskAttachmentHandler attachmentHandler; - - private boolean ignoredProperty(String propertyName) { - if (propertyName.equals(RepositoryLocation.PROPERTY_LABEL) || propertyName.equals(TaskRepository.OFFLINE) - || propertyName.equals(IRepositoryConstants.PROPERTY_ENCODING) - || propertyName.equals(TaskRepository.PROXY_HOSTNAME) || propertyName.equals(TaskRepository.PROXY_PORT) - || propertyName.equals("org.eclipse.mylyn.tasklist.repositories.savePassword") //$NON-NLS-1$ - || propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.usedefault") //$NON-NLS-1$ - || propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.savePassword") //$NON-NLS-1$ - || propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.username") //$NON-NLS-1$ - || propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.password") //$NON-NLS-1$ - || propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.enabled")) { //$NON-NLS-1$ - return true; - } - return false; - } - - private final PropertyChangeListener repositoryChangeListener4ClientCache = new PropertyChangeListener() { - - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (ignoredProperty(evt.getPropertyName())) { - return; - } - TaskRepository taskRepository = (TaskRepository) evt.getSource(); - clientCache.invalidate(new RepositoryKey(taskRepository)); - } - }; - - private final PropertyChangeListener repositoryChangeListener4ConfigurationCache = new PropertyChangeListener() { - - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (ignoredProperty(evt.getPropertyName()) - || evt.getPropertyName().equals("org.eclipse.mylyn.tasklist.repositories.password")) { //$NON-NLS-1$ - return; - } - TaskRepository taskRepository = (TaskRepository) evt.getSource(); - configurationCache.invalidate(new RepositoryKey(taskRepository)); - } - }; - - private final LoadingCache<RepositoryKey, BugzillaRestClient> clientCache = CacheBuilder.newBuilder() - .expireAfterAccess(CLIENT_CACHE_DURATION.getValue(), CLIENT_CACHE_DURATION.getUnit()) - .build(new CacheLoader<RepositoryKey, BugzillaRestClient>() { - - @Override - public BugzillaRestClient load(RepositoryKey key) throws Exception { - TaskRepository repository = key.getRepository(); - repository.addChangeListener(repositoryChangeListener4ClientCache); - return createClient(repository); - } - }); - - private final LoadingCache<RepositoryKey, Optional<BugzillaRestConfiguration>> configurationCache; - - public BugzillaRestConnector() { - this(CONFIGURATION_CACHE_REFRESH_AFTER_WRITE_DURATION); - } - - public BugzillaRestConnector(Duration refreshAfterWriteDuration) { - super(); - this.attachmentHandler = new BugzillaRestTaskAttachmentHandler(this); - configurationCache = createCacheBuilder(CONFIGURATION_CACHE_EXPIRE_DURATION, refreshAfterWriteDuration) - .build(new CacheLoader<RepositoryKey, Optional<BugzillaRestConfiguration>>() { - - @Override - public Optional<BugzillaRestConfiguration> load(RepositoryKey key) throws Exception { - BugzillaRestClient client = clientCache.get(key); - TaskRepository repository = key.getRepository(); - repository.addChangeListener(repositoryChangeListener4ConfigurationCache); - return Optional.fromNullable(client.getConfiguration(key.getRepository(), context.get())); - } - - @Override - public ListenableFuture<Optional<BugzillaRestConfiguration>> reload(final RepositoryKey key, - Optional<BugzillaRestConfiguration> oldValue) throws Exception { - // asynchronous! - ListenableFutureJob<Optional<BugzillaRestConfiguration>> job = new ListenableFutureJob<Optional<BugzillaRestConfiguration>>( - "") { - - @Override - protected IStatus run(IProgressMonitor monitor) { - BugzillaRestClient client; - try { - client = clientCache.get(key); - set(Optional - .fromNullable(client.getConfiguration(key.getRepository(), context.get()))); - } catch (ExecutionException e) { - e.printStackTrace(); - return new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, - "BugzillaRestConnector reload Configuration", e); - } - return Status.OK_STATUS; - } - }; - job.schedule(); - return job; - } - }); - } - - protected CacheBuilder<Object, Object> createCacheBuilder(Duration expireAfterWriteDuration, - Duration refreshAfterWriteDuration) { - return CacheBuilder.newBuilder() - .expireAfterWrite(expireAfterWriteDuration.getValue(), expireAfterWriteDuration.getUnit()) - .refreshAfterWrite(refreshAfterWriteDuration.getValue(), refreshAfterWriteDuration.getUnit()); - } - - @Override - public boolean canCreateNewTask(TaskRepository repository) { - return true; - } - - @Override - public boolean canCreateTaskFromKey(TaskRepository repository) { - // ignore - return false; - } - - @Override - public String getConnectorKind() { - return BugzillaRestCore.CONNECTOR_KIND; - } - - @Override - public String getLabel() { - return "Bugzilla 5.0 or later with REST"; - } - - @Override - public String getRepositoryUrlFromTaskUrl(String taskUrl) { - if (taskUrl == null) { - return null; - } - int index = taskUrl.indexOf("/rest.cgi/"); //$NON-NLS-1$ - return index == -1 ? null : taskUrl.substring(0, index); - } - - @Override - public TaskData getTaskData(TaskRepository repository, String taskIdOrKey, IProgressMonitor monitor) - throws CoreException { - return ((BugzillaRestTaskDataHandler) getTaskDataHandler()).getTaskData(repository, taskIdOrKey, monitor); - } - - @Override - public String getTaskIdFromTaskUrl(String taskUrl) { - // ignore - return null; - } - - @Override - public String getTaskUrl(String repositoryUrl, String taskIdOrKey) { - return repositoryUrl + "/rest.cgi/bug/" + taskIdOrKey; //$NON-NLS-1$ - } - - @Override - public boolean hasTaskChanged(TaskRepository taskRepository, ITask task, TaskData taskData) { - // ignore - return false; - } - - @Override - public IStatus performQuery(TaskRepository repository, IRepositoryQuery query, TaskDataCollector collector, - ISynchronizationSession session, IProgressMonitor monitor) { - monitor = Policy.monitorFor(monitor); - try { - monitor.beginTask("performQuery", IProgressMonitor.UNKNOWN); - BugzillaRestClient client = getClient(repository); - IOperationMonitor progress = OperationUtil.convert(monitor, "performQuery", 3); //$NON-NLS-1$ - return client.performQuery(repository, query, collector, progress); - } catch (CoreException e) { - return new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, IStatus.INFO, - "CoreException from performQuery", e); - } catch (BugzillaRestException e) { - return new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, IStatus.INFO, - "BugzillaRestException from performQuery", e); - } finally { - monitor.done(); - } - } - - @Override - public void updateRepositoryConfiguration(TaskRepository taskRepository, IProgressMonitor monitor) - throws CoreException { - context.set(monitor != null ? OperationUtil.convert(monitor) : new NullOperationMonitor()); - configurationCache.refresh(new RepositoryKey(taskRepository)); - context.remove(); - } - - @Override - public void updateTaskFromTaskData(TaskRepository taskRepository, ITask task, TaskData taskData) { - TaskMapper scheme = getTaskMapping(taskData); - scheme.applyTo(task); - task.setUrl(taskData.getRepositoryUrl() + "/rest.cgi/bug/" + taskData.getTaskId()); //$NON-NLS-1$ - - boolean isComplete = false; - TaskAttribute attributeStatus = taskData.getRoot().getMappedAttribute(TaskAttribute.STATUS); - if (attributeStatus != null) { - try { - BugzillaRestConfiguration configuration; - configuration = getRepositoryConfiguration(taskRepository); - if (configuration != null) { - Field stat = configuration.getFieldWithName(IBugzillaRestConstants.BUG_STATUS); - for (FieldValues fieldValue : stat.getValues()) { - if (attributeStatus.getValue().equals(fieldValue.getName())) { - isComplete = !fieldValue.isOpen(); - } - } - } - } catch (CoreException e) { - StatusHandler.log(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, - "Error during get BugzillaRestConfiguration", e)); - } - } - if (taskData.isPartial()) { - if (isComplete) { - if (task.getCompletionDate() == null) { - task.setCompletionDate(new Date(0)); - } - } else { - task.setCompletionDate(null); - } - } else { - inferCompletionDate(task, taskData, scheme, isComplete); - } - - } - - private void inferCompletionDate(ITask task, TaskData taskData, TaskMapper scheme, boolean isComplete) { - if (isComplete) { - Date completionDate = null; - List<TaskAttribute> taskComments = taskData.getAttributeMapper().getAttributesByType(taskData, - TaskAttribute.TYPE_COMMENT); - if (taskComments != null && taskComments.size() > 0) { - TaskAttribute lastComment = taskComments.get(taskComments.size() - 1); - if (lastComment != null) { - TaskAttribute attributeCommentDate = lastComment.getMappedAttribute(TaskAttribute.COMMENT_DATE); - if (attributeCommentDate != null) { - completionDate = new Date(Long.parseLong(attributeCommentDate.getValue())); - } - } - } - if (completionDate == null) { - // Use last modified date - TaskAttribute attributeLastModified = taskData.getRoot() - .getMappedAttribute(TaskAttribute.DATE_MODIFICATION); - if (attributeLastModified != null && attributeLastModified.getValue().length() > 0) { - completionDate = taskData.getAttributeMapper().getDateValue(attributeLastModified); - } - } - task.setCompletionDate(completionDate); - } else { - task.setCompletionDate(null); - } - // Bugzilla Specific Attributes - - // Product - if (scheme.getProduct() != null) { - task.setAttribute(BugzillaRestTaskSchema.getDefault().PRODUCT.getKey(), scheme.getProduct()); - } - - // Severity - TaskAttribute attrSeverity = taskData.getRoot() - .getMappedAttribute(BugzillaRestTaskSchema.getDefault().SEVERITY.getKey()); - if (attrSeverity != null && !attrSeverity.getValue().equals("")) { //$NON-NLS-1$ - task.setAttribute(BugzillaRestTaskSchema.getDefault().SEVERITY.getKey(), attrSeverity.getValue()); - } - - // Severity - TaskAttribute attrDelta = taskData.getRoot() - .getAttribute(BugzillaRestTaskSchema.getDefault().DATE_MODIFICATION.getKey()); - if (attrDelta != null && !attrDelta.getValue().equals("")) { //$NON-NLS-1$ - task.setAttribute(BugzillaRestTaskSchema.getDefault().DATE_MODIFICATION.getKey(), attrDelta.getValue()); - } - } - - @Override - public AbstractTaskDataHandler getTaskDataHandler() { - return new BugzillaRestTaskDataHandler(this); - } - - private BugzillaRestClient createClient(TaskRepository repository) { - RepositoryLocation location = new RepositoryLocation(repository.getProperties()); - AuthenticationCredentials credentials1 = repository - .getCredentials(org.eclipse.mylyn.commons.net.AuthenticationType.REPOSITORY); - UserCredentials credentials = new UserCredentials(credentials1.getUserName(), credentials1.getPassword(), null, - true); - location.setCredentials(AuthenticationType.REPOSITORY, credentials); - BugzillaRestClient client = new BugzillaRestClient(location, this); - - return client; - } - - /** - * Returns the Client for the {@link TaskRepository}. - * - * @param repository - * the {@link TaskRepository} object - * @return the client Object - * @throws CoreException - */ - public BugzillaRestClient getClient(TaskRepository repository) throws CoreException { - try { - return clientCache.get(new RepositoryKey(repository)); - } catch (ExecutionException e) { - throw new CoreException( - new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, "TaskRepositoryManager is null")); - } - } - - @Override - public RepositoryInfo validateRepository(TaskRepository repository, IProgressMonitor monitor) throws CoreException { - try { - BugzillaRestClient client = createClient(repository); - if (!client.validate(OperationUtil.convert(monitor))) { - throw new CoreException( - new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, "repository is invalide")); - } - BugzillaRestVersion version = client.getVersion(OperationUtil.convert(monitor)); - return new RepositoryInfo(new RepositoryVersion(version.toString())); - } catch (Exception e) { - throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, e.getMessage(), e)); - } - } - - public BugzillaRestConfiguration getRepositoryConfiguration(TaskRepository repository) throws CoreException { - if (clientCache.getIfPresent(new RepositoryKey(repository)) == null) { - getClient(repository); - } - try { - Optional<BugzillaRestConfiguration> configurationOptional = configurationCache - .get(new RepositoryKey(repository)); - return configurationOptional.isPresent() ? configurationOptional.get() : null; - } catch (UncheckedExecutionException e) { - throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, e.getMessage(), e)); - } catch (ExecutionException e) { - throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, e.getMessage(), e)); - } - } - - public void clearClientCache() { - clientCache.invalidateAll(); - } - - public void clearConfigurationCache() { - configurationCache.invalidateAll(); - } - - public void clearAllCaches() { - clearClientCache(); - clearConfigurationCache(); - } - - @Override - public boolean isRepositoryConfigurationStale(TaskRepository repository, IProgressMonitor monitor) - throws CoreException { - return false; - } - - @Override - public TaskMapper getTaskMapping(final TaskData taskData) { - - return new TaskMapper(taskData) { - @Override - public String getTaskKey() { - TaskAttribute attribute = getTaskData().getRoot() - .getAttribute(BugzillaRestTaskSchema.getDefault().BUG_ID.getKey()); - if (attribute != null) { - return attribute.getValue(); - } - return super.getTaskKey(); - } - - @Override - public String getTaskKind() { - return taskData.getConnectorKind(); - } - - @Override - public String getTaskUrl() { - return taskData.getRepositoryUrl(); - } - }; - } - - @Override - @Nullable - public AbstractTaskAttachmentHandler getTaskAttachmentHandler() { - return attachmentHandler; - } - -} +/*******************************************************************************
+ * Copyright (c) 2013 Frank Becker 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:
+ * Frank Becker - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.bugzilla.rest.core;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+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.jdt.annotation.Nullable;
+import org.eclipse.mylyn.commons.core.StatusHandler;
+import org.eclipse.mylyn.commons.core.operations.IOperationMonitor;
+import org.eclipse.mylyn.commons.core.operations.OperationUtil;
+import org.eclipse.mylyn.commons.net.AuthenticationCredentials;
+import org.eclipse.mylyn.commons.net.Policy;
+import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation;
+import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationType;
+import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials;
+import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Field;
+import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.FieldValues;
+import org.eclipse.mylyn.internal.commons.core.operations.NullOperationMonitor;
+import org.eclipse.mylyn.internal.tasks.core.IRepositoryConstants;
+import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
+import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.mylyn.tasks.core.RepositoryInfo;
+import org.eclipse.mylyn.tasks.core.RepositoryVersion;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentHandler;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.eclipse.mylyn.tasks.core.data.TaskDataCollector;
+import org.eclipse.mylyn.tasks.core.data.TaskMapper;
+import org.eclipse.mylyn.tasks.core.sync.ISynchronizationSession;
+
+import com.google.common.base.Optional;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.UncheckedExecutionException;
+
+public class BugzillaRestConnector extends AbstractRepositoryConnector {
+
+ public static final Duration CLIENT_CACHE_DURATION = new Duration(24, TimeUnit.HOURS);
+
+ public static final Duration CONFIGURATION_CACHE_EXPIRE_DURATION = new Duration(7, TimeUnit.DAYS);
+
+ public static final Duration CONFIGURATION_CACHE_REFRESH_AFTER_WRITE_DURATION = new Duration(1, TimeUnit.DAYS);
+
+ private static final ThreadLocal<IOperationMonitor> context = new ThreadLocal<IOperationMonitor>();
+
+ private BugzillaRestTaskAttachmentHandler attachmentHandler;
+
+ private boolean ignoredProperty(String propertyName) {
+ if (propertyName.equals(RepositoryLocation.PROPERTY_LABEL) || propertyName.equals(TaskRepository.OFFLINE)
+ || propertyName.equals(IRepositoryConstants.PROPERTY_ENCODING)
+ || propertyName.equals(TaskRepository.PROXY_HOSTNAME) || propertyName.equals(TaskRepository.PROXY_PORT)
+ || propertyName.equals("org.eclipse.mylyn.tasklist.repositories.savePassword") //$NON-NLS-1$
+ || propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.usedefault") //$NON-NLS-1$
+ || propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.savePassword") //$NON-NLS-1$
+ || propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.username") //$NON-NLS-1$
+ || propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.password") //$NON-NLS-1$
+ || propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.enabled")) { //$NON-NLS-1$
+ return true;
+ }
+ return false;
+ }
+
+ private final PropertyChangeListener repositoryChangeListener4ClientCache = new PropertyChangeListener() {
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (ignoredProperty(evt.getPropertyName())) {
+ return;
+ }
+ TaskRepository taskRepository = (TaskRepository) evt.getSource();
+ clientCache.invalidate(new RepositoryKey(taskRepository));
+ }
+ };
+
+ private final PropertyChangeListener repositoryChangeListener4ConfigurationCache = new PropertyChangeListener() {
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (ignoredProperty(evt.getPropertyName())
+ || evt.getPropertyName().equals("org.eclipse.mylyn.tasklist.repositories.password")) { //$NON-NLS-1$
+ return;
+ }
+ TaskRepository taskRepository = (TaskRepository) evt.getSource();
+ configurationCache.invalidate(new RepositoryKey(taskRepository));
+ }
+ };
+
+ private final LoadingCache<RepositoryKey, BugzillaRestClient> clientCache = CacheBuilder.newBuilder()
+ .expireAfterAccess(CLIENT_CACHE_DURATION.getValue(), CLIENT_CACHE_DURATION.getUnit())
+ .build(new CacheLoader<RepositoryKey, BugzillaRestClient>() {
+
+ @Override
+ public BugzillaRestClient load(RepositoryKey key) throws Exception {
+ TaskRepository repository = key.getRepository();
+ repository.addChangeListener(repositoryChangeListener4ClientCache);
+ return createClient(repository);
+ }
+ });
+
+ private final LoadingCache<RepositoryKey, Optional<BugzillaRestConfiguration>> configurationCache;
+
+ public BugzillaRestConnector() {
+ this(CONFIGURATION_CACHE_REFRESH_AFTER_WRITE_DURATION);
+ }
+
+ public BugzillaRestConnector(Duration refreshAfterWriteDuration) {
+ super();
+ this.attachmentHandler = new BugzillaRestTaskAttachmentHandler(this);
+ configurationCache = createCacheBuilder(CONFIGURATION_CACHE_EXPIRE_DURATION, refreshAfterWriteDuration)
+ .build(new CacheLoader<RepositoryKey, Optional<BugzillaRestConfiguration>>() {
+
+ @Override
+ public Optional<BugzillaRestConfiguration> load(RepositoryKey key) throws Exception {
+ BugzillaRestClient client = clientCache.get(key);
+ TaskRepository repository = key.getRepository();
+ repository.addChangeListener(repositoryChangeListener4ConfigurationCache);
+ return Optional.fromNullable(client.getConfiguration(key.getRepository(), context.get()));
+ }
+
+ @Override
+ public ListenableFuture<Optional<BugzillaRestConfiguration>> reload(final RepositoryKey key,
+ Optional<BugzillaRestConfiguration> oldValue) throws Exception {
+ // asynchronous!
+ ListenableFutureJob<Optional<BugzillaRestConfiguration>> job = new ListenableFutureJob<Optional<BugzillaRestConfiguration>>(
+ "") {
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ BugzillaRestClient client;
+ try {
+ client = clientCache.get(key);
+ set(Optional
+ .fromNullable(client.getConfiguration(key.getRepository(), context.get())));
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ return new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN,
+ "BugzillaRestConnector reload Configuration", e);
+ }
+ return Status.OK_STATUS;
+ }
+ };
+ job.schedule();
+ return job;
+ }
+ });
+ }
+
+ protected CacheBuilder<Object, Object> createCacheBuilder(Duration expireAfterWriteDuration,
+ Duration refreshAfterWriteDuration) {
+ return CacheBuilder.newBuilder()
+ .expireAfterWrite(expireAfterWriteDuration.getValue(), expireAfterWriteDuration.getUnit())
+ .refreshAfterWrite(refreshAfterWriteDuration.getValue(), refreshAfterWriteDuration.getUnit());
+ }
+
+ @Override
+ public boolean canCreateNewTask(TaskRepository repository) {
+ return true;
+ }
+
+ @Override
+ public boolean canCreateTaskFromKey(TaskRepository repository) {
+ // ignore
+ return false;
+ }
+
+ @Override
+ public String getConnectorKind() {
+ return BugzillaRestCore.CONNECTOR_KIND;
+ }
+
+ @Override
+ public String getLabel() {
+ return "Bugzilla 5.0 or later with REST";
+ }
+
+ @Override
+ public String getRepositoryUrlFromTaskUrl(String taskUrl) {
+ if (taskUrl == null) {
+ return null;
+ }
+ int index = taskUrl.indexOf("/rest.cgi/"); //$NON-NLS-1$
+ return index == -1 ? null : taskUrl.substring(0, index);
+ }
+
+ @Override
+ public TaskData getTaskData(TaskRepository repository, String taskIdOrKey, IProgressMonitor monitor)
+ throws CoreException {
+ return ((BugzillaRestTaskDataHandler) getTaskDataHandler()).getTaskData(repository, taskIdOrKey, monitor);
+ }
+
+ @Override
+ public String getTaskIdFromTaskUrl(String taskUrl) {
+ // ignore
+ return null;
+ }
+
+ @Override
+ public String getTaskUrl(String repositoryUrl, String taskIdOrKey) {
+ return repositoryUrl + "/rest.cgi/bug/" + taskIdOrKey; //$NON-NLS-1$
+ }
+
+ @Override
+ public boolean hasTaskChanged(TaskRepository taskRepository, ITask task, TaskData taskData) {
+ // ignore
+ return false;
+ }
+
+ @Override
+ public IStatus performQuery(TaskRepository repository, IRepositoryQuery query, TaskDataCollector collector,
+ ISynchronizationSession session, IProgressMonitor monitor) {
+ monitor = Policy.monitorFor(monitor);
+ try {
+ monitor.beginTask("performQuery", IProgressMonitor.UNKNOWN);
+ BugzillaRestClient client = getClient(repository);
+ IOperationMonitor progress = OperationUtil.convert(monitor, "performQuery", 3); //$NON-NLS-1$
+ return client.performQuery(repository, query, collector, progress);
+ } catch (CoreException e) {
+ return new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, IStatus.INFO,
+ "CoreException from performQuery", e);
+ } catch (BugzillaRestException e) {
+ return new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, IStatus.INFO,
+ "BugzillaRestException from performQuery", e);
+ } finally {
+ monitor.done();
+ }
+ }
+
+ @Override
+ public void updateRepositoryConfiguration(TaskRepository taskRepository, IProgressMonitor monitor)
+ throws CoreException {
+ context.set(monitor != null ? OperationUtil.convert(monitor) : new NullOperationMonitor());
+ configurationCache.refresh(new RepositoryKey(taskRepository));
+ context.remove();
+ }
+
+ @Override
+ public void updateTaskFromTaskData(TaskRepository taskRepository, ITask task, TaskData taskData) {
+ TaskMapper scheme = getTaskMapping(taskData);
+ scheme.applyTo(task);
+ task.setUrl(taskData.getRepositoryUrl() + "/rest.cgi/bug/" + taskData.getTaskId()); //$NON-NLS-1$
+
+ boolean isComplete = false;
+ TaskAttribute attributeStatus = taskData.getRoot().getMappedAttribute(TaskAttribute.STATUS);
+ if (attributeStatus != null) {
+ try {
+ BugzillaRestConfiguration configuration;
+ configuration = getRepositoryConfiguration(taskRepository);
+ if (configuration != null) {
+ Field stat = configuration.getFieldWithName(IBugzillaRestConstants.BUG_STATUS);
+ for (FieldValues fieldValue : stat.getValues()) {
+ if (attributeStatus.getValue().equals(fieldValue.getName())) {
+ isComplete = !fieldValue.isOpen();
+ }
+ }
+ }
+ } catch (CoreException e) {
+ StatusHandler.log(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN,
+ "Error during get BugzillaRestConfiguration", e));
+ }
+ }
+ if (taskData.isPartial()) {
+ if (isComplete) {
+ if (task.getCompletionDate() == null) {
+ task.setCompletionDate(new Date(0));
+ }
+ } else {
+ task.setCompletionDate(null);
+ }
+ } else {
+ inferCompletionDate(task, taskData, scheme, isComplete);
+ }
+
+ }
+
+ private void inferCompletionDate(ITask task, TaskData taskData, TaskMapper scheme, boolean isComplete) {
+ if (isComplete) {
+ Date completionDate = null;
+ List<TaskAttribute> taskComments = taskData.getAttributeMapper().getAttributesByType(taskData,
+ TaskAttribute.TYPE_COMMENT);
+ if (taskComments != null && taskComments.size() > 0) {
+ TaskAttribute lastComment = taskComments.get(taskComments.size() - 1);
+ if (lastComment != null) {
+ TaskAttribute attributeCommentDate = lastComment.getMappedAttribute(TaskAttribute.COMMENT_DATE);
+ if (attributeCommentDate != null) {
+ completionDate = new Date(Long.parseLong(attributeCommentDate.getValue()));
+ }
+ }
+ }
+ if (completionDate == null) {
+ // Use last modified date
+ TaskAttribute attributeLastModified = taskData.getRoot()
+ .getMappedAttribute(TaskAttribute.DATE_MODIFICATION);
+ if (attributeLastModified != null && attributeLastModified.getValue().length() > 0) {
+ completionDate = taskData.getAttributeMapper().getDateValue(attributeLastModified);
+ }
+ }
+ task.setCompletionDate(completionDate);
+ } else {
+ task.setCompletionDate(null);
+ }
+ // Bugzilla Specific Attributes
+
+ // Product
+ if (scheme.getProduct() != null) {
+ task.setAttribute(BugzillaRestTaskSchema.getDefault().PRODUCT.getKey(), scheme.getProduct());
+ }
+
+ // Severity
+ TaskAttribute attrSeverity = taskData.getRoot()
+ .getMappedAttribute(BugzillaRestTaskSchema.getDefault().SEVERITY.getKey());
+ if (attrSeverity != null && !attrSeverity.getValue().equals("")) { //$NON-NLS-1$
+ task.setAttribute(BugzillaRestTaskSchema.getDefault().SEVERITY.getKey(), attrSeverity.getValue());
+ }
+
+ // Severity
+ TaskAttribute attrDelta = taskData.getRoot()
+ .getAttribute(BugzillaRestTaskSchema.getDefault().DATE_MODIFICATION.getKey());
+ if (attrDelta != null && !attrDelta.getValue().equals("")) { //$NON-NLS-1$
+ task.setAttribute(BugzillaRestTaskSchema.getDefault().DATE_MODIFICATION.getKey(), attrDelta.getValue());
+ }
+ }
+
+ @Override
+ public AbstractTaskDataHandler getTaskDataHandler() {
+ return new BugzillaRestTaskDataHandler(this);
+ }
+
+ private BugzillaRestClient createClient(TaskRepository repository) {
+ RepositoryLocation location = new RepositoryLocation(convertProperties(repository));
+ AuthenticationCredentials credentials1 = repository
+ .getCredentials(org.eclipse.mylyn.commons.net.AuthenticationType.REPOSITORY);
+ UserCredentials credentials = new UserCredentials(credentials1.getUserName(), credentials1.getPassword(), null,
+ true);
+ location.setCredentials(AuthenticationType.REPOSITORY, credentials);
+ BugzillaRestClient client = new BugzillaRestClient(location, this);
+
+ return client;
+ }
+
+ private Map<String, String> convertProperties(TaskRepository repository) {
+ return repository.getProperties()
+ .entrySet()
+ .stream()
+ .collect(Collectors.toMap(e -> convertProperty(e.getKey()), Map.Entry::getValue));
+ }
+
+ @SuppressWarnings("restriction")
+ private String convertProperty(String key) {
+ if (TaskRepository.PROXY_USEDEFAULT.equals(key)) {
+ return RepositoryLocation.PROPERTY_PROXY_USEDEFAULT;
+ } else if (TaskRepository.PROXY_HOSTNAME.equals(key)) {
+ return RepositoryLocation.PROPERTY_PROXY_HOST;
+ } else if (TaskRepository.PROXY_PORT.equals(key)) {
+ return RepositoryLocation.PROPERTY_PROXY_PORT;
+ }
+ return key;
+ }
+
+ /**
+ * Returns the Client for the {@link TaskRepository}.
+ *
+ * @param repository
+ * the {@link TaskRepository} object
+ * @return the client Object
+ * @throws CoreException
+ */
+ public BugzillaRestClient getClient(TaskRepository repository) throws CoreException {
+ try {
+ return clientCache.get(new RepositoryKey(repository));
+ } catch (ExecutionException e) {
+ throw new CoreException(
+ new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, "TaskRepositoryManager is null"));
+ }
+ }
+
+ @Override
+ public RepositoryInfo validateRepository(TaskRepository repository, IProgressMonitor monitor) throws CoreException {
+ try {
+ BugzillaRestClient client = createClient(repository);
+ if (!client.validate(OperationUtil.convert(monitor))) {
+ throw new CoreException(
+ new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, "repository is invalide"));
+ }
+ BugzillaRestVersion version = client.getVersion(OperationUtil.convert(monitor));
+ return new RepositoryInfo(new RepositoryVersion(version.toString()));
+ } catch (Exception e) {
+ throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, e.getMessage(), e));
+ }
+ }
+
+ public BugzillaRestConfiguration getRepositoryConfiguration(TaskRepository repository) throws CoreException {
+ if (clientCache.getIfPresent(new RepositoryKey(repository)) == null) {
+ getClient(repository);
+ }
+ try {
+ Optional<BugzillaRestConfiguration> configurationOptional = configurationCache
+ .get(new RepositoryKey(repository));
+ return configurationOptional.isPresent() ? configurationOptional.get() : null;
+ } catch (UncheckedExecutionException e) {
+ throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, e.getMessage(), e));
+ } catch (ExecutionException e) {
+ throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, e.getMessage(), e));
+ }
+ }
+
+ public void clearClientCache() {
+ clientCache.invalidateAll();
+ }
+
+ public void clearConfigurationCache() {
+ configurationCache.invalidateAll();
+ }
+
+ public void clearAllCaches() {
+ clearClientCache();
+ clearConfigurationCache();
+ }
+
+ @Override
+ public boolean isRepositoryConfigurationStale(TaskRepository repository, IProgressMonitor monitor)
+ throws CoreException {
+ return false;
+ }
+
+ @Override
+ public TaskMapper getTaskMapping(final TaskData taskData) {
+
+ return new TaskMapper(taskData) {
+ @Override
+ public String getTaskKey() {
+ TaskAttribute attribute = getTaskData().getRoot()
+ .getAttribute(BugzillaRestTaskSchema.getDefault().BUG_ID.getKey());
+ if (attribute != null) {
+ return attribute.getValue();
+ }
+ return super.getTaskKey();
+ }
+
+ @Override
+ public String getTaskKind() {
+ return taskData.getConnectorKind();
+ }
+
+ @Override
+ public String getTaskUrl() {
+ return taskData.getRepositoryUrl();
+ }
+ };
+ }
+
+ @Override
+ @Nullable
+ public AbstractTaskAttachmentHandler getTaskAttachmentHandler() {
+ return attachmentHandler;
+ }
+
+}
|