Exemple #1
0
 public boolean isTracing(final String traceOption) {
   if (!Platform.inDebugMode()) {
     return false;
   }
   final String globalTraceValue = Platform.getDebugOption(ERLIDE_GLOBAL_TRACE_OPTION);
   final String value = Platform.getDebugOption(ERLIDE_GLOBAL_TRACE_OPTION + "/" + traceOption);
   if ("true".equalsIgnoreCase(globalTraceValue) && "true".equalsIgnoreCase(value)) {
     return true;
   }
   return false;
 }
  /*
   * (non-Javadoc)
   * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
   */
  @Override
  public void start(BundleContext context) throws Exception {
    fgBundleContext = context;
    super.start(context);
    DEBUG =
        "true"
            .equals(
                Platform.getDebugOption(
                    "org.eclipse.cdt.dsf.ui/debug")); //$NON-NLS-1$//$NON-NLS-2$

    fSourceDocumentProvider = new SourceDocumentProvider();

    EvaluationContextManager.startup();

    // Register the DSF backend for our disassembly view (the CDT debug UI
    // plugin registers the CDI one)
    Platform.getAdapterManager()
        .registerAdapters(new DisassemblyBackendDsfFactory(), IDMVMContext.class);
    // Register the factory that provides descriptions of stack frames
    // to the CSourceNotFoundEditor.
    Platform.getAdapterManager()
        .registerAdapters(new CSourceNotFoundDescriptionFactory(), IFrameDMContext.class);

    DsfDebugUITools.enableActivity("org.eclipse.cdt.debug.ui.cdtActivity", true); // $NON-NLS-1$
  }
Exemple #3
0
 public static boolean isOptionEnabled(String option) {
   String enabled = Platform.getDebugOption(option);
   if (enabled == null) {
     return false;
   }
   return Boolean.parseBoolean(enabled);
 }
Exemple #4
0
 /*
  * (non-Javadoc)
  * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
  */
 public void start(BundleContext context) throws Exception {
   super.start(context);
   plugin = this;
   if ("true".equals(Platform.getDebugOption("com.aptana.filesystem.ftp/ftplib_debug"))) {
     Logger.setLevel(Level.DEBUG);
   }
 }
 /** Returns a value of the option, {@code null} if not set. */
 private static String getOptionValue(String optionSuffix) {
   String option = DartCore.PLUGIN_ID + "/" + optionSuffix;
   String value = Platform.getDebugOption(option);
   if (value == null) {
     value = DartCore.getUserDefinedProperty(option);
   }
   return value;
 }
Exemple #6
0
 public static void configurePluginDebugOptions() {
   if (Activator.getDefault().isDebugging()) {
     String option = Platform.getDebugOption(SERVER_TRACING_OPTION);
     if (option != null) {
       SERVER_TRACING = option.equalsIgnoreCase("true"); // $NON-NLS-1$
     }
   }
 }
 /** @generated */
 public static int getVisualID(String type) {
   try {
     return Integer.parseInt(type);
   } catch (NumberFormatException e) {
     if (Boolean.TRUE.toString().equalsIgnoreCase(Platform.getDebugOption(DEBUG_KEY))) {
       ShortcutDiagramEditorPlugin.getInstance()
           .logError("Unable to parse view type as a visualID number: " + type);
     }
   }
   return -1;
 }
  /**
   * Determines if currently tracing a category
   *
   * @param category
   * @return true if tracing category, false otherwise
   */
  public static boolean isTracing(String category) {
    if (!isDebugging()) return false;

    String traceFilter = Platform.getDebugOption(PLUGIN_ID + TRACEFILTER_LOCATION);
    if (traceFilter != null) {
      StringTokenizer tokenizer = new StringTokenizer(traceFilter, ","); // $NON-NLS-1$
      while (tokenizer.hasMoreTokens()) {
        String cat = tokenizer.nextToken().trim();
        if (category.equals(cat)) {
          return true;
        }
      }
    }
    return false;
  }
Exemple #9
0
    /**
     * Retrieves a Boolean value indicating whether tracing is enabled for the specified debug
     * option.
     *
     * @return Whether tracing is enabled for the debug option of the plug-in.
     * @param option The debug option for which to determine trace enablement.
     */
    public boolean shouldTrace(String option) {
      if (shouldTrace()) {
        Boolean value = null;

        synchronized (cachedOptions) {
          value = cachedOptions.get(option);

          if (null == value) {
            value = Boolean.valueOf(org.eclipse.core.runtime.Platform.getDebugOption(option));

            cachedOptions.put(option, value);
          }
        }

        return value.booleanValue();
      }

      return false;
    }
 /**
  * Special hook to signal that application startup is complete and the event loop has started
  * running.
  */
 public static void startupComplete() {
   // We use a runtime debug option here for backwards compatibility (bug 96672)
   // Note that this value is only relevant if the workspace chooser is not used.
   String option = Platform.getDebugOption(Platform.PI_RUNTIME + "/debug"); // $NON-NLS-1$
   if (option == null || !"true".equalsIgnoreCase(option)) { // $NON-NLS-1$
     return;
   }
   String startString = System.getProperty("eclipse.startTime"); // $NON-NLS-1$
   if (startString == null) {
     return;
   }
   try {
     long start = Long.parseLong(startString);
     long end = System.currentTimeMillis();
     System.out.println("Startup complete: " + (end - start) + "ms"); // $NON-NLS-1$ //$NON-NLS-2$
   } catch (NumberFormatException e) {
     // this is just debugging code -- ok to swallow exception
   }
 }
Exemple #11
0
/** GDB/MI Plugin. */
public class MIPlugin extends Plugin {

  /**
   * The plug-in identifier of the Java core support (value <code>"org.eclipse.jdt.core"</code>).
   */
  public static final String PLUGIN_ID = "org.eclipse.cdt.debug.mi.core"; // $NON-NLS-1$

  /**
   * Simple identifier constant (value <code>"commandFactories"</code>) for the "gdb/mi command
   * factories" extension point.
   *
   * @since 3.1
   */
  public static final String EXTENSION_POINT_COMMAND_FACTORIES = "commandFactories"; // $NON-NLS-1$

  // The shared instance.
  private static MIPlugin plugin;

  // GDB command
  private static final String GDB = "gdb"; // $NON-NLS-1$

  private static final int INTERNAL_ERROR = 42;

  /**
   * Has tracing for this plug-in been turned on?
   *
   * @since 7.0
   */
  public static final boolean DEBUG =
      "true"
          .equals( //$NON-NLS-1$
              Platform.getDebugOption("org.eclipse.cdt.debug.mi.core/debug")); // $NON-NLS-1$
  /** The singleton command factory manager. */
  private CommandFactoryManager fCommandFactoryManager;

  private static ResourceBundle fgResourceBundle;

  static {
    try {
      fgResourceBundle =
          ResourceBundle.getBundle(
              "org.eclipse.cdt.debug.mi.core.MIPluginResources"); //$NON-NLS-1$
    } catch (MissingResourceException x) {
      fgResourceBundle = null;
    }
  }
  /**
   * The constructor
   *
   * @see org.eclipse.core.runtime.Plugin#Plugin()
   */
  public MIPlugin() {
    super();
    plugin = this;
  }

  /** Returns the singleton. */
  public static MIPlugin getDefault() {
    return plugin;
  }

  /**
   * Method createMISession.
   *
   * @param Process
   * @param PTY
   * @param int
   * @param int
   * @throws MIException
   * @return MISession
   * @deprecated
   */
  @Deprecated
  public MISession createMISession(
      MIProcess process,
      IMITTY pty,
      int timeout,
      int type,
      int launchTimeout,
      String miVersion,
      IProgressMonitor monitor)
      throws MIException {
    return new MISession(process, pty, type, timeout, launchTimeout, miVersion, monitor);
  }

  /**
   * Method createMISession.
   *
   * @param Process
   * @param PTY
   * @param type
   * @throws MIException
   * @return MISession
   * @deprecated
   */
  @Deprecated
  public MISession createMISession(
      MIProcess process, IMITTY pty, int type, String miVersion, IProgressMonitor monitor)
      throws MIException {
    MIPlugin miPlugin = getDefault();
    Preferences prefs = miPlugin.getPluginPreferences();
    int timeout = prefs.getInt(IMIConstants.PREF_REQUEST_TIMEOUT);
    int launchTimeout = prefs.getInt(IMIConstants.PREF_REQUEST_LAUNCH_TIMEOUT);
    return createMISession(process, pty, timeout, type, launchTimeout, miVersion, monitor);
  }

  private MISession createMISession0(
      int type, MIProcess process, CommandFactory commandFactory, IMITTY pty, int timeout)
      throws MIException {
    return new MISession(process, pty, type, commandFactory, timeout);
  }

  /**
   * Method createCSession; Create an new PTY instance and launch gdb in mi for local debug.
   *
   * @param program
   * @return ICDISession
   * @throws MIException
   * @deprecated use <code>createSession</code>
   */
  @Deprecated
  public Session createCSession(
      String gdb,
      String miVersion,
      File program,
      File cwd,
      String gdbinit,
      IProgressMonitor monitor)
      throws IOException, MIException {
    IMITTY pty = null;
    boolean failed = false;

    try {
      PTY pseudo = new PTY();
      pseudo.validateSlaveName();
      pty = new MITTYAdapter(pseudo);
    } catch (IOException e) {
      // Should we not print/log this ?
    }

    try {
      return createCSession(gdb, miVersion, program, cwd, gdbinit, pty, monitor);
    } catch (IOException exc) {
      failed = true;
      throw exc;
    } catch (MIException exc) {
      failed = true;
      throw exc;
    } finally {
      if (failed) {
        // Shutdown the pty console.
        if (pty != null) {
          try {
            OutputStream out = pty.getOutputStream();
            if (out != null) {
              out.close();
            }
            InputStream in = pty.getInputStream();
            if (in != null) {
              in.close();
            }
          } catch (IOException e) {
          }
        }
      }
    }
  }

  /**
   * Method createCSession; lauch gdb in mi mode for local debugging
   *
   * @param program
   * @return ICDISession
   * @throws IOException
   * @deprecated use <code>createSession</code>
   */
  @Deprecated
  public Session createCSession(
      String gdb,
      String miVersion,
      File program,
      File cwd,
      String gdbinit,
      IMITTY pty,
      IProgressMonitor monitor)
      throws IOException, MIException {
    if (gdb == null || gdb.length() == 0) {
      gdb = GDB;
    }

    String commandFile =
        (gdbinit != null && gdbinit.length() > 0)
            ? "--command=" + gdbinit
            : "--nx"; //$NON-NLS-1$ //$NON-NLS-2$

    if (monitor == null) {
      monitor = new NullProgressMonitor();
    }

    String[] args;
    if (pty != null) {
      if (program == null) {
        args =
            new String[] {
              gdb,
              "--cd=" + cwd.getAbsolutePath(),
              commandFile,
              "-q",
              "-nw",
              "-tty",
              pty.getSlaveName(),
              "-i",
              miVersion
            }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
      } else {
        args =
            new String[] {
              gdb,
              "--cd=" + cwd.getAbsolutePath(),
              commandFile,
              "-q",
              "-nw",
              "-tty",
              pty.getSlaveName(),
              "-i",
              miVersion,
              program.getAbsolutePath()
            }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
      }
    } else {
      if (program == null) {
        args =
            new String[] {
              gdb, "--cd=" + cwd.getAbsolutePath(), commandFile, "-q", "-nw", "-i", miVersion
            }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
      } else {
        args =
            new String[] {
              gdb,
              "--cd=" + cwd.getAbsolutePath(),
              commandFile,
              "-q",
              "-nw",
              "-i",
              miVersion,
              program.getAbsolutePath()
            }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
      }
    }

    int launchTimeout =
        MIPlugin.getDefault()
            .getPluginPreferences()
            .getInt(IMIConstants.PREF_REQUEST_LAUNCH_TIMEOUT);
    MIProcess pgdb = new MIProcessAdapter(args, launchTimeout, monitor);

    if (MIPlugin.DEBUG) {
      StringBuffer sb = new StringBuffer();
      for (int i = 0; i < args.length; ++i) {
        sb.append(args[i]);
        sb.append(' ');
      }
      MIPlugin.getDefault().debugLog(sb.toString());
    }

    MISession session;
    try {
      session = createMISession(pgdb, pty, MISession.PROGRAM, miVersion, monitor);
    } catch (MIException e) {
      pgdb.destroy();
      throw e;
    }
    // Try to detect if we have been attach/connected via "target remote localhost:port"
    // or "attach" and set the state to be suspended.
    try {
      CommandFactory factory = session.getCommandFactory();
      MIStackListFrames frames = factory.createMIStackListFrames();
      session.postCommand(frames);
      MIInfo info = frames.getMIInfo();
      if (info == null) {
        pgdb.destroy();
        throw new MIException(getResourceString("src.common.No_answer")); // $NON-NLS-1$
      }
      // @@@ We have to manually set the suspended state since we have some stackframes
      session.getMIInferior().setSuspended();
      session.getMIInferior().update();
    } catch (MIException e) {
      // If an exception is thrown that means ok
      // we did not attach/connect to any target.
    }
    return new Session(session, false);
  }

  /**
   * Method createCSession; Post mortem debug with a core file.
   *
   * @param program
   * @param core
   * @return ICDISession
   * @throws IOException
   * @deprecated use <code>createSession</code>
   */
  @Deprecated
  public Session createCSession(
      String gdb,
      String miVersion,
      File program,
      File core,
      File cwd,
      String gdbinit,
      IProgressMonitor monitor)
      throws IOException, MIException {
    if (gdb == null || gdb.length() == 0) {
      gdb = GDB;
    }

    String commandFile =
        (gdbinit != null && gdbinit.length() > 0)
            ? "--command=" + gdbinit
            : "--nx"; //$NON-NLS-1$ //$NON-NLS-2$

    if (monitor == null) {
      monitor = new NullProgressMonitor();
    }

    String[] args;
    if (program == null) {
      args =
          new String[] {
            gdb,
            "--cd=" + cwd.getAbsolutePath(),
            commandFile,
            "--quiet",
            "-nw",
            "-i",
            miVersion,
            "-c",
            core.getAbsolutePath()
          }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
    } else {
      args =
          new String[] {
            gdb,
            "--cd=" + cwd.getAbsolutePath(),
            commandFile,
            "--quiet",
            "-nw",
            "-i",
            miVersion,
            "-c",
            core.getAbsolutePath(),
            program.getAbsolutePath()
          }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
    }

    int launchTimeout =
        MIPlugin.getDefault()
            .getPluginPreferences()
            .getInt(IMIConstants.PREF_REQUEST_LAUNCH_TIMEOUT);
    MIProcess pgdb = new MIProcessAdapter(args, launchTimeout, monitor);

    if (MIPlugin.DEBUG) {
      StringBuffer sb = new StringBuffer();
      for (int i = 0; i < args.length; ++i) {
        sb.append(args[i]);
        sb.append(' ');
      }
      MIPlugin.getDefault().debugLog(sb.toString());
    }

    MISession session;
    try {
      session = createMISession(pgdb, null, MISession.CORE, miVersion, monitor);
      // @@@ We have to manually set the suspended state when doing post-mortem
      session.getMIInferior().setSuspended();
    } catch (MIException e) {
      pgdb.destroy();
      throw e;
    }
    return new Session(session);
  }

  /**
   * Method createCSession; remote debuging by selectin a target.
   *
   * @param program
   * @param pid
   * @return ICDISession
   * @throws IOException
   * @deprecated use <code>createSession</code>
   */
  @Deprecated
  public Session createCSession(
      String gdb,
      String miVersion,
      File program,
      int pid,
      String[] targetParams,
      File cwd,
      String gdbinit,
      IProgressMonitor monitor)
      throws IOException, MIException {
    if (gdb == null || gdb.length() == 0) {
      gdb = GDB;
    }

    String commandFile =
        (gdbinit != null && gdbinit.length() > 0)
            ? "--command=" + gdbinit
            : "--nx"; //$NON-NLS-1$ //$NON-NLS-2$

    if (monitor == null) {
      monitor = new NullProgressMonitor();
    }

    String[] args;
    if (program == null) {
      args =
          new String[] {
            gdb, "--cd=" + cwd.getAbsolutePath(), commandFile, "--quiet", "-nw", "-i", miVersion
          }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    } else {
      args =
          new String[] {
            gdb,
            "--cd=" + cwd.getAbsolutePath(),
            commandFile,
            "--quiet",
            "-nw",
            "-i",
            miVersion,
            program.getAbsolutePath()
          }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    }

    int launchTimeout =
        MIPlugin.getDefault()
            .getPluginPreferences()
            .getInt(IMIConstants.PREF_REQUEST_LAUNCH_TIMEOUT);
    MIProcess pgdb = new MIProcessAdapter(args, launchTimeout, monitor);

    if (MIPlugin.getDefault().isDebugging()) {
      StringBuffer sb = new StringBuffer();
      for (int i = 0; i < args.length; ++i) {
        sb.append(args[i]);
        sb.append(' ');
      }
      MIPlugin.getDefault().debugLog(sb.toString());
    }

    MISession session;
    try {
      session = createMISession(pgdb, null, MISession.ATTACH, miVersion, monitor);
    } catch (MIException e) {
      pgdb.destroy();
      throw e;
    }
    CommandFactory factory = session.getCommandFactory();
    try {
      if (targetParams != null && targetParams.length > 0) {
        MITargetSelect target = factory.createMITargetSelect(targetParams);
        session.postCommand(target);
        MIInfo info = target.getMIInfo();
        if (info == null) {
          throw new MIException(getResourceString("src.common.No_answer")); // $NON-NLS-1$
        }
      }
      if (pid > 0) {
        CLITargetAttach attach = factory.createCLITargetAttach(pid);
        session.postCommand(attach);
        MIInfo info = attach.getMIInfo();
        if (info == null) {
          throw new MIException(getResourceString("src.common.No_answer")); // $NON-NLS-1$
        }
        session.getMIInferior().setInferiorPID(pid);
        // @@@ for attach we nee to manually set the connected state
        // attach does not send the ^connected ack
        session.getMIInferior().setConnected();
      }
    } catch (MIException e) {
      if (session != null) session.terminate();

      pgdb.destroy();
      throw e;
    }
    // @@@ We have to manually set the suspended state when we attach
    session.getMIInferior().setSuspended();
    session.getMIInferior().update();
    return new Session(session, true);
  }

  /**
   * Starts a process by executing the following command: gdb -q -nw -i <mi_version>(extracted from
   * the command factory) -tty<pty_name> (if <code>usePTY</code> is <code>true</code>) extraArgs
   * program (if <code>program</code> is not <code>null</code>)
   *
   * @param sessionType the type of debugging session: <code>MISession.PROGRAM</code>, <code>
   *     MISession.ATTACH</code> or <code>MISession.CORE</code>
   * @param gdb the name of the gdb file
   * @param factory the command set supported by gdb
   * @param program a program to debug or <code>null</code>
   * @param extraArgs arguments to pass to gdb
   * @param usePty whether to use pty or not
   * @param monitor a progress monitor
   * @return an instance of <code>ICDISession</code>
   * @throws IOException
   * @throws MIException
   */
  public Session createSession(
      int sessionType,
      String gdb,
      CommandFactory factory,
      File program,
      String[] extraArgs,
      boolean usePty,
      IProgressMonitor monitor)
      throws IOException, MIException {
    if (monitor == null) {
      monitor = new NullProgressMonitor();
    }

    if (gdb == null || gdb.length() == 0) {
      gdb = GDB;
    }

    IMITTY pty = null;

    if (usePty) {
      try {
        PTY pseudo = new PTY();
        pseudo.validateSlaveName();
        pty = new MITTYAdapter(pseudo);
      } catch (IOException e) {
        // Should we not print/log this ?
      }
    }

    ArrayList argList = new ArrayList(extraArgs.length + 8);
    argList.add(gdb);
    argList.add("-q"); // $NON-NLS-1$
    argList.add("-nw"); // $NON-NLS-1$
    argList.add("-i"); // $NON-NLS-1$
    argList.add(factory.getMIVersion());
    if (pty != null) {
      argList.add("-tty"); // $NON-NLS-1$
      argList.add(pty.getSlaveName());
    }
    argList.addAll(Arrays.asList(extraArgs));
    if (program != null) {
      argList.add(program.getAbsolutePath());
    }
    String[] args = (String[]) argList.toArray(new String[argList.size()]);
    int launchTimeout =
        MIPlugin.getDefault()
            .getPluginPreferences()
            .getInt(IMIConstants.PREF_REQUEST_LAUNCH_TIMEOUT);

    MISession miSession = null;
    MIProcess pgdb = null;
    boolean failed = false;
    try {
      pgdb = factory.createMIProcess(args, launchTimeout, monitor);

      if (MIPlugin.DEBUG) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < args.length; ++i) {
          sb.append(args[i]);
          sb.append(' ');
        }
        MIPlugin.getDefault().debugLog(sb.toString());
      }

      miSession = createMISession0(sessionType, pgdb, factory, pty, getCommandTimeout());
    } catch (MIException e) {
      failed = true;
      throw e;
    } catch (IOException e) {
      failed = true;
      throw e;
    } finally {
      if (failed) {
        // Kill gdb
        if (pgdb != null) pgdb.destroy();
        // Shutdown the pty console.
        if (pty != null) {
          try {
            OutputStream out = pty.getOutputStream();
            if (out != null) {
              out.close();
            }
            InputStream in = pty.getInputStream();
            if (in != null) {
              in.close();
            }
          } catch (IOException e) {
          }
        }
      }
    }

    return new Session(miSession);
  }

  /** Convenience method which returns the unique identifier of this plugin. */
  public static String getUniqueIdentifier() {
    return PLUGIN_ID;
  }

  public void debugLog(String message) {
    if (getDefault().isDebugging()) {
      // Time stamp
      message =
          MessageFormat.format(
              "[{0}] {1}",
              new Object[] {new Long(System.currentTimeMillis()), message}); // $NON-NLS-1$
      // This is to verbose for a log file, better use the console.
      //	getDefault().getLog().log(StatusUtil.newStatus(Status.ERROR, message, null));
      // ALERT:FIXME: For example for big buffers say 4k length,
      // the console will simply blows taking down eclipse.
      // This seems only to happen in Eclipse-gtk and Eclipse-motif
      // on GNU/Linux, so we break the lines in smaller chunks.
      while (message.length() > 100) {
        String partial = message.substring(0, 100);
        message = message.substring(100);
        System.out.println(partial + "\\"); // $NON-NLS-1$
      }
      if (message.endsWith("\n")) { // $NON-NLS-1$
        System.out.print(message);
      } else {
        System.out.println(message);
      }
    }
  }

  public static String getResourceString(String key) {
    try {
      return fgResourceBundle.getString(key);
    } catch (MissingResourceException e) {
      return '!' + key + '!';
    } catch (NullPointerException e) {
      return '#' + key + '#';
    }
  }

  /* (non-Javadoc)
   * @see org.eclipse.core.runtime.Plugin#startup()
   */
  @Override
  public void start(BundleContext context) throws Exception {
    super.start(context);
    ICDebugConfiguration dc = CDebugCorePlugin.getDefault().getDefaultDefaultDebugConfiguration();
    if (dc == null) {
      CDebugCorePlugin.getDefault()
          .getPluginPreferences()
          .setDefault(
              ICDebugConstants.PREF_DEFAULT_DEBUGGER_TYPE,
              "org.eclipse.cdt.debug.mi.core.CDebuggerNew"); //$NON-NLS-1$
    }
  }

  /* (non-Javadoc)
   * @see org.eclipse.core.runtime.Plugin#shutdown()
   */
  @Override
  public void stop(BundleContext context) throws Exception {
    savePluginPreferences();
    super.stop(context);
  }

  public static int getCommandTimeout() {
    Preferences prefs = getDefault().getPluginPreferences();
    return prefs.getInt(IMIConstants.PREF_REQUEST_TIMEOUT);
  }

  public static int getLaunchTimeout() {
    Preferences prefs = plugin.getPluginPreferences();
    return prefs.getInt(IMIConstants.PREF_REQUEST_LAUNCH_TIMEOUT);
  }

  public static String getMIVersion(ILaunchConfiguration config) {
    String miVersion = ""; // $NON-NLS-1$
    try {
      miVersion =
          config.getAttribute(
              IMILaunchConfigurationConstants.ATTR_DEBUGGER_PROTOCOL, ""); // $NON-NLS-1$
    } catch (CoreException e) {
    }
    if (miVersion.length() == 0) {
      try {
        miVersion =
            config.getAttribute(
                ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_PROTOCOL, "mi"); // $NON-NLS-1$
      } catch (CoreException e) {
        miVersion = "mi"; // $NON-NLS-1$
      }
    }
    return miVersion;
  }

  public static String getCommandFactory(ILaunchConfiguration config) {
    String commandFactory = ""; // $NON-NLS-1$
    try {
      commandFactory =
          config.getAttribute(
              IMILaunchConfigurationConstants.ATTR_DEBUGGER_COMMAND_FACTORY, ""); // $NON-NLS-1$
    } catch (CoreException e) {
    }
    return commandFactory;
  }

  public CommandFactoryManager getCommandFactoryManager() {
    if (fCommandFactoryManager == null) {
      fCommandFactoryManager = new CommandFactoryManager();
    }
    return fCommandFactoryManager;
  }

  /**
   * Log internal error
   *
   * @param string - error message
   */
  public static void log(String string) {
    log(new Status(IStatus.ERROR, getUniqueIdentifier(), string));
  }
  /**
   * Logs the specified status with this plug-in's log.
   *
   * @param status status to log
   */
  public static void log(IStatus status) {
    getDefault().getLog().log(status);
  }

  /**
   * Logs an internal error with the specified throwable
   *
   * @param e the exception to be logged
   */
  public static void log(Throwable e) {
    log(
        new Status(
            IStatus.ERROR,
            getUniqueIdentifier(),
            INTERNAL_ERROR,
            "Internal Error",
            e)); //$NON-NLS-1$
  }
}
 private ConnectionProfileManager() {
   super();
   String debug = Platform.getDebugOption(OPTION_DEBUG_CONNECTION_PROFILE_EXTENSION);
   DEBUG_CONNECTION_PROFILE_EXTENSION =
       debug == null ? false : (debug.equalsIgnoreCase("true") ? true : false); // $NON-NLS-1$
 }
 static {
   String value =
       Platform.getDebugOption("org.eclipse.wst.sse.ui/debug/reconcilerjob"); // $NON-NLS-1$
   DEBUG = value != null && value.equalsIgnoreCase("true"); // $NON-NLS-1$
 }
 static {
   String value =
       Platform.getDebugOption(
           "org.eclipse.wst.xml.search.editor/debug/indexmanager"); //$NON-NLS-1$
   DEBUG = value != null && value.equalsIgnoreCase("true"); // $NON-NLS-1$
 }
Exemple #15
0
 static {
   String value = Platform.getDebugOption("org.eclipse.php.core/debug"); // $NON-NLS-1$
   isDebugMode = value != null && value.equalsIgnoreCase("true"); // $NON-NLS-1$
 }
public abstract class XMLAssociationProvider extends BaseAssociationProvider
    implements CMDocumentReferenceProvider {
  protected CMDocumentCache cmDocumentCache;
  protected CMDocumentManagerImpl documentManager;

  private static final boolean _trace =
      Boolean.valueOf(Platform.getDebugOption("org.eclipse.wst.xml.core/externalSchemaLocation"))
          .booleanValue(); //$NON-NLS-1$

  public XMLAssociationProvider(CMDocumentCache cmDocumentCache) {
    this.cmDocumentCache = cmDocumentCache;
    documentManager = new CMDocumentManagerImpl(cmDocumentCache, this);
  }

  public CMDocumentManager getCMDocumentManager() {
    return documentManager;
  }

  public static String[] getDoctypeInfo(Document document) {
    String[] result = null;
    DocumentType doctype = document.getDoctype();

    // defect 206833 ... here we test for DTDs that are declared inline
    // since we currently have no way of making use of inline DTDs we ignore them
    // so that the implict DTD (if any) can be used
    if (doctype != null && (doctype.getPublicId() != null || doctype.getSystemId() != null)) {
      result = new String[2];
      result[0] = doctype.getPublicId();
      result[1] = doctype.getSystemId();
    } else if (getImplictDoctype(document) != null) {
      result = getImplictDoctype(document);
    }
    return result;
  }

  protected static String[] getImplictDoctype(Document document) {
    String[] result = null;
    /*
    DOMExtension domExtension = DOMExtensionProviderRegistry.getInstance().getDOMExtension(document);
    if (domExtension != null)
    {
      result = domExtension.getImplicitDoctype();
    }*/
    return result;
  }

  public CMDocument getCorrespondingCMDocument(Node node) {
    return getCorrespondingCMDocument(node, true);
  }

  protected CMDocument getCorrespondingCMDocument(Node node, boolean getDocumentFromCMNode) {
    CMDocument result = null;
    try {
      Document document =
          node.getNodeType() == Node.DOCUMENT_NODE ? (Document) node : node.getOwnerDocument();

      String[] doctypeInfo = getDoctypeInfo(document);

      if (doctypeInfo != null) {
        result = getCMDocument(doctypeInfo[0], doctypeInfo[1], "DTD"); // $NON-NLS-1$
      }
      // defect 211236 ... in some cases calling this method can result in a cycle
      // we use the getDocumentFromCMNode as a flag to avoid this
      // TODO... see if there is a way to re-organize to avoid the need for this flag
      else if (getDocumentFromCMNode) {
        CMNode cmNode = getCMNode(node);
        if (cmNode != null) {
          // todo... add a getCMDocument() methods to CMNode
          // for now use the getProperty interface
          result = (CMDocument) cmNode.getProperty("CMDocument"); // $NON-NLS-1$
        }
      }
    } catch (Exception e) {
      Logger.logException("exception locating CMDocument for " + node, e); // $NON-NLS-1$
    }
    return result;
  }

  public CMDocument getCMDocument(Element element, String uri) {
    CMDocument result = null;
    NamespaceTable namespaceTable = new NamespaceTable(element.getOwnerDocument());
    namespaceTable.addElementLineage(element);
    NamespaceInfo namespaceInfo = namespaceTable.getNamespaceInfoForURI(uri);
    if (namespaceInfo != null) {
      result = getCMDocument(namespaceInfo.uri, namespaceInfo.locationHint, "XSD"); // $NON-NLS-1$
    }
    return result;
  }

  public CMDocument getCMDocument(String publicId, String systemId, String type) {
    // String resolvedGrammarURI = resolveGrammarURI(document, publicId, systemId);
    return documentManager.getCMDocument(publicId, systemId, type);
  }

  // public CMDocument getCMDocument(Document document, String publicId, String systemId)
  // {
  //  //String resolvedGrammarURI = resolveGrammarURI(document, publicId, systemId);
  //  return documentManager.getCMDocument(publicId, systemId);
  // }

  public String resolveGrammarURI(String publicId, String systemId) {
    return resolveGrammarURI(null, publicId, systemId);
  }

  /** This method should be specialized in order to implement specialized uri resolution */
  protected String resolveGrammarURI(Document document, String publicId, String systemId) {
    return systemId;
  }

  public CMElementDeclaration getCMElementDeclaration(Element element) {
    CMElementDeclaration result = null;
    Document document = element.getOwnerDocument();
    String[] doctypeInfo = getDoctypeInfo(document);
    if (doctypeInfo != null) {
      // we have detected doctype information so we assume that we can locate the
      // CMElementDeclaration
      // in the CMDocument's table of global elements
      CMDocument cmDocument = getCorrespondingCMDocument(element, false);

      // TODO... consider replacing above with
      // CMDocument cmDocument = getCMDocument(document, doctypeInfo[0], doctypeInfo[1]);

      if (cmDocument != null) {
        result =
            (CMElementDeclaration) cmDocument.getElements().getNamedItem(element.getNodeName());

        // this is a hack to get our xsl code assist working... we might want to handle similar
        // grammar behaviour via some established model query setting
        if (result == null && getImplictDoctype(document) != null) {
          Node parent = element.getParentNode();
          if (parent != null && parent.getNodeType() == Node.ELEMENT_NODE) {
            result = getCMElementDeclaration((Element) parent);
          }
        }
      }
    } else {
      // here we use a namespaceTable to consider if the root element has any namespace information
      //
      NamespaceTable namespaceTable = new NamespaceTable(element.getOwnerDocument());
      List list = NamespaceTable.getElementLineage(element);
      Element rootElement = (Element) list.get(0);
      namespaceTable.addElement(rootElement);

      if (namespaceTable.isNamespaceEncountered()) {
        // we assume that this is an XMLSchema style namespace aware document
        result = getCMElementDeclaration(element, list, namespaceTable);
      } else {
        result = checkExternalSchema(element);
        if (result == null) {
          // we assume that this is an inferred CMDocument for a DTD style 'namespaceless' document
          CMDocument cmDocument =
              getCMDocument("", "", "DTD"); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
          if (cmDocument != null) {
            result =
                (CMElementDeclaration) cmDocument.getElements().getNamedItem(element.getNodeName());
          }
        }
      }
    }
    return result;
  }

  protected CMElementDeclaration checkExternalSchema(Element element) {
    final Document document = element.getOwnerDocument();
    if (document instanceof IDOMDocument) {
      final String baseLocation = ((IDOMDocument) document).getModel().getBaseLocation();
      if (baseLocation != null) {
        final IPath basePath = new Path(baseLocation);
        IFile file = null;
        if (basePath.segmentCount() > 1) {
          file = ResourcesPlugin.getWorkspace().getRoot().getFile(basePath);
        }
        final URI uri =
            (file == null || !file.isAccessible())
                ? new File(baseLocation).toURI()
                : file.getLocationURI();
        if (uri != null) {
          IExternalSchemaLocationProvider[] providers =
              ExternalSchemaLocationProviderRegistry.getInstance().getProviders();
          for (int i = 0; i < providers.length; i++) {
            long time = _trace ? System.currentTimeMillis() : 0;
            final Map locations = providers[i].getExternalSchemaLocation(uri);
            if (_trace) {
              long diff = System.currentTimeMillis() - time;
              if (diff > 250)
                Logger.log(
                    Logger.INFO,
                    "Schema location provider took ["
                        + diff
                        + "ms] for URI ["
                        + uri
                        + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            }
            if (locations != null && !locations.isEmpty()) {
              Object location =
                  locations.get(IExternalSchemaLocationProvider.NO_NAMESPACE_SCHEMA_LOCATION);
              if (location != null)
                return getCMElementDeclaration(
                    element,
                    NamespaceTable.getElementLineage(element),
                    uri.toString(),
                    location.toString());
            }
          }
        }
      }
    }
    return null;
  }

  protected CMElementDeclaration getCMElementDeclaration(
      Element targetElement, List list, String publicId, String systemId) {
    CMElementDeclaration currentED = null;
    try {
      int listSize = list.size();
      for (int i = 0; i < listSize; i++) {
        Element element = (Element) list.get(i);

        final String nodeName = element.getNodeName();

        CMElementDeclaration ed = null;

        // see if the element is a local of the currentED
        //
        if (currentED != null) {
          ed = (CMElementDeclaration) currentED.getLocalElements().getNamedItem(nodeName);
        }

        if (ed == null) {
          CMDocument cmDocument = getCMDocument(publicId, systemId, "XSD"); // $NON-NLS-1$
          if (cmDocument != null) {
            ed = (CMElementDeclaration) cmDocument.getElements().getNamedItem(nodeName);
          }
        }
        currentED = ed;
      }
    } catch (Exception e) {
      Logger.logException(
          "exception locating element declaration for " + targetElement, e); // $NON-NLS-1$
    }

    return currentED;
  }

  protected CMElementDeclaration getCMElementDeclaration(
      Element targetElement, List list, NamespaceTable namespaceTable) {
    CMElementDeclaration currentED = null;
    try {
      int listSize = list.size();
      for (int i = 0; i < listSize; i++) {
        Element element = (Element) list.get(i);

        if (i != 0) {
          namespaceTable.addElement(element);
        }

        String nodeName = element.getNodeName();
        String unprefixedName = DOMNamespaceHelper.getUnprefixedName(nodeName);
        String prefix = DOMNamespaceHelper.getPrefix(nodeName);

        CMElementDeclaration ed = null;

        // see if the element is a local of the currentED
        //
        if (currentED != null) {
          ed = (CMElementDeclaration) currentED.getLocalElements().getNamedItem(unprefixedName);
        }

        if (ed == null) {
          NamespaceInfo namespaceInfo = namespaceTable.getNamespaceInfoForPrefix(prefix);
          if (namespaceInfo != null) {
            CMDocument cmDocument =
                getCMDocument(namespaceInfo.uri, namespaceInfo.locationHint, "XSD"); // $NON-NLS-1$
            if (cmDocument != null) {
              ed = (CMElementDeclaration) cmDocument.getElements().getNamedItem(unprefixedName);
            }
          }
        }
        currentED = ed;

        // handle XSIType
        if (currentED != null) {
          CMElementDeclaration derivedED =
              getDerivedCMElementDeclaration(element, currentED, namespaceTable);
          if (derivedED != null) {
            currentED = derivedED;
          }
        }
      }
    } catch (Exception e) {
      Logger.logException(
          "exception locating element declaration for " + targetElement, e); // $NON-NLS-1$
    }

    return currentED;
  }

  protected CMElementDeclaration getDerivedCMElementDeclaration(
      Element element, CMElementDeclaration ed, NamespaceTable namespaceTable) {
    CMElementDeclaration result = null;
    String xsiPrefix =
        namespaceTable.getPrefixForURI("http://www.w3.org/2001/XMLSchema-instance"); // $NON-NLS-1$
    if (xsiPrefix != null) {
      String xsiTypeValue = element.getAttribute(xsiPrefix + ":type"); // $NON-NLS-1$
      if (xsiTypeValue != null && xsiTypeValue.length() > 0) {
        String typePrefix = DOMNamespaceHelper.getPrefix(xsiTypeValue);
        String typeName = DOMNamespaceHelper.getUnprefixedName(xsiTypeValue);
        String typeURI = namespaceTable.getURIForPrefix(typePrefix);
        String uriQualifiedTypeName = typeName;
        if (typeURI != null && typeURI.length() > 0) {
          uriQualifiedTypeName = "[" + typeURI + "]" + typeName; // $NON-NLS-1$ //$NON-NLS-2$
        }
        result =
            (CMElementDeclaration)
                ed.getProperty("DerivedElementDeclaration=" + uriQualifiedTypeName); // $NON-NLS-1$
        if (result == null) {
          String reference = null;
          NamespaceInfo namespaceInfo = namespaceTable.getNamespaceInfoForPrefix(typePrefix);
          if (namespaceInfo != null) {
            String locationHint =
                resolveGrammarURI(
                    element.getOwnerDocument(), namespaceInfo.uri, namespaceInfo.locationHint);
            if (locationHint != null) {
              reference = "[" + locationHint + "]" + typeName; // $NON-NLS-1$ //$NON-NLS-2$
            }
          }
          if (reference != null) {
            result =
                (CMElementDeclaration)
                    ed.getProperty(
                        "ExternallyDerivedElementDeclaration=" + reference); // $NON-NLS-1$
          }
        }
      }
    }
    return result;
  }

  public CMAttributeDeclaration getCMAttributeDeclaration(Attr attr) {
    CMAttributeDeclaration result = null;
    Element element = attr.getOwnerElement();
    if (element != null) {
      CMElementDeclaration ed = getCMElementDeclaration(element);
      if (ed != null) {
        result = (CMAttributeDeclaration) ed.getAttributes().getNamedItem(attr.getName());
        if (result == null) {
          // try to get the unprefixed name
          String name = DOMNamespaceHelper.getUnprefixedName(attr.getName());
          result = (CMAttributeDeclaration) ed.getAttributes().getNamedItem(name);
        }
        if (result == null) {
          // todo... perhaps this is a globally defined attribute...
        }
      }
    }
    return result;
  }

  /**
   * This method returns a list of CMDocumentReferences associated with a particular node or subtree
   */
  public List getCMDocumentReferences(Node node, boolean deep) {
    List result = new ArrayList();
    Document document =
        (node.getNodeType() == Node.DOCUMENT_NODE) ? (Document) node : node.getOwnerDocument();
    DocumentType doctype = document.getDoctype();
    // defect 206833 ... here we test for DTDs that are declared inline
    // since we currently have no way of making use of inline DTDs we ingore them
    // so that the implict DTD (if any) can be used
    if (doctype != null && (doctype.getPublicId() != null || doctype.getSystemId() != null)) {
      String uri = resolveGrammarURI(document, doctype.getPublicId(), doctype.getSystemId());
      result.add(new CMDocumentReferenceImpl(doctype.getPublicId(), uri));
    } else if (getImplictDoctype(document) != null) {
      String[] implicitDoctype = getImplictDoctype(document);
      String uri = resolveGrammarURI(document, implicitDoctype[0], implicitDoctype[1]);
      result.add(new CMDocumentReferenceImpl(implicitDoctype[0], uri));
    } else {
      NamespaceTable namespaceTable = new NamespaceTable(document);
      if (node.getNodeType() == Node.ELEMENT_NODE) {
        namespaceTable.addElement((Element) node);
      }
      if (deep) {
        addChildElementsToNamespaceTable(node, namespaceTable);
      }
      List list = namespaceTable.getNamespaceInfoList();
      for (Iterator i = list.iterator(); i.hasNext(); ) {
        NamespaceInfo info = (NamespaceInfo) i.next();
        String uri = resolveGrammarURI(document, info.uri, info.locationHint);
        result.add(new CMDocumentReferenceImpl(info.uri, uri));
      }
    }
    return result;
  }

  protected void addChildElementsToNamespaceTable(Node node, NamespaceTable namespaceTable) {
    NodeList nodeList = node.getChildNodes();
    if (nodeList != null) {
      int nodeListLength = nodeList.getLength();
      for (int i = 0; i < nodeListLength; i++) {
        Node childNode = nodeList.item(i);
        if (childNode.getNodeType() == Node.ELEMENT_NODE) {
          namespaceTable.addElement((Element) childNode);
          addChildElementsToNamespaceTable(childNode, namespaceTable);
        }
      }
    }
  }
}
Exemple #17
0
 public boolean useDebugHttpClient() {
   return Boolean.parseBoolean(
       Platform.getDebugOption("org.guvnor.tools/debugHttpClient")); // $NON-NLS-1$
 }
/**
 * This is the factory registry to use for Remote VM. It adds to the standard registry, connection
 * specific information.
 *
 * <p>This will always hold onto one connection open until termination is requested. That way while
 * the IDE is up, the remove vm won't time out.
 */
public class REMProxyFactoryRegistry extends BaseProxyFactoryRegistry {

  public static final String REMOTE_REGISTRY_TYPE_ID = "org.eclipse.jem.REMOTE"; // $NON-NLS-1$

  protected int fServerPort = 0; // The server port to use when making connections.
  protected REMCallbackRegistry fCallbackServer; // The callback server thread for this remote vm.
  protected Stack fConnectionPool = new Stack(); // Stack of free connections.
  protected static int NUMBER_FREE_CONNECTIONS = 5; // Number of free connections to keep open.
  protected IProcess
      fProcess; // The process that is the server. If null and fServerPort is not zero,
  // then this registry is in test mode
  // and the server is in same the process.
  protected String fName;
  protected int fCallbackServerPort;
  protected Integer fRegistryKey;
  protected REMRegistryController fRegistryController;

  protected static final Object TERMINATE_JOB_FAMILY = new Object();

  // Package protected because only the ProxyVMStarter should set this flag. It would set it if
  // working with a debugger because we don't how long it will be to respond to requests when
  // someone is working with a debugger.
  boolean fNoTimeouts = false;

  // This is set via the static setGlobalNoTimeouts() method, or via debug options flag. It is here
  // so that
  // when debugging callbacks, but not debugging remote vm, that no timeouts for any registry will
  // occur.
  // Or it can be set through the debug .options flag.
  static boolean fGlobalNoTimeouts =
      "true"
          .equalsIgnoreCase(
              Platform.getDebugOption(
                  ProxyPlugin.getPlugin().getBundle().getSymbolicName()
                      + ProxyRemoteUtil.NO_TIMEOUTS)); // $NON-NLS-1$;

  /**
   * Typicall set through the "expression" evaluation of the debugger.
   *
   * @param noTimeouts
   * @since 1.0.0
   */
  public static void setGlobalNoTimeouts(boolean noTimeouts) {
    fGlobalNoTimeouts = noTimeouts;
  }

  // An internal thread that locks and waits for the remote vm to register itself.
  private WaitForRegistrationThread waitRegistrationThread;

  private class WaitForRegistrationThread extends Thread {
    public WaitForRegistrationThread() {
      super("Wait for remote vm registration thread"); // $NON-NLS-1$
    }

    /** @see java.lang.Thread#run() */
    public void run() {
      // Wait for registration. Put it into a thread so this
      // can occur while other stuff goes on. It locks the fConnectionPool
      // until done so that the first request for a connection by anyone
      // else will wait until this thread is finished.

      synchronized (fConnectionPool) {
        synchronized (REMProxyFactoryRegistry.this) {
          // Notify the main thread that we have the
          // connection pool locked.
          REMProxyFactoryRegistry.this.notifyAll();
        }
        synchronized (this) {
          // sync on self so that it can be notified when finally receive the registration
          long stopTime = System.currentTimeMillis() + 60000;
          while (waitRegistrationThread != null
              && (fNoTimeouts || System.currentTimeMillis() < stopTime)) {
            try {
              Thread.currentThread().wait(60000);
            } catch (InterruptedException e) {
            }
          }
        }
      }

      waitRegistrationThread = null; // No longer exists.			
    }
  }

  public REMProxyFactoryRegistry(REMRegistryController registryController, String name) {
    super(REMOTE_REGISTRY_TYPE_ID);
    fRegistryController = registryController;
    fRegistryKey =
        fRegistryController.registerRegistry(this); // Register the registry with the plugin.	
    fName = name;

    // Get the waitRegistrationThread started before we actually launch remote vm so
    // that it is waiting when the callback comes in.
    synchronized (this) {
      waitRegistrationThread = new WaitForRegistrationThread();
      waitRegistrationThread.start();

      // Now we will wait until the registration callback has been done. The thread will
      // signal us when that is done. This is so that we don't continue on and let
      // a work connection be requested before we even got a chance to start waiting
      // for the registration.
      while (true) {
        try {
          wait();
          break;
        } catch (InterruptedException e) {
        }
      }
      ;
    }
  }

  public Integer getRegistryKey() {
    return fRegistryKey;
  }

  public void initializeRegistry(IProcess process) {
    fProcess = process;
    processListener =
        new IDebugEventSetListener() {
          /** @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(DebugEvent[]) */
          public void handleDebugEvents(DebugEvent[] events) {
            for (int i = 0; i < events.length; i++) {
              DebugEvent e = events[i];
              if (e.getSource() == fProcess && e.getKind() == DebugEvent.TERMINATE) {
                // We terminating too soon. Pop up a msg.
                IStreamsProxy stProxy = fProcess.getStreamsProxy();
                java.io.StringWriter s = new java.io.StringWriter();
                java.io.PrintWriter w = new java.io.PrintWriter(s);

                String msg =
                    MessageFormat.format(
                        ProxyRemoteMessages.Proxy_Terminated_too_soon_ERROR_, new Object[] {fName});
                w.println(msg);
                w.println(ProxyRemoteMessages.VM_TERMINATED_INFO_);
                w.println(ProxyRemoteMessages.VM_COMMAND_LINE);
                w.println(fProcess.getAttribute(IProcess.ATTR_CMDLINE));
                w.println(ProxyRemoteMessages.VM_TERMINATED_LINE1);
                w.println(stProxy.getErrorStreamMonitor().getContents());
                w.println(ProxyRemoteMessages.VM_TERMINATED_LINE2);
                w.println(stProxy.getOutputStreamMonitor().getContents());
                w.println(ProxyRemoteMessages.VM_TERMINATED_LINE3);
                w.close();

                DebugModeHelper dh = new DebugModeHelper();
                dh.displayErrorMessage(ProxyRemoteMessages.Proxy_Error_Title, msg);
                ProxyPlugin.getPlugin()
                    .getLogger()
                    .log(
                        new Status(
                            IStatus.WARNING,
                            ProxyPlugin.getPlugin().getBundle().getSymbolicName(),
                            0,
                            s.toString(),
                            null));
                processListener = null;
                DebugPlugin.getDefault().removeDebugEventListener(this);
                terminateRegistry();
                break;
              }
            }
          }
        };

    DebugPlugin.getDefault().addDebugEventListener(processListener);
  }

  private IDebugEventSetListener processListener = null;

  /** Get the CallbackRegistry */
  public ICallbackRegistry getCallbackRegistry() {
    if (fCallbackServer == null) fCallbackServer = new REMCallbackRegistry(fName, this);
    return fCallbackServer;
  }

  /**
   * This is called by the registry controller to tell the registry to terminate with prejudice all
   * pending TerminateJobs.
   *
   * @since 1.1.0
   */
  public static void cancelAllTerminateJobs() {
    IJobManager jobManager = Job.getJobManager();
    jobManager.cancel(TERMINATE_JOB_FAMILY);
    try {
      jobManager.join(TERMINATE_JOB_FAMILY, null);
    } catch (OperationCanceledException e) {
    } catch (InterruptedException e) {
    }
  }

  private static class TerminateProcess extends Job {
    private IProcess process;

    public TerminateProcess(IProcess process) {
      super(ProxyRemoteMessages.REMProxyFactoryRegistry_Job_TerminateProcess_Title);
      this.process = process;
    }

    public boolean belongsTo(Object family) {
      return family == TERMINATE_JOB_FAMILY || super.belongsTo(family);
    }

    /* (non-Javadoc)
     * @see java.lang.Thread#run()
     */
    public IStatus run(IProgressMonitor mon) {
      try {
        // There is no join on a process available, so we will have to
        // busy wait. Give it 10 seconds in 1/10 second intervals.
        for (int i = 0; !process.isTerminated() && i < 100; i++) {
          try {
            Thread.sleep(100);
          } catch (InterruptedException e) {
          }
        }
        if (!process.isTerminated()) {
          process.terminate();
        }
      } catch (DebugException e) {
      }
      return Status.OK_STATUS;
    }
  }

  protected void registryTerminated(boolean wait) {
    if (processListener != null) {
      // Remove listener cause we are now going to terminate process and don't want premature
      // terminate notice.
      // Sometimes in shutdown we are called and the debug plugin may of already been shutdown. In
      // that case the db
      // will be null and there is nothing remove listener from.
      DebugPlugin db = DebugPlugin.getDefault();
      if (db != null) db.removeDebugEventListener(processListener);
      processListener = null;
    }

    Job tjob = null;
    if (waitRegistrationThread != null) {
      synchronized (waitRegistrationThread) {
        // Still waiting. close it out.
        WaitForRegistrationThread wThread = waitRegistrationThread;
        waitRegistrationThread = null;
        wThread.notifyAll();
      }
    }
    if (fServerPort != 0) {
      IREMConnection closeCon = null; // The connection we will use to close the remote vm.
      synchronized (fConnectionPool) {
        // Now we walk through all of the free connections and close them properly.
        Iterator itr = fConnectionPool.iterator();
        if (itr.hasNext()) closeCon = (IREMConnection) itr.next();
        while (itr.hasNext()) {
          IREMConnection con = (IREMConnection) itr.next();
          con.close();
        }
      }

      // Now we terminate the server.
      if (closeCon == null)
        try {
          closeCon =
              getFreeConnection(); // There weren't any free connections, so get a new one so that
                                   // we can close it.
        } catch (IllegalStateException e) {
          // Do nothing, don't want to stop termination just because we can't get a connection.
        }
      if (closeCon != null) {
        closeCon
            .terminateServer(); // We got a connection to terminate (process may of terminated
                                // early, so we would not have a conn then).
      }
      fConnectionPool.clear();
      fServerPort = 0;

      if (fProcess != null && !fRegistryController.inShutDown()) {
        tjob = new TerminateProcess(fProcess);
        tjob.setSystem(true);
        tjob.schedule();
        fProcess = null;
      }
    }

    if (fCallbackServer != null) {
      fCallbackServer.requestShutdown();
      fCallbackServer = null;
    }

    fConnectionPool.clear();
    fRegistryController.deregisterRegistry(fRegistryKey); // De-register this registry.

    if (wait && tjob != null) {
      try {
        tjob.join();
      } catch (InterruptedException e) {
        // It timed out, so we'll just go on.
      }
    }
  }

  /** Return the server port number. */
  public int getServerPort() {
    return fServerPort;
  }

  /*
   * set the server port.
   */
  void setServerPort(int serverport) {
    fServerPort = serverport;
    if (waitRegistrationThread != null) {
      synchronized (waitRegistrationThread) {
        // Close it out, we are now registered
        WaitForRegistrationThread wThread = waitRegistrationThread;
        waitRegistrationThread = null;
        wThread.notifyAll();
      }
    }
  }

  /**
   * Get a free connection
   *
   * @return
   * @throws IllegalStateException - Thrown if a connection cannot be created.
   * @since 1.0.0
   */
  public IREMConnection getFreeConnection() throws IllegalStateException {
    Thread thread = Thread.currentThread();
    if (thread instanceof REMCallbackThread) {
      // The current thread is a call back thread, so just reuse the connection.
      // But this thread could actually be trying to access another registry.
      // So if this thread is for this registry, use it, if not for this registry, create a new
      // connection.
      // But if for this registry AND is already in a transaction, we need a fresh connection.
      REMCallbackThread callbackThread = (REMCallbackThread) thread;
      if (callbackThread.registry == this && !callbackThread.inTransaction()) {
        // This way any calls out to the remote vm will be on same thread as callback caller
        // on remote vm because that thread is waiting on this connection for commands.
        IREMConnection c = (callbackThread).getConnection();
        if (c.isConnected()) return c;
        else
          throw new IllegalStateException(
              ProxyRemoteMessages.REMProxyFactoryRegistry_CallbackConnectionNotWorking_EXC_);
      }
    }
    synchronized (fConnectionPool) {
      if (!fConnectionPool.isEmpty()) return (IREMConnection) fConnectionPool.pop();
      // else we need to allocate one.
      return createConnection();
    }
  }

  /**
   * Make a new connection.
   *
   * @return
   * @throws IllegalStateException - Thrown if connection cannot be created.
   * @since 1.0.0
   */
  protected IREMConnection createConnection() throws IllegalStateException {
    // If we have a server port, then the server is probably open. If we don't then there is no
    // server.
    if (fServerPort != 0) {
      // We are putting it off into a thread because there are no timeout capabilities on getting a
      // socket.
      // So we need to allow for that.
      final Socket[] scArray = new Socket[1];
      final boolean[] waiting = new boolean[] {true};
      Thread doIt =
          new Thread(
              new Runnable() {
                public void run() {
                  try {
                    Socket sc = new Socket("localhost", fServerPort); // $NON-NLS-1$
                    synchronized (this) {
                      if (waiting[0]) scArray[0] = sc;
                      else
                        sc
                            .close(); // We are no longer waiting on this thread so close the socket
                                      // since no one will use it.
                    }
                  } catch (IOException e) {
                    ProxyPlugin.getPlugin()
                        .getLogger()
                        .log(
                            new Status(
                                IStatus.WARNING,
                                ProxyPlugin.getPlugin().getBundle().getSymbolicName(),
                                0,
                                "",
                                e)); //$NON-NLS-1$
                  }
                }
              });

      doIt.start();
      while (true) {
        try {
          doIt.join(!fNoTimeouts ? 60000 : 0);
          synchronized (doIt) {
            waiting[0] = false; // To let it know we are no longer waiting
          }
          break;
        } catch (InterruptedException e) {
        }
      }

      if (scArray[0] == null) {
        // Log where we are at so we can know where it was we down.
        ProxyPlugin.getPlugin()
            .getLogger()
            .log(
                new Status(
                    IStatus.WARNING,
                    ProxyPlugin.getPlugin().getBundle().getSymbolicName(),
                    0,
                    "",
                    new IllegalStateException(
                        ProxyRemoteMessages
                            .REMProxyFactoryRegistry_ConnectionCreationFailed_INFO_))); //$NON-NLS-1$
        throw new IllegalStateException(
            ProxyRemoteMessages
                .REMProxyFactoryRegistry_CouldNotCreateSocketConnectionToRemoteVM_EXC_); // Couldn't
                                                                                         // get one,
                                                                                         // probably
                                                                                         // server
                                                                                         // is down.
                                                                                         // //$NON-NLS-1$
      }

      REMConnection connection = new REMConnection(scArray[0], fNoTimeouts);
      if (connection.isConnected()) return connection;

      // Failed, close the socket.
      try {
        scArray[0].close();
      } catch (IOException e) {
      }
    } else
      ProxyPlugin.getPlugin()
          .getLogger()
          .log(
              new Status(
                  IStatus.WARNING,
                  ProxyPlugin.getPlugin().getBundle().getSymbolicName(),
                  0,
                  "No Server to retrieve a connection.",
                  null)); ///$NON-NLS-1$

    throw new IllegalStateException(
        ProxyRemoteMessages.REMProxyFactoryRegistry_CouldNotCreateSocketConnectionToRemoteVM_EXC_);
  }

  /** Free the connection */
  public void returnConnection(IREMConnection connection) {
    if (connection.isConnected()) {
      Thread thread = Thread.currentThread();
      if (!(thread instanceof REMCallbackThread)
          || ((REMCallbackThread) thread).getConnection() != connection) {
        // We are not a callback thread, or we are but the connection is not for the thread, then
        // the connection
        // can be returned.
        synchronized (fConnectionPool) {
          if (fConnectionPool.size() < NUMBER_FREE_CONNECTIONS) fConnectionPool.push(connection);
          else connection.close(); // We don't need to maintain more than five free connections.
        }
      }
    }
  }

  /** Release this connection. This means close it out. */
  public void closeConnection(IREMConnection connection) {
    connection.close();
  }

  public int connectionCount() {
    synchronized (fConnectionPool) {
      return fConnectionPool.size();
    }
  }
}
/**
 * Adds to DirtyRegionProcessor Job: - IDocumentListener - ValidatorStrategy - Text viewer(dispose,
 * input changed) listeners. - default, spelling, and validator strategies - DirtyRegion processing
 * logic.
 */
public class DocumentRegionProcessor extends DirtyRegionProcessor {
  private static final boolean DEBUG_VALIDATORS =
      Boolean.TRUE
          .toString()
          .equalsIgnoreCase(
              Platform.getDebugOption(
                  "org.eclipse.wst.sse.ui/debug/reconcilerValidators")); //$NON-NLS-1$

  /** A strategy to use the defined default Spelling service. */
  private IReconcilingStrategy fSpellcheckStrategy;

  /**
   * The strategy that runs validators contributed via <code>
   * org.eclipse.wst.sse.ui.extensions.sourcevalidation</code> extension point
   */
  private ValidatorStrategy fValidatorStrategy;

  private ISourceReconcilingListener[] fReconcileListeners = new ISourceReconcilingListener[0];

  private IReconcilingStrategy fSemanticHighlightingStrategy;

  /** The folding strategy for this processor */
  private AbstractStructuredFoldingStrategy fFoldingStrategy;

  private final String SSE_UI_ID = "org.eclipse.wst.sse.ui"; // $NON-NLS-1$

  /** true if as you type validation is enabled, false otherwise */
  private boolean fValidationEnabled;

  public void addReconcilingListener(ISourceReconcilingListener listener) {
    Set listeners = new HashSet(Arrays.asList(fReconcileListeners));
    listeners.add(listener);
    fReconcileListeners =
        (ISourceReconcilingListener[])
            listeners.toArray(new ISourceReconcilingListener[listeners.size()]);
  }

  protected void beginProcessing() {
    super.beginProcessing();
    ValidatorStrategy validatorStrategy = getValidatorStrategy();
    if (validatorStrategy != null) {
      validatorStrategy.beginProcessing();
    }
    if ((getTextViewer() instanceof ISourceViewer)) {
      for (int i = 0; i < fReconcileListeners.length; i++) {
        fReconcileListeners[i].aboutToBeReconciled();
      }
    }
  }

  protected void endProcessing() {
    super.endProcessing();
    ValidatorStrategy validatorStrategy = getValidatorStrategy();
    if (validatorStrategy != null) {
      validatorStrategy.endProcessing();
    }
    /* single spell-check for everything to ensure that SpellingProblem offsets are correct */
    IReconcilingStrategy spellingStrategy = getSpellcheckStrategy();
    IDocument document = getDocument();
    if (spellingStrategy != null && document != null) {
      spellingStrategy.reconcile(new Region(0, document.getLength()));
    }

    IReconcilingStrategy semanticHighlightingStrategy = getSemanticHighlightingStrategy();
    if (semanticHighlightingStrategy != null && document != null) {
      semanticHighlightingStrategy.reconcile(new Region(0, document.getLength()));
    }

    if ((getTextViewer() instanceof ISourceViewer)) {
      ISourceViewer sourceViewer = (ISourceViewer) getTextViewer();
      IAnnotationModel annotationModel = sourceViewer.getAnnotationModel();
      for (int i = 0; i < fReconcileListeners.length; i++) {
        fReconcileListeners[i].reconciled(
            document, annotationModel, false, new NullProgressMonitor());
      }
    }
  }

  public void forceReconciling() {
    super.forceReconciling();
  }

  protected String getContentType(IDocument doc) {
    if (doc == null) return null;

    String contentTypeId = null;

    IContentType ct = null;
    try {
      IContentDescription desc =
          Platform.getContentTypeManager()
              .getDescriptionFor(new StringReader(doc.get()), null, IContentDescription.ALL);
      if (desc != null) {
        ct = desc.getContentType();
        if (ct != null) contentTypeId = ct.getId();
      }
    } catch (IOException e) {
      // just bail
    }
    return contentTypeId;
  }

  protected IReconcilingStrategy getSpellcheckStrategy() {
    if (fSpellcheckStrategy == null && getDocument() != null) {
      String contentTypeId = getContentType(getDocument());
      if (contentTypeId == null) {
        contentTypeId = IContentTypeManager.CT_TEXT;
      }
      if (getTextViewer() instanceof ISourceViewer) {
        ISourceViewer viewer = (ISourceViewer) getTextViewer();
        fSpellcheckStrategy = new SpellcheckStrategy(viewer, contentTypeId);
        fSpellcheckStrategy.setDocument(getDocument());
      }
    }
    return fSpellcheckStrategy;
  }

  /**
   * Get the folding strategy for this processor. Retrieved from the extended configuration builder.
   * The processor chosen is set by the plugin.
   *
   * <p>EX:<br>
   * <code>&lt;extension point="org.eclipse.wst.sse.ui.editorConfiguration"&gt;<br />
   *  &lt;provisionalConfiguration<br />
   * 		type="foldingstrategy"<br />
   * 		class="org.eclipse.wst.xml.ui.internal.projection.XMLFoldingStrategy"<br />
   * 		target="org.eclipse.core.runtime.xml, org.eclipse.wst.xml.core.xmlsource" /&gt;<br />
   * &lt;/extension&gt;</code>
   *
   * <p>The type must be equal to <code>AbstractFoldingStrategy.ID</code> (AKA: foldingstrategy) and
   * the class must extend <code>org.eclipse.wst.sse.ui.internal.projection.AbstractFoldingStrategy
   * </code> and the target must be a structured editor content type ID
   *
   * @return the requested folding strategy or null if none can be found
   */
  protected IReconcilingStrategy getFoldingStrategy() {
    if (fFoldingStrategy == null && getDocument() != null) {
      String contentTypeId = getContentType(getDocument());
      if (contentTypeId == null) {
        contentTypeId = IContentTypeManager.CT_TEXT;
      }

      ITextViewer viewer = getTextViewer();
      if (viewer instanceof ProjectionViewer) {
        ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();

        IContentType type = Platform.getContentTypeManager().getContentType(contentTypeId);
        while (fFoldingStrategy == null && type != null) {
          fFoldingStrategy =
              (AbstractStructuredFoldingStrategy)
                  builder.getConfiguration(AbstractStructuredFoldingStrategy.ID, type.getId());

          type = type.getBaseType();
        }

        if (fFoldingStrategy != null) {
          fFoldingStrategy.setViewer((ProjectionViewer) viewer);
          fFoldingStrategy.setDocument(getDocument());
        }
      }
    }

    return fFoldingStrategy;
  }

  /**
   * Enable or disable as you type validation. Typically set by a user preference
   *
   * @param enable true to enable as you type validation, false to disable
   */
  public void setValidatorStrategyEnabled(boolean enable) {
    fValidationEnabled = enable;
  }

  /** @return Returns the ValidatorStrategy. */
  protected ValidatorStrategy getValidatorStrategy() {
    ValidatorStrategy validatorStrategy = null;
    if (fValidatorStrategy == null && fValidationEnabled) {
      if (getTextViewer() instanceof ISourceViewer) {
        ISourceViewer viewer = (ISourceViewer) getTextViewer();
        String contentTypeId = null;

        IDocument doc = viewer.getDocument();
        contentTypeId = getContentType(doc);

        if (contentTypeId != null) {
          validatorStrategy = new ValidatorStrategy(viewer, contentTypeId);
          ValidatorBuilder vBuilder = new ValidatorBuilder();
          ValidatorMetaData[] vmds = vBuilder.getValidatorMetaData(SSE_UI_ID);
          List enabledValidators = new ArrayList(1);
          /* if any "must" handle this content type, just add them */
          boolean foundSpecificContentTypeValidators = false;
          for (int i = 0; i < vmds.length; i++) {
            if (vmds[i].mustHandleContentType(contentTypeId)) {
              if (DEBUG_VALIDATORS)
                Logger.log(
                    Logger.INFO,
                    contentTypeId
                        + " using specific validator "
                        + vmds[i].getValidatorId()); // $NON-NLS-1$
              foundSpecificContentTypeValidators = true;
              enabledValidators.add(vmds[i]);
            }
          }
          if (!foundSpecificContentTypeValidators) {
            for (int i = 0; i < vmds.length; i++) {
              if (vmds[i].canHandleContentType(contentTypeId)) {
                if (DEBUG_VALIDATORS)
                  Logger.log(
                      Logger.INFO,
                      contentTypeId
                          + " using inherited(?) validator "
                          + vmds[i].getValidatorId()); // $NON-NLS-1$
                enabledValidators.add(vmds[i]);
              }
            }
          }
          for (int i = 0; i < enabledValidators.size(); i++) {
            validatorStrategy.addValidatorMetaData((ValidatorMetaData) enabledValidators.get(i));
          }
        }
      }
      fValidatorStrategy = validatorStrategy;
    } else if (fValidatorStrategy != null && fValidationEnabled) {
      validatorStrategy = fValidatorStrategy;
    }
    return validatorStrategy;
  }

  public void setSemanticHighlightingStrategy(IReconcilingStrategy semanticHighlightingStrategy) {
    fSemanticHighlightingStrategy = semanticHighlightingStrategy;
    fSemanticHighlightingStrategy.setDocument(getDocument());
  }

  protected IReconcilingStrategy getSemanticHighlightingStrategy() {
    return fSemanticHighlightingStrategy;
  }

  /** @param dirtyRegion */
  protected void process(DirtyRegion dirtyRegion) {
    if (!isInstalled() || isInRewriteSession() || dirtyRegion == null || getDocument() == null)
      return;

    super.process(dirtyRegion);

    ITypedRegion[] partitions = computePartitioning(dirtyRegion);

    // call the validator strategy once for each effected partition
    DirtyRegion dirty = null;
    for (int i = 0; i < partitions.length; i++) {
      dirty = createDirtyRegion(partitions[i], DirtyRegion.INSERT);

      // [source]validator (extension) for this partition
      if (getValidatorStrategy() != null) {
        getValidatorStrategy().reconcile(partitions[i], dirty);
      }
    }

    /* if there is a folding strategy then reconcile it for the
     * entire dirty region.
     * NOTE: the folding strategy does not care about the sub regions.
     */
    if (getFoldingStrategy() != null) {
      getFoldingStrategy().reconcile(dirtyRegion, null);
    }
  }

  public void removeReconcilingListener(ISourceReconcilingListener listener) {
    Set listeners = new HashSet(Arrays.asList(fReconcileListeners));
    listeners.remove(listener);
    fReconcileListeners =
        (ISourceReconcilingListener[])
            listeners.toArray(new ISourceReconcilingListener[listeners.size()]);
  }

  public void setDocument(IDocument doc) {
    super.setDocument(doc);

    IReconcilingStrategy validatorStrategy = getValidatorStrategy();
    if (validatorStrategy != null) {
      validatorStrategy.setDocument(doc);
    }
    if (fSemanticHighlightingStrategy != null) {
      fSemanticHighlightingStrategy.setDocument(doc);
    }

    fSpellcheckStrategy = null;
    if (fFoldingStrategy != null) {
      fFoldingStrategy.uninstall();
    }
    fFoldingStrategy = null;
  }

  protected void setEntireDocumentDirty(IDocument document) {
    super.setEntireDocumentDirty(document);

    // make the entire document dirty
    // this also happens on a "save as"
    if (document != null && isInstalled() && fLastPartitions != null && document.getLength() == 0) {
      /**
       * https://bugs.eclipse.org/bugs/show_bug.cgi?id=199053
       *
       * <p>Process the strategies for the last known-good partitions.
       */
      for (int i = 0; i < fLastPartitions.length; i++) {
        ValidatorStrategy validatorStrategy = getValidatorStrategy();
        if (validatorStrategy != null) {
          validatorStrategy.reconcile(
              fLastPartitions[i], createDirtyRegion(fLastPartitions[i], DirtyRegion.REMOVE));
        }
      }
      IReconcilingStrategy spellingStrategy = getSpellcheckStrategy();
      if (spellingStrategy != null) {
        spellingStrategy.reconcile(new Region(0, document.getLength()));
      }

      // if there is a folding strategy then reconcile it
      if (getFoldingStrategy() != null) {
        getFoldingStrategy().reconcile(new Region(0, document.getLength()));
      }
    }
  }

  /**
   * @see
   *     org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#install(org.eclipse.jface.text.ITextViewer)
   */
  public void install(ITextViewer textViewer) {
    super.install(textViewer);

    // determine if validation is enabled
    this.fValidationEnabled =
        SSEUIPlugin.getInstance()
            .getPreferenceStore()
            .getBoolean(CommonEditorPreferenceNames.EVALUATE_TEMPORARY_PROBLEMS);
  }

  /** @see org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#uninstall() */
  public void uninstall() {
    if (isInstalled()) {

      IReconcilingStrategy validatorStrategy = getValidatorStrategy();

      if (validatorStrategy != null) {
        if (validatorStrategy instanceof IReleasable) ((IReleasable) validatorStrategy).release();
      }

      if (fSpellcheckStrategy != null) {
        fSpellcheckStrategy.setDocument(null);
        fSpellcheckStrategy = null;
      }

      fReconcileListeners = new ISourceReconcilingListener[0];
    }
    super.uninstall();
  }
}
 public static boolean isDebug(String option) {
   String value = Platform.getDebugOption(option);
   return (value != null && value.equalsIgnoreCase("true") ? true : false);
 }
 public static boolean debug() {
   final String debugOption =
       Platform.getDebugOption("org.pdtextensions.repos/debug"); // $NON-NLS-1$
   return "true".equalsIgnoreCase(debugOption);
 }
Exemple #22
0
 /**
  * @param optionId name of debug option
  * @return whether a named debug option is set
  */
 private static boolean isOptionSet(final String optionId) {
   final String option = getPluginId() + optionId;
   final String value = Platform.getDebugOption(option);
   return value != null && value.equals("true");
 }
public class ConfigurableContentOutlinePage extends ContentOutlinePage implements IAdaptable {
  /*
   * Menu listener to create the additions group and add any menu items
   * contributed by the configuration; required since the context menu is
   * cleared every time it is shown
   */
  class AdditionGroupAdder implements IMenuListener {
    public void menuAboutToShow(IMenuManager manager) {
      IContributionItem[] items = manager.getItems();
      // add configuration's menu items
      IMenuListener listener = getConfiguration().getMenuListener(getTreeViewer());
      if (listener != null) {
        listener.menuAboutToShow(manager);
        manager.add(new Separator());
      }
      if (items.length > 0 && items[items.length - 1].getId() != null) {
        manager.insertAfter(
            items[items.length - 1].getId(),
            new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
      } else {
        manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
      }
    }
  }

  /** Provides double-click registration so it can be done before the Control is created. */
  class DoubleClickProvider implements IDoubleClickListener {
    private IDoubleClickListener[] listeners = null;

    void addDoubleClickListener(IDoubleClickListener newListener) {
      if (listeners == null) {
        listeners = new IDoubleClickListener[] {newListener};
      } else {
        IDoubleClickListener[] newListeners = new IDoubleClickListener[listeners.length + 1];
        System.arraycopy(listeners, 0, newListeners, 0, listeners.length);
        newListeners[listeners.length] = newListener;
        listeners = newListeners;
      }
    }

    public void doubleClick(DoubleClickEvent event) {
      fireDoubleClickEvent(event);
    }

    private void fireDoubleClickEvent(final DoubleClickEvent event) {
      IDoubleClickListener[] firingListeners = listeners;
      for (int i = 0; i < firingListeners.length; ++i) {
        final IDoubleClickListener l = firingListeners[i];
        SafeRunner.run(
            new SafeRunnable() {
              public void run() {
                l.doubleClick(event);
              }
            });
      }
    }

    void removeDoubleClickListener(IDoubleClickListener oldListener) {
      if (listeners != null) {
        if (listeners.length == 1 && listeners[0].equals(oldListener)) {
          listeners = null;
        } else {
          List newListeners = new ArrayList(Arrays.asList(listeners));
          newListeners.remove(oldListener);
          listeners =
              (IDoubleClickListener[])
                  newListeners.toArray(new IDoubleClickListener[listeners.length - 1]);
        }
      }
    }
  }

  /** Listens to post selection from the selection service, applying it to the tree viewer. */
  class PostSelectionServiceListener implements ISelectionListener {
    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
      // from selection service
      if (_DEBUG) {
        _DEBUG_TIME = System.currentTimeMillis();
      } /*
         * Bug 136310, unless this page is that part's
         * IContentOutlinePage, ignore the selection change
         */
      if (part == null
          || part.getAdapter(IContentOutlinePage.class) == ConfigurableContentOutlinePage.this) {
        ISelection validContentSelection =
            getConfiguration().getSelection(getTreeViewer(), selection);

        boolean isLinked = getConfiguration().isLinkedWithEditor(getTreeViewer());
        if (isLinked) {
          if (!getTreeViewer().getSelection().equals(validContentSelection)) {
            try {
              fIsReceivingSelection = true;
              getTreeViewer().setSelection(validContentSelection, true);
            } finally {
              fIsReceivingSelection = false;
            }
          }
        }
      }
      if (_DEBUG) {
        System.out.println(
            "(O:"
                + (System.currentTimeMillis() - _DEBUG_TIME)
                + "ms) "
                + part
                + " : "
                + selection); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      }
    }
  }

  /**
   * Forwards post-selection from the tree viewer to the listeners while acting as this page's
   * selection provider.
   */
  private class SelectionProvider implements IPostSelectionProvider {
    private class PostSelectionChangedListener implements ISelectionChangedListener {
      public void selectionChanged(SelectionChangedEvent event) {
        if (!isFiringSelection() && !fIsReceivingSelection) {
          fireSelectionChanged(event, postListeners);
          updateStatusLine(getSite().getActionBars().getStatusLineManager(), event.getSelection());
        }
      }
    }

    private class SelectionChangedListener implements ISelectionChangedListener {
      public void selectionChanged(SelectionChangedEvent event) {
        if (!isFiringSelection() && !fIsReceivingSelection) {
          fireSelectionChanged(event, listeners);
        }
      }
    }

    private boolean isFiringSelection = false;
    private ListenerList listeners = new ListenerList();
    private ListenerList postListeners = new ListenerList();
    private ISelectionChangedListener postSelectionChangedListener =
        new PostSelectionChangedListener();
    private ISelectionChangedListener selectionChangedListener = new SelectionChangedListener();

    public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
      postListeners.add(listener);
    }

    public void addSelectionChangedListener(ISelectionChangedListener listener) {
      listeners.add(listener);
    }

    public void fireSelectionChanged(final SelectionChangedEvent event, ListenerList listenerList) {
      isFiringSelection = true;
      Object[] listeners = listenerList.getListeners();
      for (int i = 0; i < listeners.length; ++i) {
        final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
        SafeRunner.run(
            new SafeRunnable() {
              public void run() {
                l.selectionChanged(event);
              }
            });
      }
      isFiringSelection = false;
    }

    public ISelectionChangedListener getPostSelectionChangedListener() {
      return postSelectionChangedListener;
    }

    public ISelection getSelection() {
      if (getTreeViewer() != null) {
        return getTreeViewer().getSelection();
      }
      return StructuredSelection.EMPTY;
    }

    public ISelectionChangedListener getSelectionChangedListener() {
      return selectionChangedListener;
    }

    public boolean isFiringSelection() {
      return isFiringSelection;
    }

    public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
      postListeners.remove(listener);
    }

    public void removeSelectionChangedListener(ISelectionChangedListener listener) {
      listeners.remove(listener);
    }

    public void setSelection(ISelection selection) {
      if (!isFiringSelection) {
        getTreeViewer().setSelection(selection);
      }
    }
  }

  private class ShowInSource implements IShowInSource {
    /*
     * Always return as an IShowInSource adapter, but a context only when
     * valid.
     *
     * @see org.eclipse.ui.part.IShowInSource#getShowInContext()
     */
    public ShowInContext getShowInContext() {
      if (fEditor != null && fEditor.getEditorSite() != null) {
        return new ShowInContext(
            fEditor.getEditorInput(),
            fEditor.getEditorSite().getSelectionProvider().getSelection());
      }
      return null;
    }
  }

  private class ShowInTarget implements IShowInTarget {
    /*
     * @see org.eclipse.ui.part.IShowInTarget#show(org.eclipse.ui.part.ShowInContext)
     */
    public boolean show(ShowInContext context) {
      setSelection(context.getSelection());
      return getTreeViewer().getSelection().equals(context.getSelection());
    }
  }

  protected static final ContentOutlineConfiguration NULL_CONFIGURATION =
      new ContentOutlineConfiguration() {
        public IContentProvider getContentProvider(TreeViewer viewer) {
          return new ITreeContentProvider() {
            public void dispose() {}

            public Object[] getChildren(Object parentElement) {
              return null;
            }

            public Object[] getElements(Object inputElement) {
              return null;
            }

            public Object getParent(Object element) {
              return null;
            }

            public boolean hasChildren(Object element) {
              return false;
            }

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

  private static final String OUTLINE_CONTEXT_MENU_ID =
      "org.eclipse.wst.sse.ui.StructuredTextEditor.OutlineContext"; //$NON-NLS-1$

  private static final String OUTLINE_CONTEXT_MENU_SUFFIX = ".source.OutlineContext"; // $NON-NLS-1$
  private static final boolean _DEBUG =
      "true"
          .equalsIgnoreCase(
              Platform.getDebugOption(
                  "org.eclipse.wst.sse.ui/contentOutline")); //$NON-NLS-1$  //$NON-NLS-2$;

  private long _DEBUG_TIME = 0;

  private TransferDragSourceListener[] fActiveDragListeners;
  private TransferDropTargetListener[] fActiveDropListeners;
  private ContentOutlineConfiguration fConfiguration;

  private Menu fContextMenu;
  private String fContextMenuId;

  private MenuManager fContextMenuManager;
  private DoubleClickProvider fDoubleClickProvider = null;

  private DelegatingDragAdapter fDragAdapter;
  private DragSource fDragSource;
  private DelegatingDropAdapter fDropAdapter;
  private DropTarget fDropTarget;
  private IEditorPart fEditor;
  private IMenuListener fGroupAdder = null;
  private Object fInput = null;

  private String fInputContentTypeIdentifier = null;
  private ISelectionListener fSelectionListener = null;

  SelectionProvider fSelectionProvider = null;

  boolean fIsReceivingSelection;

  /**
   * A ContentOutlinePage that abstract as much behavior as possible away from the Controls and
   * varies it by content type.
   */
  public ConfigurableContentOutlinePage() {
    super();
    fGroupAdder = new AdditionGroupAdder();
    fSelectionProvider = new SelectionProvider();
  }

  /**
   * Adds a listener to a list of those notified when someone double-clicks in the page.
   *
   * @param newListener - the listener to add
   */
  public void addDoubleClickListener(IDoubleClickListener newListener) {
    if (fDoubleClickProvider == null) {
      fDoubleClickProvider = new DoubleClickProvider();
    }
    fDoubleClickProvider.addDoubleClickListener(newListener);
  }

  private String computeContextMenuID() {
    String id = null;
    if (fInputContentTypeIdentifier != null) {
      id = fInputContentTypeIdentifier + OUTLINE_CONTEXT_MENU_SUFFIX;
    }
    return id;
  }

  /** @see ContentOutlinePage#createControl */
  public void createControl(Composite parent) {
    super.createControl(parent);
    ColumnViewerToolTipSupport.enableFor(getTreeViewer());

    IWorkbenchPage page = getSite().getWorkbenchWindow().getActivePage();
    if (page != null) {
      fEditor = page.getActiveEditor();
    }

    fDragAdapter = new DelegatingDragAdapter();
    fDragSource = new DragSource(getControl(), DND.DROP_COPY | DND.DROP_MOVE);
    fDropAdapter = new DelegatingDropAdapter();
    fDropTarget = new DropTarget(getControl(), DND.DROP_COPY | DND.DROP_MOVE);

    setConfiguration(getConfiguration());

    /*
     * ContentOutlinePage only implements ISelectionProvider while the
     * tree viewer implements both ISelectionProvider and
     * IPostSelectionProvider. Use an ISelectionProvider that listens to
     * post selection from the tree viewer and forward only post selection
     * to the selection service.
     */
    getTreeViewer()
        .addPostSelectionChangedListener(fSelectionProvider.getPostSelectionChangedListener());
    getTreeViewer().addSelectionChangedListener(fSelectionProvider.getSelectionChangedListener());
    if (fDoubleClickProvider == null) {
      fDoubleClickProvider = new DoubleClickProvider();
    }
    getTreeViewer().addDoubleClickListener(fDoubleClickProvider);
    getSite().setSelectionProvider(fSelectionProvider);
  }

  public void dispose() {
    getSite()
        .getWorkbenchWindow()
        .getSelectionService()
        .removePostSelectionListener(getSelectionServiceListener());
    if (fDoubleClickProvider != null) {
      getTreeViewer().removeDoubleClickListener(fDoubleClickProvider);
    }

    // dispose menu controls
    if (fContextMenu != null) {
      fContextMenu.dispose();
    }
    if (fContextMenuManager != null) {
      fContextMenuManager.removeMenuListener(fGroupAdder);
      fContextMenuManager.removeAll();
      fContextMenuManager.dispose();
    }

    fDropTarget.dispose();
    fDragSource.dispose();

    IStatusLineManager statusLineManager = getSite().getActionBars().getStatusLineManager();
    if (statusLineManager != null) {
      statusLineManager.setMessage(null);
    }
    unconfigure();
    super.dispose();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
   */
  public Object getAdapter(Class key) {
    Object adapter = null;
    if (key.equals(IShowInTarget.class)) {
      adapter = new ShowInTarget();
    } else if (key.equals(IShowInSource.class)) {
      adapter = new ShowInSource();
    } else if (key.equals(IShowInTargetList.class) && fEditor != null) {
      adapter = fEditor.getAdapter(key);
    }
    return adapter;
  }

  /** @return the currently used ContentOutlineConfiguration */
  public ContentOutlineConfiguration getConfiguration() {
    if (fConfiguration == null) {
      fConfiguration = NULL_CONFIGURATION;
    }
    return fConfiguration;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
   */
  public ISelection getSelection() {
    return fSelectionProvider.getSelection();
  }

  ISelectionListener getSelectionServiceListener() {
    if (fSelectionListener == null) {
      fSelectionListener = new PostSelectionServiceListener();
    }
    return fSelectionListener;
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * org.eclipse.ui.part.IPageBookViewPage#init(org.eclipse.ui.part.IPageSite
   * )
   */
  public void init(IPageSite pageSite) {
    super.init(pageSite);
    pageSite
        .getWorkbenchWindow()
        .getSelectionService()
        .addPostSelectionListener(getSelectionServiceListener());
  }

  /**
   * Removes a listener to a list of those notified when someone double-clicks in the page.
   *
   * @param oldListener - the listener to remove
   */
  public void removeDoubleClickListener(IDoubleClickListener oldListener) {
    if (fDoubleClickProvider != null) {
      fDoubleClickProvider.removeDoubleClickListener(oldListener);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ui.views.contentoutline.ContentOutlinePage#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
   */
  public void selectionChanged(SelectionChangedEvent event) {
    if (!fIsReceivingSelection) super.selectionChanged(event);
  }

  /**
   * Configures (or reconfigures) the page according to the given configuration.
   *
   * @param configuration
   */
  public void setConfiguration(ContentOutlineConfiguration configuration) {
    // intentionally do not check to see if the new configuration != old
    // configuration
    unconfigure();

    fConfiguration = configuration;

    if (getTreeViewer() != null && getControl() != null && !getControl().isDisposed()) {
      // (re)set the providers
      ILabelProvider labelProvider = getConfiguration().getLabelProvider(getTreeViewer());
      if (labelProvider instanceof IStyledLabelProvider) {
        getTreeViewer()
            .setLabelProvider(
                new DelegatingStyledCellLabelProvider((IStyledLabelProvider) labelProvider));
      } else {
        getTreeViewer().setLabelProvider(labelProvider);
      }
      getTreeViewer().setContentProvider(getConfiguration().getContentProvider(getTreeViewer()));

      // view toolbar
      IContributionManager toolbar = getSite().getActionBars().getToolBarManager();
      if (toolbar != null) {
        IContributionItem[] toolbarItems =
            getConfiguration().getToolbarContributions(getTreeViewer());
        if (toolbarItems != null) {
          for (int i = 0; i < toolbarItems.length; i++) {
            toolbar.add(toolbarItems[i]);
          }
          toolbar.update(true);
        }
      }
      // view menu
      IContributionManager menu = getSite().getActionBars().getMenuManager();
      if (menu != null) {
        IContributionItem[] menuItems = getConfiguration().getMenuContributions(getTreeViewer());
        if (menuItems != null) {
          for (int i = 0; i < menuItems.length; i++) {
            menuItems[i].setVisible(true);
            menu.add(menuItems[i]);
            menuItems[i].update();
          }
          menu.update(true);
        }
      }
      // add the allowed DnD listeners and types
      TransferDragSourceListener[] dragListeners =
          getConfiguration().getTransferDragSourceListeners(getTreeViewer());
      if (fDragAdapter != null && dragListeners.length > 0) {
        for (int i = 0; i < dragListeners.length; i++) {
          fDragAdapter.addDragSourceListener(dragListeners[i]);
        }
        fActiveDragListeners = dragListeners;
        fDragSource.addDragListener(fDragAdapter);
        fDragSource.setTransfer(fDragAdapter.getTransfers());
      }
      TransferDropTargetListener[] dropListeners =
          getConfiguration().getTransferDropTargetListeners(getTreeViewer());
      if (fDropAdapter != null && dropListeners.length > 0) {
        for (int i = 0; i < dropListeners.length; i++) {
          fDropAdapter.addDropTargetListener(dropListeners[i]);
        }
        fActiveDropListeners = dropListeners;
        fDropTarget.addDropListener(fDropAdapter);
        fDropTarget.setTransfer(fDropAdapter.getTransfers());
      }
      // add the key listeners
      KeyListener[] listeners = getConfiguration().getKeyListeners(getTreeViewer());
      if (listeners != null) {
        for (int i = 0; i < listeners.length; i++) {
          getControl().addKeyListener(listeners[i]);
        }
      }
    }

    if (fInput != null) {
      setInput(fInput);
    }
  }

  /** Unconfigure the content outline page */
  private void unconfigure() {
    if (getTreeViewer() != null) {
      // remove the key listeners
      if (getControl() != null && !getControl().isDisposed()) {
        KeyListener[] listeners = getConfiguration().getKeyListeners(getTreeViewer());
        if (listeners != null) {
          for (int i = 0; i < listeners.length; i++) {
            getControl().removeKeyListener(listeners[i]);
          }
        }
      }

      IContributionManager toolbar = getSite().getActionBars().getToolBarManager();
      if (toolbar != null && !toolbar.isEmpty()) {
        IContributionItem[] toolbarItems =
            getConfiguration().getToolbarContributions(getTreeViewer());
        if (toolbarItems != null && toolbarItems.length > 0) {
          for (int i = 0; i < toolbarItems.length; i++) {
            toolbar.remove(toolbarItems[i]);
          }
          toolbar.update(false);
        }
      }

      IContributionManager menubar = getSite().getActionBars().getMenuManager();
      if (menubar != null && !menubar.isEmpty()) {
        IContributionItem[] menuItems = getConfiguration().getMenuContributions(getTreeViewer());
        if (menuItems != null && menuItems.length > 0) {
          for (int i = 0; i < menuItems.length; i++) {
            menubar.remove(menuItems[i]);
          }
          menubar.remove(IWorkbenchActionConstants.MB_ADDITIONS);
          menubar.update(false);
        }
      }
      // clear the DnD listeners and transfer types
      if (fDragAdapter != null
          && !fDragAdapter.isEmpty()
          && fDragSource != null
          && !fDragSource.isDisposed()
          && fDragSource.getTransfer().length > 0) {
        if (fActiveDragListeners != null) {
          for (int i = 0; i < fActiveDragListeners.length; i++) {
            fDragAdapter.removeDragSourceListener(fActiveDragListeners[i]);
          }
        }
        fActiveDragListeners = null;
        fDragSource.removeDragListener(fDragAdapter);
        fDragSource.setTransfer(new Transfer[0]);
      }
      if (fDropAdapter != null
          && !fDropAdapter.isEmpty()
          && fDropTarget != null
          && !fDropTarget.isDisposed()
          && fDropTarget.getTransfer().length > 0) {
        if (fActiveDropListeners != null) {
          for (int i = 0; i < fActiveDropListeners.length; i++) {
            fDropAdapter.removeDropTargetListener(fActiveDropListeners[i]);
          }
        }
        fActiveDropListeners = null;
        fDropTarget.removeDropListener(fDropAdapter);
        fDropTarget.setTransfer(new Transfer[0]);
      }
      getConfiguration()
          .getContentProvider(getTreeViewer())
          .inputChanged(getTreeViewer(), fInput, null);
      // release any ties to this tree viewer
      getConfiguration().unconfigure(getTreeViewer());
    }
  }

  /** @param editor The IEditorPart that "owns" this page. Used to support the "Show In..." menu. */
  public void setEditorPart(IEditorPart editor) {
    fEditor = editor;
  }

  /**
   * @param newInput The input for the page's viewer. Should only be set after a configuration has
   *     been applied.
   */
  public void setInput(Object newInput) {
    fInput = newInput;
    /*
     * Intentionally not optimized for checking new input vs. old input so
     * that any existing content providers can be updated
     */
    if (getControl() != null && !getControl().isDisposed()) {
      getTreeViewer().setInput(fInput);
      updateContextMenuId();
    }
  }

  /** @param id - the content type identifier to use for further extension */
  public void setInputContentTypeIdentifier(String id) {
    fInputContentTypeIdentifier = id;
  }

  /** Updates the outline page's context menu for the current input */
  private void updateContextMenuId() {
    String computedContextMenuId = null;
    // update outline view's context menu control and ID

    if (fEditor == null) {
      IWorkbenchPage page = getSite().getWorkbenchWindow().getActivePage();
      if (page != null) {
        fEditor = page.getActiveEditor();
      }
    }

    computedContextMenuId = computeContextMenuID();

    if (computedContextMenuId == null) {
      computedContextMenuId = OUTLINE_CONTEXT_MENU_ID;
    }

    /*
     * Update outline context menu id if updating to a new id or if
     * context menu is not already set up
     */
    if (!computedContextMenuId.equals(fContextMenuId) || (fContextMenu == null)) {
      fContextMenuId = computedContextMenuId;

      if (getControl() != null && !getControl().isDisposed()) {
        // dispose of previous context menu
        if (fContextMenu != null) {
          fContextMenu.dispose();
        }
        if (fContextMenuManager != null) {
          fContextMenuManager.removeMenuListener(fGroupAdder);
          fContextMenuManager.removeAll();
          fContextMenuManager.dispose();
        }

        fContextMenuManager = new MenuManager(fContextMenuId, fContextMenuId);
        fContextMenuManager.setRemoveAllWhenShown(true);

        fContextMenuManager.addMenuListener(fGroupAdder);

        fContextMenu = fContextMenuManager.createContextMenu(getControl());
        getControl().setMenu(fContextMenu);

        getSite().registerContextMenu(fContextMenuId, fContextMenuManager, this);

        /*
         * also register this menu for source page part and structured
         * text outline view ids
         */
        if (fEditor != null && fEditor.getSite() != null) {
          String partId = fEditor.getSite().getId();
          if (partId != null) {
            getSite()
                .registerContextMenu(
                    partId + OUTLINE_CONTEXT_MENU_SUFFIX, fContextMenuManager, this);
          }
        }
        getSite().registerContextMenu(OUTLINE_CONTEXT_MENU_ID, fContextMenuManager, this);
      }
    }
  }

  void updateStatusLine(IStatusLineManager mgr, ISelection selection) {
    String text = null;
    Image image = null;
    ILabelProvider statusLineLabelProvider =
        getConfiguration().getStatusLineLabelProvider(getTreeViewer());
    if (statusLineLabelProvider != null
        && selection instanceof IStructuredSelection
        && !selection.isEmpty()) {
      Object firstElement = ((IStructuredSelection) selection).getFirstElement();
      text = statusLineLabelProvider.getText(firstElement);
      image = statusLineLabelProvider.getImage(firstElement);
    }
    if (image == null) {
      mgr.setMessage(text);
    } else {
      mgr.setMessage(image, text);
    }
  }

  public ContentOutlineFilterProcessor getOutlineFilterProcessor() {
    return getConfiguration().getOutlineFilterProcessor(getTreeViewer());
  }
}
/**
 * Dart UI implementation of <code>CompletionRequestor</code>. Produces {@link
 * IDartCompletionProposal}s from the proposal descriptors received via the <code>
 * CompletionRequestor</code> interface.
 *
 * <p>The lifecycle of a <code>CompletionProposalCollector</code> instance is very simple:
 *
 * <pre>
 * CompilationUnit unit= ...
 * int offset= ...
 *
 * CompletionProposalCollector collector= new CompletionProposalCollector(unit);
 * unit.codeComplete(offset, collector);
 * IDartCompletionProposal[] proposals= collector.getDartCompletionProposals();
 * String errorMessage= collector.getErrorMessage();
 *
 * &#x2f;&#x2f; display &#x2f; process proposals
 * </pre>
 *
 * Note that after a code completion operation, the collector will store any received proposals,
 * which may require a considerable amount of memory, so the collector should not be kept as a
 * reference after a completion operation.
 *
 * <p>Clients may instantiate or subclass.
 */
public class CompletionProposalCollector extends CompletionRequestor {

  /** Tells whether this class is in debug mode. */
  private static final boolean DEBUG =
      "true"
          .equalsIgnoreCase(
              Platform.getDebugOption(
                  "com.google.dart.tools.core/debug/ResultCollector")); //$NON-NLS-1$//$NON-NLS-2$

  /** Triggers for method proposals without parameters. Do not modify. */
  protected static final char[] METHOD_TRIGGERS = new char[] {';', ',', '.', '\t', '[', ' '};
  /** Triggers for method proposals. Do not modify. */
  protected static final char[] METHOD_WITH_ARGUMENTS_TRIGGERS = new char[] {'(', '-', ' '};
  /** Triggers for types. Do not modify. */
  protected static final char[] TYPE_TRIGGERS = new char[] {'.', '\t', '[', '(', ' '};
  /** Triggers for variables. Do not modify. */
  protected static final char[] VAR_TRIGGER = new char[] {'\t', ' ', '=', ';', '.'};

  /**
   * Returns an array containing all of the elements in the given collection. This is a compile-time
   * type-safe alternative to {@link Collection#toArray(Object[])}.
   *
   * @param collection the source collection
   * @param clazz the type of the array elements
   * @param <A> the type of the array elements
   * @return an array of type <code>A</code> containing all of the elements in the given collection
   * @throws NullPointerException if the specified collection or class is null
   */
  public static <A> A[] toArray(Collection<? extends A> collection, Class<A> clazz) {
    Object array = Array.newInstance(clazz, collection.size());
    @SuppressWarnings("unchecked")
    A[] typedArray = collection.toArray((A[]) array);
    return typedArray;
  }

  private final CompletionProposalLabelProvider fLabelProvider =
      new CompletionProposalLabelProvider();
  private final ImageDescriptorRegistry fRegistry = DartToolsPlugin.getImageDescriptorRegistry();

  private final List<IDartCompletionProposal> fDartProposals =
      new ArrayList<IDartCompletionProposal>();
  private final List<IDartCompletionProposal> fKeywords = new ArrayList<IDartCompletionProposal>();
  private final Set<String> fSuggestedMethodNames = new HashSet<String>();

  private final CompilationUnit fCompilationUnit;
  private final DartProject fDartProject;
  private int fUserReplacementLength;

  private CompletionContext fContext;
  private Problem fLastProblem;

  /* performance instrumentation */
  private long fStartTime;
  private long fUITime;

  /** The UI invocation context or <code>null</code>. */
  private DartContentAssistInvocationContext fInvocationContext;

  /**
   * Creates a new instance ready to collect proposals. If the passed <code>CompilationUnit</code>
   * is not contained in an {@link DartProject}, no Dart doc will be available as {@link
   * org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo() additional
   * info} on the created proposals.
   *
   * @param cu the compilation unit that the result collector will operate on
   */
  public CompletionProposalCollector(CompilationUnit cu) {
    this(cu.getDartProject(), cu, false);
  }

  /**
   * Creates a new instance ready to collect proposals. If the passed <code>CompilationUnit</code>
   * is not contained in an {@link DartProject}, no Dart doc will be available as {@link
   * org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo() additional
   * info} on the created proposals.
   *
   * @param cu the compilation unit that the result collector will operate on
   * @param ignoreAll <code>true</code> to ignore all kinds of completion proposals
   */
  public CompletionProposalCollector(CompilationUnit cu, boolean ignoreAll) {
    this(cu == null ? null : cu.getDartProject(), cu, ignoreAll); // TODO Remove getDartProject()
  }

  /**
   * Creates a new instance ready to collect proposals. Note that proposals for anonymous types and
   * method declarations are not created when using this constructor, as those need to know the
   * compilation unit that they are created on. Use {@link
   * CompletionProposalCollector#CompletionProposalCollector(CompilationUnit)} instead to get all
   * proposals.
   *
   * <p>If the passed Dart project is <code>null</code>, no Dart doc will be available as {@link
   * org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo() additional
   * info} on the created (e.g. method and type) proposals.
   *
   * @param project the project that the result collector will operate on, or <code>null</code>
   */
  public CompletionProposalCollector(DartProject project) {
    this(project, null, false);
  }

  private CompletionProposalCollector(DartProject project, CompilationUnit cu, boolean ignoreAll) {
    super(ignoreAll);
    fDartProject = project;
    fCompilationUnit = cu;

    fUserReplacementLength = -1;
    if (!ignoreAll) {
      setRequireExtendedContext(true);
    }
  }

  /**
   * {@inheritDoc}
   *
   * <p>Subclasses may replace, but usually should not need to. Consider replacing {@linkplain
   * #createDartCompletionProposal(CompletionProposal) createDartCompletionProposal} instead.
   */
  @Override
  public void accept(CompletionProposal proposal) {
    long start = DEBUG ? System.currentTimeMillis() : 0;
    try {
      if (isFiltered(proposal)) {
        return;
      }

      DartContentAssistInvocationContext ctxt = getInvocationContext();
      proposal.applyPartitionOffset(ctxt.getPartitionOffset());
      if (proposal.getKind() == CompletionProposal.POTENTIAL_METHOD_DECLARATION) {
        acceptPotentialMethodDeclaration(proposal);
      } else {
        IDartCompletionProposal dartProposal = createDartCompletionProposal(proposal);
        if (dartProposal != null) {
          fDartProposals.add(dartProposal);
          if (proposal.getKind() == CompletionProposal.KEYWORD) {
            fKeywords.add(dartProposal);
          }
        }
      }
    } catch (IllegalArgumentException e) {
      // all signature processing method may throw IAEs
      // https://bugs.eclipse.org/bugs/show_bug.cgi?id=84657
      // don't abort, but log and show all the valid proposals
      DartToolsPlugin.log(
          new Status(
              IStatus.ERROR,
              DartToolsPlugin.getPluginId(),
              IStatus.OK,
              "Exception when processing proposal for: " + String.valueOf(proposal.getCompletion()),
              e)); //$NON-NLS-1$
    }

    if (DEBUG) {
      fUITime += System.currentTimeMillis() - start;
    }
  }

  /**
   * {@inheritDoc}
   *
   * <p>Subclasses may extend, but usually should not need to.
   */
  @Override
  public void acceptContext(CompletionContext context) {
    fContext = context;
    fLabelProvider.setContext(context);
  }

  /** {@inheritDoc} Subclasses may extend, but must call the super implementation. */
  @Override
  public void beginReporting() {
    if (DEBUG) {
      fStartTime = System.currentTimeMillis();
      fUITime = 0;
    }

    fLastProblem = null;
    fDartProposals.clear();
    fKeywords.clear();
    fSuggestedMethodNames.clear();
  }

  /** {@inheritDoc} Subclasses may extend, but must call the super implementation. */
  @Override
  public void completionFailure(Problem problem) {
    fLastProblem = problem;
  }

  /** {@inheritDoc} Subclasses may extend, but must call the super implementation. */
  @Override
  public void endReporting() {
    if (DEBUG) {
      long total = System.currentTimeMillis() - fStartTime;
      System.err.println("Core Collector (core):\t" + (total - fUITime)); // $NON-NLS-1$
      System.err.println("Core Collector (ui):\t" + fUITime); // $NON-NLS-1$
    }
  }

  /**
   * Returns the unsorted list of received proposals.
   *
   * @return the unsorted list of received proposals
   */
  public final IDartCompletionProposal[] getDartCompletionProposals() {
    return toArray(fDartProposals, IDartCompletionProposal.class);
  }

  /**
   * Returns an error message about any error that may have occurred during code completion, or the
   * empty string if none.
   *
   * <p>Subclasses may replace or extend.
   *
   * @return an error message or the empty string
   */
  public String getErrorMessage() {
    if (fLastProblem != null) {
      return fLastProblem.getMessage();
    }
    return ""; //$NON-NLS-1$
  }

  @Override
  public com.google.dart.engine.ast.CompilationUnit getInputUnit() {
    return fInvocationContext.getInputUnit();
  }

  /**
   * Returns the unsorted list of received keyword proposals.
   *
   * @return the unsorted list of received keyword proposals
   */
  public final IDartCompletionProposal[] getKeywordCompletionProposals() {
    return toArray(fKeywords, IDartCompletionProposal.class);
  }

  @Override
  public void setIgnored(int completionProposalKind, boolean ignore) {
    super.setIgnored(completionProposalKind, ignore);
    if (completionProposalKind == CompletionProposal.METHOD_DECLARATION && !ignore) {
      setRequireExtendedContext(true);
    }
  }

  /**
   * Sets the invocation context.
   *
   * <p>Subclasses may extend.
   *
   * @param context the invocation context
   */
  public void setInvocationContext(DartContentAssistInvocationContext context) {
    Assert.isNotNull(context);
    fInvocationContext = context;
    context.setCollector(this);
  }

  /**
   * If the replacement length is set, it overrides the length returned from the content assist
   * infrastructure. Use this setting if code assist is called with a none empty selection.
   *
   * @param length the new replacement length, relative to the code assist offset. Must be equal to
   *     or greater than zero.
   */
  public final void setReplacementLength(int length) {
    Assert.isLegal(length >= 0);
    fUserReplacementLength = length;
  }

  /**
   * Computes the relevance for a given <code>CompletionProposal</code>.
   *
   * <p>Subclasses may replace, but usually should not need to.
   *
   * @param proposal the proposal to compute the relevance for
   * @return the relevance for <code>proposal</code>
   */
  protected int computeRelevance(CompletionProposal proposal) {
    final int baseRelevance = proposal.getRelevance() * 16;
    switch (proposal.getKind()) {
      case CompletionProposal.LIBRARY_PREFIX:
        return baseRelevance + 0;
      case CompletionProposal.LABEL_REF:
        return baseRelevance + 1;
      case CompletionProposal.KEYWORD:
        return baseRelevance + 2;
      case CompletionProposal.TYPE_REF:
        //      case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
        //      case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION:
        return baseRelevance + 3;
      case CompletionProposal.METHOD_REF:
      case CompletionProposal.CONSTRUCTOR_INVOCATION:
      case CompletionProposal.METHOD_NAME_REFERENCE:
      case CompletionProposal.METHOD_DECLARATION:
        //      case CompletionProposal.ANNOTATION_ATTRIBUTE_REF:
        return baseRelevance + 4;
      case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
        return baseRelevance + 4 /* + 99 */;
      case CompletionProposal.FIELD_REF:
        return baseRelevance + 5;
      case CompletionProposal.LOCAL_VARIABLE_REF:
      case CompletionProposal.VARIABLE_DECLARATION:
        return baseRelevance + 6;
      case CompletionProposal.ARGUMENT_LIST:
        return baseRelevance + 7;
      default:
        return baseRelevance;
    }
  }

  /**
   * Creates a new Dart completion proposal from a core proposal. This may involve computing the
   * display label and setting up some context.
   *
   * <p>This method is called for every proposal that will be displayed to the user, which may be
   * hundreds. Implementations should therefore defer as much work as possible: Labels should be
   * computed lazily to leverage virtual table usage, and any information only needed when
   * <em>applying</em> a proposal should not be computed yet.
   *
   * <p>Implementations may return <code>null</code> if a proposal should not be included in the
   * list presented to the user.
   *
   * <p>Subclasses may extend or replace this method.
   *
   * @param proposal the core completion proposal to create a UI proposal for
   * @return the created Dart completion proposal, or <code>null</code> if no proposal should be
   *     displayed
   */
  protected IDartCompletionProposal createDartCompletionProposal(CompletionProposal proposal) {
    switch (proposal.getKind()) {
      case CompletionProposal.KEYWORD:
        return createKeywordProposal(proposal);
      case CompletionProposal.LIBRARY_PREFIX:
        return createLibraryPrefixProposal(proposal);
      case CompletionProposal.TYPE_REF:
        return createTypeProposal(proposal);
        //      case CompletionProposal.JAVADOC_TYPE_REF:
        //        return createJavadocLinkTypeProposal(proposal);
      case CompletionProposal.FIELD_REF:
        //      case CompletionProposal.JAVADOC_FIELD_REF:
        //      case CompletionProposal.JAVADOC_VALUE_REF:
        return createFieldProposal(proposal);
        //      case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER:
        //        return createFieldWithCastedReceiverProposal(proposal);
      case CompletionProposal.ARGUMENT_LIST:
      case CompletionProposal.METHOD_REF:
      case CompletionProposal.CONSTRUCTOR_INVOCATION:
        //      case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER:
      case CompletionProposal.METHOD_NAME_REFERENCE:
        //      case CompletionProposal.JAVADOC_METHOD_REF:
        return createMethodReferenceProposal(proposal);
      case CompletionProposal.METHOD_DECLARATION:
        return createMethodDeclarationProposal(proposal);
        //      case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION:
        //        return createAnonymousTypeProposal(proposal, getInvocationContext());
        //      case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
        //        return createAnonymousTypeProposal(proposal, null);
      case CompletionProposal.LABEL_REF:
        return createLabelProposal(proposal);
      case CompletionProposal.LOCAL_VARIABLE_REF:
      case CompletionProposal.VARIABLE_DECLARATION:
        return createLocalVariableProposal(proposal);
      case CompletionProposal.TYPE_IMPORT:
        return createImportProposal(proposal);
      case CompletionProposal.OPTIONAL_ARGUMENT:
        return new OptionalArgumentCompletionProposal(proposal);
      case CompletionProposal.NAMED_ARGUMENT:
        return new NamedArgumentCompletionProposal(proposal);
        //      case CompletionProposal.ANNOTATION_ATTRIBUTE_REF:
        //        return createAnnotationAttributeReferenceProposal(proposal);
        //      case CompletionProposal.JAVADOC_BLOCK_TAG:
        //      case CompletionProposal.JAVADOC_PARAM_REF:
        //        return createJavadocSimpleProposal(proposal);
        //      case CompletionProposal.JAVADOC_INLINE_TAG:
        //        return createJavadocInlineTagProposal(proposal);
      case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
      default:
        return null;
    }
  }

  /**
   * Creates the context information for a given method reference proposal. The passed proposal must
   * be of kind {@link CompletionProposal#METHOD_REF}.
   *
   * @param methodProposal the method proposal for which to create context information
   * @return the context information for <code>methodProposal</code>
   */
  protected final IContextInformation createMethodContextInformation(
      CompletionProposal methodProposal) {
    Assert.isTrue(methodProposal.getKind() == CompletionProposal.METHOD_REF);
    return new ProposalContextInformation(methodProposal);
  }

  /**
   * Returns the compilation unit that the receiver operates on, or <code>null</code> if the <code>
   * DartProject</code> constructor was used to create the receiver.
   *
   * @return the compilation unit that the receiver operates on, or <code>null</code>
   */
  protected final CompilationUnit getCompilationUnit() {
    return fCompilationUnit;
  }

  /**
   * Returns the <code>CompletionContext</code> for this completion operation.
   *
   * @return the <code>CompletionContext</code> for this completion operation
   */
  protected final CompletionContext getContext() {
    return fContext;
  }

  /**
   * Returns the type signature of the declaring type of a <code>CompletionProposal</code>, or
   * <code>null</code> for proposals that do not have a declaring type. The return value is
   * <em>not</em> <code>null</code> for proposals of the following kinds:
   *
   * <ul>
   *   <li>METHOD_DECLARATION
   *   <li>METHOD_NAME_REFERENCE
   *   <li>METHOD_REF
   *   <li>ANNOTATION_ATTRIBUTE_REF
   *   <li>POTENTIAL_METHOD_DECLARATION
   *   <li>ANONYMOUS_CLASS_DECLARATION
   *   <li>FIELD_REF
   *   <li>PACKAGE_REF (returns the package, but no type)
   *   <li>TYPE_REF
   * </ul>
   *
   * @param proposal the completion proposal to get the declaring type for
   * @return the type signature of the declaring type, or <code>null</code> if there is none
   */
  protected final char[] getDeclaringType(CompletionProposal proposal) {
    switch (proposal.getKind()) {
      case CompletionProposal.METHOD_DECLARATION:
      case CompletionProposal.METHOD_NAME_REFERENCE:
        //      case CompletionProposal.JAVADOC_METHOD_REF:
      case CompletionProposal.METHOD_REF:
      case CompletionProposal.ARGUMENT_LIST:
      case CompletionProposal.CONSTRUCTOR_INVOCATION:
        //      case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION:
        //      case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER:
        //      case CompletionProposal.ANNOTATION_ATTRIBUTE_REF:
      case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
        //      case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
      case CompletionProposal.FIELD_REF:
        //      case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER:
        //      case CompletionProposal.JAVADOC_FIELD_REF:
        //      case CompletionProposal.JAVADOC_VALUE_REF:
        char[] declaration = proposal.getDeclarationSignature();
        // special methods may not have a declaring type: methods defined on arrays etc.
        // Currently known: class literals don't have a declaring type - use Object
        //        if (declaration == null) {
        //          return "java.lang.Object".toCharArray(); //$NON-NLS-1$
        //        }
        return Signature.toCharArray(declaration);
      case CompletionProposal.LIBRARY_PREFIX:
        return proposal.getDeclarationSignature();
        //      case CompletionProposal.JAVADOC_TYPE_REF:
      case CompletionProposal.TYPE_REF:
        return Signature.toCharArray(proposal.getSignature());
      case CompletionProposal.LOCAL_VARIABLE_REF:
      case CompletionProposal.VARIABLE_DECLARATION:
      case CompletionProposal.KEYWORD:
      case CompletionProposal.LABEL_REF:
      case CompletionProposal.TYPE_IMPORT:
      case CompletionProposal.OPTIONAL_ARGUMENT:
      case CompletionProposal.NAMED_ARGUMENT:
        //      case CompletionProposal.JAVADOC_BLOCK_TAG:
        //      case CompletionProposal.JAVADOC_INLINE_TAG:
        //      case CompletionProposal.JAVADOC_PARAM_REF:
        return null;
      default:
        Assert.isTrue(false);
        return null;
    }
  }

  /**
   * Returns a cached image for the given descriptor.
   *
   * @param descriptor the image descriptor to get an image for, may be <code>null</code>
   * @return the image corresponding to <code>descriptor</code>
   */
  protected final Image getImage(ImageDescriptor descriptor) {
    return (descriptor == null) ? null : fRegistry.get(descriptor);
  }

  /**
   * Returns the invocation context. If none has been set via {@link
   * #setInvocationContext(DartContentAssistInvocationContext)}, a new one is created.
   *
   * @return invocationContext the invocation context
   */
  protected final DartContentAssistInvocationContext getInvocationContext() {
    if (fInvocationContext == null) {
      setInvocationContext(new DartContentAssistInvocationContext(getCompilationUnit()));
    }
    return fInvocationContext;
  }

  /**
   * Returns the proposal label provider used by the receiver.
   *
   * @return the proposal label provider used by the receiver
   */
  protected final CompletionProposalLabelProvider getLabelProvider() {
    return fLabelProvider;
  }

  /**
   * Returns the replacement length of a given completion proposal. The replacement length is
   * usually the difference between the return values of <code>proposal.getReplaceEnd</code> and
   * <code>proposal.getReplaceStart</code>, but this behavior may be overridden by calling {@link
   * #setReplacementLength(int)}.
   *
   * @param proposal the completion proposal to get the replacement length for
   * @return the replacement length for <code>proposal</code>
   */
  protected final int getLength(CompletionProposal proposal) {
    int start = proposal.getReplaceStart();
    int end = proposal.getReplaceEnd();
    int length;
    if (fUserReplacementLength == -1) {
      length = end - start;
    } else {
      length = fUserReplacementLength;
      // extend length to begin at start
      int behindCompletion = proposal.getCompletionLocation() + 1;
      if (start < behindCompletion) {
        length += behindCompletion - start;
      }
    }
    return length;
  }

  /**
   * Returns <code>true</code> if <code>proposal</code> is filtered, e.g. should not be proposed to
   * the user, <code>false</code> if it is valid.
   *
   * <p>Subclasses may extends this method. The default implementation filters proposals set to be
   * ignored via {@linkplain CompletionRequestor#setIgnored(int, boolean) setIgnored} and types set
   * to be ignored in the preferences.
   *
   * @param proposal the proposal to filter
   * @return <code>true</code> to filter <code>proposal</code>, <code>false</code> to let it pass
   */
  protected boolean isFiltered(CompletionProposal proposal) {
    if (isIgnored(proposal.getKind())) {
      return true;
    }
    char[] declaringType = getDeclaringType(proposal);
    return declaringType != null && TypeFilter.isFiltered(declaringType);
  }

  private void acceptPotentialMethodDeclaration(CompletionProposal proposal) {
    try {
      DartElement enclosingElement = null;
      if (getContext().isExtended()) {
        enclosingElement = getContext().getEnclosingElement();
      } else if (fCompilationUnit != null) {
        enclosingElement = fCompilationUnit.getElementAt(proposal.getCompletionLocation() + 1);
      }
      if (enclosingElement == null) {
        return;
      }
      Type type = enclosingElement.getAncestor(Type.class);
      if (type != null) {
        String prefix = String.valueOf(proposal.getName());
        int completionStart = proposal.getReplaceStart();
        int completionEnd = proposal.getReplaceEnd();
        int relevance = computeRelevance(proposal);

        GetterSetterCompletionProposal.evaluateProposals(
            type,
            prefix,
            completionStart,
            completionEnd - completionStart,
            proposal.getReplaceEndIdentifier() - completionStart,
            relevance + 2,
            fSuggestedMethodNames,
            fDartProposals);
        MethodDeclarationCompletionProposal.evaluateProposals(
            type,
            prefix,
            completionStart,
            completionEnd - completionStart,
            proposal.getReplaceEndIdentifier() - completionStart,
            relevance,
            fSuggestedMethodNames,
            fDartProposals);
      }
    } catch (CoreException e) {
      DartToolsPlugin.log(e);
    }
  }

  private void adaptLength(LazyDartCompletionProposal proposal, CompletionProposal coreProposal) {
    if (fUserReplacementLength != -1) {
      proposal.setReplacementLength(getLength(coreProposal));
    }
  }

  //  private IDartCompletionProposal createAnnotationAttributeReferenceProposal(
  //      CompletionProposal proposal) {
  //    StyledString displayString= fLabelProvider.createLabelWithTypeAndDeclaration(proposal);
  //    ImageDescriptor descriptor= fLabelProvider.createMethodImageDescriptor(proposal);
  //    String completion= String.valueOf(proposal.getCompletion());
  //    DartCompletionProposal javaProposal= new DartCompletionProposal(completion,
  // proposal.getReplaceStart(), getLength(proposal), getImage(descriptor), displayString,
  // computeRelevance(proposal));
  //    if (fJavaProject != null)
  //      javaProposal.setProposalInfo(new AnnotationAtttributeProposalInfo(fJavaProject,
  // proposal));
  //    return javaProposal;
  //  }

  //  private IDartCompletionProposal createAnonymousTypeProposal(CompletionProposal proposal,
  //      DartContentAssistInvocationContext invocationContext) {
  //    if (fCompilationUnit == null || fJavaProject == null)
  //      return null;
  //
  //    char[] declarationKey= proposal.getDeclarationKey();
  //    if (declarationKey == null)
  //      return null;
  //
  //    try {
  //      DartElement element= fJavaProject.findElement(new String(declarationKey), null);
  //      if (!(element instanceof Type))
  //        return null;
  //
  //      Type type= (Type) element;
  //
  //      String completion= String.valueOf(proposal.getCompletion());
  //      int start= proposal.getReplaceStart();
  //      int length= getLength(proposal);
  //      int relevance= computeRelevance(proposal);
  //
  //      StyledString label= fLabelProvider.createAnonymousTypeLabel(proposal);
  //
  //      DartCompletionProposal javaProposal= new AnonymousTypeCompletionProposal(fJavaProject,
  // fCompilationUnit, invocationContext, start, length, completion, label, String.valueOf(proposal
  //          .getDeclarationSignature()), type, relevance);
  //      javaProposal.setProposalInfo(new AnonymousTypeProposalInfo(fJavaProject, proposal));
  //      return javaProposal;
  //    } catch (DartModelException e) {
  //      return null;
  //    }
  //  }

  private IDartCompletionProposal createFieldProposal(CompletionProposal proposal) {
    String completion = String.valueOf(proposal.getCompletion());
    int start = proposal.getReplaceStart();
    int length = getLength(proposal);
    StyledString label = fLabelProvider.createStyledLabel(proposal);
    Image image = getImage(fLabelProvider.createFieldImageDescriptor(proposal));
    int relevance = computeRelevance(proposal);

    @SuppressWarnings("deprecation")
    DartCompletionProposal dartProposal =
        new DartCompletionProposal(
            completion,
            start,
            length,
            getLengthIdentifier(proposal),
            image,
            label,
            relevance,
            getContext().isInJavadoc(),
            proposal.getElement(),
            getInvocationContext());
    // TODO(scheglov) implement documentation comment
    //    if (fDartProject != null) {
    //      dartProposal.setProposalInfo(new FieldProposalInfo(fDartProject, proposal));
    //    }

    dartProposal.setTriggerCharacters(VAR_TRIGGER);

    return dartProposal;
  }

  private IDartCompletionProposal createImportProposal(CompletionProposal proposal) {
    String completion = String.valueOf(proposal.getCompletion());
    int start = proposal.getReplaceStart();
    int length = getLength(proposal);
    StyledString label =
        new StyledString(fLabelProvider.createSimpleLabel(proposal)); // TODO(messick)
    int relevance = computeRelevance(proposal);
    ImageDescriptor imageDesc = fLabelProvider.createImageDescriptor(proposal);
    Image image = DartToolsPlugin.getImageDescriptorRegistry().get(imageDesc);
    return new DartCompletionProposal(
        completion,
        start,
        length,
        getLengthIdentifier(proposal),
        image,
        label,
        relevance,
        proposal.getElement());
  }

  //  /**
  //   * Creates the Java completion proposal for the JDT Core
  //   * {@link CompletionProposal#FIELD_REF_WITH_CASTED_RECEIVER} proposal.
  //   *
  //   * @param proposal the JDT Core proposal
  //   * @return the Java completion proposal
  //   */
  //  private IDartCompletionProposal createFieldWithCastedReceiverProposal(CompletionProposal
  // proposal) {
  //    String completion= String.valueOf(proposal.getCompletion());
  //    completion= CodeFormatterUtil.format(CodeFormatter.K_EXPRESSION, completion, 0, "\n",
  // fJavaProject); //$NON-NLS-1$
  //    int start= proposal.getReplaceStart();
  //    int length= getLength(proposal);
  //    StyledString label= fLabelProvider.createStyledLabel(proposal);
  //    Image image= getImage(fLabelProvider.createFieldImageDescriptor(proposal));
  //    int relevance= computeRelevance(proposal);
  //
  //    DartCompletionProposal javaProposal= new
  // DartFieldWithCastedReceiverCompletionProposal(completion, start, length, image, label,
  // relevance, getContext().isInJavadoc(), getInvocationContext(), proposal);
  //    if (fJavaProject != null)
  //      javaProposal.setProposalInfo(new FieldProposalInfo(fJavaProject, proposal));
  //
  //    javaProposal.setTriggerCharacters(VAR_TRIGGER);
  //
  //    return javaProposal;
  //  }

  //  private IDartCompletionProposal createJavadocInlineTagProposal(CompletionProposal
  // javadocProposal) {
  //    LazyDartCompletionProposal proposal= new JavadocInlineTagCompletionProposal(javadocProposal,
  // getInvocationContext());
  //    adaptLength(proposal, javadocProposal);
  //    return proposal;
  //  }

  //  private IDartCompletionProposal createJavadocLinkTypeProposal(CompletionProposal typeProposal)
  // {
  //    LazyDartCompletionProposal proposal= new JavadocLinkTypeCompletionProposal(typeProposal,
  // getInvocationContext());
  //    adaptLength(proposal, typeProposal);
  //    return proposal;
  //  }

  //  private IDartCompletionProposal createJavadocSimpleProposal(CompletionProposal
  // javadocProposal) {
  // TODO do better with javadoc proposals
  //    String completion= String.valueOf(proposal.getCompletion());
  //    int start= proposal.getReplaceStart();
  //    int length= getLength(proposal);
  //    String label= fLabelProvider.createSimpleLabel(proposal);
  //    Image image= getImage(fLabelProvider.createImageDescriptor(proposal));
  //    int relevance= computeRelevance(proposal);
  //
  //    DartCompletionProposal javaProposal= new DartCompletionProposal(completion, start, length,
  // image, label, relevance);
  //    if (fJavaProject != null)
  //      javaProposal.setProposalInfo(new FieldProposalInfo(fJavaProject, proposal));
  //
  //    javaProposal.setTriggerCharacters(VAR_TRIGGER);
  //
  //    return javaProposal;
  //    LazyDartCompletionProposal proposal = new LazyDartCompletionProposal(javadocProposal,
  //        getInvocationContext());
  //    adaptLength(proposal, javadocProposal);
  //    return proposal;
  //  }

  private IDartCompletionProposal createKeywordProposal(CompletionProposal proposal) {
    String completion = String.valueOf(proposal.getCompletion());
    int start = proposal.getReplaceStart();
    int length = getLength(proposal);
    StyledString label =
        new StyledString(fLabelProvider.createSimpleLabel(proposal)); // TODO(messick)
    int relevance = computeRelevance(proposal);
    return new DartCompletionProposal(
        completion,
        start,
        length,
        getLengthIdentifier(proposal),
        null,
        label,
        relevance,
        proposal.getElement());
  }

  private IDartCompletionProposal createLabelProposal(CompletionProposal proposal) {
    String completion = String.valueOf(proposal.getCompletion());
    int start = proposal.getReplaceStart();
    int length = getLength(proposal);
    StyledString label =
        new StyledString(fLabelProvider.createSimpleLabel(proposal)); // TODO(messick)
    int relevance = computeRelevance(proposal);

    return new DartCompletionProposal(
        completion,
        start,
        length,
        getLengthIdentifier(proposal),
        null,
        label,
        relevance,
        proposal.getElement());
  }

  private IDartCompletionProposal createLibraryPrefixProposal(CompletionProposal proposal) {
    String completion = String.valueOf(proposal.getCompletion());
    int start = proposal.getReplaceStart();
    int length = getLength(proposal);
    StyledString label =
        new StyledString(fLabelProvider.createSimpleLabel(proposal)); // TODO(messick)
    Image image = getImage(fLabelProvider.createLibraryImageDescriptor(proposal));
    int relevance = computeRelevance(proposal);

    return new DartCompletionProposal(
        completion,
        start,
        length,
        getLengthIdentifier(proposal),
        image,
        label,
        relevance,
        proposal.getElement());
  }

  private IDartCompletionProposal createLocalVariableProposal(CompletionProposal proposal) {
    String completion = String.valueOf(proposal.getCompletion());
    int start = proposal.getReplaceStart();
    int length = getLength(proposal);
    Image image = getImage(fLabelProvider.createLocalImageDescriptor(proposal));
    StyledString label = fLabelProvider.createLabelWithType(proposal);
    int relevance = computeRelevance(proposal);
    final DartCompletionProposal dartProposal =
        new DartCompletionProposal(
            completion,
            start,
            length,
            getLengthIdentifier(proposal),
            image,
            label,
            relevance,
            proposal.getElement());
    dartProposal.setTriggerCharacters(VAR_TRIGGER);
    return dartProposal;
  }

  private IDartCompletionProposal createMethodDeclarationProposal(CompletionProposal proposal) {
    if (fCompilationUnit == null || fDartProject == null) {
      return null;
    }

    String name = String.valueOf(proposal.getName());
    String[] paramTypes = Signature.getParameterTypes(String.valueOf(proposal.getSignature()));
    for (int index = 0; index < paramTypes.length; index++) {
      paramTypes[index] = Signature.toString(paramTypes[index]);
    }
    int start = proposal.getReplaceStart();
    int length = getLength(proposal);

    StyledString label =
        new StyledString(
            fLabelProvider.createOverrideMethodProposalLabel(proposal)); // TODO(messick)

    DartCompletionProposal dartProposal =
        new OverrideCompletionProposal(
            fDartProject,
            fCompilationUnit,
            name,
            paramTypes,
            start,
            length,
            getLengthIdentifier(proposal),
            label,
            String.valueOf(proposal.getCompletion()));
    dartProposal.setImage(getImage(fLabelProvider.createMethodImageDescriptor(proposal)));
    // TODO(scheglov) implement documentation comment
    //    dartProposal.setProposalInfo(new MethodProposalInfo(fDartProject, proposal));
    dartProposal.setRelevance(computeRelevance(proposal));

    fSuggestedMethodNames.add(new String(name));
    return dartProposal;
  }

  private IDartCompletionProposal createMethodReferenceProposal(CompletionProposal methodProposal) {
    LazyDartCompletionProposal proposal =
        new DartMethodCompletionProposal(methodProposal, getInvocationContext());
    adaptLength(proposal, methodProposal);
    return proposal;
  }

  private IDartCompletionProposal createTypeProposal(CompletionProposal typeProposal) {
    LazyDartCompletionProposal proposal =
        new LazyDartTypeCompletionProposal(typeProposal, getInvocationContext());
    adaptLength(proposal, typeProposal);
    return proposal;
  }

  private int getLengthIdentifier(CompletionProposal proposal) {
    return proposal.getReplaceEndIdentifier() - proposal.getReplaceStart();
  }
}
 private static boolean internal_isEnabled(String eventName) {
   String option = Platform.getDebugOption(eventName);
   return option != null
       && !option.equalsIgnoreCase("false")
       && !option.equalsIgnoreCase("-1"); // $NON-NLS-1$ //$NON-NLS-2$
 }
 private static boolean isOptionEnabled(String level) {
   final String debugOption = Platform.getDebugOption(level);
   return JBossJaxrsCorePlugin.getDefault() != null
       && JBossJaxrsCorePlugin.getDefault().isDebugging()
       && "true".equalsIgnoreCase(debugOption);
 }
public class JsValidator extends AbstractValidator implements IValidator, IExecutableExtension {
  private static final boolean DEBUG =
      Boolean.valueOf(Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jsvalidator"))
          .booleanValue(); //$NON-NLS-1$
  private IValidator fMessageOriginator;
  private Set fValidFileExts = new HashSet();

  private static final String[] METADATA_FILES =
      new String[] {
        ".settings/.jsdtscope",
        ".settings/org.eclipse.wst.jsdt.ui.superType.container",
        ".settings/org.eclipse.wst.jsdt.ui.superType.name"
      };
  private static final String JAVASCRIPT_TASK_MARKER_TYPE =
      "org.eclipse.wst.jsdt.core.task"; //$NON-NLS-1$

  //	private static String [] jsdtValidator =
  // {"org.eclipse.wst.jsdt.web.core.internal.validation.JsBatchValidator"}; //$NON-NLS-1$

  protected class LocalizedMessage extends Message {
    private String _message = null;

    public LocalizedMessage(int severity, String messageText) {
      this(severity, messageText, null);
    }

    public LocalizedMessage(int severity, String messageText, IResource targetObject) {
      this(severity, messageText, (Object) targetObject);
    }

    public LocalizedMessage(int severity, String messageText, Object targetObject) {
      super(null, severity, null);
      setLocalizedMessage(messageText);
      setTargetObject(targetObject);
    }

    public String getLocalizedMessage() {
      return _message;
    }

    public String getText() {
      return getLocalizedMessage();
    }

    public String getText(ClassLoader cl) {
      return getLocalizedMessage();
    }

    public String getText(Locale l) {
      return getLocalizedMessage();
    }

    public String getText(Locale l, ClassLoader cl) {
      return getLocalizedMessage();
    }

    public void setLocalizedMessage(String message) {
      _message = message;
    }
  }

  public JsValidator() {
    this.fMessageOriginator = this;
  }

  /**
   * Creates an IMessage from an IProblem
   *
   * @param problem
   * @param f
   * @param translation
   * @param textDoc
   * @return message representation of the problem, or null if it could not create one
   */
  private IMessage createMessageFromProblem(
      IProblem problem, IFile f, IJsTranslation translation, IDocument textDoc) {
    int sourceStart = problem.getSourceStart();
    int sourceEnd = problem.getSourceEnd();
    if (sourceStart == -1) {
      return null;
    }
    sourceStart = translation.getWebPageOffset(sourceStart);
    sourceEnd = translation.getWebPageOffset(sourceEnd);
    /*
     * Bug 241794 - Validation shows errors when using JSP Expressions
     * inside JavaScript code
     */
    IStructuredDocument doc = (IStructuredDocument) textDoc;
    IStructuredDocumentRegion documentRegion = doc.getRegionAtCharacterOffset(sourceStart);
    if (documentRegion != null) {
      ITextRegion textRegion = documentRegion.getRegionAtCharacterOffset(sourceStart);
      /*
       * Filter out problems from areas that aren't simple JavaScript,
       * e.g. JSP.
       */
      if (textRegion != null && textRegion instanceof ITextRegionCollection) return null;
    }

    int sev =
        problem.isError()
            ? IMessage.HIGH_SEVERITY
            : (problem.isWarning() ? IMessage.NORMAL_SEVERITY : IMessage.LOW_SEVERITY);
    IMessage m = new LocalizedMessage(sev, problem.getMessage(), f);
    // line numbers for marker starts @ 1
    // line numbers from document starts @ 0
    try {
      int lineNo = textDoc.getLineOfOffset(sourceStart) + 1;
      m.setLineNo(lineNo);
      m.setOffset(sourceStart);
      m.setLength(sourceEnd - sourceStart + 1);
    } catch (BadLocationException e) {
      Logger.logException(e);
    }
    return m;
  }

  void performValidation(IFile f, IReporter reporter, IStructuredModel model, boolean inBatch) {
    if (model instanceof IDOMModel) {
      IDOMModel domModel = (IDOMModel) model;
      JsTranslationAdapterFactory.setupAdapterFactory(domModel);
      IDOMDocument xmlDoc = domModel.getDocument();
      JsTranslationAdapter translationAdapter =
          (JsTranslationAdapter) xmlDoc.getAdapterFor(IJsTranslation.class);
      // translationAdapter.resourceChanged();
      IJsTranslation translation = translationAdapter.getJsTranslation(false);
      if (!reporter.isCancelled()) {
        translation.setProblemCollectingActive(true);
        translation.reconcileCompilationUnit();
        List problems = translation.getProblems();
        // only update task markers if the model is the same as what's on disk
        boolean updateTasks = !domModel.isDirty() && f != null && f.isAccessible();
        if (updateTasks) {
          // remove old JavaScript task markers
          try {
            IMarker[] foundMarkers =
                f.findMarkers(JAVASCRIPT_TASK_MARKER_TYPE, true, IResource.DEPTH_ONE);
            for (int i = 0; i < foundMarkers.length; i++) {
              foundMarkers[i].delete();
            }
          } catch (CoreException e) {
            Logger.logException(e);
          }
        }

        //				if(!inBatch) reporter.removeAllMessages(this, f);
        // add new messages
        for (int i = 0; i < problems.size() && !reporter.isCancelled(); i++) {
          IProblem problem = (IProblem) problems.get(i);
          IMessage m =
              createMessageFromProblem(problem, f, translation, domModel.getStructuredDocument());
          if (m != null) {
            if (problem.getID() == IProblem.Task) {
              if (updateTasks) {
                // add new JavaScript task marker
                try {
                  IMarker task = f.createMarker(JAVASCRIPT_TASK_MARKER_TYPE);
                  task.setAttribute(IMarker.LINE_NUMBER, new Integer(m.getLineNumber()));
                  task.setAttribute(IMarker.CHAR_START, new Integer(m.getOffset()));
                  task.setAttribute(IMarker.CHAR_END, new Integer(m.getOffset() + m.getLength()));
                  task.setAttribute(IMarker.MESSAGE, m.getText());
                  task.setAttribute(IMarker.USER_EDITABLE, Boolean.FALSE);

                  switch (m.getSeverity()) {
                    case IMessage.HIGH_SEVERITY:
                      {
                        task.setAttribute(IMarker.PRIORITY, new Integer(IMarker.PRIORITY_HIGH));
                        task.setAttribute(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
                      }
                      break;
                    case IMessage.LOW_SEVERITY:
                      {
                        task.setAttribute(IMarker.PRIORITY, new Integer(IMarker.PRIORITY_LOW));
                        task.setAttribute(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
                      }
                      break;
                    default:
                      {
                        task.setAttribute(IMarker.PRIORITY, new Integer(IMarker.PRIORITY_NORMAL));
                        task.setAttribute(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
                      }
                  }
                } catch (CoreException e) {
                  Logger.logException(e);
                }
              }
            } else {
              reporter.addMessage(fMessageOriginator, m);
            }
          }
        }
      }
    }
  }

  /* Read the definition for this validator and the declared valid file extensions
   * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
   */
  public void setInitializationData(IConfigurationElement config, String propertyName, Object data)
      throws CoreException {
    IConfigurationElement[] includes = config.getChildren("include"); // $NON-NLS-1$
    for (int i = 0; i < includes.length; i++) {
      IConfigurationElement[] fileexts = includes[i].getChildren("fileext"); // $NON-NLS-1$
      for (int j = 0; j < fileexts.length; j++) {
        String fileext = fileexts[j].getAttribute("ext"); // $NON-NLS-1$
        if (fileext != null) {
          fValidFileExts.add(fileext);
        }
      }
    }
  }

  boolean shouldValidate(IFile file) {
    IResource resource = file;
    do {
      if (resource.isDerived()
          || resource.isTeamPrivateMember()
          || !resource.isAccessible()
          || resource.getName().charAt(0) == '.') {
        return false;
      }
      resource = resource.getParent();
    } while ((resource.getType() & IResource.PROJECT) == 0);
    return fValidFileExts.isEmpty() || fValidFileExts.contains(file.getFileExtension());
  }

  public void validate(IValidationContext helper, IReporter reporter) throws ValidationException {
    /* Added by BC ---- */
    // if(true) return;
    /* end Added by BC ---- */

    String[] uris = helper.getURIs();
    if (uris.length > 0) {
      IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
      IFile currentFile = null;
      for (int i = 0; i < uris.length && !reporter.isCancelled(); i++) {
        currentFile = wsRoot.getFile(new Path(uris[i]));
        reporter.removeAllMessages(this, currentFile);
        if (currentFile != null && currentFile.exists()) {
          if (shouldValidate(currentFile)) { // && fragmentCheck(currentFile)) {
            int percent = (i * 100) / uris.length + 1;
            IMessage message =
                new LocalizedMessage(
                    IMessage.LOW_SEVERITY, percent + "% " + uris[i]); // $NON-NLS-1$
            reporter.displaySubtask(this, message);
            validateFile(currentFile, reporter);
          }
          if (DEBUG) {
            System.out.println("validating: [" + uris[i] + "]"); // $NON-NLS-1$ //$NON-NLS-2$
          }
        }
      }
    } else {
      // if uris[] length 0 -> validate() gets called for each project
      if (helper instanceof IWorkbenchContext) {
        IProject project = ((IWorkbenchContext) helper).getProject();
        JSFileVisitor visitor = new JSFileVisitor(reporter);
        try {
          // collect all jsp files for the project
          project.accept(visitor, IResource.DEPTH_INFINITE);
        } catch (CoreException e) {
          if (DEBUG) {
            e.printStackTrace();
          }
        }
        IFile[] files = visitor.getFiles();
        for (int i = 0; i < files.length && !reporter.isCancelled(); i++) {
          int percent = (i * 100) / files.length + 1;
          IMessage message =
              new LocalizedMessage(
                  IMessage.LOW_SEVERITY,
                  percent + "% " + files[i].getFullPath().toString()); // $NON-NLS-1$
          reporter.displaySubtask(this, message);
          validateFile(files[i], reporter);
          if (DEBUG) {
            System.out.println("validating: [" + files[i] + "]"); // $NON-NLS-1$ //$NON-NLS-2$
          }
        }
      }
    }
  }

  protected class JSFileVisitor implements IResourceProxyVisitor {
    private List fFiles = new ArrayList();
    private IReporter fReporter = null;

    public JSFileVisitor(IReporter reporter) {
      fReporter = reporter;
    }

    public final IFile[] getFiles() {
      return (IFile[]) fFiles.toArray(new IFile[fFiles.size()]);
    }

    public boolean visit(IResourceProxy proxy) throws CoreException {
      // check validation
      if (fReporter.isCancelled()) {
        return false;
      }
      if (proxy.getType() == IResource.FILE) {
        if (Util.isJsType(proxy.getName())) {
          IFile file = (IFile) proxy.requestResource();
          if (file.exists() && shouldValidate(file)) {
            if (DEBUG) {
              System.out.println("(+) JSPValidator adding file: " + file.getName()); // $NON-NLS-1$
            }
            fFiles.add(file);
            // don't search deeper for files
            return false;
          }
        }
      }
      return true;
    }
  }

  public void cleanup(IReporter reporter) {
    // nothing to do
  }
  /**
   * Validate one file. It's assumed that the file has JSP content type.
   *
   * @param f
   * @param reporter
   */
  protected void validateFile(IFile f, IReporter reporter) {
    if (JsValidator.DEBUG) {
      Logger.log(Logger.INFO, getClass().getName() + " validating: " + f); // $NON-NLS-1$
    }
    IStructuredModel model = null;
    try {
      // get jsp model, get tranlsation
      model = StructuredModelManager.getModelManager().getModelForRead(f);
      if (!reporter.isCancelled() && model != null) {
        // get DOM model then translation
        // WorkbenchReporter.removeAllMessages(f.getProject(), jsdtValidator, f.toString());
        // reporter.removeAllMessages(fMessageOriginator, f);
        performValidation(f, reporter, model, false);
      }
    } catch (IOException e) {
      Logger.logException(e);
    } catch (CoreException e) {
      Logger.logException(e);
    } finally {
      if (model != null) {
        model.releaseFromRead();
      }
    }
  }

  public ValidationResult validate(
      IResource resource, int kind, ValidationState state, IProgressMonitor monitor) {
    if (resource.getType() != IResource.FILE || !shouldValidate((IFile) resource)) return null;
    ValidationResult result = new ValidationResult();
    IReporter reporter = result.getReporter(monitor);
    IFile file = (IFile) resource;
    validateFile(file, reporter);
    result.setDependsOn(createDependencies(file));
    return result;
  }

  private IResource[] createDependencies(IFile file) {
    IFile[] depends = new IFile[METADATA_FILES.length];
    for (int i = 0; i < METADATA_FILES.length; i++) {
      depends[i] = file.getProject().getFile(METADATA_FILES[i]);
    }
    return depends;
  }
}
/**
 * A content assist processor that aggregates the proposals of the {@link
 * org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer}s contributed via the <code>
 * org.eclipse.jdt.ui.javaCompletionProposalComputer</code> extension point.
 *
 * <p>Subclasses may extend:
 *
 * <ul>
 *   <li><code>createContext</code> to provide the context object passed to the computers
 *   <li><code>createProgressMonitor</code> to change the way progress is reported
 *   <li><code>filterAndSort</code> to add sorting and filtering
 *   <li><code>getContextInformationValidator</code> to add context validation (needed if any
 *       contexts are provided)
 *   <li><code>getErrorMessage</code> to change error reporting
 * </ul>
 *
 * @since 3.2
 */
public class ContentAssistProcessor implements IContentAssistProcessor {

  /**
   * The completion listener class for this processor.
   *
   * @since 3.4
   */
  private final class CompletionListener
      implements ICompletionListener, ICompletionListenerExtension {
    /*
     * @see org.eclipse.jface.text.contentassist.ICompletionListener#assistSessionStarted(org.eclipse.jface.text.contentassist.ContentAssistEvent)
     */
    public void assistSessionStarted(ContentAssistEvent event) {
      if (event.processor != ContentAssistProcessor.this) return;

      fIterationGesture = getIterationGesture();
      KeySequence binding = getIterationBinding();

      // This may show the warning dialog if all categories are disabled
      setCategoryIteration();
      for (Iterator<CompletionProposalCategory> it = fCategories.iterator(); it.hasNext(); ) {
        CompletionProposalCategory cat = it.next();
        cat.sessionStarted();
      }

      fRepetition = 0;
      if (event.assistant instanceof IContentAssistantExtension2) {
        IContentAssistantExtension2 extension = (IContentAssistantExtension2) event.assistant;

        if (fCategoryIteration.size() == 1) {
          extension.setRepeatedInvocationMode(false);
          extension.setShowEmptyList(false);
        } else {
          extension.setRepeatedInvocationMode(true);
          extension.setStatusLineVisible(true);
          extension.setStatusMessage(createIterationMessage());
          extension.setShowEmptyList(true);
          if (extension instanceof IContentAssistantExtension3) {
            IContentAssistantExtension3 ext3 = (IContentAssistantExtension3) extension;
            ((ContentAssistant) ext3).setRepeatedInvocationTrigger(binding);
          }
        }
      }
    }

    /*
     * @see org.eclipse.jface.text.contentassist.ICompletionListener#assistSessionEnded(org.eclipse.jface.text.contentassist.ContentAssistEvent)
     */
    public void assistSessionEnded(ContentAssistEvent event) {
      if (event.processor != ContentAssistProcessor.this) return;

      for (Iterator<CompletionProposalCategory> it = fCategories.iterator(); it.hasNext(); ) {
        CompletionProposalCategory cat = it.next();
        cat.sessionEnded();
      }

      fCategoryIteration = null;
      fRepetition = -1;
      fIterationGesture = null;
      if (event.assistant instanceof IContentAssistantExtension2) {
        IContentAssistantExtension2 extension = (IContentAssistantExtension2) event.assistant;
        extension.setShowEmptyList(false);
        extension.setRepeatedInvocationMode(false);
        extension.setStatusLineVisible(false);
        if (extension instanceof IContentAssistantExtension3) {
          IContentAssistantExtension3 ext3 = (IContentAssistantExtension3) extension;
          ((ContentAssistant) ext3).setRepeatedInvocationTrigger(null);
        }
      }
    }

    /*
     * @see org.eclipse.jface.text.contentassist.ICompletionListener#selectionChanged(org.eclipse.jface.text.contentassist.ICompletionProposal, boolean)
     */
    public void selectionChanged(ICompletionProposal proposal, boolean smartToggle) {}

    /*
     * @see org.eclipse.jface.text.contentassist.ICompletionListenerExtension#assistSessionRestarted(org.eclipse.jface.text.contentassist.ContentAssistEvent)
     * @since 3.4
     */
    public void assistSessionRestarted(ContentAssistEvent event) {
      fRepetition = 0;
    }
  }

  private static final boolean DEBUG =
      "true"
          .equalsIgnoreCase(
              Platform.getDebugOption(
                  "org.eclipse.jdt.ui/debug/ResultCollector")); //$NON-NLS-1$//$NON-NLS-2$

  /**
   * Dialog settings key for the "all categories are disabled" warning dialog. See {@link
   * OptionalMessageDialog}.
   *
   * @since 3.3
   */
  private static final String PREF_WARN_ABOUT_EMPTY_ASSIST_CATEGORY =
      "EmptyDefaultAssistCategory"; //$NON-NLS-1$

  private static final Comparator<CompletionProposalCategory> ORDER_COMPARATOR =
      new Comparator<CompletionProposalCategory>() {

        public int compare(CompletionProposalCategory d1, CompletionProposalCategory d2) {
          return d1.getSortOrder() - d2.getSortOrder();
        }
      };

  private final List<CompletionProposalCategory> fCategories;
  private final String fPartition;
  private final ContentAssistant fAssistant;

  private char[] fCompletionAutoActivationCharacters;

  /* cycling stuff */
  private int fRepetition = -1;
  private List<List<CompletionProposalCategory>> fCategoryIteration = null;
  private String fIterationGesture = null;
  private int fNumberOfComputedResults = 0;
  private String fErrorMessage;

  /**
   * The completion proposal registry.
   *
   * @since 3.4
   */
  private CompletionProposalComputerRegistry fComputerRegistry;

  public ContentAssistProcessor(ContentAssistant assistant, String partition) {
    Assert.isNotNull(partition);
    Assert.isNotNull(assistant);
    fPartition = partition;
    fComputerRegistry = CompletionProposalComputerRegistry.getDefault();
    fCategories = fComputerRegistry.getProposalCategories();
    fAssistant = assistant;
    fAssistant.addCompletionListener(new CompletionListener());
  }

  /*
   * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
   */
  public final ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
    long start = DEBUG ? System.currentTimeMillis() : 0;

    clearState();

    IProgressMonitor monitor = createProgressMonitor();
    monitor.beginTask(
        JavaTextMessages.ContentAssistProcessor_computing_proposals, fCategories.size() + 1);

    ContentAssistInvocationContext context = createContext(viewer, offset);
    long setup = DEBUG ? System.currentTimeMillis() : 0;

    monitor.subTask(JavaTextMessages.ContentAssistProcessor_collecting_proposals);
    List<ICompletionProposal> proposals = collectProposals(viewer, offset, monitor, context);
    long collect = DEBUG ? System.currentTimeMillis() : 0;

    monitor.subTask(JavaTextMessages.ContentAssistProcessor_sorting_proposals);
    List<ICompletionProposal> filtered = filterAndSortProposals(proposals, monitor, context);
    fNumberOfComputedResults = filtered.size();
    long filter = DEBUG ? System.currentTimeMillis() : 0;

    ICompletionProposal[] result = filtered.toArray(new ICompletionProposal[filtered.size()]);
    monitor.done();

    if (DEBUG) {
      System.err.println(
          "Code Assist Stats (" + result.length + " proposals)"); // $NON-NLS-1$ //$NON-NLS-2$
      System.err.println("Code Assist (setup):\t" + (setup - start)); // $NON-NLS-1$
      System.err.println("Code Assist (collect):\t" + (collect - setup)); // $NON-NLS-1$
      System.err.println("Code Assist (sort):\t" + (filter - collect)); // $NON-NLS-1$
    }

    return result;
  }

  private void clearState() {
    fErrorMessage = null;
    fNumberOfComputedResults = 0;
  }

  /**
   * Collects the proposals.
   *
   * @param viewer the text viewer
   * @param offset the offset
   * @param monitor the progress monitor
   * @param context the code assist invocation context
   * @return the list of proposals
   */
  private List<ICompletionProposal> collectProposals(
      ITextViewer viewer,
      int offset,
      IProgressMonitor monitor,
      ContentAssistInvocationContext context) {
    List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
    List<CompletionProposalCategory> providers = getCategories();
    for (Iterator<CompletionProposalCategory> it = providers.iterator(); it.hasNext(); ) {
      CompletionProposalCategory cat = it.next();
      List<ICompletionProposal> computed =
          cat.computeCompletionProposals(context, fPartition, new SubProgressMonitor(monitor, 1));
      proposals.addAll(computed);
      if (fErrorMessage == null) fErrorMessage = cat.getErrorMessage();
    }

    return proposals;
  }

  /**
   * Filters and sorts the proposals. The passed list may be modified and returned, or a new list
   * may be created and returned.
   *
   * @param proposals the list of collected proposals (element type: {@link ICompletionProposal})
   * @param monitor a progress monitor
   * @param context TODO
   * @return the list of filtered and sorted proposals, ready for display (element type: {@link
   *     ICompletionProposal})
   */
  protected List<ICompletionProposal> filterAndSortProposals(
      List<ICompletionProposal> proposals,
      IProgressMonitor monitor,
      ContentAssistInvocationContext context) {
    return proposals;
  }

  /*
   * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
   */
  public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
    clearState();

    IProgressMonitor monitor = createProgressMonitor();
    monitor.beginTask(
        JavaTextMessages.ContentAssistProcessor_computing_contexts, fCategories.size() + 1);

    monitor.subTask(JavaTextMessages.ContentAssistProcessor_collecting_contexts);
    List<IContextInformation> proposals = collectContextInformation(viewer, offset, monitor);

    monitor.subTask(JavaTextMessages.ContentAssistProcessor_sorting_contexts);
    List<IContextInformation> filtered = filterAndSortContextInformation(proposals, monitor);
    fNumberOfComputedResults = filtered.size();

    IContextInformation[] result = filtered.toArray(new IContextInformation[filtered.size()]);
    monitor.done();
    return result;
  }

  private List<IContextInformation> collectContextInformation(
      ITextViewer viewer, int offset, IProgressMonitor monitor) {
    List<IContextInformation> proposals = new ArrayList<IContextInformation>();
    ContentAssistInvocationContext context = createContext(viewer, offset);

    List<CompletionProposalCategory> providers = getCategories();
    for (Iterator<CompletionProposalCategory> it = providers.iterator(); it.hasNext(); ) {
      CompletionProposalCategory cat = it.next();
      List<IContextInformation> computed =
          cat.computeContextInformation(context, fPartition, new SubProgressMonitor(monitor, 1));
      proposals.addAll(computed);
      if (fErrorMessage == null) fErrorMessage = cat.getErrorMessage();
    }

    return proposals;
  }

  /**
   * Filters and sorts the context information objects. The passed list may be modified and
   * returned, or a new list may be created and returned.
   *
   * @param contexts the list of collected proposals (element type: {@link IContextInformation})
   * @param monitor a progress monitor
   * @return the list of filtered and sorted proposals, ready for display (element type: {@link
   *     IContextInformation})
   */
  protected List<IContextInformation> filterAndSortContextInformation(
      List<IContextInformation> contexts, IProgressMonitor monitor) {
    return contexts;
  }

  /**
   * Sets this processor's set of characters triggering the activation of the completion proposal
   * computation.
   *
   * @param activationSet the activation set
   */
  public final void setCompletionProposalAutoActivationCharacters(char[] activationSet) {
    fCompletionAutoActivationCharacters = activationSet;
  }

  /*
   * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
   */
  public final char[] getCompletionProposalAutoActivationCharacters() {
    return fCompletionAutoActivationCharacters;
  }

  /*
   * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
   */
  public char[] getContextInformationAutoActivationCharacters() {
    return null;
  }

  /*
   * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
   */
  public String getErrorMessage() {
    if (fErrorMessage != null) return fErrorMessage;
    if (fNumberOfComputedResults > 0) return null;
    return JavaUIMessages.JavaEditor_codeassist_noCompletions;
  }

  /*
   * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
   */
  public IContextInformationValidator getContextInformationValidator() {
    return null;
  }

  /**
   * Creates a progress monitor.
   *
   * <p>The default implementation creates a <code>NullProgressMonitor</code>.
   *
   * @return a progress monitor
   */
  protected IProgressMonitor createProgressMonitor() {
    return new NullProgressMonitor();
  }

  /**
   * Creates the context that is passed to the completion proposal computers.
   *
   * @param viewer the viewer that content assist is invoked on
   * @param offset the content assist offset
   * @return the context to be passed to the computers
   */
  protected ContentAssistInvocationContext createContext(ITextViewer viewer, int offset) {
    return new ContentAssistInvocationContext(viewer, offset);
  }

  private List<CompletionProposalCategory> getCategories() {
    if (fCategoryIteration == null) return fCategories;

    int iteration = fRepetition % fCategoryIteration.size();
    fAssistant.setStatusMessage(createIterationMessage());
    fAssistant.setEmptyMessage(createEmptyMessage());
    fRepetition++;

    //		fAssistant.setShowMessage(fRepetition % 2 != 0);

    return fCategoryIteration.get(iteration);
  }

  // This may show the warning dialog if all categories are disabled
  private void setCategoryIteration() {
    fCategoryIteration = getCategoryIteration();
  }

  private List<List<CompletionProposalCategory>> getCategoryIteration() {
    List<List<CompletionProposalCategory>> sequence =
        new ArrayList<List<CompletionProposalCategory>>();
    sequence.add(getDefaultCategories());
    for (Iterator<CompletionProposalCategory> it = getSeparateCategories().iterator();
        it.hasNext(); ) {
      CompletionProposalCategory cat = it.next();
      sequence.add(Collections.singletonList(cat));
    }
    return sequence;
  }

  private List<CompletionProposalCategory> getDefaultCategories() {
    // default mix - enable all included computers
    List<CompletionProposalCategory> included = getDefaultCategoriesUnchecked();

    if (fComputerRegistry.hasUninstalledComputers(fPartition, included)) {
      if (informUserAboutEmptyDefaultCategory())
        // preferences were restored - recompute the default categories
        included = getDefaultCategoriesUnchecked();
      fComputerRegistry.resetUnistalledComputers();
    }

    return included;
  }

  private List<CompletionProposalCategory> getDefaultCategoriesUnchecked() {
    List<CompletionProposalCategory> included = new ArrayList<CompletionProposalCategory>();
    for (Iterator<CompletionProposalCategory> it = fCategories.iterator(); it.hasNext(); ) {
      CompletionProposalCategory category = it.next();
      if (category.isIncluded() && category.hasComputers(fPartition)) included.add(category);
    }
    return included;
  }

  /**
   * Informs the user about the fact that there are no enabled categories in the default content
   * assist set and shows a link to the preferences.
   *
   * @return <code>true</code> if the default should be restored
   * @since 3.3
   */
  private boolean informUserAboutEmptyDefaultCategory() {
    if (OptionalMessageDialog.isDialogEnabled(PREF_WARN_ABOUT_EMPTY_ASSIST_CATEGORY)) {
      final Shell shell = JavaPlugin.getActiveWorkbenchShell();
      String title = JavaTextMessages.ContentAssistProcessor_all_disabled_title;
      String message = JavaTextMessages.ContentAssistProcessor_all_disabled_message;
      // see PreferencePage#createControl for the 'defaults' label
      final String restoreButtonLabel = JFaceResources.getString("defaults"); // $NON-NLS-1$
      final String linkMessage =
          Messages.format(
              JavaTextMessages.ContentAssistProcessor_all_disabled_preference_link,
              LegacyActionTools.removeMnemonics(restoreButtonLabel));
      final int restoreId = IDialogConstants.CLIENT_ID + 10;
      final int settingsId = IDialogConstants.CLIENT_ID + 11;
      final OptionalMessageDialog dialog =
          new OptionalMessageDialog(
              PREF_WARN_ABOUT_EMPTY_ASSIST_CATEGORY,
              shell,
              title,
              null /* default image */,
              message,
              MessageDialog.WARNING,
              new String[] {restoreButtonLabel, IDialogConstants.CLOSE_LABEL},
              1) {
            /*
             * @see org.eclipse.jdt.internal.ui.dialogs.OptionalMessageDialog#createCustomArea(org.eclipse.swt.widgets.Composite)
             */
            @Override
            protected Control createCustomArea(Composite composite) {
              // wrap link and checkbox in one composite without space
              Composite parent = new Composite(composite, SWT.NONE);
              GridLayout layout = new GridLayout();
              layout.marginHeight = 0;
              layout.marginWidth = 0;
              layout.verticalSpacing = 0;
              parent.setLayout(layout);

              Composite linkComposite = new Composite(parent, SWT.NONE);
              layout = new GridLayout();
              layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
              layout.marginWidth =
                  convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
              layout.horizontalSpacing =
                  convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
              linkComposite.setLayout(layout);

              Link link = new Link(linkComposite, SWT.NONE);
              link.setText(linkMessage);
              link.addSelectionListener(
                  new SelectionAdapter() {
                    @Override
                    public void widgetSelected(SelectionEvent e) {
                      setReturnCode(settingsId);
                      close();
                    }
                  });
              GridData gridData = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
              gridData.widthHint = this.getMinimumMessageWidth();
              link.setLayoutData(gridData);

              // create checkbox and "don't show this message" prompt
              super.createCustomArea(parent);

              return parent;
            }

            /*
             * @see org.eclipse.jface.dialogs.MessageDialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
             */
            @Override
            protected void createButtonsForButtonBar(Composite parent) {
              Button[] buttons = new Button[2];
              buttons[0] = createButton(parent, restoreId, restoreButtonLabel, false);
              buttons[1] =
                  createButton(
                      parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, true);
              setButtons(buttons);
            }
          };
      int returnValue = dialog.open();
      if (restoreId == returnValue || settingsId == returnValue) {
        if (restoreId == returnValue) {
          IPreferenceStore store = JavaPlugin.getDefault().getPreferenceStore();
          store.setToDefault(PreferenceConstants.CODEASSIST_CATEGORY_ORDER);
          store.setToDefault(PreferenceConstants.CODEASSIST_EXCLUDED_CATEGORIES);
        }
        if (settingsId == returnValue)
          PreferencesUtil.createPreferenceDialogOn(
                  shell, "org.eclipse.jdt.ui.preferences.CodeAssistPreferenceAdvanced", null, null)
              .open(); //$NON-NLS-1$
        fComputerRegistry.reload();
        return true;
      }
    }
    return false;
  }

  private List<CompletionProposalCategory> getSeparateCategories() {
    ArrayList<CompletionProposalCategory> sorted = new ArrayList<CompletionProposalCategory>();
    for (Iterator<CompletionProposalCategory> it = fCategories.iterator(); it.hasNext(); ) {
      CompletionProposalCategory category = it.next();
      if (category.isSeparateCommand() && category.hasComputers(fPartition)) sorted.add(category);
    }
    Collections.sort(sorted, ORDER_COMPARATOR);
    return sorted;
  }

  private String createEmptyMessage() {
    return Messages.format(
        JavaTextMessages.ContentAssistProcessor_empty_message,
        new String[] {getCategoryLabel(fRepetition)});
  }

  private String createIterationMessage() {
    return Messages.format(
        JavaTextMessages.ContentAssistProcessor_toggle_affordance_update_message,
        new String[] {
          getCategoryLabel(fRepetition), fIterationGesture, getCategoryLabel(fRepetition + 1)
        });
  }

  private String getCategoryLabel(int repetition) {
    int iteration = repetition % fCategoryIteration.size();
    if (iteration == 0) return JavaTextMessages.ContentAssistProcessor_defaultProposalCategory;
    return toString(fCategoryIteration.get(iteration).get(0));
  }

  private String toString(CompletionProposalCategory category) {
    return category.getDisplayName();
  }

  private String getIterationGesture() {
    TriggerSequence binding = getIterationBinding();
    return binding != null
        ? Messages.format(
            JavaTextMessages.ContentAssistProcessor_toggle_affordance_press_gesture,
            new Object[] {binding.format()})
        : JavaTextMessages.ContentAssistProcessor_toggle_affordance_click_gesture;
  }

  private KeySequence getIterationBinding() {
    final IBindingService bindingSvc =
        (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class);
    TriggerSequence binding =
        bindingSvc.getBestActiveBindingFor(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
    if (binding instanceof KeySequence) return (KeySequence) binding;
    return null;
  }
}
Exemple #29
0
 /**
  * Performs the Platform.getDebugOption true check on the provided trace
  *
  * <p>Note: ProjectUIPlugin.getDefault().isDebugging() must also be on.
  *
  * <ul>
  *   <li>Trace.RENDER - trace rendering progress
  * </ul>
  *
  * @param trace currently only RENDER is defined
  */
 public static boolean isDebugging(final String trace) {
   return getDefault().isDebugging()
       && "true".equalsIgnoreCase(Platform.getDebugOption(trace)); // $NON-NLS-1$
 }
Exemple #30
0
/** An utility class for computing a qualified name for some model elements. */
public final class JavaUtil {

  private static final String TRACEID_GETQNAME =
      "org.eclipse.gmt.modisco.java/debug/JavaUtil/getQualifiedNames"; //$NON-NLS-1$
  private static final boolean TRACE_GETQNAME =
      JavaPlugin.getDefault().isDebugging()
          && new Boolean(Platform.getDebugOption(JavaUtil.TRACEID_GETQNAME));
  private static final String TRACEID_NE_BY_QN =
      "org.eclipse.gmt.modisco.java/debug/JavaUtil/getNamedElementByQualifiedName"; //$NON-NLS-1$
  private static final boolean TRACE_NE_BY_QN =
      JavaPlugin.getDefault().isDebugging()
          && new Boolean(Platform.getDebugOption(JavaUtil.TRACEID_NE_BY_QN));

  private JavaUtil() {}

  /**
   * Convenience method for {@code getQualifiedName(object, true)}.
   *
   * @see #getQualifiedName(ASTNode, boolean)
   */
  public static String getQualifiedName(final ASTNode object) {
    return getQualifiedName(object, true);
  }

  /**
   * Computes a qualified name for named elements (types, methods, parameters, ...).
   *
   * @param object a model element.
   * @param removeGenerics if we have to remove the generics.
   * @return the qualified name or {@code null} if the object type is not a named type.
   */
  public static String getQualifiedName(final ASTNode object, final boolean removeGenerics) {
    StringBuilder buffer = new StringBuilder();
    if (object instanceof UnresolvedItem) {
      buffer.append(((UnresolvedItem) object).getName());
    } else if (object instanceof AnnotationTypeMemberDeclaration) {
      String containerQName = getQualifiedName((ASTNode) object.eContainer(), removeGenerics);
      buffer.append(containerQName);
      buffer.append("."); // $NON-NLS-1$
      buffer.append(((AnnotationTypeMemberDeclaration) object).getName());
      buffer.append("()"); // $NON-NLS-1$
    } else if (object instanceof EnumConstantDeclaration) {
      String containerQName = getQualifiedName((ASTNode) object.eContainer(), removeGenerics);
      buffer.append(containerQName);
      buffer.append("."); // $NON-NLS-1$
      buffer.append(((EnumConstantDeclaration) object).getName());
    } else if (object instanceof VariableDeclarationFragment) {
      if (object.eContainer() instanceof FieldDeclaration) {
        VariableDeclarationFragment singleVariableDeclaration =
            (VariableDeclarationFragment) object;
        String containerQN =
            getQualifiedName(
                (ASTNode) singleVariableDeclaration.eContainer().eContainer(), removeGenerics);
        buffer.append(containerQN);
        buffer.append("."); // $NON-NLS-1$
        buffer.append(singleVariableDeclaration.getName());
      }
    } else if (object instanceof AbstractMethodDeclaration) {
      AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) object;
      String containerQName = getQualifiedName((ASTNode) object.eContainer(), removeGenerics);
      buffer.append(containerQName);
      buffer.append('.');
      buffer.append(methodDeclaration.getName());
      buffer.append('(');
      for (int i = 0; i < methodDeclaration.getParameters().size(); i++) {
        if (i > 0) {
          buffer.append(","); // $NON-NLS-1$
        }
        SingleVariableDeclaration svd = methodDeclaration.getParameters().get(i);
        buffer.append(getQualifiedName(svd.getType(), true));
      }
      buffer.append(")"); // $NON-NLS-1$
    } else if (object instanceof ArrayType) {
      ArrayType arraytype = (ArrayType) object;
      buffer.append(arraytype.getName());
    } else if (object instanceof TypeParameter) {
      TypeParameter typeParameter = (TypeParameter) object;
      if (removeGenerics) {
        if (typeParameter.getBounds().size() > 0) {
          // get the erasure
          buffer.append(getQualifiedName(typeParameter.getBounds().get(0), true));
        } else {
          buffer.append("java.lang.Object"); // $NON-NLS-1$
        }
      } else {
        buffer.append(typeParameter.getName());
      }
    } else if (object instanceof WildCardType) {
      WildCardType wildcardType = (WildCardType) object;
      buffer.append(wildcardType.getName());
    } else if (object instanceof ParameterizedType) {
      ParameterizedType parameterizedType = (ParameterizedType) object;
      if (removeGenerics) {
        buffer.append(getQualifiedName(parameterizedType.getType(), removeGenerics));
      } else {
        buffer.append(parameterizedType.getName());
      }
    } else if (object instanceof AbstractTypeDeclaration) {
      AbstractTypeDeclaration typeDeclaration = (AbstractTypeDeclaration) object;
      if (typeDeclaration.eContainer() instanceof AbstractTypeDeclaration) {
        AbstractTypeDeclaration superTypeDeclaration =
            (AbstractTypeDeclaration) typeDeclaration.eContainer();
        buffer.append(getQualifiedName(superTypeDeclaration, removeGenerics));
        buffer.append('.');
      } else if (typeDeclaration.eContainer() instanceof Package) {
        Package packaje = (Package) typeDeclaration.eContainer();
        buffer.append(getQualifiedName(packaje, removeGenerics));
        buffer.append('.');
      } else if (typeDeclaration.eContainer() instanceof Model) {
        // No prefix if container is a Model instance
        assert true; // misc statement for checkstyle rule
      } else if (typeDeclaration.eContainer() != null) {
        MoDiscoLogger.logWarning(
            "Not managed type declaration: typeDeclaration.eContainer().getClass()= " //$NON-NLS-1$
            ,
            JavaPlugin.getDefault());
      } else {
        MoDiscoLogger.logWarning(
            "Type with null container" //$NON-NLS-1$
            ,
            JavaPlugin.getDefault());
      }
      buffer.append(typeDeclaration.getName());
    } else if (object instanceof Package) {
      Package packaje = (Package) object;
      if (packaje.eContainer() instanceof Package) {
        Package superPackage = (Package) packaje.eContainer();
        buffer.append(getQualifiedName(superPackage, removeGenerics));
        buffer.append('.');
      }
      buffer.append(packaje.getName());
    } else if (object instanceof TypeAccess) {
      TypeAccess typeAccess = (TypeAccess) object;
      buffer.append(getQualifiedName(typeAccess.getType(), removeGenerics));
    } else if (object instanceof Model) {
      Exception e =
          new Exception(
              "getQualified name should note be called with a model as parameter"); //$NON-NLS-1$
      IStatus status = new Status(IStatus.ERROR, JavaPlugin.PLUGIN_ID, e.getMessage(), e);
      JavaPlugin.getDefault().getLog().log(status);
    } else if (object instanceof PrimitiveType) {
      PrimitiveType primitiveType = (PrimitiveType) object;
      buffer.append(primitiveType.getName());
    } else if (object instanceof AnonymousClassDeclaration) {
      // No qualified name for AnonymousClassDeclaration
      assert true; // misc statement for checkstyle rule
    } else if (object instanceof SingleVariableDeclaration) {
      SingleVariableDeclaration singleVariableDeclaration = (SingleVariableDeclaration) object;
      if (!(singleVariableDeclaration.eContainer() instanceof CatchClause)) {
        buffer.append(
            getQualifiedName((ASTNode) singleVariableDeclaration.eContainer(), removeGenerics));
        buffer.append('.');
      }
      buffer.append(singleVariableDeclaration.getName());
    } else if (object != null) {
      Exception e =
          new Exception(
              "Not managed type: " //$NON-NLS-1$
                  + object.getClass().getName());
      IStatus status = new Status(IStatus.ERROR, JavaPlugin.PLUGIN_ID, e.getMessage(), e);
      JavaPlugin.getDefault().getLog().log(status);
    } else {
      // May occur when parent model element is not complete (e.g.
      // unresolved type of parameter of method)
      // Exception e = new Exception("Null parameter");
      // IStatus status = new Status(IStatus.ERROR, JavaPlugin.PLUGIN_ID,
      // e
      // .getMessage(), e);
      // JavaPlugin.getDefault().getLog().log(status);
      buffer.append("<<null>>"); // $NON-NLS-1$
    }
    if (Platform.inDebugMode() && JavaUtil.TRACE_GETQNAME) {
      System.out.println(
          "JavaUtil.getQualifiedName(EObject)= " //$NON-NLS-1$
              + buffer.toString());
    }
    return buffer.toString();
  }

  private class CurrentElement {

    private EObject currentElement = null;
    private final List<EObject> element = new ArrayList<EObject>();
    private boolean hasChanged = false;
    private boolean hasChanged2 = true;
    private boolean init = true;

    public CurrentElement() {
      // TODO Auto-generated constructor stub
    }

    public void setElement(final EObject element) {
      this.element.add(element);
      if (this.currentElement == null) {
        this.currentElement = element;
      }
      this.hasChanged = false;
      this.hasChanged2 = true;
    }

    @SuppressWarnings("unused")
    public boolean hasChanged() {
      if (this.hasChanged) {
        this.hasChanged = false;
        return true;
      } else {
        return false;
      }
    }

    public boolean hasChanged2() {
      if (this.hasChanged2) {
        this.hasChanged2 = false;
        if (this.element.size() > 0) {
          this.currentElement = this.element.get(0);
          this.element.remove(0);
        }
        return true;
      } else {
        return false;
      }
    }

    public EObject getElement() {
      return this.currentElement;
    }

    public boolean isEmpty() {
      return this.currentElement == null;
    }

    public boolean nextIndex() {
      if (this.init) {
        this.init = false;
        return true;
      } else {
        this.hasChanged = false;
        this.hasChanged2 = true;
        return (this.element.size() > 0);
        // if (this.element.size() > 0) {
        // this.currentElement = this.element.get(0);
        // this.element.remove(0);
        // return true;
        // } else {
        // return false;
        // }
      }
    }
  }

  /**
   * @param model
   * @param searchedQualifiedName
   * @return the model element or null if not found
   */
  public static NamedElement getNamedElementByQualifiedName(
      final Model model, final String searchedQualifiedName) {
    return getNamedElementByQualifiedName(
        model, searchedQualifiedName, new HashMap<String, NamedElement>());
  }

  /**
   * @param model
   * @param searchedQualifiedName
   * @param targets is the discoverer target hash map. This parameter is helpful to prevent
   *     discovery error caused by the visit of non valid model element.
   * @return the model element or null if not found
   */
  public static NamedElement getNamedElementByQualifiedName(
      final Model model,
      final String searchedQualifiedName,
      final Map<String, NamedElement> targets) {
    if (JavaUtil.TRACE_NE_BY_QN) {
      System.out.println(
          "Begin getNamedElementByQualifiedName(Model, String): " //$NON-NLS-1$
              + searchedQualifiedName);
    }
    NamedElement resultNamedElement = null;
    JavaUtil javaUtil = new JavaUtil();
    CurrentElement currentElement = javaUtil.new CurrentElement();
    if (searchedQualifiedName == null) {
      MoDiscoLogger.logError(
          "JavaDiscovererUtils::getNamedElementByQualifiedName(): qualifiedName parameter is null", //$NON-NLS-1$
          JavaPlugin.getDefault());
    } else {
      Iterator<Type> orphanTypes = model.getOrphanTypes().iterator();
      while (orphanTypes.hasNext()) {
        Type orphanType = orphanTypes.next();
        if (searchedQualifiedName.equals(orphanType.getName())) {
          resultNamedElement = orphanType;
        }
      }
      boolean end = false;
      while (currentElement.nextIndex() && resultNamedElement == null) {
        while (resultNamedElement == null && !end && currentElement.hasChanged2()) {
          try {
            if (currentElement.isEmpty()) {
              Iterator<Package> packages = model.getOwnedElements().iterator();
              while (packages.hasNext() && resultNamedElement == null
              /* && !currentElement.hasChanged() */ ) {
                Package packaje = packages.next();
                String currentPackageName = JavaUtil.getQualifiedName(packaje, false);
                if (searchedQualifiedName.startsWith(currentPackageName)) {
                  if (searchedQualifiedName.equals(currentPackageName)) {
                    resultNamedElement = packaje;
                  } else {
                    currentElement.setElement(packaje);
                  }
                }
              }
            } else {
              if (currentElement.getElement() instanceof Package) {
                Package packaje = (Package) currentElement.getElement();
                Iterator<Package> packages = packaje.getOwnedPackages().iterator();
                while (packages.hasNext() && resultNamedElement == null
                /* && !currentElement.hasChanged() */ ) {
                  Package subpackage = packages.next();
                  String subPackageName = JavaUtil.getQualifiedName(subpackage, false);
                  if (searchedQualifiedName.startsWith(subPackageName)) {
                    if (searchedQualifiedName.equals(subPackageName)) {
                      resultNamedElement = subpackage;
                    } else {
                      currentElement.setElement(subpackage);
                    }
                  }
                }
                Iterator<AbstractTypeDeclaration> abstractTypeDeclarations =
                    packaje.getOwnedElements().iterator();
                while (abstractTypeDeclarations.hasNext() && (resultNamedElement == null)
                /* && (!currentElement.hasChanged()) */ ) {
                  AbstractTypeDeclaration atd = abstractTypeDeclarations.next();
                  String atdName = JavaUtil.getQualifiedName(atd, false);
                  if (searchedQualifiedName.startsWith(atdName)) {
                    if (searchedQualifiedName.equals(atdName)) {
                      resultNamedElement = atd;
                    } else {
                      currentElement.setElement(atd);
                    }
                  }
                }
              } else if (currentElement.getElement() instanceof AbstractTypeDeclaration) {
                AbstractTypeDeclaration abstractTypeDeclaration =
                    (AbstractTypeDeclaration) currentElement.getElement();
                List<BodyDeclaration> bodyDeclarations =
                    abstractTypeDeclaration.getBodyDeclarations();
                // for enums, we have to retrieve enums
                // constants
                if (abstractTypeDeclaration instanceof EnumDeclaration) {
                  bodyDeclarations.addAll(
                      ((EnumDeclaration) abstractTypeDeclaration).getEnumConstants());
                }
                Iterator<BodyDeclaration> it = bodyDeclarations.iterator();
                while (it.hasNext() && resultNamedElement == null
                /* && !currentElement.hasChanged() */ ) {
                  BodyDeclaration bodyDeclaration = it.next();
                  if (bodyDeclaration instanceof AbstractTypeDeclaration) {
                    AbstractTypeDeclaration subAbstractTypeDeclaration =
                        (AbstractTypeDeclaration) bodyDeclaration;
                    String subATDQN = JavaUtil.getQualifiedName(subAbstractTypeDeclaration, false);
                    if (searchedQualifiedName.startsWith(subATDQN)) {
                      if (searchedQualifiedName.equals(subATDQN)) {
                        resultNamedElement = subAbstractTypeDeclaration;
                      } else {
                        currentElement.setElement(subAbstractTypeDeclaration);
                      }
                    }
                  } else if (!targets.containsValue(bodyDeclaration)) {
                    if (bodyDeclaration instanceof AbstractMethodDeclaration) {
                      AbstractMethodDeclaration abstractMethodDeclaration =
                          (AbstractMethodDeclaration) bodyDeclaration;
                      String amdQN = JavaUtil.getQualifiedName(abstractMethodDeclaration, true);
                      if (amdQN.contains("<<null>>")) { // $NON-NLS-1$
                        IStatus status =
                            new Status(
                                IStatus.WARNING,
                                JavaPlugin.PLUGIN_ID,
                                "Failed to compute qualifiedName:" //$NON-NLS-1$
                                    + amdQN
                                    + " ; searchedQualifiedName= " //$NON-NLS-1$
                                    + searchedQualifiedName,
                                new Exception());
                        JavaPlugin.getDefault().getLog().log(status);
                      }
                      if (searchedQualifiedName.startsWith(amdQN)) {
                        if (searchedQualifiedName.equals(amdQN)) {
                          resultNamedElement = abstractMethodDeclaration;
                        } else {
                          currentElement.setElement(abstractMethodDeclaration);
                        }
                      }
                    } else if (bodyDeclaration instanceof FieldDeclaration) {
                      FieldDeclaration fieldDeclaration = (FieldDeclaration) bodyDeclaration;
                      Iterator<VariableDeclarationFragment> variableDeclarationFragments =
                          fieldDeclaration.getFragments().iterator();
                      while (variableDeclarationFragments.hasNext()) {
                        VariableDeclarationFragment variableDeclarationFragment =
                            variableDeclarationFragments.next();
                        String variableDeclarationFragmentQN =
                            JavaUtil.getQualifiedName(variableDeclarationFragment, false);
                        if (searchedQualifiedName.equals(variableDeclarationFragmentQN)) {
                          resultNamedElement = variableDeclarationFragment;
                        }
                      }
                    } else if (bodyDeclaration instanceof EnumConstantDeclaration) {
                      EnumConstantDeclaration enumConstantDeclaration =
                          (EnumConstantDeclaration) bodyDeclaration;
                      String enumConstantQN =
                          JavaUtil.getQualifiedName(enumConstantDeclaration, false);
                      if (searchedQualifiedName.equals(enumConstantQN)) {
                        resultNamedElement = enumConstantDeclaration;
                      }
                    } else if (bodyDeclaration instanceof AnnotationTypeMemberDeclaration) {
                      AnnotationTypeMemberDeclaration annoMemberDeclaration =
                          (AnnotationTypeMemberDeclaration) bodyDeclaration;
                      String enumConstantQN =
                          JavaUtil.getQualifiedName(annoMemberDeclaration, false);
                      if (searchedQualifiedName.equals(enumConstantQN)) {
                        resultNamedElement = annoMemberDeclaration;
                      }
                    } else if (bodyDeclaration instanceof Initializer) {
                      // Nothing to do
                      assert true; // misc statement for
                      // checkstyle rule
                    } else {
                      throw new RuntimeException(
                          "Unexpected type in an AbstractTypeDeclaration contaiment: " //$NON-NLS-1$
                              + bodyDeclaration.getClass().getName());
                    }
                  }
                }
              } else {
                end = true;
              }
            }
          } catch (Exception e) {
            RuntimeException runtimeException =
                new RuntimeException(
                    "getNamedElementByQualifiedName failed while reading:" //$NON-NLS-1$
                        + JavaUtil.getQualifiedName((ASTNode) currentElement.getElement(), false),
                    e);
            IStatus status =
                new Status(
                    IStatus.ERROR,
                    JavaPlugin.PLUGIN_ID,
                    runtimeException.getMessage(),
                    runtimeException);
            JavaPlugin.getDefault().getLog().log(status);
            throw runtimeException;
          }
        }
      }
      if (JavaUtil.TRACE_NE_BY_QN) {
        System.out.println(
            "End getNamedElementByQualifiedName(Model, String): result=" //$NON-NLS-1$
                + resultNamedElement);
      }
    }
    return resultNamedElement;
  }
}