/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/search/basic/OrderBy.java,v 1.8.2.2 2004/02/05 16:05:10 mholz Exp $
* $Revision: 1.8.2.2 $
* $Date: 2004/02/05 16:05:10 $
*
* ====================================================================
*
* Copyright 1999-2002 The Apache Software Foundation
*
* Licensed 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.slide.search.basic;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.apache.slide.common.PropertyName;
import org.apache.slide.search.CompareHint;
import org.apache.slide.search.InvalidQueryException;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jdom.Namespace;
/**
* Encapsulate an OrderBy expression. Also supplies a Comparator according
* to the specified parameters in the OrderBy expression,
*
* @author <a href="mailto:martin.wallmer@softwareag.com">Martin Wallmer</a>
* @version $Revision: 1.8.2.2 $
*/
public class OrderBy {
/** the comparator according to this expression */
private Comparator theComparator = new _Comparator ();
/** all orderby elements of this expression */
protected List orderByElements = new ArrayList ();
/**
* initializes an OrderBy.
*
* @param orderByElement the JDOM element containing the
* orderBy expression
*/
public void init (Element orderByElement) throws InvalidQueryException {
Namespace nameSpace = orderByElement.getNamespace ();
Iterator it =
orderByElement.getChildren (Literals.ORDER, nameSpace).iterator();
while (it.hasNext()) {
Element order = (Element) it.next();
PropertyName p = getProperty (order);
boolean isAscending = isAscending (order);
boolean isCaseSensitive = isCaseSensitive (order);
orderByElements.add
(createCompareHint (p, isAscending, isCaseSensitive));
}
}
protected CompareHint createCompareHint (PropertyName prop,
boolean isAscending,
boolean isCaseSensitive) {
return new CompareHint (prop, isAscending, isCaseSensitive) ;
}
/**
* Method getComparator
*
* @return the comparator according to the OrderBy expression
*
*/
public Comparator getComparator () {
return theComparator;
}
/**
* Method isCaseSensitive
*
* @param order an order Element
*
* @return true if this order element shall regard case
*
*/
private boolean isCaseSensitive (Element order) {
boolean result = true;
Attribute caseSens =
order.getAttribute (Literals.CASESENSITIVE, order.getNamespace());
if (caseSens != null) {
try {
result = caseSens.getBooleanValue();
}
catch (org.jdom.DataConversionException e) {
e.printStackTrace();
}
}
return result;
}
/**
* Method isAscending
*
* @param order an Element
*
* @return a boolean
*
* @throws InvalidQueryException if ascending and descending is supplied
*
*/
private boolean isAscending (Element order) throws InvalidQueryException {
Element asc = order.getChild (Literals.ASCENDING, order.getNamespace());
Element desc = order.getChild (Literals.DESCENDING, order.getNamespace());
boolean result = true;
if (asc != null && desc != null)
throw new InvalidQueryException ("either ascending or descending may be supplied");
if (desc != null)
result = false;
return result;
}
/**
* Method getPropName
*
* @param order an Element
*
* @return a String
*
* @throws InvalidQueryException
*
*/
private PropertyName getProperty (Element orderElem) throws InvalidQueryException {
List propList =
orderElem.getChild (Literals.PROP, orderElem.getNamespace()).getChildren();
if (propList.size() != 1)
throw new InvalidQueryException
("Expected exactly 1 prop element, found " + propList.size());
Element propElem = (Element)propList.get(0);
return createProperty (propElem);
}
/**
* Method createProperty
*
* @param propElem an Element
*
* @return a _Property
*
*/
protected PropertyName createProperty (Element propElem) throws InvalidQueryException {
String name = propElem.getName();
String nameSpace = propElem.getNamespace().getURI();
return new PropertyName (name, nameSpace);
}
/**
* a comparator that sorts according to the OrderBy element
*/
private class _Comparator implements Comparator {
/**
* Compares two ComparableResources. Two resources are equal, if they
* have the same URI. Each <order> element within <orderby> generates
* a CompareHint object containing the property to compare and ascending
* / descending. If the two resources are not equal, they are compared
* according the first CompareHint. If this one returns "equal" (0),
* they are compared according the next CompareHint and so on. If the
* two resources are equal according all CompareHints, the first one is
* considered to be greater than the second.
*
* @param o1 an Object
* @param o2 an Object
*
* @return an int
*
*/
public int compare(Object o1, Object o2) {
ComparableResource r1 = (ComparableResource)o1;
ComparableResource r2 = (ComparableResource)o2;
int result = 0;
if (r1.getInternalHref().equals (r2.getInternalHref())) {
result = 0;
}
else {
Iterator it = orderByElements.iterator();
while (it.hasNext() && result == 0) {
CompareHint obe = (CompareHint)it.next();
result = r1.compareTo (r2, obe);
}
if (result == 0)
result = 1;
}
return result;
}
}
}