001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.xml; 029 030import org.opencms.xml.types.I_CmsXmlSchemaType; 031 032import java.util.Comparator; 033 034/** 035 * Comparator for XPaths of an XML content. 036 * Paths are sorted according to the sequence definitions in the content definition. 037 * That means the sort order corresponds to the order in which the elements 038 * are displayed in the content editor. 039 */ 040public class CmsXmlDisplayOrderPathComparator implements Comparator<String> { 041 042 /** The content definition used to determine the order of the node sequence. */ 043 private CmsXmlContentDefinition m_definition; 044 045 /** 046 * Constructs a comparator for paths that fit for the provided content definition. 047 * @param definition the content definition to sort paths for. 048 */ 049 public CmsXmlDisplayOrderPathComparator(CmsXmlContentDefinition definition) { 050 051 m_definition = definition; 052 } 053 054 /** 055 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) 056 */ 057 @Override 058 public int compare(String p1, String p2) { 059 060 int firstSlash1 = p1.indexOf('/'); 061 int firstSlash2 = p2.indexOf('/'); 062 String firstPart1 = firstSlash1 > 0 ? p1.substring(0, firstSlash1) : p1; 063 String firstPart2 = firstSlash2 > 0 ? p2.substring(0, firstSlash2) : p2; 064 if (firstPart1.equals(firstPart2)) { 065 CmsXmlDisplayOrderPathComparator subComparator = new CmsXmlDisplayOrderPathComparator( 066 m_definition.getSchemaType( 067 org.opencms.acacia.shared.CmsContentDefinition.removeIndex(firstPart1)).getContentDefinition()); 068 return subComparator.compare( 069 p1.substring(firstSlash1 + 1, p1.length()), 070 p2.substring(firstSlash2 + 1, p2.length())); 071 } 072 String firstNode1 = CmsXmlUtils.removeXpathIndex(firstPart1); 073 int idx1 = CmsXmlUtils.getXpathIndexInt(firstPart1); 074 String firstNode2 = CmsXmlUtils.removeXpathIndex(firstPart2); 075 int idx2 = CmsXmlUtils.getXpathIndexInt(firstPart2); 076 if (firstNode1.equals(firstNode2)) { 077 return idx1 - idx2; 078 } 079 for (I_CmsXmlSchemaType t : m_definition.getTypeSequence()) { 080 if (t.getName().equals(firstNode1)) { 081 return -1; 082 } 083 if (t.getName().equals(firstNode2)) { 084 return 1; 085 } 086 } 087 return 0; 088 } 089}