/** * Copyright 2010 JBoss Inc * * 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.eclipse.webdav.dom; import java.util.Enumeration; import java.util.NoSuchElementException; import org.eclipse.webdav.Policy; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * An element editor for sets of hrefs, for example, the WebDAV * predecessor-set element. * <p> * <b>Note:</b> This class/interface is part of an interim API that is still under * development and expected to change significantly before reaching stability. * It is being made available at this early stage to solicit feedback from pioneering * adopters on the understanding that any code that uses this API will almost * certainly be broken (repeatedly) as the API evolves. * </p> */ public class HrefSet extends ElementEditor { /** * Creates a new editor on the given href set element with the given * name. The element is assumed to be well formed. * * @param root an href element * @param name the name of the element that this editor is expected * to manipulate. * @throws MalformedElementException if there is reason to * believe that the element is not well formed */ public HrefSet(Element root, QualifiedName name) throws MalformedElementException { super(root, name.getLocalName()); ensure(DAV_NS.equals(name.getQualifier()), Policy.bind("ensure.mustHaveDAVQualifier")); //$NON-NLS-1$ } /** * Adds the given href to the end of the set of hrefs. If the href * already exists it is not added. * * @param href the href to add to the end of the set of hrefs */ public void addHref(String href) { String encodedHref = encodeHref(href); if (isDuplicate(encodedHref)) return; appendChild(root, "href", encodedHref); //$NON-NLS-1$ } /** * Creates a new href set element with the given name and sets it as * the root of the given document. Returns an editor on the new href set * element. The document must not be <code>null</code>, and must not * already have a root element. * * @param document the document that will become the root of a new * href set element * @return an element editor on a href set element */ public static HrefSet create(Document document, QualifiedName name) { Assert.isNotNull(document); Assert.isTrue(document.getOwnerDocument() == null); Assert.isNotNull(name); Assert.isTrue(DAV_NS.equals(name.getQualifier())); Element element = create(document, name.getLocalName()); try { return new HrefSet(element, name); } catch (MalformedElementException e) { Assert.isTrue(false, Policy.bind("assert.internalError")); //$NON-NLS-1$ return null; // Never reached. } } /** * Returns an <code>Enumeration</code> over the set of hrefs. * * @return an <code>Enumeration</code> of href <code>String</code>s */ public Enumeration getHrefs() { final Element firstHref = getFirstChild(root, "href"); //$NON-NLS-1$ Enumeration e = new Enumeration() { Element currentHref = firstHref; public boolean hasMoreElements() { return currentHref != null; } public Object nextElement() { if (!hasMoreElements()) throw new NoSuchElementException(); String href = getFirstText(currentHref); currentHref = getNextSibling(currentHref, "href"); //$NON-NLS-1$ return decodeHref(href); } }; return e; } /** * Inserts the given newHref after the given refHref in the set of * hrefs. If newHref already exists it is not inserted. * * @param refHref the existing href * @param newHref the new href to be inserted after the existing href */ public void insertHrefAfter(String refHref, String newHref) { String refHrefEncoded = encodeHref(refHref); String newHrefEncoded = encodeHref(newHref); if (isDuplicate(newHrefEncoded)) return; Element child = getFirstChild(root, "href"); //$NON-NLS-1$ while (child != null) { if (refHrefEncoded.equals(getFirstText(child))) { Element nextSibling = getNextSibling(child, "href"); //$NON-NLS-1$ if (nextSibling == null) appendChild(root, "href", newHrefEncoded); //$NON-NLS-1$ else insertBefore(nextSibling, "href", newHrefEncoded); //$NON-NLS-1$ return; } child = getNextSibling(child, "href"); //$NON-NLS-1$ } Assert.isTrue(false, Policy.bind("assert.noHrefRef")); //$NON-NLS-1$ } /** * Inserts the given newHref before the given refHref in the set of * hrefs. If newHref already exists it is not inserted. * * @param refHref the existing href * @param newHref the new href to be inserted before the existing href */ public void insertHrefBefore(String newHref, String refHref) { String refHrefEncoded = encodeHref(refHref); String newHrefEncoded = encodeHref(newHref); if (isDuplicate(newHrefEncoded)) return; Element child = getFirstChild(root, "href"); //$NON-NLS-1$ while (child != null) { if (refHrefEncoded.equals(getFirstText(child))) { insertBefore(child, "href", newHrefEncoded); //$NON-NLS-1$ return; } child = getNextSibling(child, "href"); //$NON-NLS-1$ } Assert.isTrue(false, Policy.bind("assert.noHrefRef")); //$NON-NLS-1$ } protected boolean isDuplicate(String encodedHref) { Element child = getFirstChild(root, "href"); //$NON-NLS-1$ while (child != null) { if (encodedHref.equals(getFirstText(child))) return true; child = getNextSibling(child, "href"); //$NON-NLS-1$ } return false; } /** * Remove the given href from the set of hrefs. * * @param href the href to remove from the set of hrefs */ public void removeHref(String href) { String encodedHref = encodeHref(href); Element child = getFirstChild(root, "href"); //$NON-NLS-1$ while (child != null) { if (encodedHref.equals(getFirstText(child))) { root.removeChild(child); return; } child = getNextSibling(child, "href"); //$NON-NLS-1$ } } }