/**
   * Tests that the output folder settings for a source folder cause the class file containers to be
   * updated
   */
  public void testWPUpdateOutputFolderSrcFolderChanged() throws Exception {
    IJavaProject project = getTestingProject();
    IApiComponent component = getWorkspaceBaseline().getApiComponent(project.getElementName());
    assertNotNull("the workspace component must exist", component);
    int before = component.getApiTypeContainers().length;

    ProjectUtils.addFolderToProject(project.getProject(), "bin3");
    IContainer container = ProjectUtils.addFolderToProject(project.getProject(), "src2");
    // add to bundle class path
    IBundleProjectService service = ProjectUtils.getBundleProjectService();
    IBundleClasspathEntry next =
        service.newBundleClasspathEntry(new Path("src2"), new Path("bin3"), new Path("next.jar"));
    ProjectUtils.addBundleClasspathEntry(project.getProject(), next);
    waitForAutoBuild();

    // retrieve updated component
    component = getWorkspaceBaseline().getApiComponent(project.getElementName());
    assertTrue(
        "there must be one more container after the change",
        before < component.getApiTypeContainers().length);
    IPackageFragmentRoot root = project.getPackageFragmentRoot(container);
    assertTrue(
        "the class file container for src2 must be 'bin3'",
        "bin3".equals(root.getRawClasspathEntry().getOutputLocation().toFile().getName()));
  }
  /**
   * Tests that an exported package removal in the PDE model is reflected in the workspace api
   * baseline
   */
  public void testWPUpdateExportPackageRemoved() throws Exception {
    IJavaProject project = getTestingProject();
    assertNotNull("The testing project must exist", project);

    // add package
    assertTestPackage(
        project,
        new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute(),
        "export1");

    setPackageToApi(project, "export1");
    IApiAnnotations annot =
        getTestProjectApiDescription().resolveAnnotations(Factory.packageDescriptor("export1"));
    assertNotNull("there must be an annotation for the new exported package", annot);
    assertTrue(
        "the newly exported package must be API visibility",
        annot.getVisibility() == VisibilityModifiers.API);

    // remove exported packages
    IBundleProjectService service = ProjectUtils.getBundleProjectService();
    IBundleProjectDescription description = service.getDescription(project.getProject());
    description.setPackageExports(null);
    description.apply(null);

    // check the API description
    annot = getTestProjectApiDescription().resolveAnnotations(Factory.packageDescriptor("export1"));
    assertNotNull("should still be an annotation for the package", annot);
    assertTrue(
        "unexported package must be private", VisibilityModifiers.isPrivate(annot.getVisibility()));
  }
  /**
   * Adds a test library with the given name to the test projects' class path. The library is
   * imported from the {@link #PLUGIN_LOC} location.
   *
   * @param project the project to add the library classpath entry to
   * @param folderpath the path in the project where the library should be imported to
   * @param libname the name of the library
   */
  public IFolder assertTestLibrary(IJavaProject project, IPath folderpath, String libname)
      throws CoreException, InvocationTargetException, IOException {
    IFolder folder = null;
    // import library
    folder = project.getProject().getFolder(folderpath);
    if (!folder.exists()) {
      folder.create(false, true, null);
    }
    FileUtils.importFileFromDirectory(
        PLUGIN_LOC.append(libname).toFile(), folder.getFullPath(), null);
    IPath libPath = folder.getFullPath().append(libname);

    // add to manifest bundle classpath
    ProjectUtils.addBundleClasspathEntry(
        project.getProject(),
        ProjectUtils.getBundleProjectService()
            .newBundleClasspathEntry(null, null, libPath.removeFirstSegments(1)));
    waitForAutoBuild();
    return folder;
  }
  /** Tests removing a library from the classpath of a project */
  public void testWPUpdateLibraryRemovedFromClasspath() throws Exception {
    IPath libPath = null;
    try {
      IJavaProject project = getTestingProject();
      assertNotNull("The testing project must exist", project);

      // add to classpath
      IFolder folder = assertTestLibrary(project, new Path("libx"), "component.a_1.0.0.jar");
      IApiComponent component = getWorkspaceBaseline().getApiComponent(project.getElementName());
      assertNotNull("the workspace component must exist", component);
      int before = component.getApiTypeContainers().length;
      libPath = folder.getFullPath().append("component.a_1.0.0.jar");

      // remove classpath entry
      ProjectUtils.removeFromClasspath(project, JavaCore.newLibraryEntry(libPath, null, null));
      waitForAutoBuild();

      // remove from bundle class path
      IBundleProjectService service = ProjectUtils.getBundleProjectService();
      IBundleProjectDescription description = service.getDescription(project.getProject());
      description.setBundleClasspath(
          new IBundleClasspathEntry[] {
            service.newBundleClasspathEntry(new Path(ProjectUtils.SRC_FOLDER), null, null)
          });
      description.apply(null);
      waitForAutoBuild();

      // retrieve updated component
      component = getWorkspaceBaseline().getApiComponent(project.getElementName());
      assertTrue(
          "there must be less containers after the removal",
          before > component.getApiTypeContainers().length);
    } finally {
      if (libPath != null) {
        FileUtils.delete(libPath.toOSString());
      }
    }
  }
 /**
  * Tests that changing the output folder settings for a project cause the class file containers to
  * be updated
  */
 public void testWPUpdateDefaultOutputFolderChanged() throws Exception {
   IJavaProject project = getTestingProject();
   assertNotNull("The testing project must exist", project);
   IContainer container = ProjectUtils.addFolderToProject(project.getProject(), "bin2");
   assertNotNull("the new output folder cannot be null", container);
   IApiComponent component = getWorkspaceBaseline().getApiComponent(project.getElementName());
   assertNotNull("the workspace component must exist", component);
   int before = component.getApiTypeContainers().length;
   project.setOutputLocation(container.getFullPath(), new NullProgressMonitor());
   waitForAutoBuild();
   assertTrue(
       "there must be the same number of containers after the change",
       before == component.getApiTypeContainers().length);
   assertTrue(
       "the new output location should be 'bin2'",
       "bin2".equalsIgnoreCase(project.getOutputLocation().toFile().getName()));
 }
  /**
   * Tests that changing a directive to x-internal on an exported package causes the workspace api
   * baseline to be updated
   */
  public void testWPUPdateExportPackageDirectiveChangedToInternal() throws Exception {
    IJavaProject project = getTestingProject();
    assertNotNull("The testing project must exist", project);

    // add package
    assertTestPackage(
        project,
        new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute(),
        "export1");

    // export the package
    ProjectUtils.addExportedPackage(project.getProject(), "export1", true, null);

    // check the description
    IApiAnnotations annot =
        getTestProjectApiDescription().resolveAnnotations(Factory.packageDescriptor("export1"));
    assertNotNull("there must be an annotation for the new exported package", annot);
    assertTrue(
        "the changed exported package must be PRIVATE visibility",
        annot.getVisibility() == VisibilityModifiers.PRIVATE);
  }
 /**
  * sets the given package name to be an Exported-Package
  *
  * @param name
  */
 private void setPackageToApi(IJavaProject project, String name) throws CoreException {
   ProjectUtils.addExportedPackage(project.getProject(), name, false, null);
 }