Package net.sf.redmine_mylyn.core

Source Code of net.sf.redmine_mylyn.core.RedmineRepositoryConnector

package net.sf.redmine_mylyn.core;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;

import net.sf.redmine_mylyn.api.exception.RedmineApiErrorException;
import net.sf.redmine_mylyn.api.model.Configuration;
import net.sf.redmine_mylyn.api.model.Issue;
import net.sf.redmine_mylyn.api.model.IssueStatus;
import net.sf.redmine_mylyn.api.model.Project;
import net.sf.redmine_mylyn.api.model.Tracker;
import net.sf.redmine_mylyn.api.query.Query;
import net.sf.redmine_mylyn.core.client.IClient;
import net.sf.redmine_mylyn.internal.core.Messages;
import net.sf.redmine_mylyn.internal.core.RedmineAttachmentHandler;
import net.sf.redmine_mylyn.internal.core.RedmineTaskMapper;
import net.sf.redmine_mylyn.internal.core.client.ClientManager;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.commons.net.Policy;
import org.eclipse.mylyn.internal.tasks.core.TaskTask;
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.TaskRepository;
import org.eclipse.mylyn.tasks.core.TaskRepositoryLocationFactory;
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.data.TaskRelation;
import org.eclipse.mylyn.tasks.core.sync.ISynchronizationSession;


public class RedmineRepositoryConnector extends AbstractRepositoryConnector {

  private TaskRepositoryLocationFactory locationFactory;
 
  private RedmineTaskDataHandler taskDataHandler;
 
  private ClientManager clientManager;
 
  public RedmineRepositoryConnector() {
    taskDataHandler = new RedmineTaskDataHandler(this);
  }

  public synchronized IRedmineClientManager getClientManager() {
    if (clientManager == null) {
      IPath path = RedmineCorePlugin.getDefault().getRepostioryAttributeCachePath();
      IPath path2 = RedmineCorePlugin.getDefault().getRepostioryAttributeCachePath2();
      clientManager = new ClientManager(locationFactory, path.toFile(), path2.toFile());
    }
    return clientManager;
  }
 
  public Configuration getRepositoryConfiguration(TaskRepository repository) {
    try {
      return getClientManager().getClient(repository).getConfiguration();
    } catch (RedmineStatusException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return new Configuration();
  }
 
  public void setTaskRepositoryLocationFactory(TaskRepositoryLocationFactory repositoryLocationFactory) {
    this.locationFactory = repositoryLocationFactory;
  }

  @Override
  public boolean canCreateNewTask(TaskRepository repository) {
    try {
      IClient client = getClientManager().getClient(repository);
      if (client!=null) {
        Configuration conf = client.getConfiguration();
        if (!conf.getProjects().isEmpty() && !conf.getTrackers().isEmpty()) {
          Project project = conf.getProjects().getAll().get(0);
          List<Tracker> trackers = conf.getTrackers().getById(project.getTrackerIds());
          if (trackers.size()>0) {
            return true;
          }
        }
       
      }
    } catch (RedmineStatusException e) {
      return false;
    }
    return false;
  }

  @Override
  public boolean canCreateTaskFromKey(TaskRepository repository) {
    try {
      return getClientManager().getClient(repository) != null;
    } catch (RedmineStatusException e) {
      return false;
    }
  }
 
  @Override
  public String getConnectorKind() {
    return RedmineCorePlugin.REPOSITORY_KIND;
  }

  @Override
  public String getLabel() {
    return Messages.REDMINE_CONNECTOR_LABEL;
  }

  @Override
  public String getRepositoryUrlFromTaskUrl(String arg0) {
    int index=arg0.indexOf(IRedmineConstants.REDMINE_URL_TICKET);
    return (index>0) ? arg0.substring(0, index) : null;
  }

  @Override
  public TaskData getTaskData(TaskRepository repository, String taskId, IProgressMonitor monitor) throws CoreException {
    monitor = Policy.monitorFor(monitor);
    monitor.beginTask(Messages.PROGRESS_TASK_DOWNLOAD, IProgressMonitor.UNKNOWN);
   
    TaskData taskData = null;
   
    try {
      int id = Integer.parseInt(taskId);

      IClient client = getClientManager().getClient(repository);
      Issue issue = client.getIssue(id, monitor);

      if(issue==null) {
        IStatus status = new Status(IStatus.INFO, RedmineCorePlugin.PLUGIN_ID, Messages.ERRMSG_CANT_FIND_ISSUE+taskId);
        throw new CoreException(status);
      }
      taskData = taskDataHandler.createTaskDataFromIssue(repository, issue, monitor);
    } catch (OperationCanceledException e) {
      throw new CoreException(new Status(IStatus.CANCEL, RedmineCorePlugin.PLUGIN_ID, Messages.OPERATION_CANCELED));
    } catch(NumberFormatException e) {
      throw new CoreException(RedmineCorePlugin.toStatus(e, Messages.ERRMSG_INVALID_TASKID_X, taskId));
    } catch (RedmineStatusException e) {
      throw new CoreException(e.getStatus());
    } finally {
      monitor.done();
    }

    return taskData;
  }

  public TaskData[] getTaskData(TaskRepository repository, Set<String> taskIds, IProgressMonitor monitor) throws CoreException {
    monitor = Policy.monitorFor(monitor);
    monitor.beginTask(Messages.PROGRESS_TASK_DOWNLOAD, IProgressMonitor.UNKNOWN);

    TaskData[] taskData = new TaskData[taskIds.size()];
   
    try {
      IClient client = getClientManager().getClient(repository);
      Issue[] issues = client.getIssues(taskIds, monitor);
     
      if(issues!=null) {
        for (int i=issues.length-1; i>=0; i--) {
          taskData[i] = taskDataHandler.createTaskDataFromIssue(repository, issues[i], monitor);
        }
      }
    } catch (OperationCanceledException e) {
      throw new CoreException(new Status(IStatus.CANCEL, RedmineCorePlugin.PLUGIN_ID, Messages.OPERATION_CANCELED));
    } catch (RedmineStatusException e) {
      throw new CoreException(e.getStatus());
    } finally {
      monitor.done();
    }
   
    return taskData;
  }
 
  @Override
  public String getTaskIdFromTaskUrl(String arg0) {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public String getTaskUrl(String repositoryUrl, String taskId) {
    return getTaskUrl(repositoryUrl, Integer.parseInt(taskId));
  }
 
  public static String getTaskUrl(String repositoryUrl, int taskId) {
    return repositoryUrl + IRedmineConstants.REDMINE_URL_TICKET + taskId;
  }

  @Override
  public boolean hasTaskChanged(TaskRepository taskRepository, ITask task, TaskData taskData) {
    TaskAttribute attribute = taskData.getRoot().getMappedAttribute(RedmineAttribute.DATE_UPDATED.getTaskKey());
    String repositoryDate = attribute.getValue();
    Date localeDate = task.getModificationDate();
    if (localeDate!=null) {
      //repo > local => 1
      return RedmineUtil.parseDate(repositoryDate).compareTo(localeDate)>0;
    }

    return true;
  }
 
  @SuppressWarnings("restriction")
  @Override
  public boolean canSynchronizeTask(TaskRepository taskRepository, ITask task) {
    //WORKAROUND: http://sourceforge.net/tracker/index.php?func=detail&aid=3069723&group_id=228995&atid=1075435
    if (task.getConnectorKind().equals("redmine")) { //$NON-NLS-1$
      if(task instanceof TaskTask) {
        try {
          Field f = TaskTask.class.getDeclaredField("connectorKind"); //$NON-NLS-1$
          f.setAccessible(true);
          f.set(task, RedmineCorePlugin.REPOSITORY_KIND);
        } catch (Exception e) {
          return false;
        }
      }
    }
    return true;
  }
 
  @Override
  public IStatus performQuery(TaskRepository repository, IRepositoryQuery repositoryQuery, TaskDataCollector collector, ISynchronizationSession session, IProgressMonitor monitor) {
   
    try {
      Query query = Query.fromUrl(repositoryQuery.getUrl(), repository.getCharacterEncoding(), getRepositoryConfiguration(repository));

      IClient client = getClientManager().getClient(repository);
      Issue[] partialIssues = client.query(query, monitor);
     
      for(Issue partialIssue : partialIssues) {
        Date updated = partialIssue.getUpdatedOn();
       
        // UpdatedOn should never be null
        if(updated==null) {
          IStatus status = new Status(IStatus.ERROR, RedmineCorePlugin.PLUGIN_ID, Messages.ERRMSG_MISSING_UPDATEDON);
          collector.failed(""+partialIssue.getId(), status); //$NON-NLS-1$
          continue;
        }

        TaskData taskData = taskDataHandler.createTaskDataFromIssue(repository, partialIssue, monitor);
        taskData.setPartial(true);
       
        collector.accept(taskData);
      }
     
    } catch (RedmineStatusException e) {
      IStatus status = e.getStatus();
      StatusHandler.log(status);
      return status;
    } catch (RedmineApiErrorException e) {
      IStatus status = RedmineCorePlugin.toStatus(e, Messages.ERRMSG_SYNCRONIZATION_FAILED);
      StatusHandler.log(status);
      return status;
    } catch (CoreException e) {
      e.getStatus();
    }
   
    return Status.OK_STATUS;
  }
 
  @Override
  public void preSynchronization(ISynchronizationSession session, IProgressMonitor monitor) throws CoreException {
    if (session.getTasks().isEmpty()) {
      return;
    }

    monitor = Policy.monitorFor(monitor);
    monitor.beginTask(Messages.PROGRESS_CHECKING_CHANGED_TASKS, 1);
   
    TaskRepository repository = session.getTaskRepository();
    if(repository.getSynchronizationTimeStamp()==null || repository.getSynchronizationTimeStamp().isEmpty()) {
      for (ITask task : session.getTasks()) {
        session.markStale(task);
      }
      return;
    }
   
    try {
      Date updatedSince = RedmineUtil.parseDate(repository.getSynchronizationTimeStamp());
      Set<ITask> tasks = session.getTasks();

      IClient client = getClientManager().getClient(repository);
      int[] changedIds = client.getUpdatedIssueIds(tasks, updatedSince, monitor);

      if(changedIds!=null && changedIds.length>0) {
        Arrays.sort(changedIds);
        for(ITask task : tasks) {
          if(Arrays.binarySearch(changedIds, RedmineUtil.parseIntegerId(task.getTaskId()))>=0) {
            session.markStale(task);
          }
        }
      }
    } catch (RedmineStatusException e) {
      throw new CoreException(e.getStatus());
    }
  }

  @Override
  public void postSynchronization(ISynchronizationSession event, IProgressMonitor monitor) throws CoreException {
    monitor = Policy.monitorFor(monitor);
    try {
      monitor.beginTask("", 1); //$NON-NLS-1$
      if (event.isFullSynchronization() && event.getStatus() == null) {
        event.getTaskRepository().setSynchronizationTimeStamp(""+getSynchronizationTimestamp(event)); //$NON-NLS-1$
      } else {
       
      }
    } finally {
      monitor.done();
    }
  }

  @Override
  public void updateRepositoryConfiguration(TaskRepository repository, IProgressMonitor monitor) throws CoreException {
    try {
      getClientManager().getClient(repository).updateConfiguration(monitor);
    } catch (RedmineStatusException e) {
      throw new CoreException(e.getStatus());
    }
  }

  @Override
  public void updateTaskFromTaskData(TaskRepository taskRepository, ITask task, TaskData taskData) {
    TaskMapper mapper = getTaskMapping(taskData);
    mapper.applyTo(task);

    task.setUrl(getTaskUrl(taskRepository.getUrl(), task.getTaskId()));
   
    Configuration configuration = getRepositoryConfiguration(taskRepository);
    Assert.isNotNull(configuration);
   
    //Set CompletionDate, if Closed-Status
    TaskAttribute attribute = taskData.getRoot().getMappedAttribute(RedmineAttribute.STATUS.getTaskKey());
    IssueStatus issueStatus = configuration.getIssueStatuses().getById(RedmineUtil.parseIntegerId(attribute.getValue()));
    if(issueStatus==null) {
      IStatus status = new Status(IStatus.ERROR, RedmineCorePlugin.PLUGIN_ID, Messages.ERRMSG_MISSING_ISSUE_STATUS+attribute.getValue());
      StatusHandler.log(status);
    } else {
      if(issueStatus.isClosed()) {
        Date date = task.getCompletionDate();
        attribute =  taskData.getRoot().getMappedAttribute(RedmineAttribute.DATE_UPDATED.getTaskKey());
        try {
          date = new Date(Long.parseLong(attribute.getValue()));
        } catch(NumberFormatException e) {
          IStatus status = RedmineCorePlugin.toStatus(e, Messages.ERRMSG_INVALID_TIMESTAMP_X, attribute.getValue());
          StatusHandler.log(status);
          date = new Date(0);
        }
        task.setCompletionDate(date);
      } else {
        task.setCompletionDate(null);
      }
    }

  }

  @Override
  public Collection<TaskRelation> getTaskRelations(TaskData taskData) {

    Collection<TaskRelation> relations = null;
   
    TaskAttribute parentAttribute = taskData.getRoot().getAttribute(RedmineAttribute.PARENT.getTaskKey());
    if (parentAttribute!=null && !parentAttribute.getValue().isEmpty()) {
     
      relations = new ArrayList<TaskRelation>(1);
      relations.add(TaskRelation.parentTask(parentAttribute.getValue()));
    }
   
    TaskAttribute subtaskAttribute = taskData.getRoot().getAttribute(RedmineAttribute.SUBTASKS.getTaskKey());
    if (subtaskAttribute!=null && subtaskAttribute.getValues().size()>0) {
      if (relations==null) {
        relations = new ArrayList<TaskRelation>();
      }
     
      for(String stringVal : subtaskAttribute.getValues()) {
        relations.add(TaskRelation.subtask(stringVal));
      }
    }
   
    return relations;
  }
 
 
  @Override
  public AbstractTaskDataHandler getTaskDataHandler() {
    return taskDataHandler;
  }

  @Override
  public TaskMapper getTaskMapping(TaskData taskData) {
    TaskRepository repository = taskData.getAttributeMapper().getTaskRepository();
    return new RedmineTaskMapper(taskData, getRepositoryConfiguration(repository));
  }

  @Override
  public AbstractTaskAttachmentHandler getTaskAttachmentHandler() {
    return new RedmineAttachmentHandler(this);
  }
 
  private long getSynchronizationTimestamp(ISynchronizationSession event) {
    Date mostRecent = new Date(0);
    String mostRecentTimeStamp = event.getTaskRepository().getSynchronizationTimeStamp();
    if (mostRecentTimeStamp != null) {
      mostRecent = RedmineUtil.parseDate(mostRecentTimeStamp);
    }
   
    for (ITask task : event.getChangedTasks()) {
      Date taskModifiedDate = task.getModificationDate();
      if (taskModifiedDate != null && taskModifiedDate.after(mostRecent)) {
        mostRecent = taskModifiedDate;
      }
    }
    return mostRecent.getTime();
  }
}
TOP

Related Classes of net.sf.redmine_mylyn.core.RedmineRepositoryConnector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.