All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.marklogic.client.impl.NamespacesManagerImpl Maven / Gradle / Ivy

/*
 * Copyright 2012-2016 MarkLogic Corporation
 *
 * 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 com.marklogic.client.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.marklogic.client.util.EditableNamespaceContext;
import com.marklogic.client.FailedRequestException;
import com.marklogic.client.ForbiddenUserException;
import com.marklogic.client.MarkLogicInternalException;
import com.marklogic.client.admin.NamespacesManager;
import com.marklogic.client.ResourceNotFoundException;

class NamespacesManagerImpl
    extends AbstractLoggingManager
    implements NamespacesManager
{
	static final private Logger logger = LoggerFactory.getLogger(NamespacesManagerImpl.class);

	static final private Pattern NAMESPACE_PATTERN = Pattern.compile(
		"<([^: >]+:)?uri(\\s[^>]+)?>([^<>]+)]+:)?uri>"
		);

	private RESTServices services;

	NamespacesManagerImpl(RESTServices services) {
		super();
		this.services = services;
	}

	@Override
	public String readPrefix(String prefix) throws ForbiddenUserException, FailedRequestException {
		if (prefix == null)
			throw new IllegalArgumentException("Cannot read namespace for null prefix");
		if (prefix.length() == 0)
			throw new IllegalArgumentException("Server does not maintain a default namespace");

		String binding = services.getValue(
				requestLogger, "config/namespaces", prefix, true, "application/xml", String.class);
		if (binding == null)
			return null;

		Matcher matcher = NAMESPACE_PATTERN.matcher(binding);
		if (!matcher.find()) {
			if (logger.isWarnEnabled())
				logger.warn("Failed to extract namespace from {}", binding);
			return null;
		}

		return matcher.toMatchResult().group(3);
	}
	@Override
	public NamespaceContext readAll() throws ForbiddenUserException, FailedRequestException {
		EditableNamespaceContext context = new EditableNamespaceContext();

		try {
			InputStream stream = services.getValues(requestLogger, "config/namespaces", "application/xml", InputStream.class);
			if (stream == null)
				return null;

			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			factory.setNamespaceAware(true);
			factory.setValidating(false);

			Document document = factory.newDocumentBuilder().parse(stream);
			NodeList bindings =
				document.getElementsByTagNameNS("http://marklogic.com/rest-api", "namespace");
			if (bindings == null)
				return null;
	
			int bindingsCount = bindings.getLength();
			if (bindingsCount < 1)
				return null;

			for (int i=0; i < bindingsCount; i++) {
				Node binding = bindings.item(i);

				NodeList children = binding.getChildNodes();
				if (children == null)
					continue;

				String prefix = null;
				String namespaceUri = null;
				for (int j=0; j < children.getLength(); j++) {
					Node child = children.item(j);
					if (child.getNodeType() != Node.ELEMENT_NODE)
						continue;

					Element element = (Element) child;
					if ("prefix".equals(element.getLocalName()))
						prefix = element.getTextContent();
					else if ("uri".equals(element.getLocalName()))
						namespaceUri = element.getTextContent();
				}
				if (prefix == null || namespaceUri == null)
					continue;

				context.put(prefix, namespaceUri);
			}
		} catch (SAXException e) {
			logger.error("Failed to parse DOM document for namespace bindings",e);
			throw new MarkLogicInternalException(e);
		} catch (IOException e) {
			logger.error("Failed to parse DOM document for namespace bindings",e);
			throw new MarkLogicInternalException(e);
		} catch (ParserConfigurationException e) {
			logger.error("Failed to parse DOM document for namespace bindings",e);
			throw new MarkLogicInternalException(e);
		}

		return context;
	}
	@Override
	public void addPrefix(String prefix, String namespaceUri) throws ForbiddenUserException, FailedRequestException {
		if (prefix == null)
			throw new IllegalArgumentException("Cannot write binding for null prefix");
		if (prefix.length() == 0)
			throw new IllegalArgumentException("Cannot specify a default namespace");
		if (namespaceUri == null)
			throw new IllegalArgumentException("Cannot write binding for null namespaceUri");

		String structure =
			"\n"+
			"" +
			"\n"+
			"    "+prefix+"\n"+
			"    "+namespaceUri+"\n"+
			"\n"+
			"";

		services.postValue(requestLogger, "config/namespaces", prefix, "application/xml", structure);
	}
	@Override
	public void updatePrefix(String prefix, String namespaceUri) throws ResourceNotFoundException, ForbiddenUserException, FailedRequestException {
		if (prefix == null)
			throw new IllegalArgumentException("Cannot write binding for null prefix");
		if (prefix.length() == 0)
			throw new IllegalArgumentException("Cannot specify a default namespace");
		if (namespaceUri == null)
			throw new IllegalArgumentException("Cannot write binding for null namespaceUri");

		String structure =
			"\n"+
			"\n"+
			"    "+prefix+"\n"+
			"    "+namespaceUri+"\n"+
			"\n";

		services.putValue(requestLogger, "config/namespaces", prefix, "application/xml", structure);
	}
	@Override
	public void deletePrefix(String prefix) throws ResourceNotFoundException, ForbiddenUserException, FailedRequestException {
		if (prefix == null)
			throw new IllegalArgumentException("Cannot delete binding for null prefix");
		if (prefix.length() == 0)
			throw new IllegalArgumentException("Server does not maintain a default namespace");

		services.deleteValue(requestLogger, "config/namespaces", prefix);
	}
	@Override
	public void deleteAll() throws ForbiddenUserException, FailedRequestException {
		services.deleteValues(requestLogger, "config/namespaces");
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy