blob: 84dcf824961fe8aa4c1ba329adc4fcd8913e99d0 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2009, 2019 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.r.objectbrowser;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Locale;
import com.ibm.icu.text.Collator;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RReference;
import org.eclipse.statet.rj.data.RStore;
class SortByTypeComparator extends ViewerComparator implements Comparator<Object> {
private final Collator classNameCollator = Collator.getInstance(Locale.ENGLISH);
@Override
public void sort(final Viewer viewer, final Object[] elements) {
if (elements != null && elements.length > 0 && elements[0] instanceof CombinedRElement) {
final CombinedRElement parent = ((CombinedRElement) elements[0]).getModelParent();
if (parent != null && parent.getRObjectType() == RObject.TYPE_ENVIRONMENT) {
Arrays.sort(elements, this);
}
}
}
@Override
public int compare(final Object o1, final Object o2) {
return compare((CombinedRElement) o1, (CombinedRElement) o2);
}
public int compare(final CombinedRElement e1, final CombinedRElement e2) {
{ // By type
final int cat1 = category(e1);
final int cat2 = category(e2);
if (cat1 != cat2) {
return cat1 - cat2;
}
if (cat1 == RObject.TYPE_VECTOR || cat1 == RObject.TYPE_ARRAY) {
final int d1 = getDataOrder(e1.getData().getStoreType());
final int d2 = getDataOrder(e2.getData().getStoreType());
if (d1 != d2) {
return d1 - d2;
}
}
}
{ // By classname
final int diff = this.classNameCollator.compare(e1.getRClassName(), e2.getRClassName());
if (diff != 0) {
return diff;
}
}
{ // By index
final RElementName name1 = e1.getElementName();
final RElementName name2 = e2.getElementName();
if (name1 instanceof RElementName.IndexElementName
&& name2 instanceof RElementName.IndexElementName) {
// index
return ((RElementName.IndexElementName) name1).getIndex() -
((RElementName.IndexElementName) name2).getIndex();
}
}
// By name
return ObjectBrowserView.ELEMENTNAME_COMPARATOR.compare(e1, e2);
}
private int getDataOrder(final int dataType) {
switch (dataType) {
case RStore.NUMERIC:
return 1;
case RStore.COMPLEX:
return 2;
case RStore.LOGICAL:
return 3;
case RStore.INTEGER:
return 4;
case RStore.FACTOR:
return 4;
case RStore.CHARACTER:
return 5;
case RStore.RAW:
return 6;
default:
return 7;
}
}
public int category(final CombinedRElement element) {
byte objectType = element.getRObjectType();
if (objectType == RObject.TYPE_REFERENCE) {
final RObject realObject = ((RReference) element).getResolvedRObject();
if (realObject != null) {
objectType = realObject.getRObjectType();
}
}
if (objectType == RObject.TYPE_ARRAY) {
objectType = RObject.TYPE_VECTOR;
}
return objectType;
}
}