org.opencastproject.util.XmlNamespaceContext Maven / Gradle / Ivy
/*
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community 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://opensource.org/licenses/ecl2.txt
*
* 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.opencastproject.util;
import static com.entwinemedia.fn.Stream.$;
import static org.opencastproject.util.EqualsUtil.eq;
import static org.opencastproject.util.data.Option.option;
import org.opencastproject.util.data.Function0;
import com.entwinemedia.fn.Fn;
import com.entwinemedia.fn.Fn2;
import com.entwinemedia.fn.Stream;
import com.entwinemedia.fn.data.Opt;
import com.entwinemedia.fn.fns.Booleans;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
public final class XmlNamespaceContext implements NamespaceContext {
// the number of default bindings
private static final int DEFAULT_BINDINGS = 2;
// prefix -> namespace URI
private final Map prefixToUri = new HashMap();
/**
* Create a new namespace context with bindings from prefix to URI and bind the
* default namespaces as described in the documentation of {@link javax.xml.namespace.NamespaceContext}.
*/
public XmlNamespaceContext(Map prefixToUri) {
this.prefixToUri.putAll(prefixToUri);
this.prefixToUri.put(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI);
this.prefixToUri.put(XMLConstants.XMLNS_ATTRIBUTE, XMLConstants.XMLNS_ATTRIBUTE_NS_URI);
}
public static XmlNamespaceContext mk(Map prefixToUri) {
return new XmlNamespaceContext(prefixToUri);
}
public static XmlNamespaceContext mk(XmlNamespaceBinding... bindings) {
return mk($(bindings));
}
public static XmlNamespaceContext mk(String prefix, String namespaceUri) {
return new XmlNamespaceContext(Collections.singletonMap(prefix, namespaceUri));
}
public static XmlNamespaceContext mk(List bindings) {
return mk($(bindings));
}
public static XmlNamespaceContext mk(Stream bindings) {
return new XmlNamespaceContext(
bindings.foldl(
new HashMap(),
new Fn2, XmlNamespaceBinding, HashMap>() {
@Override
public HashMap apply(
HashMap prefixToUri, XmlNamespaceBinding binding) {
prefixToUri.put(binding.getPrefix(), binding.getNamespaceURI());
return prefixToUri;
}
}));
}
@Override
public String getNamespaceURI(String prefix) {
return Opt.nul(prefixToUri.get(prefix)).getOr(XMLConstants.NULL_NS_URI);
}
@Override
public String getPrefix(String uri) {
return $(prefixToUri.entrySet()).find(Booleans.eq(RequireUtil.notNull(uri, "uri")).o(value)).map(key).orNull();
}
@Override
public Iterator getPrefixes(String uri) {
return $(prefixToUri.entrySet()).filter(Booleans.eq(uri).o(value)).map(key).iterator();
}
public List getBindings() {
return $(prefixToUri.entrySet()).map(toBinding).toList();
}
/** Create a new context with the given bindings added. Existing bindings will not be overwritten. */
public XmlNamespaceContext add(XmlNamespaceBinding... bindings) {
return add($(bindings));
}
/** Create a new context with the given bindings added. Existing bindings will not be overwritten. */
public XmlNamespaceContext add(XmlNamespaceContext bindings) {
if (bindings.prefixToUri.size() == DEFAULT_BINDINGS) {
// bindings contains only the default bindings
return this;
} else {
return add($(bindings.getBindings()));
}
}
private XmlNamespaceContext add(Stream bindings) {
return mk(bindings.append(getBindings()));
}
private static final Fn, String> key = new Fn, String>() {
@Override public String apply(Entry e) {
return e.getKey();
}
};
private static final Fn, String> value = new Fn, String>() {
@Override public String apply(Entry e) {
return e.getValue();
}
};
private static final Fn, XmlNamespaceBinding> toBinding = new Fn, XmlNamespaceBinding>() {
@Override public XmlNamespaceBinding apply(Entry e) {
return new XmlNamespaceBinding(e.getKey(), e.getValue());
}
};
public NamespaceContext merge(final NamespaceContext precedence) {
return merge(this, precedence);
}
/** Merge b
into a
so that b
takes precedence over a
. */
public static NamespaceContext merge(final NamespaceContext a, final NamespaceContext b) {
return new NamespaceContext() {
@Override public String getNamespaceURI(String prefix) {
final String uri = b.getNamespaceURI(prefix);
if (eq(XMLConstants.DEFAULT_NS_PREFIX, prefix) && eq(XMLConstants.NULL_NS_URI, uri)) {
return a.getNamespaceURI(prefix);
} else {
return uri;
}
}
@Override public String getPrefix(final String uri) {
return option(b.getPrefix(uri)).getOrElse(new Function0() {
@Override public String apply() {
return a.getPrefix(uri);
}
});
}
@Override public Iterator getPrefixes(String uri) {
final Iterator prefixes = b.getPrefixes(uri);
if (prefixes.hasNext()) {
return prefixes;
} else {
return a.getPrefixes(uri);
}
}
};
}
}