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

org.eclipse.persistence.internal.oxm.Context Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Blaise Doughan - 2.5 - initial implementation
package org.eclipse.persistence.internal.oxm;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import javax.xml.namespace.QName;

import org.eclipse.persistence.core.mappings.CoreMapping;
import org.eclipse.persistence.core.sessions.CoreProject;
import org.eclipse.persistence.core.sessions.CoreSession;
import org.eclipse.persistence.core.sessions.CoreSessionEventListener;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.databaseaccess.CorePlatform;
import org.eclipse.persistence.internal.core.descriptors.CoreObjectBuilder;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;

public abstract class Context<
    ABSTRACT_SESSION extends CoreAbstractSession,
    DESCRIPTOR extends Descriptor,
    FIELD extends Field,
    NAMESPACE_RESOLVER extends NamespaceResolver,
    PROJECT extends CoreProject,
    SESSION extends CoreSession,
    SESSION_EVENT_LISTENER extends CoreSessionEventListener> {

    public static class ContextState<
        ABSTRACT_SESSION extends CoreAbstractSession,
        DESCRIPTOR extends Descriptor,
        PROJECT extends CoreProject,
        SESSION extends CoreSession,
        SESSION_EVENT_LISTENER extends CoreSessionEventListener> {

        protected Context context;
        protected Map descriptorsByQName;
        protected Map descriptorsByGlobalType;
        protected SESSION session;
        private Collection sessionEventListeners;

        protected ContextState() {
            descriptorsByQName = new HashMap<>();
            descriptorsByGlobalType = new HashMap<>();
        }

        protected ContextState(Context context, PROJECT project, ClassLoader classLoader, Collection sessionEventListeners) {
            this();
            this.context = context;
            preLogin(project, classLoader);
            session = (SESSION) project.createDatabaseSession();

            // if an event listener was passed in as a parameter, register it with the event manager
            if (sessionEventListeners != null) {
                for(SESSION_EVENT_LISTENER sessionEventListener : sessionEventListeners) {
                    session.getEventManager().addListener(sessionEventListener);
                }
            }

            setupSession(session);
            storeDescriptorsByQName(session);
        }

        public void addDescriptorByQName(QName qName, DESCRIPTOR descriptor) {
            XPathQName xpathQName = new XPathQName(qName, true);
            addDescriptorByQName(xpathQName, descriptor);
        }

        private void addDescriptorByQName(XPathQName qName, DESCRIPTOR descriptor) {
            descriptorsByQName.put(qName, descriptor);
        }

        protected void preLogin(PROJECT project, ClassLoader classLoader) {
        }

        /**
         * INTERNAL: Return the Descriptor with the default root mapping matching
         * the QName parameter.
         */
        private DESCRIPTOR getDescriptor(QName qName) {
            XPathQName xpathQName = new XPathQName(qName, true);
            return descriptorsByQName.get(xpathQName);
        }

        /**
         * INTERNAL: Return the Descriptor with the default root mapping matching
         * the QName parameter.
         */
        private DESCRIPTOR getDescriptor(XPathQName qName) {
            return descriptorsByQName.get(qName);
        }

        /**
         * INTERNAL: Return the Descriptor mapped to the global type matching the
         * XPathFragment parameter.
         */
        private DESCRIPTOR getDescriptorByGlobalType(XPathFragment xPathFragment) {
            return this.descriptorsByGlobalType.get(xPathFragment);
        }

        protected SESSION getSession() {
            return session;
        }

        /**
         * INTERNAL: Return the session corresponding to this class. Since the class
         * may be mapped by more that one of the projects used to create the
         * Context, this method will return the first match.
         */
        protected ABSTRACT_SESSION getSession(Class clazz) {
            if (null == clazz) {
                return null;
            }
            if (session.getDescriptor(clazz) != null) {
                return (ABSTRACT_SESSION) session;
            }
            throw XMLMarshalException.descriptorNotFoundInProject(clazz.getName());
        }

        /**
         * INTERNAL: Return the session corresponding to this Descriptor. Since
         * the class may be mapped by more that one of the projects used to create
         * the Context, this method will return the first match.
         */
        protected ABSTRACT_SESSION getSession(DESCRIPTOR descriptor) {
            if (null == descriptor) {
                return null;
            }
            if (session.getProject().getOrderedDescriptors().contains(descriptor)) {
                return (ABSTRACT_SESSION) session;
            }
            throw XMLMarshalException.descriptorNotFoundInProject(descriptor.getJavaClass().getName());
        }

        /**
         * INTERNAL: Return the session corresponding to this object. Since the
         * object may be mapped by more that one of the projects used to create the
         * Context, this method will return the first match.
         */
        protected ABSTRACT_SESSION getSession(Object object) {
            if (null == object) {
                return null;
            }
            if (session.getDescriptor(object) != null) {
                return (ABSTRACT_SESSION) session;
            }
            throw XMLMarshalException.descriptorNotFoundInProject(object.getClass().getName());
        }

        protected void setupSession(SESSION session) {
        }

        /**
         * INTERNAL:
         */
        public void storeDescriptorByQName(DESCRIPTOR descriptor, CorePlatform platform, Set processedDescriptors) {
            XPathQName descriptorQName;
            String defaultRootName;

            if (processedDescriptors == null) {
                processedDescriptors = new HashSet<>();
            }

            if (processedDescriptors.contains(descriptor)) {
                return;
            } else {
                processedDescriptors.add(descriptor);
                if (descriptor.hasInheritance() && !descriptor.getInheritancePolicy().isRootParentDescriptor()) {
                    //this means we have a descriptor that is a child in an inheritance hierarchy
                    storeDescriptorByQName((DESCRIPTOR) descriptor.getInheritancePolicy().getParentDescriptor(), platform, processedDescriptors);
                }
            }

            List tableNames = descriptor.getTableNames();
            for (int i = 0; i < tableNames.size(); i++) {
                defaultRootName = (String) tableNames.get(i);

                if (null != defaultRootName) {
                    int index = defaultRootName.indexOf(':');
                    String defaultRootLocalName = defaultRootName.substring(index + 1);
                    if (!defaultRootLocalName.isEmpty()) {
                        if (index > -1) {
                            String defaultRootPrefix = defaultRootName.substring(0, index);
                            String defaultRootNamespaceURI = descriptor.getNamespaceResolver().resolveNamespacePrefix(defaultRootPrefix);
                            descriptorQName = new XPathQName(defaultRootNamespaceURI, defaultRootLocalName, true);
                        } else {
                            if(descriptor.getNamespaceResolver() != null) {
                                descriptorQName = new XPathQName(descriptor.getNamespaceResolver().getDefaultNamespaceURI(), defaultRootLocalName, true);
                            } else {
                                descriptorQName = new XPathQName(defaultRootLocalName, true);
                            }
                        }
                        if (!descriptor.hasInheritance() || descriptor.getInheritancePolicy().isRootParentDescriptor()) {
                            addDescriptorByQName(descriptorQName, descriptor);
                        } else {
                            Descriptor existingDescriptor = getDescriptor(descriptorQName);
                            if (existingDescriptor == null) {
                                addDescriptorByQName(descriptorQName, descriptor);
                            }
                        }
                    }
                }
            }

            XMLSchemaReference xmlSchemaReference = descriptor.getSchemaReference();
            if (null != xmlSchemaReference) {
                String schemaContext = xmlSchemaReference.getSchemaContext();
                if ((xmlSchemaReference.getType() == XMLSchemaReference.COMPLEX_TYPE) || (xmlSchemaReference.getType() == XMLSchemaReference.SIMPLE_TYPE)) {
                    if ((null != schemaContext) && (schemaContext.lastIndexOf('/') == 0)) {
                        schemaContext = schemaContext.substring(1, schemaContext.length());
                        XPathFragment typeFragment = new XPathFragment(schemaContext);
                        if (null != descriptor.getNamespaceResolver()) {
                           String uri = descriptor.getNamespaceResolver().resolveNamespacePrefix(typeFragment.getPrefix());
                           if(uri == null && xmlSchemaReference.getSchemaContextAsQName() != null){
                               uri = xmlSchemaReference.getSchemaContextAsQName().getNamespaceURI();
                           }
                           typeFragment.setNamespaceURI(uri);
                        }
                        this.descriptorsByGlobalType.put(typeFragment, descriptor);
                    } else {
                        QName qname = xmlSchemaReference.getSchemaContextAsQName();
                        if (qname != null) {
                            if (descriptor.isWrapper() && descriptor.getJavaClassName().contains("ObjectWrapper")) {
                                return;
                            }
                            XPathFragment typeFragment = new XPathFragment();
                            typeFragment.setLocalName(qname.getLocalPart());
                            typeFragment.setNamespaceURI(qname.getNamespaceURI());
                            this.descriptorsByGlobalType.put(typeFragment, descriptor);
                        }
                    }
                }
            }
        }

        public void storeDescriptorsByQName(CoreSession session) {
            Iterator iterator = session.getProject().getOrderedDescriptors().iterator();
            Set processedDescriptors = new HashSet<>();
            while (iterator.hasNext()) {
                DESCRIPTOR descriptor = (DESCRIPTOR) iterator.next();
                storeDescriptorByQName(descriptor, session.getDatasourcePlatform(), processedDescriptors);
            }
        }

    }

    private static class XPathQueryResult {
        /*
         * Mapping corresponding to the XPath query
         */
        private CoreMapping mapping;

        /*
         * Mapping's owning object
         */
        private Object owner;

        /*
         * Index into mapping, from XPath query (may be null)
         */
        private Integer index;
    }

    protected volatile ContextState contextState;

    private  T createByXPath(Object object, CoreObjectBuilder objectBuilder, StringTokenizer stringTokenizer, NAMESPACE_RESOLVER namespaceResolver, Class returnType) {
        XPathQueryResult queryResult = getMappingForXPath(object, objectBuilder, stringTokenizer, namespaceResolver);

        if (null != queryResult.mapping) {
            DESCRIPTOR refDescriptor = (DESCRIPTOR) queryResult.mapping.getReferenceDescriptor();
            if (null != refDescriptor) {
                return (T) refDescriptor.getInstantiationPolicy().buildNewInstance();
            }
        }
        return null;
    }

    /**
     * Create a new object instance for a given XPath, relative to the parentObject.
     *
     * @param 
     *      The return type of this method corresponds to the returnType parameter.
     * @param parentObject
     *      The XPath will be executed relative to this object.
     * @param xPath
     *      The XPath statement.
     * @param namespaceResolver
     *      A NamespaceResolver containing the prefix/URI pairings from the XPath statement.
     * @param returnType
     *      The return type.
     *
     * @return
     *      An instance of the Java class mapped to the supplied return type, or null
     *      if no result was found.
     */
    public  T createByXPath(Object parentObject, String xPath, NAMESPACE_RESOLVER namespaceResolver, Class returnType) {
        ABSTRACT_SESSION session = this.getSession(parentObject);
        DESCRIPTOR descriptor = (DESCRIPTOR) session.getDescriptor(parentObject);
        StringTokenizer stringTokenizer = new StringTokenizer(xPath, "/");
        return createByXPath(parentObject, descriptor.getObjectBuilder(), stringTokenizer, namespaceResolver, returnType);
    }

    protected abstract FIELD createField(String path);

    public abstract Marshaller createMarshaller();

    public abstract Unmarshaller createUnmarshaller();

    /**
     * INTERNAL:
     * Return the Descriptor with the default root mapping matching the QName
     * parameter.
     */
    public DESCRIPTOR getDescriptor(QName qName) {
        XPathQName xpathQName = new XPathQName(qName, true);
        return contextState.getDescriptor(xpathQName);
    }

    /**
     * INTERNAL:
     * Return the Descriptor with the default root mapping matching the
     * XPathQName parameter.
     */
    public DESCRIPTOR getDescriptor(XPathQName xpathQName) {
        return contextState.getDescriptor(xpathQName);
    }

    /**
     * INTERNAL:
     * Return the Descriptor mapped to the global type matching the
     * XPathFragment parameter.
     */
    public DESCRIPTOR getDescriptorByGlobalType(XPathFragment xPathFragment) {
        return contextState.getDescriptorByGlobalType(xPathFragment);
    }

    private XPathQueryResult getMappingForXPath(Object object, CoreObjectBuilder objectBuilder, StringTokenizer stringTokenizer, NAMESPACE_RESOLVER namespaceResolver) {
        XPathQueryResult queryResult = new XPathQueryResult();

        String xPath = "";
        FIELD field = createField(null);
        field.setNamespaceResolver(namespaceResolver);
        while (stringTokenizer.hasMoreElements()) {
            String nextToken = stringTokenizer.nextToken();
            field.setXPath(xPath + nextToken);
            field.initialize();
            CoreMapping mapping = objectBuilder.getMappingForField(field);
            if (null == mapping) {
                // XPath might have indexes, while the mapping's XPath may not,
                // so remove them and look again
                XPathFragment xPathFragment = new XPathFragment(nextToken);
                int fieldIndex = field.getXPathFragment().getIndexValue();
                int fragmentIndex = xPathFragment.getIndexValue();
                if (fieldIndex > 0 || fragmentIndex > 0) {
                    int index = fieldIndex - 1;
                    if (index < 0) {
                        index = fragmentIndex - 1;
                    }
                    String xPathNoIndexes = removeIndexesFromXPath(field.getXPath());
                    field.setXPath(xPathNoIndexes);
                    field.initialize();
                    mapping = objectBuilder.getMappingForField(field);
                    if (null == mapping) {
                        // Try adding /text()
                        field.setXPath(xPathNoIndexes + Constants.XPATH_SEPARATOR + Constants.TEXT);
                        field.initialize();
                        mapping = objectBuilder.getMappingForField(field);
                    }
                    if (null != mapping) {
                        if (field.getXPath().endsWith(Constants.TEXT) || !stringTokenizer.hasMoreElements()) {
                            // End of the line, we found a mapping so return it
                            queryResult.mapping = mapping;
                            queryResult.owner = object;
                            queryResult.index = index;
                            return queryResult;
                        } else {
                            // We need to keep looking -- get the mapping value,
                            // then recurse into getMappingForXPath with new root object
                            Object childObject = mapping.getAttributeValueFromObject(object);
                            if (mapping.isCollectionMapping()) {
                                Object collection = mapping.getAttributeValueFromObject(object);
                                if (null != collection  && List.class.isAssignableFrom(collection.getClass())) {
                                    List list = (List) collection;
                                    if (index >= list.size()) {
                                        // Index used in query is out of range, no matches
                                        return null;
                                    }
                                    childObject = list.get(index);
                                }
                            }
                            if (null == childObject) {
                                childObject = mapping.getReferenceDescriptor().getObjectBuilder().buildNewInstance();
                            }
                            CoreObjectBuilder childObjectBuilder = mapping.getReferenceDescriptor().getObjectBuilder();
                            return getMappingForXPath(childObject, childObjectBuilder, stringTokenizer, namespaceResolver);
                        }
                    }
                }
            } else {
                if (!stringTokenizer.hasMoreElements()) {
                    // End of the line, we found a mapping so return it
                    queryResult.mapping = mapping;
                    queryResult.owner = object;
                    return queryResult;
                } else {
                    // We need to keep looking -- get the mapping value,
                    // then recurse into getMappingForXPath with new root object
                    Object childObject = mapping.getAttributeValueFromObject(object);
                    if (mapping.isCollectionMapping()) {
                        Object collection = mapping.getAttributeValueFromObject(object);
                        if (null != collection && List.class.isAssignableFrom(collection.getClass())) {
                            List list = (List) collection;
                            if (0 >= list.size()) {
                                return null;
                            }
                            childObject = list.get(0);
                        }
                    }
                    if (null == childObject) {
                        childObject = mapping.getReferenceDescriptor().getObjectBuilder().buildNewInstance();
                    }
                    CoreObjectBuilder childObjectBuilder = mapping.getReferenceDescriptor().getObjectBuilder();
                    return getMappingForXPath(childObject, childObjectBuilder, stringTokenizer, namespaceResolver);
                }
            }
            xPath = xPath + nextToken + Constants.XPATH_SEPARATOR;
        }
        return null;
    }

    /**
     * INTERNAL:
     * Return the session corresponding to this class. Since the class
     * may be mapped by more that one of the projects used to create the
     * Context, this method will return the first match.
     */
    public ABSTRACT_SESSION getSession(Class clazz) {
        return contextState.getSession(clazz);
    }

    /**
     * INTERNAL:
     */
    public SESSION getSession() {
        return contextState.getSession();
    }

    public ABSTRACT_SESSION getSession(DESCRIPTOR descriptor) {
        return contextState.getSession(descriptor);
    }

    /**
     * INTERNAL:
     * Return the session corresponding to this object. Since the
     * object may be mapped by more that one of the projects used to create the
     * Context, this method will return the first match.
     */
    public ABSTRACT_SESSION getSession(Object object) {
        return contextState.getSession(object);
    }

    /**
     * 

Query the object model based on the corresponding document. The following pairings are equivalent:

* * Return the Customer's ID *
 Integer id = context.getValueByXPath(customer, "@id", null, Integer.class);
     * Integer id = customer.getId();
* * Return the Customer's Name *
 String name = context.getValueByXPath(customer, "ns:personal-info/ns:name/text()", null, String.class);
     * String name = customer.getName();
* * Return the Customer's Address *
 Address address = context.getValueByXPath(customer, "ns:contact-info/ns:address", aNamespaceResolver, Address.class);
     * Address address = customer.getAddress();
* * Return all the Customer's PhoneNumbers *
 List phoneNumbers = context.getValueByXPath(customer, "ns:contact-info/ns:phone-number", aNamespaceResolver, List.class);
     * List phoneNumbers = customer.getPhoneNumbers();
* * Return the Customer's second PhoneNumber *
 PhoneNumber phoneNumber = context.getValueByXPath(customer, "ns:contact-info/ns:phone-number[2]", aNamespaceResolver, PhoneNumber.class);
     * PhoneNumber phoneNumber = customer.getPhoneNumbers().get(1);
* * Return the base object *
 Customer customer = context.getValueByXPath(customer, ".", aNamespaceResolver, Customer.class);
     * Customer customer = customer;
     * 
* * @param The return type of this method corresponds to the returnType parameter. * @param object The XPath will be executed relative to this object. * @param xPath The XPath statement * @param namespaceResolver A NamespaceResolver containing the prefix/URI pairings from the XPath statement. * @param returnType The return type. * @return The object corresponding to the XPath or null if no result was found. */ public T getValueByXPath(Object object, String xPath, NAMESPACE_RESOLVER namespaceResolver, Class returnType) { if (null == xPath || null == object) { return null; } if (".".equals(xPath)) { return (T) object; } ABSTRACT_SESSION session = this.getSession(object); DESCRIPTOR descriptor = (DESCRIPTOR) session.getDescriptor(object); StringTokenizer stringTokenizer = new StringTokenizer(xPath, Constants.XPATH_SEPARATOR); T value = getValueByXPath(object, descriptor.getObjectBuilder(), stringTokenizer, namespaceResolver, returnType); if (null == value) { CoreMapping selfMapping = descriptor.getObjectBuilder().getMappingForField(createField(String.valueOf(Constants.DOT))); if (null != selfMapping && selfMapping.getReferenceDescriptor() != null) { return getValueByXPath(selfMapping.getAttributeValueFromObject(object), selfMapping.getReferenceDescriptor().getObjectBuilder(), new StringTokenizer(xPath, Constants.XPATH_SEPARATOR), ((DESCRIPTOR) selfMapping.getReferenceDescriptor()).getNamespaceResolver(), returnType); } } return value; } private T getValueByXPath(Object object, CoreObjectBuilder objectBuilder, StringTokenizer stringTokenizer, NAMESPACE_RESOLVER namespaceResolver, Class returnType) { XPathQueryResult queryResult = getMappingForXPath(object, objectBuilder, stringTokenizer, namespaceResolver); if (null != queryResult) { CoreMapping mapping = queryResult.mapping; Object owner = queryResult.owner; Integer index = queryResult.index; if (null != owner) { Object childObject = null; if (mapping.isCollectionMapping()) { Object collection = mapping.getAttributeValueFromObject(owner); if (List.class.isAssignableFrom(collection.getClass())) { List list = (List) collection; if (null == index) { return (T) collection; } if (index >= list.size()) { return null; } childObject = list.get(index); } } else { childObject = mapping.getAttributeValueFromObject(owner); } return (T) childObject; } } return null; } /** * INTERNAL: * Return true if any session held onto by this context has a document preservation * policy that requires unmarshalling from a Node. */ public abstract boolean hasDocumentPreservation(); private String removeIndexesFromXPath(String xpathWithIndexes) { String newXPath = xpathWithIndexes; while (newXPath.contains(Constants.XPATH_INDEX_OPEN)) { int open = newXPath.lastIndexOf(Constants.XPATH_INDEX_OPEN); int closed = newXPath.lastIndexOf(Constants.XPATH_INDEX_CLOSED); newXPath = newXPath.substring(0, open) + newXPath.substring(closed + 1); } return newXPath; } private void setValueByXPath(Object object, CoreObjectBuilder objectBuilder, StringTokenizer stringTokenizer, NAMESPACE_RESOLVER namespaceResolver, Object value) { XPathQueryResult queryResult = getMappingForXPath(object, objectBuilder, stringTokenizer, namespaceResolver); if (null != queryResult) { CoreMapping mapping = queryResult.mapping; Object owner = queryResult.owner; Integer index = queryResult.index; if (null != owner) { if (mapping.isCollectionMapping()) { Object childObject = null; Object collection = mapping.getAttributeValueFromObject(owner); if (List.class.isAssignableFrom(collection.getClass())) { List list = (List) collection; if (null == index) { // We are setting the whole collection, not an element in the collection if (value.getClass().isArray()) { ArrayList newList = new ArrayList(); int length = Array.getLength(value); for (int i = 0; i < length; i++) { newList.add(Array.get(value, i)); } value = newList; } mapping.setAttributeValueInObject(owner, value); return; } if (index >= list.size()) { return; } // Set into collection list.set(index, value); mapping.setAttributeValueInObject(owner, list); return; } } else { mapping.setAttributeValueInObject(owner, value); } } } } /** *

Set values in the object model based on the corresponding document. The following pairings are equivalent:

* * Set the Customer's ID *
 context.setValueByXPath(customer, "@id", null, Integer.valueOf(123));
     * customer.setId(Integer.valueOf(123));
* * Set the Customer's Name *
 context.setValueByXPath(customer, "ns:personal-info/ns:name/text()", aNamespaceResolver, "Jane Doe");
     * customer.setName("Jane Doe");
* * Set the Customer's Address *
 context.setValueByXPath(customer, "ns:contact-info/ns:address", aNamespaceResolver, anAddress);
     * customer.setAddress(anAddress);
* * Set the Customer's PhoneNumbers *
 context.setValueByXPath(customer, "ns:contact-info/ns:phone-number", aNamespaceResolver, phoneNumbers);
     * customer.setPhoneNumbers(phoneNumbers);
* * Set the Customer's second PhoneNumber *
 context.setValueByXPath(customer, "ns:contact-info/ns:phone-number[2]", aNamespaceResolver, aPhoneNumber);
     * customer.getPhoneNumbers().get(1);
* * @param object The XPath will be executed relative to this object. * @param xPath The XPath statement * @param namespaceResolver A NamespaceResolver containing the prefix/URI pairings from the XPath statement. * @param value The value to be set. */ public void setValueByXPath(Object object, String xPath, NAMESPACE_RESOLVER namespaceResolver, Object value) { ABSTRACT_SESSION session = this.getSession(object); DESCRIPTOR descriptor = (DESCRIPTOR) session.getDescriptor(object); StringTokenizer stringTokenizer = new StringTokenizer(xPath, "/"); setValueByXPath(object, descriptor.getObjectBuilder(), stringTokenizer, namespaceResolver, value); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy