Example #1
0
public class RepositoryUtils {
  private static final ILogger logger = Logger.getLogger();

  private static final Object CACHE_REPO = "cache";
  private static final String VERSION_LATEST = "latest";

  public static List<RepositoryPlugin> listRepositories(boolean hideCache) {
    Workspace workspace;
    try {
      workspace = Central.getWorkspace();
    } catch (Exception e1) {
      return Collections.emptyList();
    }

    try {
      List<RepositoryPlugin> plugins = workspace.getPlugins(RepositoryPlugin.class);
      List<RepositoryPlugin> repos = new ArrayList<RepositoryPlugin>(plugins.size() + 1);

      repos.add(Central.getWorkspaceRepository());

      for (RepositoryPlugin plugin : plugins) {
        if (!hideCache || !CACHE_REPO.equals(plugin.getName())) repos.add(plugin);
      }
      return repos;
    } catch (Exception e) {
      logger.logError("Error loading repositories", e);
      return Collections.emptyList();
    }
  }

  public static VersionedClause convertRepoBundle(RepositoryBundle bundle) {
    Attrs attribs = new Attrs();
    if (isWorkspaceRepo(bundle.getRepo())) {
      attribs.put(Constants.VERSION_ATTRIBUTE, VERSION_LATEST);
    }
    return new VersionedClause(bundle.getBsn(), attribs);
  }

  public static VersionedClause convertRepoBundleVersion(RepositoryBundleVersion bundleVersion) {
    Attrs attribs = new Attrs();
    if (isWorkspaceRepo(bundleVersion.getBundle().getRepo()))
      attribs.put(Constants.VERSION_ATTRIBUTE, VERSION_LATEST);
    else attribs.put(Constants.VERSION_ATTRIBUTE, bundleVersion.getVersion().toString());
    return new VersionedClause(bundleVersion.getBundle().getBsn(), attribs);
  }

  public static boolean isWorkspaceRepo(RepositoryPlugin repo) {
    if (repo.getClass() == WorkspaceRepository.class) return true;
    return false;
  }
}
Example #2
0
public class BndEditor extends ExtendedFormEditor implements IResourceChangeListener {
  private static final ILogger logger = Logger.getLogger();

  public static final String WORKSPACE_EDITOR = "bndtools.bndWorkspaceConfigEditor";

  static final String WORKSPACE_PAGE = "__workspace_page";
  static final String WORKSPACE_EXT_PAGE = "__workspace_ext_page";
  static final String DESCRIPTION_PAGE = "__description_page";
  static final String CONTENT_PAGE = "__content_page";
  static final String BUILD_PAGE = "__build_page";
  static final String PROJECT_RUN_PAGE = "__project_run_page";
  static final String TEST_SUITES_PAGE = "__test_suites_page";
  static final String SOURCE_PAGE = "__source_page";

  private final Map<String, IFormPageFactory> pageFactories =
      new LinkedHashMap<String, IFormPageFactory>();

  private final BndEditModel model = new BndEditModel();
  private final BndSourceEditorPage sourcePage = new BndSourceEditorPage(SOURCE_PAGE, this);

  private final Image buildFileImg =
      AbstractUIPlugin.imageDescriptorFromPlugin(Plugin.PLUGIN_ID, "icons/bndtools-logo-16x16.png")
          .createImage();

  public BndEditor() {
    pageFactories.put(WORKSPACE_PAGE, WorkspacePage.MAIN_FACTORY);
    pageFactories.put(WORKSPACE_EXT_PAGE, WorkspacePage.EXT_FACTORY);
    pageFactories.put(CONTENT_PAGE, BundleContentPage.FACTORY);
    pageFactories.put(DESCRIPTION_PAGE, BundleDescriptionPage.FACTORY);
    pageFactories.put(BUILD_PAGE, ProjectBuildPage.FACTORY);
    pageFactories.put(PROJECT_RUN_PAGE, ProjectRunPage.FACTORY);
    pageFactories.put(TEST_SUITES_PAGE, TestSuitesPage.FACTORY);

    IConfigurationElement[] configElems =
        Platform.getExtensionRegistry()
            .getConfigurationElementsFor(Plugin.PLUGIN_ID, "editorPages");
    if (configElems != null)
      for (IConfigurationElement configElem : configElems) {
        String id = configElem.getAttribute("id");
        if (id != null) {
          if (pageFactories.containsKey(id)) logger.logError("Duplicate form page ID: " + id, null);
          else pageFactories.put(id, new DelayedPageFactory(configElem));
        }
      }
  }

  static Pair<String, String> getFileAndProject(IEditorInput input) {
    String path;
    String projectName;
    if (input instanceof IFileEditorInput) {
      IFile file = ((IFileEditorInput) input).getFile();
      path = file.getProjectRelativePath().toString();
      projectName = file.getProject().getName();
    } else {
      path = input.getName();
      projectName = null;
    }
    return Pair.newInstance(path, projectName);
  }

  void updatePages() {
    List<String> requiredPageIds = new LinkedList<String>();

    // Need to know the file and project names.
    Pair<String, String> fileAndProject = getFileAndProject(getEditorInput());
    String path = fileAndProject.getFirst();
    String projectName = fileAndProject.getSecond();

    if (isMainWorkspaceConfig(path, projectName)) {
      requiredPageIds.add(WORKSPACE_PAGE);
    } else if (isExtWorkspaceConfig(path, projectName)) {
      requiredPageIds.add(WORKSPACE_EXT_PAGE);
      setTitleImage(buildFileImg);
    } else if (path.endsWith(LaunchConstants.EXT_BNDRUN)) {
      requiredPageIds.addAll(getPagesBndRun());
    } else {
      requiredPageIds.addAll(getPagesBnd(path));
    }
    requiredPageIds.add(SOURCE_PAGE);

    // Remove pages no longer required and remember the rest in a map
    int i = 0;
    Map<String, IFormPage> pageCache = new HashMap<String, IFormPage>(requiredPageIds.size());
    while (i < getPageCount()) {
      IFormPage current = (IFormPage) pages.get(i);
      if (!requiredPageIds.contains(current.getId())) removePage(i);
      else {
        pageCache.put(current.getId(), current);
        i++;
      }
    }

    // Cache new pages
    for (String pageId : requiredPageIds) {
      if (!pageCache.containsKey(pageId)) {
        IFormPage page =
            SOURCE_PAGE.equals(pageId)
                ? sourcePage
                : pageFactories.get(pageId).createPage(this, model, pageId);
        pageCache.put(pageId, page);
      }
    }

    // Add pages back in
    int requiredPointer = 0;
    int existingPointer = 0;

    while (requiredPointer < requiredPageIds.size()) {
      try {
        String requiredId = requiredPageIds.get(requiredPointer);
        if (existingPointer >= getPageCount()) {
          if (SOURCE_PAGE.equals(requiredId)) addPage(sourcePage, getEditorInput());
          else addPage(pageCache.get(requiredId));
        } else {
          IFormPage existingPage = (IFormPage) pages.get(existingPointer);
          if (!requiredId.equals(existingPage.getId())) {
            if (SOURCE_PAGE.equals(requiredId))
              addPage(existingPointer, sourcePage, getEditorInput());
            else addPage(existingPointer, pageCache.get(requiredId));
          }
        }
        existingPointer++;
      } catch (PartInitException e) {
        logger.logError("Error adding page(s) to the editor.", e);
      }
      requiredPointer++;
    }

    // Set the source page title
    setPageText(sourcePage.getIndex(), "Source");
  }

  private static boolean isMainWorkspaceConfig(String path, String projectName) {
    if (Workspace.CNFDIR.equals(projectName) || Workspace.BNDDIR.equals(projectName)) {
      return Workspace.BUILDFILE.equals(path);
    }
    return false;
  }

  private static boolean isExtWorkspaceConfig(String path, String projectName) {
    if (Workspace.CNFDIR.equals(projectName) || Workspace.BNDDIR.equals(projectName)) {
      return path.startsWith("ext/") && path.endsWith(".bnd");
    }
    return false;
  }

  private final AtomicBoolean saving = new AtomicBoolean(false);

  @Override
  public void doSave(IProgressMonitor monitor) {
    final Shell shell = getEditorSite().getShell();

    // Commit dirty pages
    if (sourcePage.isActive() && sourcePage.isDirty()) {
      sourcePage.commit(true);
    } else {
      commitPages(true);
      sourcePage.refresh();
    }

    ResolveMode resolveMode = getResolveMode();

    // If auto resolve, then resolve and save in background thread.
    if (resolveMode == ResolveMode.auto && !PlatformUI.getWorkbench().isClosing()) {
      final IFile file = ResourceUtil.getFile(getEditorInput());
      if (file == null) {
        MessageDialog.openError(
            shell,
            "Resolution Error",
            "Unable to run OBR resolution because the file is not in the workspace. NB.: the file will still be saved.");
        reallySave(monitor);
        return;
      }

      // Create resolver job and pre-validate
      final ResolveJob job = new ResolveJob(model);
      IStatus validation = job.validateBeforeRun();
      if (!validation.isOK()) {
        String message = "Unable to run the OBR resolver. NB.: the file will still be saved.";
        ErrorDialog.openError(
            shell,
            "Resolution Validation Problem",
            message,
            validation,
            IStatus.ERROR | IStatus.WARNING);
        reallySave(monitor);
        return;
      }

      // Add operation to perform at the end of resolution (i.e. display
      // results and actually save the file)
      final UIJob completionJob =
          new UIJob(shell.getDisplay(), "Display Resolution Results") {
            @Override
            public IStatus runInUIThread(IProgressMonitor monitor) {
              ResolutionResult result = job.getResolutionResult();
              ResolutionWizard wizard = new ResolutionWizard(model, file, result);
              if (result.getOutcome() != ResolutionResult.Outcome.Resolved
                  || !result.getResolve().getOptionalResources().isEmpty()) {
                WizardDialog dialog = new WizardDialog(shell, wizard);
                if (dialog.open() != Window.OK) {
                  if (!wizard.performFinish()) {
                    MessageDialog.openError(
                        shell,
                        "Error",
                        "Unable to store resolution results into Run Bundles list.");
                  }
                }
              } else {
                if (!wizard.performFinish()) {
                  MessageDialog.openError(
                      shell, "Error", "Unable to store resolution results into Run Bundles list.");
                }
              }
              reallySave(monitor);
              return Status.OK_STATUS;
            }
          };
      job.addJobChangeListener(
          new JobChangeAdapter() {
            @Override
            public void done(IJobChangeEvent event) {
              completionJob.schedule();
            }
          });

      // Start job
      job.setUser(true);
      job.schedule();
    } else {
      // Not auto-resolving, just save
      reallySave(monitor);
    }
  }

  private ResolveMode getResolveMode() {
    ResolveMode resolveMode = ResolveMode.manual;
    try {
      String str = (String) model.genericGet(BndConstants.RESOLVE_MODE);
      if (str != null) resolveMode = Enum.valueOf(ResolveMode.class, str);
    } catch (Exception e) {
      logger.logError("Error parsing '-resolve' header.", e);
    }
    return resolveMode;
  }

  private void reallySave(IProgressMonitor monitor) {
    // Actually save, via the source editor
    try {
      boolean saveLocked = this.saving.compareAndSet(false, true);
      if (!saveLocked) {
        logger.logError("Tried to save while already saving", null);
        return;
      }
      sourcePage.doSave(monitor);
      updatePages();
    } finally {
      this.saving.set(false);
    }
  }

  protected void ensurePageExists(String pageId, IFormPage page, int index) {
    IFormPage existingPage = findPage(pageId);
    if (existingPage != null) return;

    try {
      addPage(index, page);
    } catch (PartInitException e) {
      ErrorDialog.openError(
          getSite().getShell(),
          "Error",
          null,
          new Status(IStatus.ERROR, Plugin.PLUGIN_ID, 0, "Error adding page to editor.", e));
    }
  }

  protected void removePage(String pageId) {
    IFormPage page = findPage(pageId);
    if (page != null) {
      removePage(page.getIndex());
    }
  }

  @Override
  public void doSaveAs() {}

  @Override
  public boolean isSaveAsAllowed() {
    return false;
  }

  @Override
  protected void handlePropertyChange(int propertyId) {
    super.handlePropertyChange(propertyId);
  }

  @Override
  protected void addPages() {
    updatePages();

    showHighestPriorityPage();
  }

  void showHighestPriorityPage() {
    int selectedPrio = Integer.MIN_VALUE;
    String selected = null;

    BndPreferences prefs = new BndPreferences();
    if (prefs.getEditorOpenSourceTab()) {
      selected = SOURCE_PAGE;
      selectedPrio = 0;
    }

    for (Object pageObj : pages) {
      IFormPage page = (IFormPage) pageObj;
      int priority = 0;
      if (page instanceof IPriority) priority = ((IPriority) page).getPriority();
      if (priority > selectedPrio) {
        selected = page.getId();
        selectedPrio = priority;
      }
    }

    if (selected != null) setActivePage(selected);
  }

  private List<String> getPagesBnd(String fileName) {
    List<String> pages = new ArrayList<String>(5);

    boolean isProjectFile = Project.BNDFILE.equals(fileName);
    List<String> subBndFiles = model.getSubBndFiles();
    boolean isSubBundles = subBndFiles != null && !subBndFiles.isEmpty();

    for (Entry<String, IFormPageFactory> pageEntry : pageFactories.entrySet()) {
      String pageId = pageEntry.getKey();
      IFormPageFactory page = pageEntry.getValue();

      if (!isSubBundles && page.supportsMode(IFormPageFactory.Mode.bundle)) pages.add(pageId);
      else if (isProjectFile && page.supportsMode(IFormPageFactory.Mode.build)) pages.add(pageId);
      else if (isProjectFile && page.supportsMode(IFormPageFactory.Mode.run)) pages.add(pageId);
    }

    return pages;
  }

  private List<String> getPagesBndRun() {
    List<String> pageIds = new ArrayList<String>(3);
    for (Entry<String, IFormPageFactory> pageEntry : pageFactories.entrySet()) {
      if (pageEntry.getValue().supportsMode(IFormPageFactory.Mode.run))
        pageIds.add(pageEntry.getKey());
    }
    return pageIds;
  }

  @Override
  public void init(IEditorSite site, IEditorInput input) throws PartInitException {
    super.init(site, input);
    sourcePage.init(site, input);

    setPartNameForInput(input);

    IResource resource = ResourceUtil.getResource(input);
    if (resource != null) {
      resource.getWorkspace().addResourceChangeListener(this);
    }

    final IDocumentProvider docProvider = sourcePage.getDocumentProvider();
    IDocument document = docProvider.getDocument(input);
    try {
      model.loadFrom(new IDocumentWrapper(document));
      model.setProjectFile(Project.BNDFILE.equals(input.getName()));

      if (resource != null) {
        model.setBndResource(resource.getLocation().toFile());
      }
      // model.addPropertyChangeListener(modelListener);
    } catch (IOException e) {
      throw new PartInitException("Error reading editor input.", e);
    }

    // Ensure the field values are updated if the file content is replaced
    docProvider.addElementStateListener(
        new IElementStateListener() {
          public void elementMoved(Object originalElement, Object movedElement) {}

          public void elementDirtyStateChanged(Object element, boolean isDirty) {}

          public void elementDeleted(Object element) {}

          public void elementContentReplaced(Object element) {
            try {
              model.loadFrom(new IDocumentWrapper(docProvider.getDocument(element)));
            } catch (IOException e) {
              logger.logError("Error loading model from document.", e);
            }
          }

          public void elementContentAboutToBeReplaced(Object element) {}
        });
  }

  private void setPartNameForInput(IEditorInput input) {
    Pair<String, String> fileAndProject = getFileAndProject(input);
    String path = fileAndProject.getFirst();
    String projectName = fileAndProject.getSecond();

    String name = input.getName();
    if (isMainWorkspaceConfig(path, projectName) || isExtWorkspaceConfig(path, projectName)) {
      name = path;
    } else if (Project.BNDFILE.equals(name)) {
      IResource resource = ResourceUtil.getResource(input);
      if (resource != null) name = projectName;
    } else if (name.endsWith(".bnd")) {
      IResource resource = ResourceUtil.getResource(input);
      if (resource != null)
        name = projectName + "." + name.substring(0, name.length() - ".bnd".length());
    } else if (name.endsWith(".bndrun")) {
      name = name.substring(0, name.length() - ".bndrun".length());
    }
    setPartName(name);
  }

  @Override
  public void dispose() {
    IResource resource = ResourceUtil.getResource(getEditorInput());

    super.dispose();

    if (resource != null) {
      resource.getWorkspace().removeResourceChangeListener(this);
    }

    buildFileImg.dispose();
  }

  public BndEditModel getEditModel() {
    return this.model;
  }

  public void resourceChanged(IResourceChangeEvent event) {
    IResource myResource = ResourceUtil.getResource(getEditorInput());

    IResourceDelta delta = event.getDelta();
    if (delta == null) return;
    IPath fullPath = myResource.getFullPath();
    delta = delta.findMember(fullPath);
    if (delta == null) return;

    // Delegate to any interested pages
    for (Object page : pages) {
      if (page instanceof IResourceChangeListener) {
        ((IResourceChangeListener) page).resourceChanged(event);
      }
    }

    // Close editor if file removed or switch to new location if file moved
    if (delta.getKind() == IResourceDelta.REMOVED) {
      if ((delta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
        IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(delta.getMovedToPath());
        final FileEditorInput newInput = new FileEditorInput(file);

        setInput(newInput);
        Display display = getEditorSite().getShell().getDisplay();
        if (display != null) {
          SWTConcurrencyUtil.execForDisplay(
              display,
              true,
              new Runnable() {
                public void run() {
                  setPartNameForInput(newInput);
                  sourcePage.setInput(newInput);
                }
              });
        }
      } else {
        close(false);
      }

    }
    // File content updated externally => reload all pages
    else if ((delta.getKind() & IResourceDelta.CHANGED) > 0
        && (delta.getFlags() & IResourceDelta.CONTENT) > 0) {
      if (!saving.get()) {
        final IDocumentProvider docProvider = sourcePage.getDocumentProvider();
        final IDocument document = docProvider.getDocument(getEditorInput());
        SWTConcurrencyUtil.execForControl(
            getEditorSite().getShell(),
            true,
            new Runnable() {
              public void run() {
                try {
                  model.loadFrom(new IDocumentWrapper(document));
                  updatePages();
                } catch (IOException e) {
                  logger.logError("Failed to reload document", e);
                }
              }
            });
      }
    }
  }

  @Override
  public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
    if (IContentOutlinePage.class == adapter) {
      return new BndEditorContentOutlinePage(this, model);
    }
    return super.getAdapter(adapter);
  }
}