/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.isis.core.metamodel.layout.memberorderfacet; import java.util.Comparator; import java.util.StringTokenizer; import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet; public class MemberOrderFacetComparator implements Comparator<MemberOrderFacet> { private boolean ensureInSameGroup; public MemberOrderFacetComparator(boolean ensureInSameGroup) { this.ensureInSameGroup = ensureInSameGroup; } @Override public int compare(final MemberOrderFacet m1, final MemberOrderFacet m2) { if (m1 == null && m2 == null) { return 0; } if (m1 == null && m2 != null) { return +1; // annotated before non-annotated } if (m1 != null && m2 == null) { return -1; // annotated before non-annotated } if (ensureInSameGroup && !m1.name().equals(m2.name())) { throw new IllegalArgumentException("Not in same group"); } final String sequence1 = m1.sequence(); final String sequence2 = m2.sequence(); final String[] components1 = componentsFor(sequence1); final String[] components2 = componentsFor(sequence2); final int length1 = components1.length; final int length2 = components2.length; // shouldn't happen but just in case. if (length1 == 0 && length2 == 0) { return 0; } // continue to loop until we run out of components. int n = 0; while (true) { final int length = n + 1; // check if run out of components in either side if (length1 < length && length2 >= length) { return -1; // o1 before o2 } if (length2 < length && length1 >= length) { return +1; // o2 before o1 } if (length1 < length && length2 < length) { // run out of components return 0; } // we have this component on each side int componentCompare = 0; try { final Integer c1 = Integer.valueOf(components1[n]); final Integer c2 = Integer.valueOf(components2[n]); componentCompare = c1.compareTo(c2); } catch (final NumberFormatException nfe) { // not integers compare as strings componentCompare = components1[n].compareTo(components2[n]); } if (componentCompare != 0) { return componentCompare; } // this component is the same; lets look at the next n++; } } private static String[] componentsFor(final String sequence) { final StringTokenizer tokens = new StringTokenizer(sequence, ".", false); final String[] components = new String[tokens.countTokens()]; for (int i = 0; tokens.hasMoreTokens(); i++) { components[i] = tokens.nextToken(); } return components; } }