public int findInsertionPointIndex(String token, final AtomicBoolean interrupted) {
    token = normalizeToken(token);

    int start = 0;
    int end = sortedIndexEntries.size();

    final Collator sortCollator = sortLanguage.getCollator();
    while (start < end) {
      final int mid = (start + end) / 2;
      if (interrupted.get()) {
        return -1;
      }
      final IndexEntry midEntry = sortedIndexEntries.get(mid);

      final int comp = sortCollator.compare(token, midEntry.normalizedToken());
      if (comp == 0) {
        final int result = windBackCase(token, mid, interrupted);
        return result;
      } else if (comp < 0) {
        // System.out.println("Upper bound: " + midEntry + ", norm=" +
        // midEntry.normalizedToken() + ", mid=" + mid);
        end = mid;
      } else {
        // System.out.println("Lower bound: " + midEntry + ", norm=" +
        // midEntry.normalizedToken() + ", mid=" + mid);
        start = mid + 1;
      }
    }

    // If we search for a substring of a string that's in there, return
    // that.
    int result = Math.min(start, sortedIndexEntries.size() - 1);
    result = windBackCase(sortedIndexEntries.get(result).normalizedToken(), result, interrupted);
    return result;
  }
 public void testThreadSafe() throws Exception {
   int iters = 20 * RANDOM_MULTIPLIER;
   for (int i = 0; i < iters; i++) {
     Locale locale = Locale.GERMAN;
     Collator collator = Collator.getInstance(locale);
     collator.setStrength(Collator.IDENTICAL);
     assertThreadSafe(new ICUCollationKeyAnalyzer(TEST_VERSION_CURRENT, collator));
   }
 }
Esempio n. 3
0
 public int compare(Object o1, Object o2) {
   if (o1 == o2) return 0;
   Collator collator = Collator.getInstance();
   if (o1 instanceof MethodElement && o2 instanceof MethodElement) {
     return collator.compare(((MethodElement) o1).getName(), ((MethodElement) o2).getName());
   }
   Object o1unwrap = TngUtil.unwrap(o1);
   Object o2unwrap = TngUtil.unwrap(o2);
   if (o1unwrap instanceof MethodElement && o2unwrap instanceof MethodElement) {
     return collator.compare(
         ((MethodElement) o1unwrap).getName(), ((MethodElement) o2unwrap).getName());
   }
   return 0;
 }
Esempio n. 4
0
 private static int comparePresentationName(MethodElement e1, MethodElement e2) {
   Collator collator = Collator.getInstance();
   String name1 =
       e1 instanceof BreakdownElement
           ? ProcessUtil.getPresentationName((BreakdownElement) e1)
           : e1.getPresentationName();
   if (name1.length() < 1) name1 = e1.getName();
   String name2 =
       e2 instanceof BreakdownElement
           ? ProcessUtil.getPresentationName((BreakdownElement) e2)
           : e2.getPresentationName();
   if (name2.length() < 1) name2 = e2.getName();
   return collator.compare(name1, name2);
 }
 /**
  * Must override if own collator is used, otherwise always the default collator of the given
  * locale is used
  */
 @Override
 public int getDecomposition() {
   if (locale == null) {
     locale = ULocale.getDefault();
   }
   return Collator.getInstance(locale).getDecomposition();
 }
 @Override
 public String getRules() {
   if (locale == null) {
     locale = ULocale.getDefault();
   }
   return ((RuleBasedCollator) Collator.getInstance(locale)).getRules();
 }
 /**
  * Must override if own collator is used, otherwise always the default collator of the given
  * locale is used
  */
 @Override
 public int getStrength() {
   if (locale == null) {
     locale = ULocale.getDefault();
   }
   return Collator.getInstance(locale).getStrength();
 }
 /**
  * @param input Source token stream
  * @param collator CollationKey generator
  */
 public ICUCollationKeyFilter(TokenStream input, Collator collator) {
   super(input);
   // clone the collator: see http://userguide.icu-project.org/collation/architecture
   try {
     this.collator = (Collator) collator.clone();
   } catch (CloneNotSupportedException e) {
     throw new RuntimeException(e);
   }
 }
Esempio n. 9
0
        public int compare(Object o1, Object o2) {
          if (o1 == o2) return 0;
          o1 = getMethodElement(o1);
          if (o1 == null) {
            return 0;
          }

          o2 = getMethodElement(o2);
          if (o2 == null) {
            return 0;
          }
          MethodElement e1 = (MethodElement) o1;
          MethodElement e2 = (MethodElement) o2;

          Collator collator = Collator.getInstance();
          ;
          return collator.compare(e1.getName() + e1.getGuid(), e2.getName() + e2.getGuid());
        }
 public static TermsFacetComparator getInstance(
     String type, boolean reverse, ULocale locale, String rules, int decomp, int strength) {
   if (locale == null) {
     locale = ULocale.getDefault();
   }
   if ("count".equals(type) || "reverse_count".equals(type) || "reverseCount".equals(type)) {
     if (type.startsWith("reverse")) {
       reverse = true; // compatibility mode
     }
     return new TermsFacetCountComparator("count", reverse);
   } else if ("term".equals(type) || "reverse_term".equals(type) || "reverseTerm".equals(type)) {
     if (type.startsWith("reverse")) {
       reverse = true; // compatibility mode
     }
     TermsFacetCollationComparator comparator = new TermsFacetCollationComparator("term", reverse);
     comparator.setLocale(locale);
     Collator collator = Collator.getInstance(locale);
     if (rules == null) {
       if (strength != -1) {
         collator.setStrength(strength);
       }
       if (decomp != -1) {
         collator.setDecomposition(decomp);
       }
       comparator.setCollator(collator);
     } else {
       try {
         comparator.setRules(rules);
         RuleBasedCollator rc = (RuleBasedCollator) collator;
         comparator.setCollator(new RuleBasedCollator(rc.getRules() + rules));
       } catch (Exception e) {
         comparator.setCollator(Collator.getInstance(locale));
       }
     }
     return comparator;
   }
   throw new ElasticSearchIllegalArgumentException(
       "No type argument match for terms facet comparator [" + type + "]");
 }
  // Test using various international locales with accented characters (which
  // sort differently depending on locale)
  //
  // Copied (and slightly modified) from
  // org.apache.lucene.search.TestSort.testInternationalSort()
  //
  public void testCollationKeySort() throws Exception {
    Analyzer usAnalyzer =
        new ICUCollationKeyAnalyzer(TEST_VERSION_CURRENT, Collator.getInstance(Locale.ROOT));
    Analyzer franceAnalyzer =
        new ICUCollationKeyAnalyzer(TEST_VERSION_CURRENT, Collator.getInstance(Locale.FRANCE));
    Analyzer swedenAnalyzer =
        new ICUCollationKeyAnalyzer(
            TEST_VERSION_CURRENT, Collator.getInstance(new Locale("sv", "se")));
    Analyzer denmarkAnalyzer =
        new ICUCollationKeyAnalyzer(
            TEST_VERSION_CURRENT, Collator.getInstance(new Locale("da", "dk")));

    // The ICU Collator and java.text.Collator implementations differ in their
    // orderings - "BFJHD" is the ordering for the ICU Collator for Locale.ROOT.
    testCollationKeySort(
        usAnalyzer,
        franceAnalyzer,
        swedenAnalyzer,
        denmarkAnalyzer,
        "BFJHD",
        "ECAGI",
        "BJDFH",
        "BJDHF");
  }
    public int compare(Object o1, Object o2) {
      if (((String) o1).equals(o2)) return 0;

      History history = QualifiedTypeNameHistory.getDefault();

      int pos1 = history.getPosition(o1);
      int pos2 = history.getPosition(o2);

      if (pos1 == pos2) return Collator.getInstance().compare(o1, o2);

      if (pos1 > pos2) {
        return -1;
      } else {
        return 1;
      }
    }
 @Override
 public boolean incrementToken() throws IOException {
   if (input.incrementToken()) {
     char[] termBuffer = termAtt.buffer();
     String termText = new String(termBuffer, 0, termAtt.length());
     collator.getRawCollationKey(termText, reusableKey);
     int encodedLength =
         IndexableBinaryStringTools.getEncodedLength(reusableKey.bytes, 0, reusableKey.size);
     if (encodedLength > termBuffer.length) {
       termAtt.resizeBuffer(encodedLength);
     }
     termAtt.setLength(encodedLength);
     IndexableBinaryStringTools.encode(
         reusableKey.bytes, 0, reusableKey.size, termAtt.buffer(), 0, encodedLength);
     return true;
   } else {
     return false;
   }
 }
Esempio n. 14
0
/**
 * A menu for opening file revisions in the workbench.
 *
 * <p>An <code>OpenWithMenu</code> is used to populate a menu with "Open With" actions. One action
 * is added for each editor which is applicable to the selected file. If the user selects one of
 * these items, the corresponding editor is opened on the file.
 */
public class OpenWithMenu extends ContributionItem {

  private IStructuredSelection selection;

  private HistoryPage page;

  private IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry();

  private static Hashtable imageCache = new Hashtable(11);

  /** The id of this action. */
  public static final String ID = PlatformUI.PLUGIN_ID + ".OpenWithMenu"; // $NON-NLS-1$

  /**
   * Match both the input and id, so that different types of editor can be opened on the same input.
   */
  private static final int MATCH_BOTH = IWorkbenchPage.MATCH_INPUT | IWorkbenchPage.MATCH_ID;

  /*
   * Compares the labels from two IEditorDescriptor objects
   */
  private static final Comparator comparer =
      new Comparator() {
        private Collator collator = Collator.getInstance();

        public int compare(Object arg0, Object arg1) {
          String s1 = ((IEditorDescriptor) arg0).getLabel();
          String s2 = ((IEditorDescriptor) arg1).getLabel();
          return collator.compare(s1, s2);
        }
      };

  /**
   * Constructs a new instance of <code>OpenWithMenu</code>.
   *
   * @param page the page where the editor is opened if an item within the menu is selected
   */
  public OpenWithMenu(HistoryPage page) {
    super(ID);
    this.page = page;
  }

  /**
   * Returns an image to show for the corresponding editor descriptor.
   *
   * @param editorDesc the editor descriptor, or null for the system editor
   * @return the image or null
   */
  private Image getImage(IEditorDescriptor editorDesc) {
    ImageDescriptor imageDesc = getImageDescriptor(editorDesc);
    if (imageDesc == null) {
      return null;
    }
    Image image = (Image) imageCache.get(imageDesc);
    if (image == null) {
      image = imageDesc.createImage();
      imageCache.put(imageDesc, image);
    }
    return image;
  }

  /** Returns the image descriptor for the given editor descriptor, or null if it has no image. */
  private ImageDescriptor getImageDescriptor(IEditorDescriptor editorDesc) {
    ImageDescriptor imageDesc = null;
    if (editorDesc == null) {
      imageDesc = registry.getImageDescriptor(getFileRevision().getName());
      // TODO: is this case valid, and if so, what are the implications
      // for content-type editor bindings?
    } else {
      imageDesc = editorDesc.getImageDescriptor();
    }
    if (imageDesc == null) {
      if (editorDesc.getId().equals(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID)) {
        imageDesc = registry.getSystemExternalEditorImageDescriptor(getFileRevision().getName());
      }
    }
    return imageDesc;
  }

  /**
   * Creates the menu item for the editor descriptor.
   *
   * @param menu the menu to add the item to
   * @param descriptor the editor descriptor, or null for the system editor
   * @param preferredEditor the descriptor of the preferred editor, or <code>null</code>
   */
  private MenuItem createMenuItem(
      Menu menu, final IEditorDescriptor descriptor, final IEditorDescriptor preferredEditor) {
    // XXX: Would be better to use bold here, but SWT does not support it.
    final MenuItem menuItem = new MenuItem(menu, SWT.RADIO);
    boolean isPreferred =
        preferredEditor != null && descriptor.getId().equals(preferredEditor.getId());
    menuItem.setSelection(isPreferred);
    menuItem.setText(descriptor.getLabel());
    Image image = getImage(descriptor);
    if (image != null) {
      menuItem.setImage(image);
    }
    Listener listener =
        new Listener() {
          public void handleEvent(Event event) {
            switch (event.type) {
              case SWT.Selection:
                if (menuItem.getSelection()) {
                  openEditor(descriptor, false);
                }
                break;
            }
          }
        };
    menuItem.addListener(SWT.Selection, listener);
    return menuItem;
  }

  /**
   * Creates the Other... menu item
   *
   * @param menu the menu to add the item to
   */
  private void createOtherMenuItem(final Menu menu) {
    final IFileRevision fileResource = getFileRevision();
    if (fileResource == null) {
      return;
    }
    new MenuItem(menu, SWT.SEPARATOR);
    final MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
    menuItem.setText(TeamUIMessages.LocalHistoryPage_OpenWithMenu_Other);
    Listener listener =
        new Listener() {
          public void handleEvent(Event event) {
            switch (event.type) {
              case SWT.Selection:
                EditorSelectionDialog dialog = new EditorSelectionDialog(menu.getShell());
                dialog.setMessage(
                    NLS.bind(
                        TeamUIMessages.LocalHistoryPage_OpenWithMenu_OtherDialogDescription,
                        fileResource.getName()));
                if (dialog.open() == Window.OK) {
                  IEditorDescriptor editor = dialog.getSelectedEditor();
                  if (editor != null) {
                    openEditor(editor, editor.isOpenExternal());
                  }
                }
                break;
            }
          }
        };
    menuItem.addListener(SWT.Selection, listener);
  }

  public void fill(Menu menu, int index) {
    final IFileRevision fileRevision = getFileRevision();
    if (fileRevision == null) {
      return;
    }

    IEditorDescriptor defaultTextEditor =
        registry.findEditor("org.eclipse.ui.DefaultTextEditor"); // $NON-NLS-1$
    IEditorDescriptor preferredEditor = Utils.getDefaultEditor(fileRevision);

    Object[] editors = Utils.getEditors(fileRevision);
    Collections.sort(Arrays.asList(editors), comparer);
    boolean defaultFound = false;

    // Check that we don't add it twice. This is possible
    // if the same editor goes to two mappings.
    ArrayList alreadyMapped = new ArrayList();

    for (int i = 0; i < editors.length; i++) {
      IEditorDescriptor editor = (IEditorDescriptor) editors[i];
      if (!alreadyMapped.contains(editor)) {
        createMenuItem(menu, editor, preferredEditor);
        if (defaultTextEditor != null && editor.getId().equals(defaultTextEditor.getId())) {
          defaultFound = true;
        }
        alreadyMapped.add(editor);
      }
    }

    // Only add a separator if there is something to separate
    if (editors.length > 0) {
      new MenuItem(menu, SWT.SEPARATOR);
    }

    // Add default editor. Check it if it is saved as the preference.
    if (!defaultFound && defaultTextEditor != null) {
      createMenuItem(menu, defaultTextEditor, preferredEditor);
    }

    // TODO : We might perhaps enable inplace and system external editors menu items
    /*// Add system editor
    IEditorDescriptor descriptor = registry
    		.findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID);
    final MenuItem systemEditorMenuItem = createMenuItem(menu, descriptor,
    		preferredEditor);
    systemEditorMenuItem.setEnabled(false);

    // Add system in-place editor
    descriptor = registry
    		.findEditor(IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID);

    final MenuItem inPlaceEditorMenuItem = (descriptor != null) ? createMenuItem(
    		menu, descriptor, preferredEditor)
    		: null;
    if (inPlaceEditorMenuItem != null)
    	inPlaceEditorMenuItem.setEnabled(false);

    Job job = new Job("updateOpenWithMenu") { //$NON-NLS-1$
    	protected IStatus run(IProgressMonitor monitor) {
    		try {
    			final boolean isFile = fileRevision.getStorage(monitor) instanceof IFile;
    			Display.getDefault().asyncExec(new Runnable() {
    				public void run() {
    					if (inPlaceEditorMenuItem != null
    							&& !inPlaceEditorMenuItem.isDisposed())
    						inPlaceEditorMenuItem.setEnabled(isFile);
    					if (!systemEditorMenuItem.isDisposed())
    						systemEditorMenuItem.setEnabled(isFile);
    				}
    			});
    			return Status.OK_STATUS;
    		} catch (CoreException e) {
    			return new Status(IStatus.WARNING, TeamUIPlugin.ID, null, e);
    		}
    	};
    };
    job.setSystem(true);
    job.schedule();*/

    createDefaultMenuItem(menu, fileRevision);

    // add Other... menu item
    createOtherMenuItem(menu);
  }

  public void createDefaultMenuItem(Menu menu, final IFileRevision revision) {
    final MenuItem menuItem = new MenuItem(menu, SWT.RADIO);
    menuItem.setSelection(Utils.getDefaultEditor(revision) == null);
    menuItem.setText(TeamUIMessages.LocalHistoryPage_OpenWithMenu_DefaultEditorDescription);

    Listener listener =
        new Listener() {
          public void handleEvent(Event event) {
            switch (event.type) {
              case SWT.Selection:
                if (menuItem.getSelection()) {
                  openEditor(Utils.getDefaultEditor(revision), false);
                }
                break;
            }
          }
        };

    menuItem.addListener(SWT.Selection, listener);
  }

  /** Opens the given editor on the selected file revision. */
  protected void openEditor(IEditorDescriptor editorDescriptor, boolean openUsingDescriptor) {
    IFileRevision fileRevision = getFileRevision();
    if (fileRevision == null) {
      return;
    }
    try {
      IProgressMonitor monitor = new NullProgressMonitor();
      IStorage storage = fileRevision.getStorage(monitor);
      boolean isFile = storage instanceof IFile;

      if (openUsingDescriptor) {
        // discouraged access to open system editors
        ((WorkbenchPage) (page.getSite().getPage()))
            .openEditorFromDescriptor(
                isFile
                    ? new FileEditorInput((IFile) storage)
                    : (IEditorInput)
                        FileRevisionEditorInput.createEditorInputFor(fileRevision, monitor),
                editorDescriptor,
                true,
                null);
      } else {
        String editorId =
            editorDescriptor == null
                ? IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID
                : editorDescriptor.getId();
        page.getSite()
            .getPage()
            .openEditor(
                isFile
                    ? new FileEditorInput((IFile) storage)
                    : (IEditorInput)
                        FileRevisionEditorInput.createEditorInputFor(fileRevision, monitor),
                editorId,
                true,
                MATCH_BOTH);
      }
    } catch (PartInitException e) {
      StatusAdapter statusAdapter = new StatusAdapter(e.getStatus());
      statusAdapter.setProperty(
          IStatusAdapterConstants.TITLE_PROPERTY, TeamUIMessages.LocalHistoryPage_OpenEditorError);
      StatusManager.getManager().handle(statusAdapter, StatusManager.SHOW);
    } catch (CoreException e) {
      StatusAdapter statusAdapter = new StatusAdapter(e.getStatus());
      statusAdapter.setProperty(
          IStatusAdapterConstants.TITLE_PROPERTY, TeamUIMessages.LocalHistoryPage_OpenEditorError);
      StatusManager.getManager().handle(statusAdapter, StatusManager.LOG);
    }
  }

  private IFileRevision getFileRevision() {
    IStructuredSelection structSel = selection;

    IFileRevision revision = null;

    if (structSel == null) return null;

    Object[] objArray = structSel.toArray();

    for (int i = 0; i < objArray.length; i++) {
      Object tempRevision = objArray[i];
      // If not a revision, don't try opening
      if (tempRevision instanceof AbstractHistoryCategory) continue;

      revision = (IFileRevision) tempRevision;
    }
    return revision;
  }

  /*
   * (non-Javadoc) Returns whether this menu is dynamic.
   */
  public boolean isDynamic() {
    return true;
  }

  public void selectionChanged(IStructuredSelection selection) {
    if (selection instanceof IStructuredSelection) {
      this.selection = selection;
    } else {
      this.selection = StructuredSelection.EMPTY;
    }
  }
}
Esempio n. 15
0
 public int compare(Object arg0, Object arg1) {
   String s1 = ((IEditorDescriptor) arg0).getLabel();
   String s2 = ((IEditorDescriptor) arg1).getLabel();
   return collator.compare(s1, s2);
 }
/**
 * Common API of dynamic contribution of items to manipulate configurations of a working set.
 *
 * @author Christian W. Damus (cdamus)
 * @since 6.0
 */
abstract class AbstractWorkingSetConfigsContribution extends CompoundContributionItem {

  private IWorkingSetProxy workingSet;

  private Comparator<IWorkingSetConfiguration> configOrdering =
      new Comparator<IWorkingSetConfiguration>() {
        private Collator collator = Collator.getInstance();

        @Override
        public int compare(IWorkingSetConfiguration o1, IWorkingSetConfiguration o2) {
          return collator.compare(o1.getName(), o2.getName());
        }
      };

  /**
   * Initializes me without a working set. I figure it out, later. This is only appropriate usage
   * for context-menu contribution, where the workbench selection is obvious.
   */
  public AbstractWorkingSetConfigsContribution() {
    super();
  }

  /**
   * Initializes me with my working set.
   *
   * @param workingSet my working set
   */
  AbstractWorkingSetConfigsContribution(IWorkingSetProxy workingSet) {
    super();

    this.workingSet = workingSet;
  }

  @Override
  protected IContributionItem[] getContributionItems() {
    if (getWorkingSet() == null) {
      return new IContributionItem[0];
    }

    // sort the configurations by name
    List<IWorkingSetConfiguration> configs =
        new java.util.ArrayList<IWorkingSetConfiguration>(getWorkingSet().getConfigurations());
    Collections.sort(configs, configOrdering);

    IContributionItem[] result = new IContributionItem[configs.size()];
    int i = 0;
    for (IWorkingSetConfiguration next : configs) {
      result[i] = createContribution(next, i);
      i++;
    }

    return result;
  }

  /**
   * Creates a contribution item for a specific configuration of my working set.
   *
   * @param config a configuration of my working set
   * @param index the index of the contribution in the composite
   * @return the contribution
   */
  protected abstract IContributionItem createContribution(
      IWorkingSetConfiguration config, int index);

  /**
   * Obtains my working set. It may be lazily determined from the current workbench selection.
   *
   * @return my working set
   */
  protected IWorkingSetProxy getWorkingSet() {
    if (workingSet == null) {
      ISelection sel = CUIPlugin.getActivePage().getSelection();
      if (sel instanceof IStructuredSelection) {
        IStructuredSelection ssel = (IStructuredSelection) sel;

        if (!ssel.isEmpty()) {
          Object first = ssel.getFirstElement();
          if (first instanceof IWorkingSet) {
            workingSet =
                WorkingSetConfigurationManager.getDefault()
                    .getWorkingSet(((IWorkingSet) first).getName());
          }
        }
      }
    }

    return workingSet;
  }
}
 @Override
 public int compare(IWorkingSetConfiguration o1, IWorkingSetConfiguration o2) {
   return collator.compare(o1.getName(), o2.getName());
 }
public class TestICUCollationKeyAnalyzer extends CollationTestBase {

  private Collator collator = Collator.getInstance(new Locale("fa"));
  private Analyzer analyzer = new ICUCollationKeyAnalyzer(TEST_VERSION_CURRENT, collator);

  private BytesRef firstRangeBeginning =
      new BytesRef(collator.getCollationKey(firstRangeBeginningOriginal).toByteArray());
  private BytesRef firstRangeEnd =
      new BytesRef(collator.getCollationKey(firstRangeEndOriginal).toByteArray());
  private BytesRef secondRangeBeginning =
      new BytesRef(collator.getCollationKey(secondRangeBeginningOriginal).toByteArray());
  private BytesRef secondRangeEnd =
      new BytesRef(collator.getCollationKey(secondRangeEndOriginal).toByteArray());

  public void testFarsiRangeFilterCollating() throws Exception {
    testFarsiRangeFilterCollating(
        analyzer, firstRangeBeginning, firstRangeEnd, secondRangeBeginning, secondRangeEnd);
  }

  public void testFarsiRangeQueryCollating() throws Exception {
    testFarsiRangeQueryCollating(
        analyzer, firstRangeBeginning, firstRangeEnd, secondRangeBeginning, secondRangeEnd);
  }

  public void testFarsiTermRangeQuery() throws Exception {
    testFarsiTermRangeQuery(
        analyzer, firstRangeBeginning, firstRangeEnd, secondRangeBeginning, secondRangeEnd);
  }

  // Test using various international locales with accented characters (which
  // sort differently depending on locale)
  //
  // Copied (and slightly modified) from
  // org.apache.lucene.search.TestSort.testInternationalSort()
  //
  public void testCollationKeySort() throws Exception {
    Analyzer usAnalyzer =
        new ICUCollationKeyAnalyzer(TEST_VERSION_CURRENT, Collator.getInstance(Locale.ROOT));
    Analyzer franceAnalyzer =
        new ICUCollationKeyAnalyzer(TEST_VERSION_CURRENT, Collator.getInstance(Locale.FRANCE));
    Analyzer swedenAnalyzer =
        new ICUCollationKeyAnalyzer(
            TEST_VERSION_CURRENT, Collator.getInstance(new Locale("sv", "se")));
    Analyzer denmarkAnalyzer =
        new ICUCollationKeyAnalyzer(
            TEST_VERSION_CURRENT, Collator.getInstance(new Locale("da", "dk")));

    // The ICU Collator and java.text.Collator implementations differ in their
    // orderings - "BFJHD" is the ordering for the ICU Collator for Locale.ROOT.
    testCollationKeySort(
        usAnalyzer,
        franceAnalyzer,
        swedenAnalyzer,
        denmarkAnalyzer,
        "BFJHD",
        "ECAGI",
        "BJDFH",
        "BJDHF");
  }

  public void testThreadSafe() throws Exception {
    int iters = 20 * RANDOM_MULTIPLIER;
    for (int i = 0; i < iters; i++) {
      Locale locale = Locale.GERMAN;
      Collator collator = Collator.getInstance(locale);
      collator.setStrength(Collator.IDENTICAL);
      assertThreadSafe(new ICUCollationKeyAnalyzer(TEST_VERSION_CURRENT, collator));
    }
  }
}
Esempio n. 19
0
 public int compareTo(Object o) {
   return collator.compare(label, ((ResourceDescriptor) o).label);
 }
Esempio n. 20
0
/**
 * Shows a list of resources to the user with a text entry field for a string pattern used to filter
 * the list of resources.
 *
 * <p>
 *
 * @since 2.1
 */
public class ResourceListSelectionDialog extends SelectionDialog {

  private static final String DIALOG_SETTINGS_SECTION =
      "ResourceListSelectionDialogSettings"; //$NON-NLS-1$

  Text pattern;

  Table resourceNames;

  Table folderNames;

  String patternString;

  IContainer container;

  int typeMask;

  private static Collator collator = Collator.getInstance();

  boolean gatherResourcesDynamically = true;

  StringMatcher stringMatcher;

  UpdateFilterThread updateFilterThread;

  UpdateGatherThread updateGatherThread;

  ResourceDescriptor[] descriptors;

  int descriptorsSize;

  WorkbenchLabelProvider labelProvider = new WorkbenchLabelProvider();

  boolean okEnabled = false;

  private boolean showDerived = false;

  private Button showDerivedButton;

  private boolean allowUserToToggleDerived;

  static class ResourceDescriptor implements Comparable {
    String label;

    ArrayList resources = new ArrayList();

    boolean resourcesSorted = true;

    public int compareTo(Object o) {
      return collator.compare(label, ((ResourceDescriptor) o).label);
    }
  }

  class UpdateFilterThread extends Thread {
    boolean stop = false;

    int firstMatch = 0;

    int lastMatch = descriptorsSize - 1;

    public void run() {
      Display display = resourceNames.getDisplay();
      final int itemIndex[] = {0};
      final int itemCount[] = {0};
      // Keep track of if the widget got disposed
      // so that we can abort if required
      final boolean[] disposed = {false};
      display.syncExec(
          new Runnable() {
            public void run() {
              // Be sure the widget still exists
              if (resourceNames.isDisposed()) {
                disposed[0] = true;
                return;
              }
              itemCount[0] = resourceNames.getItemCount();
            }
          });

      if (disposed[0]) {
        return;
      }

      int last;
      if ((patternString.indexOf('?') == -1)
          && (patternString.endsWith("*"))
          && //$NON-NLS-1$
          (patternString.indexOf('*') == patternString.length() - 1)) {
        // Use a binary search to get first and last match when the pattern
        // string ends with "*" and has no other embedded special characters.
        // For this case, we can be smarter about getting the first and last
        // match since the items are in sorted order.
        firstMatch = getFirstMatch();
        if (firstMatch == -1) {
          firstMatch = 0;
          lastMatch = -1;
        } else {
          lastMatch = getLastMatch();
        }
        last = lastMatch;
        for (int i = firstMatch; i <= lastMatch; i++) {
          if (i % 50 == 0) {
            try {
              Thread.sleep(10);
            } catch (InterruptedException e) {
              // ignore
            }
          }
          if (stop || resourceNames.isDisposed()) {
            disposed[0] = true;
            return;
          }
          final int index = i;
          display.syncExec(
              new Runnable() {
                public void run() {
                  if (stop || resourceNames.isDisposed()) {
                    return;
                  }
                  updateItem(index, itemIndex[0], itemCount[0]);
                  itemIndex[0]++;
                }
              });
        }
      } else {
        last = lastMatch;
        boolean setFirstMatch = true;
        for (int i = firstMatch; i <= lastMatch; i++) {
          if (i % 50 == 0) {
            try {
              Thread.sleep(10);
            } catch (InterruptedException e) {
              // ignore
            }
          }
          if (stop || resourceNames.isDisposed()) {
            disposed[0] = true;
            return;
          }
          final int index = i;
          if (match(descriptors[index].label)) {
            if (setFirstMatch) {
              setFirstMatch = false;
              firstMatch = index;
            }
            last = index;
            display.syncExec(
                new Runnable() {
                  public void run() {
                    if (stop || resourceNames.isDisposed()) {
                      return;
                    }
                    updateItem(index, itemIndex[0], itemCount[0]);
                    itemIndex[0]++;
                  }
                });
          }
        }
      }

      if (disposed[0]) {
        return;
      }

      lastMatch = last;
      display.syncExec(
          new Runnable() {
            public void run() {
              if (resourceNames.isDisposed()) {
                return;
              }
              itemCount[0] = resourceNames.getItemCount();
              if (itemIndex[0] < itemCount[0]) {
                resourceNames.setRedraw(false);
                resourceNames.remove(itemIndex[0], itemCount[0] - 1);
                resourceNames.setRedraw(true);
              }
              // If no resources, remove remaining folder entries
              if (resourceNames.getItemCount() == 0) {
                folderNames.removeAll();
                updateOKState(false);
              }
            }
          });
    }
  }

  class UpdateGatherThread extends Thread {
    boolean stop = false;

    int lastMatch = -1;

    int firstMatch = 0;

    boolean refilter = false;

    public void run() {
      Display display = resourceNames.getDisplay();
      final int itemIndex[] = {0};
      final int itemCount[] = {0};
      // Keep track of if the widget got disposed
      // so that we can abort if required
      final boolean[] disposed = {false};
      display.syncExec(
          new Runnable() {
            public void run() {
              // Be sure the widget still exists
              if (resourceNames.isDisposed()) {
                disposed[0] = true;
                return;
              }
              itemCount[0] = resourceNames.getItemCount();
            }
          });

      if (disposed[0]) {
        return;
      }

      if (!refilter) {
        for (int i = 0; i <= lastMatch; i++) {
          if (i % 50 == 0) {
            try {
              Thread.sleep(10);
            } catch (InterruptedException e) {
              // ignore
            }
          }
          if (stop || resourceNames.isDisposed()) {
            disposed[0] = true;
            return;
          }
          final int index = i;
          display.syncExec(
              new Runnable() {
                public void run() {
                  if (stop || resourceNames.isDisposed()) {
                    return;
                  }
                  updateItem(index, itemIndex[0], itemCount[0]);
                  itemIndex[0]++;
                }
              });
        }
      } else {
        // we're filtering the previous list
        for (int i = firstMatch; i <= lastMatch; i++) {
          if (i % 50 == 0) {
            try {
              Thread.sleep(10);
            } catch (InterruptedException e) {
              // ignore
            }
          }
          if (stop || resourceNames.isDisposed()) {
            disposed[0] = true;
            return;
          }
          final int index = i;
          if (match(descriptors[index].label)) {
            display.syncExec(
                new Runnable() {
                  public void run() {
                    if (stop || resourceNames.isDisposed()) {
                      return;
                    }
                    updateItem(index, itemIndex[0], itemCount[0]);
                    itemIndex[0]++;
                  }
                });
          }
        }
      }

      if (disposed[0]) {
        return;
      }

      display.syncExec(
          new Runnable() {
            public void run() {
              if (resourceNames.isDisposed()) {
                return;
              }
              itemCount[0] = resourceNames.getItemCount();
              if (itemIndex[0] < itemCount[0]) {
                resourceNames.setRedraw(false);
                resourceNames.remove(itemIndex[0], itemCount[0] - 1);
                resourceNames.setRedraw(true);
              }
              // If no resources, remove remaining folder entries
              if (resourceNames.getItemCount() == 0) {
                folderNames.removeAll();
                updateOKState(false);
              }
            }
          });
    }
  }

  /**
   * Creates a new instance of the class.
   *
   * @param parentShell shell to parent the dialog on
   * @param resources resources to display in the dialog
   */
  public ResourceListSelectionDialog(Shell parentShell, IResource[] resources) {
    super(parentShell);
    gatherResourcesDynamically = false;
    initDescriptors(resources);
  }

  /**
   * Creates a new instance of the class. When this constructor is used to create the dialog,
   * resources will be gathered dynamically as the pattern string is specified. Only resources of
   * the given types that match the pattern string will be listed. To further filter the matching
   * resources,
   *
   * @see #select(IResource)
   * @param parentShell shell to parent the dialog on
   * @param container container to get resources from
   * @param typeMask mask containing IResource types to be considered
   */
  public ResourceListSelectionDialog(Shell parentShell, IContainer container, int typeMask) {
    super(parentShell);
    this.container = container;
    this.typeMask = typeMask;
  }

  /** Adjust the pattern string for matching. */
  protected String adjustPattern() {
    String text = pattern.getText().trim();
    if (text.endsWith("<")) { // $NON-NLS-1$
      // the < character indicates an exact match search
      return text.substring(0, text.length() - 1);
    }
    if (!text.equals("") && !text.endsWith("*")) { // $NON-NLS-1$ //$NON-NLS-2$
      return text + "*"; // $NON-NLS-1$
    }
    return text;
  }

  /** @see org.eclipse.jface.dialogs.Dialog#cancelPressed() */
  protected void cancelPressed() {
    setResult(null);
    super.cancelPressed();
  }

  /** @see org.eclipse.jface.window.Window#close() */
  public boolean close() {
    boolean result = super.close();
    labelProvider.dispose();
    return result;
  }

  /** @see org.eclipse.jface.window.Window#create() */
  public void create() {
    super.create();
    pattern.setFocus();
    getButton(IDialogConstants.OK_ID).setEnabled(okEnabled);
  }

  /**
   * Creates the contents of this dialog, initializes the listener and the update thread.
   *
   * @param parent parent to create the dialog widgets in
   */
  protected Control createDialogArea(Composite parent) {

    Composite dialogArea = (Composite) super.createDialogArea(parent);
    Label l = new Label(dialogArea, SWT.NONE);
    l.setText(IDEWorkbenchMessages.ResourceSelectionDialog_label);
    GridData data = new GridData(GridData.FILL_HORIZONTAL);
    l.setLayoutData(data);

    pattern = new Text(dialogArea, SWT.SINGLE | SWT.BORDER);
    pattern.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
    l = new Label(dialogArea, SWT.NONE);
    l.setText(IDEWorkbenchMessages.ResourceSelectionDialog_matching);
    data = new GridData(GridData.FILL_HORIZONTAL);
    l.setLayoutData(data);
    resourceNames = new Table(dialogArea, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL);
    data = new GridData(GridData.FILL_BOTH);
    data.heightHint = 12 * resourceNames.getItemHeight();
    resourceNames.setLayoutData(data);

    l = new Label(dialogArea, SWT.NONE);
    l.setText(IDEWorkbenchMessages.ResourceSelectionDialog_folders);
    data = new GridData(GridData.FILL_HORIZONTAL);
    l.setLayoutData(data);

    folderNames = new Table(dialogArea, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
    data = new GridData(GridData.FILL_BOTH);
    data.widthHint = 300;
    data.heightHint = 4 * folderNames.getItemHeight();
    folderNames.setLayoutData(data);

    if (gatherResourcesDynamically) {
      updateGatherThread = new UpdateGatherThread();
    } else {
      updateFilterThread = new UpdateFilterThread();
    }

    pattern.addKeyListener(
        new KeyAdapter() {
          public void keyReleased(KeyEvent e) {
            if (e.keyCode == SWT.ARROW_DOWN) {
              resourceNames.setFocus();
            }
          }
        });

    pattern.addModifyListener(
        new ModifyListener() {
          public void modifyText(ModifyEvent e) {
            refresh(false);
          }
        });

    resourceNames.addSelectionListener(
        new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            updateFolders((ResourceDescriptor) e.item.getData());
          }

          public void widgetDefaultSelected(SelectionEvent e) {
            okPressed();
          }
        });

    folderNames.addSelectionListener(
        new SelectionAdapter() {
          public void widgetDefaultSelected(SelectionEvent e) {
            okPressed();
          }
        });

    if (getAllowUserToToggleDerived()) {
      showDerivedButton = new Button(dialogArea, SWT.CHECK);
      showDerivedButton.setText(IDEWorkbenchMessages.ResourceSelectionDialog_showDerived);
      showDerivedButton.addSelectionListener(
          new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
              setShowDerived(showDerivedButton.getSelection());
              refresh(true);
            }
          });
      showDerivedButton.setSelection(getShowDerived());
    }

    applyDialogFont(dialogArea);
    return dialogArea;
  }

  /**
   * Returns whether to include a "Show derived resources" checkbox in the dialog. The default is
   * <code>false</code>.
   *
   * @return <code>true</code> to include the checkbox, <code>false</code> to omit
   * @since 3.1
   */
  public boolean getAllowUserToToggleDerived() {
    return allowUserToToggleDerived;
  }

  /**
   * Sets whether to include a "Show derived resources" checkbox in the dialog.
   *
   * @param allow <code>true</code> to include the checkbox, <code>false</code> to omit
   * @since 3.1
   */
  public void setAllowUserToToggleDerived(boolean allow) {
    allowUserToToggleDerived = allow;
  }

  /** */
  private void filterResources(boolean force) {
    String oldPattern = force ? null : patternString;
    patternString = adjustPattern();
    if (!force && patternString.equals(oldPattern)) {
      return;
    }

    updateFilterThread.stop = true;
    stringMatcher = new StringMatcher(patternString, true, false);
    UpdateFilterThread oldThread = updateFilterThread;
    updateFilterThread = new UpdateFilterThread();
    if (patternString.equals("")) { // $NON-NLS-1$
      updateFilterThread.firstMatch = 0;
      updateFilterThread.lastMatch = -1;
      updateFilterThread.start();
      return;
    }

    if (oldPattern != null
        && (oldPattern.length() != 0)
        && oldPattern.endsWith("*")
        && patternString.endsWith("*")) { // $NON-NLS-1$ //$NON-NLS-2$
      int matchLength = oldPattern.length() - 1;
      if (patternString.regionMatches(0, oldPattern, 0, matchLength)) {
        // filter the previous list of items, this is done when the
        // new pattern is a derivative of the old pattern
        updateFilterThread.firstMatch = oldThread.firstMatch;
        updateFilterThread.lastMatch = oldThread.lastMatch;
        updateFilterThread.start();
        return;
      }
    }

    // filter the entire list
    updateFilterThread.firstMatch = 0;
    updateFilterThread.lastMatch = descriptorsSize - 1;
    updateFilterThread.start();
  }

  /**
   * Use a binary search to get the first match for the patternString. This method assumes the
   * patternString does not contain any '?' characters and that it contains only one '*' character
   * at the end of the string.
   */
  private int getFirstMatch() {
    int high = descriptorsSize;
    int low = -1;
    boolean match = false;
    ResourceDescriptor desc = new ResourceDescriptor();
    desc.label = patternString.substring(0, patternString.length() - 1);
    while (high - low > 1) {
      int index = (high + low) / 2;
      String label = descriptors[index].label;
      if (match(label)) {
        high = index;
        match = true;
      } else {
        int compare = descriptors[index].compareTo(desc);
        if (compare == -1) {
          low = index;
        } else {
          high = index;
        }
      }
    }
    if (match) {
      return high;
    }
    return -1;
  }

  /** */
  private void gatherResources(boolean force) {
    String oldPattern = force ? null : patternString;
    patternString = adjustPattern();
    if (!force && patternString.equals(oldPattern)) {
      return;
    }

    updateGatherThread.stop = true;
    updateGatherThread = new UpdateGatherThread();

    if (patternString.equals("")) { // $NON-NLS-1$
      updateGatherThread.start();
      return;
    }
    stringMatcher = new StringMatcher(patternString, true, false);

    if (oldPattern != null
        && (oldPattern.length() != 0)
        && oldPattern.endsWith("*")
        && patternString.endsWith("*")) { // $NON-NLS-1$ //$NON-NLS-2$
      // see if the new pattern is a derivative of the old pattern
      int matchLength = oldPattern.length() - 1;
      if (patternString.regionMatches(0, oldPattern, 0, matchLength)) {
        updateGatherThread.refilter = true;
        updateGatherThread.firstMatch = 0;
        updateGatherThread.lastMatch = descriptorsSize - 1;
        updateGatherThread.start();
        return;
      }
    }

    final ArrayList resources = new ArrayList();
    BusyIndicator.showWhile(
        getShell().getDisplay(),
        new Runnable() {
          public void run() {
            getMatchingResources(resources);
            IResource resourcesArray[] = new IResource[resources.size()];
            resources.toArray(resourcesArray);
            initDescriptors(resourcesArray);
          }
        });

    updateGatherThread.firstMatch = 0;
    updateGatherThread.lastMatch = descriptorsSize - 1;
    updateGatherThread.start();
  }

  /**
   * Return an image for a resource descriptor.
   *
   * @param desc resource descriptor to return image for
   * @return an image for a resource descriptor.
   */
  private Image getImage(ResourceDescriptor desc) {
    IResource r = (IResource) desc.resources.get(0);
    return labelProvider.getImage(r);
  }

  /**
   * Use a binary search to get the last match for the patternString. This method assumes the
   * patternString does not contain any '?' characters and that it contains only one '*' character
   * at the end of the string.
   */
  private int getLastMatch() {
    int high = descriptorsSize;
    int low = -1;
    boolean match = false;
    ResourceDescriptor desc = new ResourceDescriptor();
    desc.label = patternString.substring(0, patternString.length() - 1);
    while (high - low > 1) {
      int index = (high + low) / 2;
      String label = descriptors[index].label;
      if (match(label)) {
        low = index;
        match = true;
      } else {
        int compare = descriptors[index].compareTo(desc);
        if (compare == -1) {
          low = index;
        } else {
          high = index;
        }
      }
    }
    if (match) {
      return low;
    }
    return -1;
  }

  /**
   * Gather the resources of the specified type that match the current pattern string. Gather the
   * resources using the proxy visitor since this is quicker than getting the entire resource.
   *
   * @param resources resources that match
   */
  private void getMatchingResources(final ArrayList resources) {
    try {
      container.accept(
          new IResourceProxyVisitor() {
            public boolean visit(IResourceProxy proxy) {
              // optionally exclude derived resources (bugs 38085 and 81333)
              if (!getShowDerived() && proxy.isDerived()) {
                return false;
              }
              int type = proxy.getType();
              if ((typeMask & type) != 0) {
                if (match(proxy.getName())) {
                  IResource res = proxy.requestResource();
                  if (select(res)) {
                    resources.add(res);
                    return true;
                  }
                  return false;
                }
              }
              if (type == IResource.FILE) {
                return false;
              }
              return true;
            }
          },
          IResource.NONE);
    } catch (CoreException e) {
      // ignore
    }
  }

  private Image getParentImage(IResource resource) {
    IResource parent = resource.getParent();
    return labelProvider.getImage(parent);
  }

  private String getParentLabel(IResource resource) {
    IResource parent = resource.getParent();
    String text;
    if (parent.getType() == IResource.ROOT) {
      // Get readable name for workspace root ("Workspace"), without duplicating language-specific
      // string here.
      text = labelProvider.getText(parent);
    } else {
      text = parent.getFullPath().makeRelative().toString();
    }
    if (text == null) {
      return ""; //$NON-NLS-1$
    }
    return text;
  }

  /**
   * Returns whether derived resources should be shown in the list. The default is <code>false
   * </code>.
   *
   * @return <code>true</code> to show derived resources, <code>false</code> to hide them
   * @since 3.1
   */
  protected boolean getShowDerived() {
    return showDerived;
  }

  /**
   * Sets whether derived resources should be shown in the list.
   *
   * @param show <code>true</code> to show derived resources, <code>false</code> to hide them
   * @since 3.1
   */
  protected void setShowDerived(boolean show) {
    showDerived = show;
  }

  /**
   * Creates a ResourceDescriptor for each IResource, sorts them and removes the duplicated ones.
   *
   * @param resources resources to create resource descriptors for
   */
  private void initDescriptors(final IResource resources[]) {
    BusyIndicator.showWhile(
        null,
        new Runnable() {
          public void run() {
            descriptors = new ResourceDescriptor[resources.length];
            for (int i = 0; i < resources.length; i++) {
              IResource r = resources[i];
              ResourceDescriptor d = new ResourceDescriptor();
              // TDB: Should use the label provider and compare performance.
              d.label = r.getName();
              d.resources.add(r);
              descriptors[i] = d;
            }
            Arrays.sort(descriptors);
            descriptorsSize = descriptors.length;

            // Merge the resource descriptor with the same label and type.
            int index = 0;
            if (descriptorsSize < 2) {
              return;
            }
            ResourceDescriptor current = descriptors[index];
            IResource currentResource = (IResource) current.resources.get(0);
            for (int i = 1; i < descriptorsSize; i++) {
              ResourceDescriptor next = descriptors[i];
              IResource nextResource = (IResource) next.resources.get(0);
              if (nextResource.getType() == currentResource.getType()
                  && next.label.equals(current.label)) {
                current.resources.add(nextResource);
                // If we are merging resources with the same name, into a single descriptor,
                // then we must mark the descriptor unsorted so that we will sort the folder
                // names.
                // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=76496
                current.resourcesSorted = false;
              } else {
                if (current.resources.size() > 1) {
                  current.resourcesSorted = false;
                }
                descriptors[index + 1] = descriptors[i];
                index++;
                current = descriptors[index];
                currentResource = (IResource) current.resources.get(0);
              }
            }
            descriptorsSize = index + 1;
          }
        });
  }

  /**
   * Returns true if the label matches the chosen pattern.
   *
   * @param label label to match with the current pattern
   * @return true if the label matches the chosen pattern. false otherwise.
   */
  private boolean match(String label) {
    if ((patternString == null)
        || (patternString.equals(""))
        || (patternString.equals("*"))) { // $NON-NLS-1$ //$NON-NLS-2$
      return true;
    }
    return stringMatcher.match(label);
  }

  /**
   * The user has selected a resource and the dialog is closing. Set the selected resource as the
   * dialog result.
   */
  protected void okPressed() {
    TableItem items[] = folderNames.getSelection();
    if (items.length == 1) {
      ArrayList result = new ArrayList();
      result.add(items[0].getData());
      setResult(result);
    }
    super.okPressed();
  }

  /**
   * Use this method to further filter resources. As resources are gathered, if a resource matches
   * the current pattern string, this method will be called. If this method answers false, the
   * resource will not be included in the list of matches and the resource's children will NOT be
   * considered for matching.
   */
  protected boolean select(IResource resource) {
    return true;
  }

  /**
   * Refreshes the filtered list of resources. Called when the text in the pattern text entry has
   * changed.
   *
   * @param force if <code>true</code> a refresh is forced, if <code>false</code> a refresh only
   *     occurs if the pattern has changed
   * @since 3.1
   */
  protected void refresh(boolean force) {
    if (gatherResourcesDynamically) {
      gatherResources(force);
    } else {
      filterResources(force);
    }
  }

  /**
   * A new resource has been selected. Change the contents of the folder names list.
   *
   * @desc resource descriptor of the selected resource
   */
  private void updateFolders(final ResourceDescriptor desc) {
    BusyIndicator.showWhile(
        getShell().getDisplay(),
        new Runnable() {
          public void run() {
            if (!desc.resourcesSorted) {
              // sort the folder names
              Collections.sort(
                  desc.resources,
                  new Comparator() {
                    public int compare(Object o1, Object o2) {
                      String s1 = getParentLabel((IResource) o1);
                      String s2 = getParentLabel((IResource) o2);
                      return collator.compare(s1, s2);
                    }
                  });
              desc.resourcesSorted = true;
            }
            folderNames.removeAll();
            for (int i = 0; i < desc.resources.size(); i++) {
              TableItem newItem = new TableItem(folderNames, SWT.NONE);
              IResource r = (IResource) desc.resources.get(i);
              newItem.setText(getParentLabel(r));
              newItem.setImage(getParentImage(r));
              newItem.setData(r);
            }
            folderNames.setSelection(0);
          }
        });
  }

  /**
   * Update the specified item with the new info from the resource descriptor. Create a new table
   * item if there is no item.
   *
   * @param index index of the resource descriptor
   * @param itemPos position of the existing item to update
   * @param itemCount number of items in the resources table widget
   */
  private void updateItem(int index, int itemPos, int itemCount) {
    ResourceDescriptor desc = descriptors[index];
    TableItem item;
    if (itemPos < itemCount) {
      item = resourceNames.getItem(itemPos);
      if (item.getData() != desc) {
        item.setText(desc.label);
        item.setData(desc);
        item.setImage(getImage(desc));
        if (itemPos == 0) {
          resourceNames.setSelection(0);
          updateFolders(desc);
        }
      }
    } else {
      item = new TableItem(resourceNames, SWT.NONE);
      item.setText(desc.label);
      item.setData(desc);
      item.setImage(getImage(desc));
      if (itemPos == 0) {
        resourceNames.setSelection(0);
        updateFolders(desc);
      }
    }
    updateOKState(true);
  }

  /**
   * Update the enabled state of the OK button. To be called when the resource list is updated.
   *
   * @param state the new enabled state of the button
   */
  protected void updateOKState(boolean state) {
    Button okButton = getButton(IDialogConstants.OK_ID);
    if (okButton != null && !okButton.isDisposed() && state != okEnabled) {
      okButton.setEnabled(state);
      okEnabled = state;
    }
  }

  /* (non-Javadoc)
   * @see org.eclipse.jface.window.Dialog#getDialogBoundsSettings()
   *
   * @since 3.2
   */
  protected IDialogSettings getDialogBoundsSettings() {
    IDialogSettings settings = IDEWorkbenchPlugin.getDefault().getDialogSettings();
    IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION);
    if (section == null) {
      section = settings.addNewSection(DIALOG_SETTINGS_SECTION);
    }
    return section;
  }
}
 @Override
 public int compare(MappingUiDefinition def1, MappingUiDefinition def2) {
   return Collator.getInstance().compare(def1.getLabel(), def2.getLabel());
 }
  private void createContentsForFormattingGroup(Composite parent) {
    Group formattingGroup = createGroup(parent, 2);
    formattingGroup.setText(HTMLUIMessages.Formatting_UI_);

    createLabel(formattingGroup, HTMLUIMessages.Line_width__UI_);
    fLineWidthText = new Text(formattingGroup, SWT.SINGLE | SWT.BORDER);
    GridData gData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.BEGINNING);
    gData.widthHint = 25;
    fLineWidthText.setLayoutData(gData);
    fLineWidthText.addModifyListener(this);

    fSplitMultiAttrs = createCheckBox(formattingGroup, HTMLUIMessages.Split_multiple_attributes);
    ((GridData) fSplitMultiAttrs.getLayoutData()).horizontalSpan = 2;
    fAlignEndBracket = createCheckBox(formattingGroup, HTMLUIMessages.Align_final_bracket);
    ((GridData) fAlignEndBracket.getLayoutData()).horizontalSpan = 2;
    fClearAllBlankLines = createCheckBox(formattingGroup, HTMLUIMessages.Clear_all_blank_lines_UI_);
    ((GridData) fClearAllBlankLines.getLayoutData()).horizontalSpan = 2;

    // [269224] - Place the indent controls in their own composite for proper tab ordering
    Composite indentComposite = createComposite(formattingGroup, 1);
    ((GridData) indentComposite.getLayoutData()).horizontalSpan = 2;
    ((GridLayout) indentComposite.getLayout()).marginWidth = 0;
    ((GridLayout) indentComposite.getLayout()).marginHeight = 0;

    fIndentUsingTabs = createRadioButton(indentComposite, HTMLUIMessages.Indent_using_tabs);
    ((GridData) fIndentUsingTabs.getLayoutData()).horizontalSpan = 1;

    fIndentUsingSpaces = createRadioButton(indentComposite, HTMLUIMessages.Indent_using_spaces);
    ((GridData) fIndentUsingSpaces.getLayoutData()).horizontalSpan = 1;

    createLabel(formattingGroup, HTMLUIMessages.Indentation_size);
    fIndentationSize = new Spinner(formattingGroup, SWT.BORDER);
    GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
    fIndentationSize.setLayoutData(gd);
    fIndentationSize.setToolTipText(HTMLUIMessages.Indentation_size_tip);
    fIndentationSize.setMinimum(MIN_INDENTATION_SIZE);
    fIndentationSize.setMaximum(MAX_INDENTATION_SIZE);
    fIndentationSize.setIncrement(1);
    fIndentationSize.setPageIncrement(4);
    fIndentationSize.addModifyListener(this);

    GridData data;

    Composite inlineGroup = new Composite(formattingGroup, SWT.NONE);
    GridLayout layout = new GridLayout();
    layout.numColumns = 2;
    layout.marginWidth = 0;
    layout.marginHeight = 0;
    inlineGroup.setLayout(layout);

    data = new GridData(GridData.FILL_BOTH);
    data.horizontalSpan = 2;
    inlineGroup.setLayoutData(data);

    Label label = createLabel(inlineGroup, HTMLUIMessages.Inline_elements_table_label);
    data = new GridData(GridData.FILL_HORIZONTAL);
    data.horizontalSpan = 2;
    label.setLayoutData(data);

    final TableViewer viewer =
        new TableViewer(
            inlineGroup, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION);
    data = new GridData(GridData.FILL_HORIZONTAL);
    data.horizontalSpan = 1;
    data.verticalAlignment = SWT.BEGINNING;
    data.heightHint = convertHeightInCharsToPixels(10);
    viewer.getTable().setLayoutData(data);

    Composite buttonContainer = new Composite(inlineGroup, SWT.NONE);
    data = new GridData(GridData.FILL_VERTICAL);
    buttonContainer.setLayoutData(data);
    layout = new GridLayout();
    layout.numColumns = 1;
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    buttonContainer.setLayout(layout);

    fAddButton = new Button(buttonContainer, SWT.PUSH);
    fAddButton.setText(HTMLUIMessages.Add_inline);
    fAddButton.addSelectionListener(
        new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            HTMLElementDialog dialog = new HTMLElementDialog(getShell());
            dialog.setMessage(HTMLUIMessages.Elements_Dialog_message);
            dialog.setTitle(HTMLUIMessages.Elements_Dialog_title);
            dialog.setMultipleSelection(true);
            dialog.setAllowDuplicates(false);
            dialog.open();
            Object[] result = dialog.getResult();
            if (result != null) {
              for (int i = 0; i < result.length; i++) {
                fContentProvider.addElement(result[i].toString());
              }
              fViewer.refresh();
            }
          }
        });
    data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
    int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
    data.widthHint = Math.max(widthHint, fAddButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
    data.horizontalSpan = 1;
    fAddButton.setLayoutData(data);

    fRemoveButton = new Button(buttonContainer, SWT.PUSH);
    fRemoveButton.setText(HTMLUIMessages.Remove_inline);
    fRemoveButton.addSelectionListener(
        new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            ISelection selection = viewer.getSelection();
            if (selection != null
                && !selection.isEmpty()
                && selection instanceof StructuredSelection) {
              Object[] remove = ((StructuredSelection) selection).toArray();
              for (int i = 0; i < remove.length; i++) {
                fContentProvider.removeElement(remove[i].toString());
              }
              if (remove.length > 0) {
                fViewer.refresh();
              }
            }
          }
        });
    data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
    data.horizontalSpan = 1;
    fRemoveButton.setLayoutData(data);

    fViewer = viewer;
    fContentProvider = new ContentProvider();
    viewer.setContentProvider(fContentProvider);
    viewer.setInput(this);
    viewer.setComparator(new ViewerComparator(Collator.getInstance()));
  }