1 11 package org.eclipse.team.core; 12 13 import java.net.URI ; 14 import java.util.*; 15 16 import org.eclipse.core.filesystem.EFS; 17 import org.eclipse.core.filesystem.URIUtil; 18 import org.eclipse.core.resources.*; 19 import org.eclipse.core.resources.team.*; 20 import org.eclipse.core.runtime.*; 21 import org.eclipse.core.runtime.jobs.*; 22 import org.eclipse.osgi.util.NLS; 23 import org.eclipse.team.core.history.IFileHistoryProvider; 24 import org.eclipse.team.core.subscribers.Subscriber; 25 import org.eclipse.team.internal.core.*; 26 27 56 public abstract class RepositoryProvider implements IProjectNature, IAdaptable { 57 58 private final static String TEAM_SETID = "org.eclipse.team.repository-provider"; 60 private final static List AllProviderTypeIds = initializeAllProviderTypes(); 61 62 private IProject project; 64 65 private static final ILock mappingLock = Job.getJobManager().newLock(); 67 68 private static final Object NOT_MAPPED = new Object (); 70 71 85 public static void map(IProject project, String id) throws TeamException { 86 ISchedulingRule rule = ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(project); 87 try { 88 Job.getJobManager().beginRule(rule, null); 95 try { 96 mappingLock.acquire(); 97 RepositoryProvider existingProvider = null; 98 99 if(project.getPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY) != null) 100 existingProvider = getProvider(project); 102 if(existingProvider != null) { 105 if(existingProvider.getID().equals(id)) 106 return; else 108 unmap(project); 109 } 110 111 RepositoryProvider provider = mapNewProvider(project, id); 114 115 try { 117 project.setPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY, id); 118 } catch (CoreException outer) { 119 try { 121 project.setSessionProperty(TeamPlugin.PROVIDER_PROP_KEY, null); 122 } catch (CoreException inner) { 123 TeamPlugin.log(IStatus.ERROR, NLS.bind(Messages.RepositoryProvider_couldNotClearAfterError, new String [] { project.getName(), id }), inner); 125 } 126 throw outer; 127 } 128 129 provider.configure(); 130 131 project.touch(null); 133 134 TeamHookDispatcher.setProviderRuleFactory(project, provider.getRuleFactory()); 137 138 RepositoryProviderManager.getInstance().providerMapped(provider); 140 } finally { 141 mappingLock.release(); 142 } 143 } catch (CoreException e) { 144 throw TeamPlugin.wrapException(e); 145 } finally { 146 Job.getJobManager().endRule(rule); 147 } 148 } 149 150 161 private static RepositoryProvider mapNewProvider(final IProject project, final String id) throws TeamException { 162 final RepositoryProvider provider = newProvider(id); 164 if(provider == null) 165 throw new TeamException(NLS.bind(Messages.RepositoryProvider_couldNotInstantiateProvider, new String [] { project.getName(), id })); 166 167 if (!provider.canHandleLinkedResourceURI()) { 169 try { 170 project.accept(new IResourceProxyVisitor() { 171 public boolean visit(IResourceProxy proxy) throws CoreException { 172 if (proxy.isLinked()) { 173 if (!provider.canHandleLinkedResources() || 174 proxy.requestFullPath().segmentCount() > 2 || 175 !EFS.SCHEME_FILE.equals(proxy.requestResource().getLocationURI().getScheme())) 176 throw new TeamException(new Status(IStatus.ERROR, TeamPlugin.ID, IResourceStatus.LINKING_NOT_ALLOWED, NLS.bind(Messages.RepositoryProvider_linkedURIsExist, new String [] { project.getName(), id }), null)); 177 } 178 return true; 179 } 180 }, IResource.NONE); 181 } catch (CoreException e) { 182 if (e instanceof TeamException) { 183 TeamException te = (TeamException) e; 184 throw te; 185 } 186 throw new TeamException(e); 187 } 188 } 189 if (!provider.canHandleLinkedResources()) { 190 try { 191 IResource[] members = project.members(); 192 for (int i = 0; i < members.length; i++) { 193 IResource resource = members[i]; 194 if (resource.isLinked()) { 195 throw new TeamException(new Status(IStatus.ERROR, TeamPlugin.ID, IResourceStatus.LINKING_NOT_ALLOWED, NLS.bind(Messages.RepositoryProvider_linkedResourcesExist, new String [] { project.getName(), id }), null)); 196 } 197 } 198 } catch (CoreException e) { 199 throw TeamPlugin.wrapException(e); 200 } 201 } 202 203 try { 205 project.setSessionProperty(TeamPlugin.PROVIDER_PROP_KEY, provider); 206 provider.setProject(project); 207 } catch (CoreException e) { 208 throw TeamPlugin.wrapException(e); 209 } 210 return provider; 211 } 212 213 private static RepositoryProvider mapExistingProvider(IProject project, String id) throws TeamException { 214 try { 215 mappingLock.acquire(); 218 try { 219 String currentId = project.getPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY); 222 if (currentId == null) { 223 return null; 225 } 226 if (!currentId.equals(id)) { 227 return lookupProviderProp(project); 231 } 232 } catch (CoreException e) { 233 throw TeamPlugin.wrapException(e); 234 } 235 return mapNewProvider(project, id); 236 } finally { 237 mappingLock.release(); 238 } 239 } 240 245 public static void unmap(IProject project) throws TeamException { 246 ISchedulingRule rule = ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(project); 247 try{ 248 Job.getJobManager().beginRule(rule, null); 250 try { 251 mappingLock.acquire(); 252 String id = project.getPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY); 253 254 if(id == null) { 256 throw new TeamException(NLS.bind(Messages.RepositoryProvider_No_Provider_Registered, new String [] { project.getName() })); 257 } 258 259 RepositoryProvider provider = getProvider(project); 262 if (provider == null) { 263 TeamPlugin.log(IStatus.ERROR, NLS.bind(Messages.RepositoryProvider_couldNotInstantiateProvider, new String [] { project.getName(), id }), null); 267 } 268 269 if (provider != null) provider.deconfigure(); 270 271 project.setSessionProperty(TeamPlugin.PROVIDER_PROP_KEY, null); 272 project.setPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY, null); 273 274 if (provider != null) provider.deconfigured(); 275 276 project.touch(null); 278 279 TeamHookDispatcher.setProviderRuleFactory(project, null); 282 283 RepositoryProviderManager.getInstance().providerUnmapped(project); 285 } finally { 286 mappingLock.release(); 287 } 288 } catch (CoreException e) { 289 throw TeamPlugin.wrapException(e); 290 } finally { 291 Job.getJobManager().endRule(rule); 292 } 293 } 294 295 298 private static RepositoryProvider lookupProviderProp(IProject project) throws CoreException { 299 Object provider = project.getSessionProperty(TeamPlugin.PROVIDER_PROP_KEY); 300 if (provider instanceof RepositoryProvider) { 301 return (RepositoryProvider) provider; 302 } 303 return null; 304 } 305 306 307 311 public RepositoryProvider() { 312 } 313 314 321 abstract public void configureProject() throws CoreException; 322 323 332 final public void configure() throws CoreException { 333 try { 334 configureProject(); 335 } catch(CoreException e) { 336 try { 337 RepositoryProvider.unmap(getProject()); 338 } catch(TeamException e2) { 339 throw new CoreException(new Status(IStatus.ERROR, TeamPlugin.ID, 0, Messages.RepositoryProvider_Error_removing_nature_from_project___1 + getID(), e2)); 340 } 341 throw e; 342 } 343 } 344 345 350 protected void deconfigured() { 351 } 352 353 359 abstract public String getID(); 360 361 372 public IFileModificationValidator getFileModificationValidator() { 373 return null; 374 } 375 376 397 public FileModificationValidator getFileModificationValidator2() { 398 final IFileModificationValidator fileModificationValidator = getFileModificationValidator(); 399 if (fileModificationValidator == null) 400 return null; 401 return new FileModificationValidator() { 402 public IStatus validateSave(IFile file) { 403 return fileModificationValidator.validateSave(file); 404 } 405 public IStatus validateEdit(IFile[] files, 406 FileModificationValidationContext context) { 407 Object shell; 409 if (context == null) 410 shell = null; 411 else 412 shell = context.getShell(); 413 return fileModificationValidator.validateEdit(files, shell); 414 } 415 }; 416 } 417 418 425 public IFileHistoryProvider getFileHistoryProvider(){ 426 return null; 427 } 428 429 440 public IMoveDeleteHook getMoveDeleteHook() { 441 return null; 442 } 443 444 453 public String toString() { 454 return NLS.bind(Messages.RepositoryProvider_toString, new String [] { getProject().getName(), getID() }); 455 } 456 457 462 final public static String [] getAllProviderTypeIds() { 463 IProjectNatureDescriptor[] desc = ResourcesPlugin.getWorkspace().getNatureDescriptors(); 464 Set teamSet = new HashSet(); 465 466 teamSet.addAll(AllProviderTypeIds); 468 for (int i = 0; i < desc.length; i++) { 470 String [] setIds = desc[i].getNatureSetIds(); 471 for (int j = 0; j < setIds.length; j++) { 472 if(setIds[j].equals(TEAM_SETID)) { 473 teamSet.add(desc[i].getNatureId()); 474 } 475 } 476 } 477 return (String []) teamSet.toArray(new String [teamSet.size()]); 478 } 479 480 489 final public static RepositoryProvider getProvider(IProject project) { 490 try { 491 if(project.isAccessible()) { 492 493 RepositoryProvider provider = lookupProviderProp(project); 496 if(provider != null) 497 return provider; 498 if (isMarkedAsUnshared(project)) 501 return null; 502 503 String id = project.getPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY); 506 if(id != null) 507 return mapExistingProvider(project, id); 508 509 IProjectDescription projectDesc = project.getDescription(); 512 String [] natureIds = projectDesc.getNatureIds(); 513 IWorkspace workspace = ResourcesPlugin.getWorkspace(); 514 for (int i = 0; i < natureIds.length; i++) { 517 IProjectNatureDescriptor desc = workspace.getNatureDescriptor(natureIds[i]); 518 if (desc != null) { 520 String [] setIds = desc.getNatureSetIds(); 521 for (int j = 0; j < setIds.length; j++) { 522 if(setIds[j].equals(TEAM_SETID)) { 523 return getProvider(project, natureIds[i]); 524 } 525 } 526 } 527 } 528 } 529 } catch(CoreException e) { 530 if (!isAcceptableException(e)) { 531 TeamPlugin.log(e); 532 } 533 } 534 markAsUnshared(project); 535 return null; 536 } 537 538 543 private static boolean isAcceptableException(CoreException e) { 544 return e.getStatus().getCode() == IResourceStatus.RESOURCE_NOT_FOUND; 545 } 546 547 556 final public static RepositoryProvider getProvider(IProject project, String id) { 557 try { 558 if(project.isAccessible()) { 559 RepositoryProvider provider = lookupProviderProp(project); if(provider != null) { 562 if (provider.getID().equals(id)) { 563 return provider; 564 } else { 565 return null; 566 } 567 } 568 if (isMarkedAsUnshared(project)) 571 return null; 572 573 String existingID = project.getPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY); 575 if(id.equals(existingID)) { 576 RepositoryProvider newProvider = mapExistingProvider(project, id); 578 if (newProvider!= null && newProvider.getID().equals(id)) { 579 return newProvider; 580 } else { 581 return null; 583 } 584 } 585 586 589 IProjectNatureDescriptor desc = ResourcesPlugin.getWorkspace().getNatureDescriptor(id); 592 if(desc == null) return null; 594 595 String [] setIds = desc.getNatureSetIds(); 596 for (int i = 0; i < setIds.length; i++) { 597 if(setIds[i].equals(TEAM_SETID)) { 598 return (RepositoryProvider)project.getNature(id); 599 } 600 } 601 } 602 } catch(CoreException e) { 603 if (!isAcceptableException(e)) { 604 TeamPlugin.log(e); 605 } 606 } 607 markAsUnshared(project); 608 return null; 609 } 610 611 626 public static boolean isShared(IProject project) { 627 if (!project.isAccessible()) return false; 628 try { 629 if (lookupProviderProp(project) != null) return true; 630 if (isMarkedAsUnshared(project)) 633 return false; 634 boolean shared = project.getPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY) != null; 635 if (!shared) 636 markAsUnshared(project); 637 return shared; 638 } catch (CoreException e) { 639 TeamPlugin.log(e); 640 return false; 641 } 642 } 643 644 private static boolean isMarkedAsUnshared(IProject project) { 645 try { 646 return project.getSessionProperty(TeamPlugin.PROVIDER_PROP_KEY) == NOT_MAPPED; 647 } catch (CoreException e) { 648 return false; 649 } 650 } 651 652 private static void markAsUnshared(IProject project) { 653 try { 654 project.setSessionProperty(TeamPlugin.PROVIDER_PROP_KEY, NOT_MAPPED); 655 } catch (CoreException e) { 656 } 658 } 659 660 663 public IProject getProject() { 664 return project; 665 } 666 667 670 public void setProject(IProject project) { 671 this.project = project; 672 } 673 674 private static List initializeAllProviderTypes() { 675 List allIDs = new ArrayList(); 676 677 TeamPlugin plugin = TeamPlugin.getPlugin(); 678 if (plugin != null) { 679 IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(TeamPlugin.ID, TeamPlugin.REPOSITORY_EXTENSION); 680 if (extension != null) { 681 IExtension[] extensions = extension.getExtensions(); 682 for (int i = 0; i < extensions.length; i++) { 683 IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); 684 for (int j = 0; j < configElements.length; j++) { 685 String extensionId = configElements[j].getAttribute("id"); allIDs.add(extensionId); 687 } 688 } 689 } 690 } 691 return allIDs; 692 } 693 694 private static RepositoryProvider newProvider(String id) { 695 TeamPlugin plugin = TeamPlugin.getPlugin(); 696 if (plugin != null) { 697 IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(TeamPlugin.ID, TeamPlugin.REPOSITORY_EXTENSION); 698 if (extension != null) { 699 IExtension[] extensions = extension.getExtensions(); 700 for (int i = 0; i < extensions.length; i++) { 701 IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); 702 for (int j = 0; j < configElements.length; j++) { 703 String extensionId = configElements[j].getAttribute("id"); if (extensionId != null && extensionId.equals(id)) { 705 try { 706 return (RepositoryProvider) configElements[j].createExecutableExtension("class"); } catch (CoreException e) { 708 TeamPlugin.log(e); 709 } catch (ClassCastException e) { 710 String className = configElements[j].getAttribute("class"); TeamPlugin.log(IStatus.ERROR, NLS.bind(Messages.RepositoryProvider_invalidClass, new String [] { id, className }), e); 712 } 713 return null; 714 } 715 } 716 } 717 } 718 } 719 return null; 720 } 721 722 740 public IStatus validateCreateLink(IResource resource, int updateFlags, IPath location) { 741 if (canHandleLinkedResources()) { 742 return Team.OK_STATUS; 743 } else { 744 return new Status(IStatus.ERROR, TeamPlugin.ID, IResourceStatus.LINKING_NOT_ALLOWED, NLS.bind(Messages.RepositoryProvider_linkedResourcesNotSupported, new String [] { getProject().getName(), getID() }), null); 745 } 746 } 747 748 765 public IStatus validateCreateLink(IResource resource, int updateFlags, URI location) { 766 if (resource.getProjectRelativePath().segmentCount() == 1 && EFS.SCHEME_FILE.equals(location.getScheme())) { 767 return validateCreateLink(resource, updateFlags, URIUtil.toPath(location)); 770 } 771 if (canHandleLinkedResourceURI()) { 772 return Team.OK_STATUS; 773 } else { 774 return new Status(IStatus.ERROR, TeamPlugin.ID, IResourceStatus.LINKING_NOT_ALLOWED, NLS.bind(Messages.RepositoryProvider_linkedURIsNotSupported, new String [] { getProject().getName(), getID() }), null); 775 } 776 } 777 778 794 public boolean canHandleLinkedResources() { 795 return canHandleLinkedResourceURI(); 796 } 797 798 818 public boolean canHandleLinkedResourceURI() { 819 return false; 820 } 821 822 823 826 public Object getAdapter(Class adapter) { 827 return null; 828 } 829 830 848 public IResourceRuleFactory getRuleFactory() { 849 return new PessimisticResourceRuleFactory(); 850 } 851 852 861 public final Subscriber getSubscriber() { 862 RepositoryProviderType type = RepositoryProviderType.getProviderType(getID()); 863 if (type != null) 864 return type.getSubscriber(); 865 return null; 866 } 867 } 868 | Popular Tags |