/******************************************************************************* * Copyright (c) 2012 VMware, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMware, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.metadata.ui; import java.util.Comparator; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.springframework.util.AntPathMatcher; /** * @author Leo Dos Santos */ public class RequestMappingViewSorter extends ViewerSorter { private RequestMappingViewLabelProvider labelProvider; private AntPathMatcher matcher; private int sortColumn; private int sortDirection; public RequestMappingViewSorter( RequestMappingViewLabelProvider labelProvider) { matcher = new AntPathMatcher(); this.labelProvider = labelProvider; } @Override public int compare(Viewer viewer, Object e1, Object e2) { int result = compareColumn(viewer, e1, e2); if (sortDirection == SWT.UP) { return result; } return result * -1; } public void setSortColumn(int column) { sortColumn = column; } public void setSortDirection(int direction) { sortDirection = direction; } private int compareColumn(Viewer viewer, Object e1, Object e2) { if (sortColumn == RequestMappingView.COLUMN_URL) { return sortByUrl(e1, e2); } else if (sortColumn == RequestMappingView.COLUMN_REQUEST_METHOD) { int result = sortByRequestMethod(e1, e2); if (result == 0) { result = sortByHandlerMethod(e1, e2); } return result; } else if (sortColumn == RequestMappingView.COLUMN_HANDLER_METHOD) { return sortByHandlerMethod(e1, e2); } return 0; } private int sortByHandlerMethod(Object e1, Object e2) { String str1 = labelProvider.getColumnText(e1, RequestMappingView.COLUMN_HANDLER_METHOD); String str2 = labelProvider.getColumnText(e2, RequestMappingView.COLUMN_HANDLER_METHOD); return str1.compareTo(str2); } private int sortByRequestMethod(Object e1, Object e2) { String str1 = labelProvider.getColumnText(e1, RequestMappingView.COLUMN_REQUEST_METHOD); String str2 = labelProvider.getColumnText(e2, RequestMappingView.COLUMN_REQUEST_METHOD); return str1.compareTo(str2); } private int sortByUrl(Object e1, Object e2) { String str1 = labelProvider.getColumnText(e1, RequestMappingView.COLUMN_URL); String str2 = labelProvider.getColumnText(e2, RequestMappingView.COLUMN_URL); String prefix = getCommonPrefix(str1, str2); str1 = str1.substring(prefix.length(), str1.length()); str2 = str2.substring(prefix.length(), str2.length()); // workaround for a bug in AntPathMatcher, dealing with a path that starts with a "*" if (str1.startsWith("*")) { str1 = "/" + str1; } if (str2.startsWith("*")) { str2 = "/" + str2; } Comparator<String> comparator = matcher.getPatternComparator(prefix); if (prefix.length() > 1 && (matcher.isPattern(str1) || str1.contains("{") //$NON-NLS-1$ || matcher.isPattern(str2) || str2.contains("{"))) { //$NON-NLS-1$ return comparator.compare(str1, str2); } else { int strResult = str1.compareTo(str2); if (strResult == 0) { // If urls are equal, sort by method name strResult = sortByHandlerMethod(e1, e2); } return strResult; } } private String getCommonPrefix(String str1, String str2) { if (str1.equals(str2)) { return str1; } String prefix = ""; //$NON-NLS-1$ int i = 0; while (i < str1.length() && i < str2.length()) { String s = str1.substring(i, i + 1); if (s.equals(str2.substring(i, i + 1))) { prefix = prefix.concat(s); i++; } else { break; } } return prefix; } }