public abstract class AbstractOSGiLaunchDelegate extends JavaLaunchDelegate {
  @SuppressWarnings("deprecation")
  private static final String ATTR_LOGLEVEL = LaunchConstants.ATTR_LOGLEVEL;

  private static final ILogger logger = Logger.getLogger(AbstractOSGiLaunchDelegate.class);

  protected Project model;

  protected abstract ProjectLauncher getProjectLauncher() throws CoreException;

  protected abstract void initialiseBndLauncher(ILaunchConfiguration configuration, Project model)
      throws Exception;

  protected abstract IStatus getLauncherStatus();

  @Override
  public boolean buildForLaunch(
      ILaunchConfiguration configuration, String mode, IProgressMonitor monitor)
      throws CoreException {
    boolean result = super.buildForLaunch(configuration, mode, monitor);

    model = LaunchUtils.getBndProject(configuration);
    try {
      initialiseBndLauncher(configuration, model);
    } catch (Exception e) {
      throw new CoreException(
          new Status(IStatus.ERROR, Plugin.PLUGIN_ID, 0, "Error initialising bnd launcher", e));
    }

    return result;
  }

  @Override
  public boolean finalLaunchCheck(
      ILaunchConfiguration configuration, String mode, IProgressMonitor monitor)
      throws CoreException {
    // Check for existing launches of same resource
    BndPreferences prefs = new BndPreferences();
    if (prefs.getWarnExistingLaunches()) {
      IResource launchResource = LaunchUtils.getTargetResource(configuration);
      if (launchResource == null)
        throw new CoreException(
            new Status(
                IStatus.ERROR,
                Plugin.PLUGIN_ID,
                0,
                "Bnd launch target was not specified or does not exist.",
                null));

      int processCount = 0;
      for (ILaunch l : DebugPlugin.getDefault().getLaunchManager().getLaunches()) {
        // ... is it the same launch resource?
        ILaunchConfiguration launchConfig = l.getLaunchConfiguration();
        if (launchConfig == null) {
          continue;
        }
        if (launchResource.equals(LaunchUtils.getTargetResource(launchConfig))) {
          // Iterate existing processes
          for (IProcess process : l.getProcesses()) {
            if (!process.isTerminated()) processCount++;
          }
        }
      }

      // Warn if existing processes running
      if (processCount > 0) {
        Status status =
            new Status(
                IStatus.WARNING,
                Plugin.PLUGIN_ID,
                0,
                "One or more OSGi Frameworks have already been launched for this configuration. Additional framework instances may interfere with each other due to the shared storage directory.",
                null);
        IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(status);
        if (prompter != null) {
          boolean okay = (Boolean) prompter.handleStatus(status, launchResource);
          if (!okay) return okay;
        }
      }
    }

    IStatus launchStatus = getLauncherStatus();

    IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(launchStatus);
    if (prompter != null) return (Boolean) prompter.handleStatus(launchStatus, model);
    return true;
  }

  @Override
  public void launch(
      ILaunchConfiguration configuration,
      String mode,
      final ILaunch launch,
      IProgressMonitor monitor)
      throws CoreException {
    // Register listener to clean up temp files on exit of launched JVM
    final ProjectLauncher launcher = getProjectLauncher();
    IDebugEventSetListener listener =
        new IDebugEventSetListener() {
          @Override
          public void handleDebugEvents(DebugEvent[] events) {
            for (DebugEvent event : events) {
              if (event.getKind() == DebugEvent.TERMINATE) {
                Object source = event.getSource();
                if (source instanceof IProcess) {
                  ILaunch processLaunch = ((IProcess) source).getLaunch();
                  if (processLaunch == launch) {
                    // Not interested in any further events =>
                    // unregister this listener
                    DebugPlugin.getDefault().removeDebugEventListener(this);

                    // Cleanup. Guard with a draconian catch because
                    // changes in the ProjectLauncher API
                    // *may* cause LinkageErrors.
                    try {
                      launcher.cleanup();
                    } catch (Throwable t) {
                      logger.logError("Error cleaning launcher temporary files", t);
                    }
                  }
                }
              }
            }
          }
        };
    DebugPlugin.getDefault().addDebugEventListener(listener);

    // Now actually launch
    super.launch(configuration, mode, launch, monitor);
  }

  @Override
  public String[] getClasspath(ILaunchConfiguration configuration) throws CoreException {
    Collection<String> paths = getProjectLauncher().getClasspath();
    return paths.toArray(new String[paths.size()]);
  }

  @Override
  public String getMainTypeName(ILaunchConfiguration configuration) throws CoreException {
    return getProjectLauncher().getMainTypeName();
  }

  @Override
  public File verifyWorkingDirectory(ILaunchConfiguration configuration) throws CoreException {
    try {
      return (model != null) ? model.getBase() : null;
    } catch (Exception e) {
      throw new CoreException(
          new Status(
              IStatus.ERROR,
              Plugin.PLUGIN_ID,
              0,
              "Error getting working directory for Bnd project.",
              e));
    }
  }

  @Override
  public String getVMArguments(ILaunchConfiguration configuration) throws CoreException {
    StringBuilder builder = new StringBuilder();
    Collection<String> runVM = getProjectLauncher().getRunVM();
    for (Iterator<String> iter = runVM.iterator(); iter.hasNext(); ) {
      builder.append(iter.next());
      if (iter.hasNext()) builder.append(" ");
    }
    String args = builder.toString();

    args = addJavaLibraryPath(configuration, args);
    return args;
  }

  @Override
  public String getProgramArguments(ILaunchConfiguration configuration) throws CoreException {
    StringBuilder builder = new StringBuilder();

    Collection<String> args = getProjectLauncher().getRunProgramArgs();
    for (Iterator<String> iter = args.iterator(); iter.hasNext(); ) {
      builder.append(iter.next());
      if (iter.hasNext()) builder.append(" ");
    }

    return builder.toString();
  }

  protected String addJavaLibraryPath(ILaunchConfiguration configuration, String args)
      throws CoreException {
    String a = args;
    // Following code copied from AbstractJavaLaunchConfigurationDelegate
    int libraryPath = a.indexOf("-Djava.library.path"); // $NON-NLS-1$
    if (libraryPath < 0) {
      // if a library path is already specified, do not override
      String[] javaLibraryPath = getJavaLibraryPath(configuration);
      if (javaLibraryPath != null && javaLibraryPath.length > 0) {
        StringBuffer path = new StringBuffer(a);
        path.append(" -Djava.library.path="); // $NON-NLS-1$
        path.append("\""); // $NON-NLS-1$
        for (int i = 0; i < javaLibraryPath.length; i++) {
          if (i > 0) {
            path.append(File.pathSeparatorChar);
          }
          path.append(javaLibraryPath[i]);
        }
        path.append("\""); // $NON-NLS-1$
        a = path.toString();
      }
    }
    return a;
  }

  protected static void enableTraceOptionIfSetOnConfiguration(
      ILaunchConfiguration configuration, ProjectLauncher launcher) throws CoreException {
    if (configuration.hasAttribute(LaunchConstants.ATTR_TRACE)) {
      launcher.setTrace(
          configuration.getAttribute(LaunchConstants.ATTR_TRACE, LaunchConstants.DEFAULT_TRACE));
    }
    String logLevelStr = configuration.getAttribute(ATTR_LOGLEVEL, (String) null);
    if (logLevelStr != null) {
      Plugin.getDefault()
          .getLog()
          .log(
              new Status(
                  IStatus.WARNING,
                  Plugin.PLUGIN_ID,
                  0,
                  MessageFormat.format(
                      "The {0} attribute is no longer supported, use {1} instead.",
                      ATTR_LOGLEVEL, LaunchConstants.ATTR_TRACE),
                  null));
      Level logLevel = Level.parse(logLevelStr);
      launcher.setTrace(launcher.getTrace() || logLevel.intValue() <= Level.FINE.intValue());
    }
  }

  protected static MultiStatus createStatus(
      String message, List<String> errors, List<String> warnings) {
    MultiStatus status = new MultiStatus(Plugin.PLUGIN_ID, 0, message, null);

    for (String error : errors) {
      status.add(new Status(IStatus.ERROR, Plugin.PLUGIN_ID, 0, error, null));
    }
    for (String warning : warnings) {
      status.add(new Status(IStatus.WARNING, Plugin.PLUGIN_ID, 0, warning, null));
    }

    return status;
  }
}
Ejemplo n.º 2
0
public class PkgRenameParticipant extends RenameParticipant implements ISharableParticipant {
  private static final ILogger logger = Logger.getLogger(PkgRenameParticipant.class);

  private final Map<IPackageFragment, RenameArguments> pkgFragments =
      new HashMap<IPackageFragment, RenameArguments>();
  private String changeTitle = null;

  @Override
  protected boolean initialize(Object element) {
    IPackageFragment pkgFragment = (IPackageFragment) element;
    RenameArguments args = getArguments();
    pkgFragments.put(pkgFragment, args);

    StringBuilder sb = new StringBuilder(256);
    sb.append("Bndtools: rename package '");
    sb.append(pkgFragment.getElementName());
    sb.append("' ");
    if (((RenamePackageProcessor) this.getProcessor()).getRenameSubpackages())
      sb.append("and subpackages ");
    sb.append("to '");
    sb.append(args.getNewName());
    sb.append("'");
    changeTitle = sb.toString();

    return true;
  }

  public void addElement(Object element, RefactoringArguments arguments) {
    this.pkgFragments.put((IPackageFragment) element, (RenameArguments) arguments);
  }

  @Override
  public String getName() {
    return "Bndtools Package Rename Participant";
  }

  @Override
  public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context)
      throws OperationCanceledException {
    return new RefactoringStatus();
  }

  private static final String grammarSeparator = "[\\s,\"';]";

  @Override
  public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
    final Map<IFile, TextChange> fileChanges = new HashMap<IFile, TextChange>();

    IResourceProxyVisitor visitor =
        new IResourceProxyVisitor() {
          public boolean visit(IResourceProxy proxy) throws CoreException {
            if ((proxy.getType() == IResource.FOLDER) || (proxy.getType() == IResource.PROJECT)) {
              return true;
            }

            if (!((proxy.getType() == IResource.FILE)
                && proxy.getName().toLowerCase().endsWith(".bnd"))) {
              return false;
            }

            /* we're dealing with a *.bnd file */

            /* get the proxied file */
            IFile resource = (IFile) proxy.requestResource();

            /* read the file as a single string */
            String bndFileText = null;
            try {
              bndFileText = FileUtils.readFully(resource).get();
            } catch (Exception e) {
              String str = "Could not read file " + proxy.getName();
              logger.logError(str, e);
              throw new OperationCanceledException(str);
            }

            /*
             * get the previous change for this file if it exists, or otherwise create a new change for it, but do
             * not store it yet: wait until we know if there are actually changes in the file
             */
            TextChange fileChange = getTextChange(resource);
            final boolean fileChangeIsNew = (fileChange == null);
            if (fileChange == null) {
              fileChange = new TextFileChange(proxy.getName(), resource);
              fileChange.setEdit(new MultiTextEdit());
            }
            TextEdit rootEdit = fileChange.getEdit();

            /* loop over all renames to perform */
            for (Map.Entry<IPackageFragment, RenameArguments> entry : pkgFragments.entrySet()) {
              IPackageFragment pkgFragment = entry.getKey();
              RenameArguments arguments = entry.getValue();

              final String oldName = pkgFragment.getElementName();
              final String newName = arguments.getNewName();

              Pattern pattern =
                  Pattern.compile(
                      /* match start boundary */ "(^|"
                          + grammarSeparator
                          + ")"
                          +
                          /* match itself / package name */ "("
                          + Pattern.quote(oldName)
                          + ")"
                          +
                          /* match end boundary */ "("
                          + grammarSeparator
                          + "|"
                          + Pattern.quote(".*")
                          + "|"
                          + Pattern.quote("\\")
                          + "|$)");

              /* find all matches to replace and add them to the root edit */
              Matcher matcher = pattern.matcher(bndFileText);
              while (matcher.find()) {
                rootEdit.addChild(
                    new ReplaceEdit(matcher.start(2), matcher.group(2).length(), newName));
              }

              pattern =
                  Pattern.compile(
                      /* match start boundary */ "(^|"
                          + grammarSeparator
                          + ")"
                          +
                          /* match bundle activator */ "(Bundle-Activator\\s*:\\s*)"
                          +
                          /* match itself / package name */ "("
                          + Pattern.quote(oldName)
                          + ")"
                          +
                          /* match class name */ "(\\.[^\\.]+)"
                          +
                          /* match end boundary */ "("
                          + grammarSeparator
                          + "|"
                          + Pattern.quote("\\")
                          + "|$)");

              /* find all matches to replace and add them to the root edit */
              matcher = pattern.matcher(bndFileText);
              while (matcher.find()) {
                rootEdit.addChild(
                    new ReplaceEdit(matcher.start(3), matcher.group(3).length(), newName));
              }
            }

            /*
             * only store the changes when no changes were stored before for this file and when there are actually
             * changes.
             */
            if (fileChangeIsNew && rootEdit.hasChildren()) {
              fileChanges.put(resource, fileChange);
            }

            return false;
          }
        };

    /* determine which projects have to be visited */
    Set<IProject> projectsToVisit = new HashSet<IProject>();
    for (IPackageFragment pkgFragment : pkgFragments.keySet()) {
      projectsToVisit.add(pkgFragment.getResource().getProject());
      for (IProject projectToVisit :
          pkgFragment.getResource().getProject().getReferencingProjects()) {
        projectsToVisit.add(projectToVisit);
      }
      for (IProject projectToVisit :
          pkgFragment.getResource().getProject().getReferencedProjects()) {
        projectsToVisit.add(projectToVisit);
      }
    }

    /* visit the projects */
    for (IProject projectToVisit : projectsToVisit) {
      projectToVisit.accept(visitor, IContainer.NONE);
    }

    if (fileChanges.isEmpty()) {
      /* no changes at all */
      return null;
    }

    /* build a composite change with all changes */
    CompositeChange cs = new CompositeChange(changeTitle);
    for (TextChange fileChange : fileChanges.values()) {
      cs.add(fileChange);
    }

    return cs;
  }
}
public class RepositoryTreeContentProvider implements ITreeContentProvider {

  private static final String CACHE_REPOSITORY = "cache";
  private static final ILogger logger = Logger.getLogger(RepositoryTreeContentProvider.class);

  private final EnumSet<ResolutionPhase> phases;

  private String filter = null;
  private boolean showRepos = true;

  public RepositoryTreeContentProvider() {
    this.phases = EnumSet.allOf(ResolutionPhase.class);
  }

  public RepositoryTreeContentProvider(ResolutionPhase mode) {
    this.phases = EnumSet.of(mode);
  }

  public RepositoryTreeContentProvider(EnumSet<ResolutionPhase> modes) {
    this.phases = modes;
  }

  public String getFilter() {
    return filter;
  }

  public void setFilter(String filter) {
    this.filter = filter;
  }

  public void setShowRepos(boolean showRepos) {
    this.showRepos = showRepos;
  }

  public boolean isShowRepos() {
    return showRepos;
  }

  @SuppressWarnings("unchecked")
  public Object[] getElements(Object inputElement) {
    Collection<Object> result;
    if (inputElement instanceof Workspace) {
      result = new ArrayList<Object>();
      Workspace workspace = (Workspace) inputElement;
      addRepositoryPlugins(result, workspace);
    } else if (inputElement instanceof Collection) {
      result = new ArrayList<Object>();
      addCollection(result, (Collection<Object>) inputElement);
    } else if (inputElement instanceof Object[]) {
      result = new ArrayList<Object>();
      addCollection(result, Arrays.asList(inputElement));
    } else {
      result = Collections.emptyList();
    }

    return result.toArray(new Object[result.size()]);
  }

  public void dispose() {}

  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}

  public Object[] getChildren(Object parentElement) {
    Object[] result = null;

    if (parentElement instanceof RepositoryPlugin) {
      RepositoryPlugin repo = (RepositoryPlugin) parentElement;
      result = getRepositoryBundles(repo);
    } else if (parentElement instanceof RepositoryBundle) {
      RepositoryBundle bundle = (RepositoryBundle) parentElement;
      result = getRepositoryBundleVersions(bundle);
    } else if (parentElement instanceof Project) {
      Project project = (Project) parentElement;
      result = getProjectBundles(project);
    }

    return result;
  }

  public Object getParent(Object element) {
    if (element instanceof RepositoryBundle) {
      return ((RepositoryBundle) element).getRepo();
    }
    if (element instanceof RepositoryBundleVersion) {
      return ((RepositoryBundleVersion) element).getBundle();
    }
    return null;
  }

  public boolean hasChildren(Object element) {
    return element instanceof RepositoryPlugin
        || element instanceof RepositoryBundle
        || element instanceof Project;
  }

  private void addRepositoryPlugins(Collection<Object> result, Workspace workspace) {
    workspace.getErrors().clear();
    List<RepositoryPlugin> repoPlugins = workspace.getPlugins(RepositoryPlugin.class);
    for (String error : workspace.getErrors()) {
      logger.logError(error, null);
    }
    for (RepositoryPlugin repoPlugin : repoPlugins) {
      if (CACHE_REPOSITORY.equals(repoPlugin.getName())) continue;
      if (repoPlugin instanceof IndexProvider) {
        IndexProvider indexProvider = (IndexProvider) repoPlugin;
        if (!supportsPhase(indexProvider)) continue;
      }
      if (showRepos) result.add(repoPlugin);
      else result.addAll(Arrays.asList(getRepositoryBundles(repoPlugin)));
    }
  }

  private void addCollection(Collection<Object> result, Collection<Object> inputs) {
    for (Object input : inputs) {
      if (input instanceof RepositoryPlugin) {
        RepositoryPlugin repo = (RepositoryPlugin) input;
        if (repo instanceof IndexProvider) {
          if (!supportsPhase((IndexProvider) repo)) continue;
        }

        if (showRepos) {
          result.add(repo);
        } else {
          Object[] bundles = getRepositoryBundles(repo);
          if (bundles != null && bundles.length > 0) result.addAll(Arrays.asList(bundles));
        }
      }
    }
  }

  private boolean supportsPhase(IndexProvider provider) {
    Set<ResolutionPhase> supportedPhases = provider.getSupportedPhases();
    for (ResolutionPhase phase : phases) {
      if (supportedPhases.contains(phase)) return true;
    }
    return false;
  }

  Object[] getProjectBundles(Project project) {
    ProjectBundle[] result = null;
    try {
      Collection<? extends Builder> builders = project.getSubBuilders();
      result = new ProjectBundle[builders.size()];

      int i = 0;
      for (Builder builder : builders) {
        ProjectBundle bundle = new ProjectBundle(project, builder.getBsn());
        result[i++] = bundle;
      }
    } catch (Exception e) {
      logger.logError(
          MessageFormat.format("Error querying sub-bundles for project {0}.", project.getName()),
          e);
    }
    return result;
  }

  Object[] getRepositoryBundleVersions(RepositoryBundle bundle) {
    RepositoryBundleVersion[] result = null;

    SortedSet<Version> versions = null;
    try {
      versions = bundle.getRepo().versions(bundle.getBsn());
    } catch (Exception e) {
      logger.logError(
          MessageFormat.format(
              "Error querying versions for bundle {0} in repository {1}.",
              bundle.getBsn(), bundle.getRepo().getName()),
          e);
    }
    if (versions != null) {
      result = new RepositoryBundleVersion[versions.size()];
      int i = 0;
      for (Version version : versions) {
        result[i++] = new RepositoryBundleVersion(bundle, version);
      }
    }
    return result;
  }

  Object[] getRepositoryBundles(RepositoryPlugin repo) {
    Object[] result = null;

    List<String> bsns = null;
    try {
      bsns = repo.list(filter);
    } catch (Exception e) {
      logger.logError(MessageFormat.format("Error querying repository {0}.", repo.getName()), e);
    }
    if (bsns != null) {
      Collections.sort(bsns);
      result = new RepositoryBundle[bsns.size()];
      int i = 0;
      for (String bsn : bsns) {
        result[i++] = new RepositoryBundle(repo, bsn);
      }
    }
    return result;
  }
}
Ejemplo n.º 4
0
class LaunchThread extends Thread implements IProcess {
  private static final ILogger logger = Logger.getLogger(OSGiRunLaunchDelegate.class);
  private final ProjectLauncher launcher;
  private final AtomicBoolean terminated = new AtomicBoolean(false);
  private final BundleContext context =
      FrameworkUtil.getBundle(LaunchThread.class).getBundleContext();
  private final ILaunch launch;
  private final Map<String, String> attributes = new HashMap<String, String>();
  private int exitValue;
  private BndStreamsProxy sproxy;
  private final RunSession session;

  LaunchThread(ProjectLauncher pl, RunSession session, ILaunch launch) {
    super("bnd::launch-" + pl.getProject());

    super.setDaemon(true);

    this.launcher = pl;
    this.launch = launch;
    this.session = session;

    attributes.put(IProcess.ATTR_PROCESS_TYPE, session.getName());
    attributes.put(IProcess.ATTR_PROCESS_LABEL, session.getLabel());
    attributes.put(IProcess.ATTR_CMDLINE, session.getLabel());
  }

  void doDebug(IProgressMonitor monitor) throws InterruptedException {
    monitor.setTaskName(
        "Connecting debugger "
            + session.getName()
            + " to "
            + session.getHost()
            + ":"
            + session.getJdb());

    Map<String, String> parameters = new HashMap<String, String>();
    parameters.put("hostname", session.getHost());
    parameters.put("port", session.getJdb() + "");
    parameters.put("timeout", session.getTimeout() + "");
    IVMConnector connector = JavaRuntime.getDefaultVMConnector();

    while (!monitor.isCanceled()) {

      try {
        connector.connect(parameters, monitor, launch);
        break;
      } catch (Exception e) {
        Thread.sleep(500);
      }
    }
  }

  /** This is the reason for this thread. We launch the remote process and wait until it returns. */
  @Override
  public void run() {
    fireCreationEvent();

    //
    // We wait for build changes. We never update during a build
    // and we will wait a bit after a build ends.
    //

    UpdateGuard guard =
        new UpdateGuard(context) {
          @Override
          protected void update() {
            LaunchThread.this.update();
          }
        };

    guard.open();

    try {
      exitValue = session.launch();
    } catch (Exception e) {
      logger.logWarning("Exception from launcher", e);
      e.printStackTrace();
    } finally {
      guard.close();
      terminate();
    }
  }

  private void update() {
    if (isTerminated()) return;

    try {
      //
      // TODO Should use listener
      //

      if (launcher.getProject() instanceof Run) launcher.getProject().refresh();

      launcher.update();
    } catch (Exception e) {
      logger.logWarning("Exception from update", e);
    }
    fireChangeEvent();
  }

  @Override
  public void terminate() {
    if (terminated.getAndSet(true)) return;

    if (sproxy != null) sproxy.close();

    try {
      launcher.cancel();
    } catch (Exception e) {
      // ignore
    } finally {
      fireTerminateEvent();
    }
    IDebugTarget[] debugTargets = launch.getDebugTargets();
    for (int i = 0; i < debugTargets.length; i++) {
      IDebugTarget target = debugTargets[i];
      if (target.canDisconnect()) {
        try {
          target.disconnect();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
  }

  @SuppressWarnings("rawtypes")
  @Override
  public Object getAdapter(Class adapter) {
    if (adapter.equals(IProcess.class)) {
      return this;
    }
    if (adapter.equals(IDebugTarget.class)) {
      ILaunch launch = getLaunch();
      IDebugTarget[] targets = launch.getDebugTargets();
      for (int i = 0; i < targets.length; i++) {
        if (this.equals(targets[i].getProcess())) {
          return targets[i];
        }
      }
      return null;
    }
    if (adapter.equals(ILaunch.class)) {
      return getLaunch();
    }
    if (adapter.equals(ILaunchConfiguration.class)) {
      return getLaunch().getLaunchConfiguration();
    }
    return null;
  }

  @Override
  public boolean canTerminate() {
    return !isTerminated();
  }

  @Override
  public boolean isTerminated() {
    return terminated.get();
  }

  @Override
  public String getLabel() {
    return launcher.getProject().toString();
  }

  @Override
  public ILaunch getLaunch() {
    return launch;
  }

  @Override
  public IStreamsProxy getStreamsProxy() {
    if (sproxy == null) {
      sproxy = new BndStreamsProxy(launcher, session);
    }
    return sproxy;
  }

  @Override
  public void setAttribute(String key, String value) {
    attributes.put(key, value);
  }

  @Override
  public String getAttribute(String key) {
    return attributes.get(key);
  }

  @Override
  public int getExitValue() throws DebugException {
    if (!terminated.get())
      throw new DebugException(new Status(IStatus.ERROR, BndtoolsConstants.CORE_PLUGIN_ID, ""));
    return exitValue;
  }

  /** Fires a creation event. */
  protected void fireCreationEvent() {
    fireEvent(new DebugEvent(this, DebugEvent.CREATE));
  }

  /** Fires a terminate event. */
  protected void fireTerminateEvent() {
    fireEvent(new DebugEvent(this, DebugEvent.TERMINATE));
  }

  /** Fires a change event. */
  protected void fireChangeEvent() {
    fireEvent(new DebugEvent(this, DebugEvent.CHANGE));
  }

  /**
   * Fires the given debug event.
   *
   * @param event debug event to fire
   */
  protected void fireEvent(DebugEvent event) {
    DebugPlugin manager = DebugPlugin.getDefault();
    if (manager != null) {
      manager.fireDebugEventSet(new DebugEvent[] {event});
    }
  }
}
Ejemplo n.º 5
0
public class RepositoriesView extends ViewPart implements RepositoryListenerPlugin {
  static final Pattern LABEL_PATTERN = Pattern.compile("(-)?(!)?([^{}]+)(?:\\{([^}]+)\\})?");
  private static final String DROP_TARGET = "dropTarget";

  private static final ILogger logger = Logger.getLogger(RepositoriesView.class);

  private final FilterPanelPart filterPart =
      new FilterPanelPart(Plugin.getDefault().getScheduler());
  private final SearchableRepositoryTreeContentProvider contentProvider =
      new SearchableRepositoryTreeContentProvider();
  private TreeViewer viewer;

  private Action collapseAllAction;
  private Action refreshAction;
  private Action addBundlesAction;

  private ServiceRegistration<RepositoryListenerPlugin> registration;

  @Override
  public void createPartControl(Composite parent) {
    // CREATE CONTROLS
    Composite mainPanel = new Composite(parent, SWT.NONE);
    Control filterPanel = filterPart.createControl(mainPanel, 5, 5);
    Tree tree = new Tree(mainPanel, SWT.FULL_SELECTION | SWT.MULTI);
    filterPanel.setBackground(tree.getBackground());

    viewer = new TreeViewer(tree);
    viewer.setContentProvider(contentProvider);
    ColumnViewerToolTipSupport.enableFor(viewer);

    viewer.setLabelProvider(new RepositoryTreeLabelProvider(false));
    getViewSite().setSelectionProvider(viewer);

    createActions();

    JpmPreferences jpmPrefs = new JpmPreferences();
    final boolean showJpmOnClick =
        jpmPrefs.getBrowserSelection() != JpmPreferences.PREF_BROWSER_EXTERNAL;

    // LISTENERS
    filterPart.addPropertyChangeListener(
        new PropertyChangeListener() {
          @Override
          public void propertyChange(PropertyChangeEvent event) {
            String filter = (String) event.getNewValue();
            updatedFilter(filter);
          }
        });
    ViewerDropAdapter dropAdapter =
        new ViewerDropAdapter(viewer) {
          @Override
          public boolean validateDrop(Object target, int operation, TransferData transferType) {
            if (canDrop(target, transferType)) return true;

            boolean valid = false;
            if (target instanceof RepositoryPlugin) {
              if (((RepositoryPlugin) target).canWrite()) {

                if (URLTransfer.getInstance().isSupportedType(transferType)) return true;

                if (LocalSelectionTransfer.getTransfer().isSupportedType(transferType)) {
                  ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
                  if (selection instanceof IStructuredSelection) {
                    for (Iterator<?> iter = ((IStructuredSelection) selection).iterator();
                        iter.hasNext(); ) {
                      Object element = iter.next();
                      if (element instanceof RepositoryBundle
                          || element instanceof RepositoryBundleVersion) {
                        valid = true;
                        break;
                      }
                      if (element instanceof IFile) {
                        valid = true;
                        break;
                      }
                      if (element instanceof IAdaptable) {
                        IFile file = (IFile) ((IAdaptable) element).getAdapter(IFile.class);
                        if (file != null) {
                          valid = true;
                          break;
                        }
                      }
                    }
                  }
                } else {
                  valid = true;
                }
              }
            }
            return valid;
          }

          @Override
          public void dragEnter(DropTargetEvent event) {
            super.dragEnter(event);
            event.detail = DND.DROP_COPY;
          }

          @Override
          public boolean performDrop(Object data) {
            if (RepositoriesView.this.performDrop(
                getCurrentTarget(), getCurrentEvent().currentDataType)) {
              viewer.refresh(getCurrentTarget(), true);
              return true;
            }

            boolean copied = false;
            if (URLTransfer.getInstance().isSupportedType(getCurrentEvent().currentDataType)) {
              try {
                URL url =
                    new URL(
                        (String)
                            URLTransfer.getInstance()
                                .nativeToJava(getCurrentEvent().currentDataType));
                File tmp = File.createTempFile("dwnl", ".jar");
                IO.copy(url, tmp);
                copied =
                    addFilesToRepository((RepositoryPlugin) getCurrentTarget(), new File[] {tmp});
              } catch (Exception e) {
                return false;
              }
            } else if (data instanceof String[]) {
              String[] paths = (String[]) data;
              File[] files = new File[paths.length];
              for (int i = 0; i < paths.length; i++) {
                files[i] = new File(paths[i]);
              }
              copied = addFilesToRepository((RepositoryPlugin) getCurrentTarget(), files);
            } else if (data instanceof IResource[]) {
              IResource[] resources = (IResource[]) data;
              File[] files = new File[resources.length];
              for (int i = 0; i < resources.length; i++) {
                files[i] = resources[i].getLocation().toFile();
              }
              copied = addFilesToRepository((RepositoryPlugin) getCurrentTarget(), files);
            } else if (data instanceof IStructuredSelection) {
              File[] files = convertSelectionToFiles((IStructuredSelection) data);
              if (files != null && files.length > 0)
                copied = addFilesToRepository((RepositoryPlugin) getCurrentTarget(), files);
            }
            return copied;
          }
        };
    dropAdapter.setFeedbackEnabled(false);
    dropAdapter.setExpandEnabled(false);

    viewer.addDropSupport(
        DND.DROP_COPY | DND.DROP_MOVE,
        new Transfer[] {
          URLTransfer.getInstance(),
          FileTransfer.getInstance(),
          ResourceTransfer.getInstance(),
          LocalSelectionTransfer.getTransfer()
        },
        dropAdapter);
    viewer.addDragSupport(
        DND.DROP_COPY | DND.DROP_MOVE,
        new Transfer[] {LocalSelectionTransfer.getTransfer()},
        new SelectionDragAdapter(viewer));

    viewer.addSelectionChangedListener(
        new ISelectionChangedListener() {
          @Override
          public void selectionChanged(SelectionChangedEvent event) {
            boolean writableRepoSelected = false;
            IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
            Object element = selection.getFirstElement();
            if (element instanceof RepositoryPlugin) {
              RepositoryPlugin repo = (RepositoryPlugin) element;
              writableRepoSelected = repo.canWrite();
            }
            addBundlesAction.setEnabled(writableRepoSelected);
          }
        });
    tree.addMouseListener(
        new MouseAdapter() {
          @Override
          public void mouseUp(MouseEvent ev) {
            Object element = ((IStructuredSelection) viewer.getSelection()).getFirstElement();
            if (element instanceof ContinueSearchElement) {
              try {
                getViewSite()
                    .getPage()
                    .showView(
                        Plugin.JPM_BROWSER_VIEW_ID,
                        null,
                        showJpmOnClick ? IWorkbenchPage.VIEW_ACTIVATE : IWorkbenchPage.VIEW_CREATE);
              } catch (PartInitException e) {
                Plugin.getDefault().getLog().log(e.getStatus());
              }
            }
          }
        });
    viewer.addDoubleClickListener(
        new IDoubleClickListener() {
          @Override
          public void doubleClick(DoubleClickEvent event) {
            if (!event.getSelection().isEmpty()) {
              IStructuredSelection selection = (IStructuredSelection) event.getSelection();
              Object element = selection.getFirstElement();
              if (element instanceof IAdaptable) {
                URI uri = (URI) ((IAdaptable) element).getAdapter(URI.class);
                if (uri != null) {
                  IWorkbenchPage page = getSite().getPage();
                  try {
                    IFileStore fileStore = EFS.getLocalFileSystem().getStore(uri);
                    IDE.openEditorOnFileStore(page, fileStore);
                  } catch (PartInitException e) {
                    logger.logError("Error opening editor for " + uri, e);
                  }
                }
              } else if (element instanceof ContinueSearchElement) {
                ContinueSearchElement searchElement = (ContinueSearchElement) element;
                try {
                  JpmPreferences jpmPrefs = new JpmPreferences();
                  if (jpmPrefs.getBrowserSelection() == JpmPreferences.PREF_BROWSER_EXTERNAL)
                    getViewSite()
                        .getWorkbenchWindow()
                        .getWorkbench()
                        .getBrowserSupport()
                        .getExternalBrowser()
                        .openURL(new URL("https://www.jpm4j.org/" + searchElement.getFilter()));
                  else
                    getViewSite()
                        .getPage()
                        .showView(Plugin.JPM_BROWSER_VIEW_ID, null, IWorkbenchPage.VIEW_VISIBLE);
                } catch (PartInitException e) {
                  Plugin.getDefault().getLog().log(e.getStatus());
                } catch (MalformedURLException e) {
                  // ignore
                }
              }
            }
          }
        });

    createContextMenu();

    // LOAD
    Central.onWorkspaceInit(
        new Function<Workspace, Void>() {
          @Override
          public Void run(Workspace a) {
            final List<RepositoryPlugin> repositories = RepositoryUtils.listRepositories(true);
            SWTConcurrencyUtil.execForControl(
                viewer.getControl(),
                true,
                new Runnable() {
                  @Override
                  public void run() {
                    viewer.setInput(repositories);
                  }
                });
            return null;
          }
        });

    // LAYOUT
    GridLayout layout = new GridLayout(1, false);
    layout.horizontalSpacing = 0;
    layout.verticalSpacing = 0;
    layout.marginWidth = 0;
    layout.marginHeight = 0;
    mainPanel.setLayout(layout);

    tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    filterPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

    // Toolbar
    createActions();
    fillToolBar(getViewSite().getActionBars().getToolBarManager());

    // Register as repository listener
    registration =
        Activator.getDefault()
            .getBundleContext()
            .registerService(RepositoryListenerPlugin.class, this, null);
  }

  @Override
  public void setFocus() {
    filterPart.setFocus();
  }

  private static File[] convertSelectionToFiles(ISelection selection) {
    if (!(selection instanceof IStructuredSelection)) return new File[0];

    IStructuredSelection structSel = (IStructuredSelection) selection;
    List<File> files = new ArrayList<File>(structSel.size());

    for (Iterator<?> iter = structSel.iterator(); iter.hasNext(); ) {
      Object element = iter.next();
      if (element instanceof IFile) files.add(((IFile) element).getLocation().toFile());
      else if (element instanceof IAdaptable) {
        IAdaptable adaptable = (IAdaptable) element;
        IFile ifile = (IFile) adaptable.getAdapter(IFile.class);
        if (ifile != null) {
          files.add(ifile.getLocation().toFile());
        } else {
          File file = (File) adaptable.getAdapter(File.class);
          if (file != null) {
            files.add(file);
          }
        }
      }
    }

    return files.toArray(new File[files.size()]);
  }

  @Override
  public void dispose() {
    registration.unregister();
    super.dispose();
  }

  boolean addFilesToRepository(RepositoryPlugin repo, File[] files) {
    AddFilesToRepositoryWizard wizard = new AddFilesToRepositoryWizard(repo, files);
    WizardDialog dialog = new WizardDialog(getViewSite().getShell(), wizard);
    dialog.open();
    viewer.refresh(repo);
    return true;
  }

  private void updatedFilter(String filterString) {
    String newFilter;
    if (filterString == null || filterString.length() == 0 || filterString.trim().equals("*"))
      newFilter = null;
    else newFilter = "*" + filterString.trim() + "*";

    contentProvider.setFilter(newFilter);
    viewer.refresh();
    if (newFilter != null) viewer.expandToLevel(2);
  }

  void createActions() {
    collapseAllAction =
        new Action() {
          @Override
          public void run() {
            viewer.collapseAll();
          }
        };
    collapseAllAction.setText("Collapse All");
    collapseAllAction.setToolTipText("Collapse All");
    collapseAllAction.setImageDescriptor(
        AbstractUIPlugin.imageDescriptorFromPlugin(Plugin.PLUGIN_ID, "/icons/collapseall.gif"));

    refreshAction =
        new Action() {
          @Override
          public void run() {
            doRefresh();
          }
        };
    refreshAction.setText("Refresh");
    refreshAction.setToolTipText("Refresh Repositories Tree");
    refreshAction.setImageDescriptor(
        AbstractUIPlugin.imageDescriptorFromPlugin(Plugin.PLUGIN_ID, "/icons/arrow_refresh.png"));

    addBundlesAction =
        new Action() {
          @Override
          public void run() {
            IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
            Object element = selection.getFirstElement();
            if (element != null && element instanceof RepositoryPlugin) {
              RepositoryPlugin repo = (RepositoryPlugin) element;
              if (repo.canWrite()) {
                AddFilesToRepositoryWizard wizard =
                    new AddFilesToRepositoryWizard(repo, new File[0]);
                WizardDialog dialog = new WizardDialog(getViewSite().getShell(), wizard);
                dialog.open();

                viewer.refresh(repo);
              }
            }
          }
        };
    addBundlesAction.setEnabled(false);
    addBundlesAction.setText("Add");
    addBundlesAction.setToolTipText("Add Bundles to Repository");
    addBundlesAction.setImageDescriptor(
        AbstractUIPlugin.imageDescriptorFromPlugin(Plugin.PLUGIN_ID, "/icons/brick_add.png"));
  }

  void createContextMenu() {
    MenuManager mgr = new MenuManager();
    Menu menu = mgr.createContextMenu(viewer.getControl());
    viewer.getControl().setMenu(menu);
    mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
    getSite().registerContextMenu(mgr, viewer);

    mgr.addMenuListener(
        new IMenuListener() {

          @Override
          public void menuAboutToShow(IMenuManager manager) {
            try {
              manager.removeAll();
              IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
              if (!selection.isEmpty()) {
                Object firstElement = selection.getFirstElement();
                if (firstElement instanceof Actionable) {
                  //
                  // Use the Actionable interface to fill the menu
                  // Should extend this to allow other menu entries
                  // from the view, but currently there are none
                  //
                  final Actionable act = (Actionable) firstElement;
                  Map<String, Runnable> actions = act.actions();
                  if (actions != null) {
                    for (final Entry<String, Runnable> e : actions.entrySet()) {
                      String label = e.getKey();
                      boolean enabled = true;
                      boolean checked = false;
                      String description = null;
                      Matcher m = LABEL_PATTERN.matcher(label);
                      if (m.matches()) {
                        if (m.group(1) != null) enabled = false;

                        if (m.group(2) != null) checked = true;

                        label = m.group(3);

                        description = m.group(4);
                      }
                      Action a =
                          new Action(label) {
                            @Override
                            public void run() {
                              try {
                                e.getValue().run();
                              } catch (Exception e) {
                                throw new RuntimeException(e);
                              }
                              viewer.refresh(act);
                            }
                          };
                      a.setEnabled(enabled);
                      if (description != null) a.setDescription(description);
                      a.setChecked(checked);
                      manager.add(a);
                    }
                  }
                }
              }
            } catch (Exception e) {
              throw new RuntimeException(e);
            }
          }
        });
  }

  private void doRefresh() {
    // Remember names of expanded repositories
    Set<String> expandedRepoNames = new HashSet<String>();
    Object[] expandedElems = viewer.getExpandedElements();
    for (Object expandedElem : expandedElems) {
      if (expandedElem instanceof RepositoryPlugin) {
        expandedRepoNames.add(((RepositoryPlugin) expandedElem).getName());
      }
    }

    // Reload repositories
    List<RepositoryPlugin> repos = RepositoryUtils.listRepositories(true);
    viewer.setInput(repos);

    // Expand any repos that have the same name as a repository that
    // was expanded before the reload.
    for (RepositoryPlugin repo : repos) {
      if (expandedRepoNames.contains(repo.getName())) {
        viewer.setExpandedState(repo, true);
      }
    }
  }

  private void fillToolBar(IToolBarManager toolBar) {
    toolBar.add(refreshAction);
    toolBar.add(collapseAllAction);
    toolBar.add(addBundlesAction);
    toolBar.add(new Separator());
  }

  @Override
  public void bundleAdded(final RepositoryPlugin repository, Jar jar, File file) {
    if (viewer != null)
      SWTConcurrencyUtil.execForControl(
          viewer.getControl(),
          true,
          new Runnable() {
            @Override
            public void run() {
              viewer.refresh(repository);
            }
          });
  }

  @Override
  public void bundleRemoved(final RepositoryPlugin repository, Jar jar, File file) {
    if (viewer != null)
      SWTConcurrencyUtil.execForControl(
          viewer.getControl(),
          true,
          new Runnable() {
            @Override
            public void run() {
              viewer.refresh(repository);
            }
          });
  }

  @Override
  public void repositoryRefreshed(final RepositoryPlugin repository) {
    if (viewer != null)
      SWTConcurrencyUtil.execForControl(
          viewer.getControl(),
          true,
          new Runnable() {
            @Override
            public void run() {
              viewer.refresh(repository);
            }
          });
  }

  @Override
  public void repositoriesRefreshed() {
    if (viewer != null)
      SWTConcurrencyUtil.execForControl(
          viewer.getControl(),
          true,
          new Runnable() {
            @Override
            public void run() {
              doRefresh();
            }
          });
  }

  /**
   * Handle the drop on targets that understand drops.
   *
   * @param target The current target
   * @param data The transfer data
   * @return true if the data is acceptable, otherwise false
   */
  boolean canDrop(Object target, TransferData data) {
    try {
      Class<?> type = toJavaType(data);
      if (type != null) {
        target.getClass().getMethod(DROP_TARGET, type);
        return true;
      }
    } catch (Exception e) {
      // Ignore
    }
    return false;
  }

  /**
   * Try a drop on the target. A drop is allowed if the target implements a {@code dropTarget}
   * method that returns a boolean.
   *
   * @param target the target being dropped upon
   * @param data the data
   * @return true if dropped and processed, false if not
   */
  boolean performDrop(Object target, TransferData data) {
    try {
      Object java = toJava(data);
      if (java == null) return false;

      Method m = target.getClass().getMethod(DROP_TARGET, java.getClass());
      return (Boolean) m.invoke(target, java);
    } catch (Exception e) {
      return false;
    }
  }

  /**
   * Return the class of the dropped object
   *
   * <pre>
   *    URLTransfer             URI
   *    FileTransfer            File[]
   *    TextTransfer            String
   *    ImageTransfer           ImageData
   * </pre>
   *
   * @param data the dropped object
   * @return the class of the dropped object, or null when it's unknown
   * @throws Exception upon error
   */
  Class<?> toJavaType(TransferData data) throws Exception {
    if (URLTransfer.getInstance().isSupportedType(data)) return URI.class;
    if (FileTransfer.getInstance().isSupportedType(data)) return File[].class;
    if (TextTransfer.getInstance().isSupportedType(data)) return String.class;
    //        if (ImageTransfer.getInstance().isSupportedType(data))
    //            return Image.class;
    return null;
  }

  /**
   * Return a native data type that represents the dropped object
   *
   * <pre>
   *    URLTransfer             URI
   *    FileTransfer            File[]
   *    TextTransfer            String
   *    ImageTransfer           ImageData
   * </pre>
   *
   * @param data the dropped object
   * @return a native data type that represents the dropped object, or null when the data type is
   *     unknown
   * @throws Exception upon error
   */
  Object toJava(TransferData data) throws Exception {
    if (URLTransfer.getInstance().isSupportedType(data))
      return Converter.cnv(URI.class, URLTransfer.getInstance().nativeToJava(data));
    else if (FileTransfer.getInstance().isSupportedType(data)) {
      return Converter.cnv(File[].class, FileTransfer.getInstance().nativeToJava(data));
    } else if (TextTransfer.getInstance().isSupportedType(data)) {
      return TextTransfer.getInstance().nativeToJava(data);
    }
    // Need to write the transfer code since the ImageTransfer turns it into
    // something very Eclipsy
    //        else if (ImageTransfer.getInstance().isSupportedType(data))
    //            return ImageTransfer.getInstance().nativeToJava(data);

    return null;
  }
}