PageRenderTime 60ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/com.atlassian.connector.eclipse.team.ui/src/com/atlassian/connector/eclipse/team/ui/DefaultTeamUiResourceConnector.java

https://github.com/spingel/mylyn-reviews
Java | 382 lines | 273 code | 52 blank | 57 comment | 80 complexity | 4ab06d314b872af524c17228911029ce MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2009 Atlassian and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * Atlassian - initial API and implementation
  10. ******************************************************************************/
  11. package com.atlassian.connector.eclipse.team.ui;
  12. import com.atlassian.connector.eclipse.team.ui.exceptions.UnsupportedTeamProviderException;
  13. import com.atlassian.theplugin.commons.VersionedVirtualFile;
  14. import com.atlassian.theplugin.commons.crucible.api.UploadItem;
  15. import com.atlassian.theplugin.commons.crucible.api.model.CrucibleFileInfo;
  16. import com.atlassian.theplugin.commons.crucible.api.model.Review;
  17. import com.atlassian.theplugin.commons.util.MiscUtil;
  18. import org.eclipse.core.resources.IContainer;
  19. import org.eclipse.core.resources.IFile;
  20. import org.eclipse.core.resources.IProject;
  21. import org.eclipse.core.resources.IResource;
  22. import org.eclipse.core.resources.ResourcesPlugin;
  23. import org.eclipse.core.runtime.CoreException;
  24. import org.eclipse.core.runtime.IPath;
  25. import org.eclipse.core.runtime.IProgressMonitor;
  26. import org.eclipse.core.runtime.IStatus;
  27. import org.eclipse.core.runtime.Path;
  28. import org.eclipse.core.runtime.Platform;
  29. import org.eclipse.core.runtime.Status;
  30. import org.eclipse.mylyn.commons.core.StatusHandler;
  31. import org.eclipse.osgi.util.NLS;
  32. import org.eclipse.team.core.RepositoryProvider;
  33. import org.eclipse.team.core.TeamException;
  34. import org.eclipse.team.core.history.IFileHistory;
  35. import org.eclipse.team.core.history.IFileHistoryProvider;
  36. import org.eclipse.team.core.history.IFileRevision;
  37. import org.eclipse.team.core.subscribers.Subscriber;
  38. import org.eclipse.team.core.synchronize.SyncInfo;
  39. import org.jetbrains.annotations.NotNull;
  40. import org.jetbrains.annotations.Nullable;
  41. import org.osgi.framework.Bundle;
  42. import java.net.URI;
  43. import java.util.Collection;
  44. import java.util.Collections;
  45. import java.util.List;
  46. /**
  47. * A default team resource provider that just uses the limited Eclipse team API
  48. *
  49. * @author Shawn Minto
  50. */
  51. public class DefaultTeamUiResourceConnector extends AbstractTeamUiConnector {
  52. private static final String SUBVERSIVE_MINIMUM_VERSION = "0.7.8";
  53. public static final String TEAM_PROV_ID_SVN_SUBVERSIVE = "org.eclipse.team.svn.core.svnnature";
  54. public boolean isEnabled() {
  55. // the default one is always enabled
  56. return true;
  57. }
  58. public IFileRevision getFileRevision(IResource resource, String revisionString, IProgressMonitor monitor) {
  59. IProject project = resource.getProject();
  60. if (project == null) {
  61. StatusHandler.log(new Status(IStatus.ERROR, AtlassianTeamUiPlugin.PLUGIN_ID,
  62. "Unable to get project for resource"));
  63. return null;
  64. }
  65. RepositoryProvider rp = RepositoryProvider.getProvider(project);
  66. checkIfSupportedTeamProvider(rp);
  67. if (rp != null) {
  68. // this project has a team nature associated with it in the workspace
  69. IFileHistoryProvider historyProvider = rp.getFileHistoryProvider();
  70. if (historyProvider != null) {
  71. IFileHistory fileHistory = historyProvider.getFileHistoryFor(resource, IFileHistoryProvider.NONE,
  72. monitor);
  73. if (fileHistory != null) {
  74. IFileRevision fileRevision = fileHistory.getFileRevision(revisionString);
  75. if (fileRevision == null) {
  76. StatusHandler.log(new Status(IStatus.ERROR, AtlassianTeamUiPlugin.PLUGIN_ID, NLS.bind(
  77. "Could not get revision {0}", revisionString)));
  78. }
  79. return fileRevision;
  80. } else {
  81. StatusHandler.log(new Status(IStatus.ERROR, AtlassianTeamUiPlugin.PLUGIN_ID, NLS.bind(
  82. "Could not get file history for {0}", resource.getName())));
  83. }
  84. } else {
  85. StatusHandler.log(new Status(IStatus.ERROR, AtlassianTeamUiPlugin.PLUGIN_ID,
  86. "Could not get file history provider"));
  87. }
  88. } else {
  89. StatusHandler.log(new Status(IStatus.ERROR, AtlassianTeamUiPlugin.PLUGIN_ID, NLS.bind(
  90. "Could not get repository provider for project {0}", project.getName())));
  91. }
  92. return null;
  93. }
  94. public LocalStatus getLocalRevision(IResource resource) throws CoreException {
  95. //resource
  96. final IProject project = resource.getProject();
  97. if (project == null) {
  98. return null;
  99. }
  100. RepositoryProvider rp = RepositoryProvider.getProvider(project);
  101. checkIfSupportedTeamProvider(rp);
  102. if (rp == null) {
  103. return null;
  104. }
  105. final IFileHistoryProvider historyProvider = rp.getFileHistoryProvider();
  106. if (historyProvider != null) {
  107. // this project has a team nature associated with it in the workspace
  108. IFileRevision localFileRevision = historyProvider.getWorkspaceFileRevision(resource);
  109. if (localFileRevision == null) {
  110. return null;
  111. }
  112. final URI uri = localFileRevision.getURI();
  113. if (uri != null) {
  114. // for CVS URI will include also query with revision number (like ?r=3.23), we want to cut it off
  115. // without introducing dependency on CVS
  116. final String query = uri.getQuery();
  117. String uriStr = uri.toString();
  118. final int index = uriStr.lastIndexOf("?" + query);
  119. if (index != -1) {
  120. uriStr = uriStr.substring(0, index);
  121. }
  122. return LocalStatus.makeVersioned(uriStr, localFileRevision.getContentIdentifier());
  123. }
  124. return LocalStatus.makeAdded(localFileRevision.getContentIdentifier(), false);
  125. //
  126. // boolean inSync = isRemoteFileInSync(file, rp);
  127. //
  128. // if (inSync && localFileRevision.getContentIdentifier() != null) {
  129. //
  130. // for (CrucibleFileInfo fileInfo : activeReviewFiles) {
  131. // VersionedVirtualFile fileDescriptor = fileInfo.getFileDescriptor();
  132. // VersionedVirtualFile oldFileDescriptor = fileInfo.getOldFileDescriptor();
  133. //
  134. // IPath newPath = new Path(fileDescriptor.getUrl());
  135. // final IResource newResource = ResourcesPlugin.getWorkspace().getRoot().findMember(newPath);
  136. //
  137. // IPath oldPath = new Path(fileDescriptor.getUrl());
  138. // final IResource oldResource = ResourcesPlugin.getWorkspace().getRoot().findMember(oldPath);
  139. //
  140. // if ((newResource != null && newResource.equals(file))
  141. // || (oldResource != null && oldResource.equals(file))) {
  142. //
  143. // String revision = localFileRevision.getContentIdentifier();
  144. //
  145. // if (revision.equals(fileDescriptor.getRevision())) {
  146. // return new CrucibleFile(fileInfo, false);
  147. // }
  148. // if (revision.equals(oldFileDescriptor.getRevision())) {
  149. // return new CrucibleFile(fileInfo, true);
  150. // }
  151. // }
  152. // }
  153. //
  154. // return null;
  155. // }
  156. }
  157. return null;
  158. }
  159. public Collection<ScmRepository> getRepositories(IProgressMonitor monitor) {
  160. // @todo wseliga implement it
  161. return Collections.emptyList();
  162. }
  163. public ScmRepository getApplicableRepository(IResource resource) {
  164. // @todo wseliga
  165. return null;
  166. }
  167. public String getName() {
  168. return "Team API (partial support)";
  169. }
  170. public boolean haveMatchingResourcesRecursive(IResource[] roots, State filter) {
  171. return false;
  172. }
  173. @NotNull
  174. public Collection<UploadItem> getUploadItemsForResources(@NotNull IResource[] resources,
  175. @NotNull IProgressMonitor monitor) throws CoreException {
  176. return MiscUtil.buildArrayList();
  177. }
  178. @NotNull
  179. public IResource[] getMembersForContainer(@NotNull IContainer element) throws CoreException {
  180. return new IResource[0];
  181. }
  182. public List<IResource> getResourcesByFilterRecursive(IResource[] roots, State filter) {
  183. return MiscUtil.buildArrayList();
  184. }
  185. public boolean isResourceManagedBy(IResource resource) {
  186. return false;
  187. }
  188. private static void checkIfSupportedTeamProvider(RepositoryProvider rp) {
  189. //only support subversive > 0.7.8
  190. Bundle bundle = Platform.getBundle("org.eclipse.team.svn");
  191. if (bundle != null) {
  192. Object version = bundle.getHeaders().get("Bundle-Version");
  193. if (version != null && version instanceof String) {
  194. if (((String) version).compareTo(SUBVERSIVE_MINIMUM_VERSION) < 0) {
  195. throw new UnsupportedTeamProviderException("Subversive versions < 0.7.8 are not supported");
  196. } else {
  197. return;
  198. }
  199. }
  200. }
  201. if (rp != null && rp.getID().equals(TEAM_PROV_ID_SVN_SUBVERSIVE)) {
  202. throw new UnsupportedTeamProviderException("Subversive not supported");
  203. }
  204. }
  205. private String getLocalEncoding(IResource resource) {
  206. if (resource instanceof IFile) {
  207. IFile file = (IFile) resource;
  208. try {
  209. return file.getCharset();
  210. } catch (CoreException e) {
  211. StatusHandler.log(e.getStatus());
  212. }
  213. }
  214. return null;
  215. }
  216. @Nullable
  217. public CrucibleFile getCrucibleFileFromReview(@NotNull Review activeReview, @NotNull String fileUrl,
  218. @NotNull String revision) {
  219. for (CrucibleFileInfo fileInfo : activeReview.getFiles()) {
  220. VersionedVirtualFile fileDescriptor = fileInfo.getFileDescriptor();
  221. VersionedVirtualFile oldFileDescriptor = fileInfo.getOldFileDescriptor();
  222. String oldUrl = oldFileDescriptor.getUrl();
  223. String newUrl = fileDescriptor.getUrl();
  224. if ((newUrl != null && newUrl.length() > 0 && fileUrl.endsWith(newUrl))
  225. || (oldUrl != null && oldUrl.length() > 0 && fileUrl.endsWith(oldUrl))) {
  226. if (revision.equals(fileDescriptor.getRevision())) {
  227. return new CrucibleFile(fileInfo, false);
  228. }
  229. if (revision.equals(oldFileDescriptor.getRevision())) {
  230. return new CrucibleFile(fileInfo, true);
  231. }
  232. }
  233. }
  234. return null;
  235. }
  236. public CrucibleFile getCrucibleFileFromReview(Review review, IFile file) {
  237. IProject project = file.getProject();
  238. if (project == null) {
  239. StatusHandler.log(new Status(IStatus.ERROR, AtlassianTeamUiPlugin.PLUGIN_ID,
  240. "Unable to get project for resource"));
  241. return null;
  242. }
  243. RepositoryProvider rp = RepositoryProvider.getProvider(project);
  244. checkIfSupportedTeamProvider(rp);
  245. if (rp != null && rp.getFileHistoryProvider() != null) {
  246. // this project has a team nature associated with it in the workspace
  247. final IFileHistoryProvider historyProvider = rp.getFileHistoryProvider();
  248. IFileRevision localFileRevision = historyProvider.getWorkspaceFileRevision(file);
  249. boolean inSync = isRemoteFileInSync(file, rp);
  250. if (inSync && localFileRevision.getContentIdentifier() != null) {
  251. for (CrucibleFileInfo fileInfo : review.getFiles()) {
  252. VersionedVirtualFile fileDescriptor = fileInfo.getFileDescriptor();
  253. VersionedVirtualFile oldFileDescriptor = fileInfo.getOldFileDescriptor();
  254. IPath newPath = new Path(fileDescriptor.getUrl());
  255. final IResource newResource = findResourceForPath(newPath.toPortableString());
  256. IPath oldPath = new Path(fileDescriptor.getUrl());
  257. final IResource oldResource = findResourceForPath(oldPath.toPortableString());
  258. if ((newResource != null && newResource.equals(file))
  259. || (oldResource != null && oldResource.equals(file))) {
  260. String revision = localFileRevision.getContentIdentifier();
  261. if (revision.equals(fileDescriptor.getRevision())) {
  262. return new CrucibleFile(fileInfo, false);
  263. }
  264. if (revision.equals(oldFileDescriptor.getRevision())) {
  265. return new CrucibleFile(fileInfo, true);
  266. }
  267. }
  268. }
  269. return null;
  270. }
  271. }
  272. return null;
  273. }
  274. private static IResource findResourceForPath(String filePath) {
  275. IPath path = new Path(filePath);
  276. final IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
  277. if (resource == null) {
  278. return findResourceForPath2(filePath);
  279. }
  280. return resource;
  281. }
  282. private static IResource findResourceForPath2(String filePath) {
  283. if (filePath == null || filePath.length() <= 0) {
  284. return null;
  285. }
  286. IContainer location = ResourcesPlugin.getWorkspace().getRoot();
  287. IPath path = new Path(filePath);
  288. IResource resource = null;
  289. while (!path.isEmpty() && resource == null) {
  290. resource = match(location, path);
  291. path = path.removeFirstSegments(1);
  292. }
  293. return resource;
  294. }
  295. private static IResource match(IContainer location, IPath path) {
  296. if (!path.isEmpty()) {
  297. return location.findMember(path);
  298. }
  299. return null;
  300. }
  301. private static boolean isRemoteFileInSync(IResource resource, RepositoryProvider rp) {
  302. boolean inSync = false;
  303. Subscriber subscriber = rp.getSubscriber();
  304. if (subscriber != null) {
  305. try {
  306. SyncInfo syncInfo = subscriber.getSyncInfo(resource);
  307. if (syncInfo != null) {
  308. inSync = SyncInfo.isInSync(syncInfo.getKind());
  309. } else {
  310. StatusHandler.log(new Status(IStatus.WARNING, AtlassianTeamUiPlugin.PLUGIN_ID,
  311. "Unable to determine if file is in sync. Trying to open remote file."));
  312. }
  313. } catch (TeamException e) {
  314. StatusHandler.log(new Status(IStatus.WARNING, AtlassianTeamUiPlugin.PLUGIN_ID,
  315. "Unable to determine if file is in sync. Trying to open remote file.", e));
  316. }
  317. } else {
  318. StatusHandler.log(new Status(IStatus.WARNING, AtlassianTeamUiPlugin.PLUGIN_ID,
  319. "Unable to determine if file is in sync. Trying to open remote file."));
  320. }
  321. return inSync;
  322. }
  323. public boolean isResourceAcceptedByFilter(IResource resource, State state) {
  324. // ignore
  325. return false;
  326. }
  327. public boolean canHandleFile(IFile file) {
  328. return true;
  329. }
  330. }