org.apache.jackrabbit.webdav.ordering.Position Maven / Gradle / Ivy
/*
* 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.jackrabbit.webdav.ordering;
import org.apache.jackrabbit.webdav.xml.DomUtil;
import org.apache.jackrabbit.webdav.xml.ElementIterator;
import org.apache.jackrabbit.webdav.xml.XmlSerializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.util.HashSet;
import java.util.Set;
/**
* Position
encapsulates the position in ordering information
* contained in a Webdav request. This includes both the
* {@link OrderingConstants#HEADER_POSITION Position header} and the position
* Xml element present in the request body of an ORDERPATCH request.
*
* @see OrderingConstants#HEADER_POSITION
* @see OrderingConstants#XML_POSITION
* @see OrderPatch
*/
public class Position implements OrderingConstants, XmlSerializable {
private static Logger log = LoggerFactory.getLogger(Position.class);
private static final Set VALID_TYPES = new HashSet();
static {
VALID_TYPES.add(XML_FIRST);
VALID_TYPES.add(XML_LAST);
VALID_TYPES.add(XML_AFTER);
VALID_TYPES.add(XML_BEFORE);
}
private final String type;
private final String segment;
/**
* Create a new Position
object with the specified type.
* Since any type except for {@link #XML_FIRST first} and {@link #XML_LAST last}
* must be combined with a segment, only the mentioned types are valid
* arguments.
*
* @param type {@link #XML_FIRST first} or {@link #XML_LAST last}
* @throws IllegalArgumentException if the given type is other than {@link #XML_FIRST}
* or {@link #XML_LAST}.
*/
public Position(String type) {
if (!VALID_TYPES.contains(type)) {
throw new IllegalArgumentException("Invalid type: " + type);
}
if (!(XML_FIRST.equals(type) || XML_LAST.equals(type))) {
throw new IllegalArgumentException("If type is other than 'first' or 'last' a segment must be specified");
}
this.type = type;
this.segment = null;
}
/**
* Create a new Position
object with the specified type and
* segment.
*
* @param type
* @param segment
* @throws IllegalArgumentException if the specified type and segment do not
* form a valid pair.
*/
public Position(String type, String segment) {
if (!VALID_TYPES.contains(type)) {
throw new IllegalArgumentException("Invalid type: " + type);
}
if ((XML_AFTER.equals(type) || XML_BEFORE.equals(type)) && (segment == null || "".equals(segment))) {
throw new IllegalArgumentException("If type is other than 'first' or 'last' a segment must be specified");
}
this.type = type;
this.segment = segment;
}
/**
* Return the type of this Position
object, which may be any
* of the following valid types: {@link #XML_FIRST first},
* {@link #XML_LAST last}, {@link #XML_AFTER after}, {@link #XML_BEFORE before}
*
* @return type
*/
public String getType() {
return type;
}
/**
* Returns the segment used to create this Position
object or
* null
if no segment is present with the type.
*
* @return segment or null
* @see #getType()
*/
public String getSegment() {
return segment;
}
//------------------------------------------< XmlSerializable interface >---
/**
* @see org.apache.jackrabbit.webdav.xml.XmlSerializable#toXml(Document)
* @param document
*/
public Element toXml(Document document) {
Element positionElement = DomUtil.createElement(document, XML_POSITION, NAMESPACE);
Element typeElement = DomUtil.addChildElement(positionElement, type, NAMESPACE);
if (segment != null) {
DomUtil.addChildElement(typeElement, XML_SEGMENT, NAMESPACE, segment);
}
return positionElement;
}
//-----------------------------------------------------< static methods >---
/**
* Create a new Position
object from the specified position
* element. The element must fulfill the following structure:
*
* <!ELEMENT position (first | last | before | after) >
* <!ELEMENT segment (#PCDATA) >
* <!ELEMENT first EMPTY >
* <!ELEMENT last EMPTY >
* <!ELEMENT before segment >
* <!ELEMENT after segment >
*
*
* @param positionElement Xml element defining the position.
* @throws IllegalArgumentException if the given Xml element is not valid.
*/
public static Position createFromXml(Element positionElement) {
if (!DomUtil.matches(positionElement, XML_POSITION, NAMESPACE)) {
throw new IllegalArgumentException("The 'DAV:position' element required.");
}
ElementIterator it = DomUtil.getChildren(positionElement);
if (it.hasNext()) {
Element el = it.nextElement();
String type = el.getLocalName();
// read the text of DAV:segment child element inside the type
String segmentText = DomUtil.getChildText(el, XML_SEGMENT, NAMESPACE);
// stop after the first iteration
return new Position(type, segmentText);
} else {
throw new IllegalArgumentException("The 'DAV:position' element required with exact one child indicating the type.");
}
}
}