org.xchain.framework.util.JXPathContextUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.xchain.framework.util.JXPathContextUtil.java

Source

/**
 *    Copyright 2011 meltmedia
 *
 *    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.xchain.framework.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.namespace.QName;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.regex.PatternSyntaxException;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.JXPathException;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;

/**
 * Utility class for JXPathContext related methods.
 *
 * @author Christian Trimble
 * @author Devon Tackett
 * @author Josh Kennedy
 */
public class JXPathContextUtil {
    public static Logger log = LoggerFactory.getLogger(JXPathContextUtil.class);

    /** A regex pattern the matches qNames of the form '{uri}local-name' */
    public static Pattern uriLocalNamePattern;
    /** A regex pattern that matches qNames of the form 'prefix:local-name' */
    public static Pattern prefixLocalNamePattern;
    /** A regex pattern that matches qNames of the form 'local-name' */
    public static Pattern localNamePattern;

    static {
        try {
            uriLocalNamePattern = Pattern.compile("\\{([^{]*)\\}(.+)");
            prefixLocalNamePattern = Pattern.compile("([^:]*):([^:]+)");
            localNamePattern = Pattern.compile("([^:]+)");
        } catch (PatternSyntaxException pse) {
            if (log.isErrorEnabled()) {
                log.error("Could not compile a qName pattern.", pse);
            }
        }
    }

    /**
     * Converts a string to a qName based on the mappings in the context object.
     */
    public static QName stringToQName(JXPathContext context, String value) {
        Matcher matcher = uriLocalNamePattern.matcher(value);
        if (matcher.matches()) {
            String uri = matcher.group(1);
            String localName = matcher.group(2);
            return new QName(uri, localName);
        }

        matcher = prefixLocalNamePattern.matcher(value);
        if (matcher.matches()) {
            String prefix = matcher.group(1);
            String localName = matcher.group(2);

            // get the uri for the prefix.
            String uri = context.getNamespaceURI(prefix);

            if (uri != null) {
                return new QName(uri, localName);
            } else {
                throw new RuntimeException("Could not find uri for prefix '" + prefix + "'.");
            }
        }

        matcher = localNamePattern.matcher(value);
        if (matcher.matches()) {
            return new QName(matcher.group(1));
        }

        throw new RuntimeException("Could not parse the qName '" + value + "'.");
    }

    public static String stringToQNameString(JXPathContext context, String value) {
        return stringToQName(context, value).toString();
    }

    /**
     * <p>A conversion utility that will properly convert enumeration types.  All other conversion are done with
     * org.apache.commons.beanutils.ConvertUtils.convert( Object, Class ).</p>
     *
     * @param value the value to convert.
     * @param type the target type for the value.
     * @return the converted type.
     */
    public static Object convert(Object value, Class type) {
        if (Enum.class.isAssignableFrom(type)) {
            //System.out.println("The type "+type+" is assignable to Enum.");
            Object result = org.apache.commons.beanutils.ConvertUtils.convert(value, type);
            if (result == null) {
                return null;
            } else if (type.isAssignableFrom(result.getClass())) {
                return result;
            } else {
                return Enum.valueOf(type, result.toString());
            }
        } else {
            //System.out.println("The type "+type+" is not assignable to Enum.");
            return org.apache.commons.beanutils.ConvertUtils.convert(value, type);
        }
    }

    public static void validate(String value, NamespaceContext namespaceContext) {
        Matcher matcher = uriLocalNamePattern.matcher(value);
        if (matcher.matches()) {
            // this is valid, so return.
            return;
        }

        matcher = prefixLocalNamePattern.matcher(value);
        if (matcher.matches()) {
            String prefix = matcher.group(1);

            if (prefix != null && !XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)
                    && XMLConstants.NULL_NS_URI.equals(namespaceContext.getNamespaceURI(prefix))) {
                throw new JXPathException(
                        "There is not namespace mapping for the prefix of qname '" + value + "'.");
            }
            return;
        }

        matcher = localNamePattern.matcher(value);
        if (matcher.matches()) {
            return;
        }

        throw new JXPathException("There is a syntax error in the qname '" + value + "'.");
    }
}