| /* |
| * Copyright (c) 2011, 2020 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: |
| // Matt MacIvor = 2.1 - Initial contribution |
| package org.eclipse.persistence.oxm.annotations; |
| |
| import java.lang.annotation.ElementType; |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| import java.lang.annotation.Target; |
| |
| /** |
| * <p>XPath based mapping is what allows an existing object model to be mapped |
| * to an existing XML schema. The {@code @XmlPath} annotation is the means by |
| * which XPath based mapping is achieved.</p> |
| * <b>Example 1 - Using {@code @XmlPath} to Add a Grouping Element</b> |
| * <p>Sometimes grouping elements are added to your document to organise data. |
| * JAXB has this concept for collection properties in the form of |
| * {@code @XmlElementWrapper}. Here we'll use {@code @XmlPath} for |
| * non-collection properties. In this case we'll nest the billing/shipping |
| * address data within the "contact-info" element.</p> |
| * <pre> |
| * import jakarta.xml.bind.annotation.*; |
| * import org.eclipse.persistence.oxm.annotations.XmlPath; |
| * |
| * @XmlRootElement |
| * @XmlAccessorType(XmlAccessType.FIELD) |
| * public class Customer { |
| * @XmlPath("contact-info/billing-address") |
| * private Address billingAddress; |
| * |
| * @XmlPath("contact-info/shipping-address") |
| * private Address shippingAddress; |
| * } |
| * </pre> |
| * This will produce XML like: |
| * <pre>{@code |
| * <xmp> |
| * <customer> |
| * <contact-info> |
| * <billing-address> |
| * <street>1 Billing Street</street> |
| * </billing-address> |
| * <shipping-address> |
| * <street>2 Shipping Road</street> |
| * </shipping-address> |
| * </contact-info> |
| * </customer> |
| * </xmp>} |
| * </pre> |
| * <b>Example 2 - Using {@code @XmlPath} to Map by Position</b> |
| * <p>Normally in JAXB elements with the same name must be mapped to a |
| * collection property. Using the @XmlPath extension you map non-collection |
| * properties to a repeated element by index.</p> |
| * <pre> |
| * import jakarta.xml.bind.annotation.*; |
| * import org.eclipse.persistence.oxm.annotations.XmlPath; |
| * |
| * @XmlRootElement |
| * @XmlAccessorType(XmlAccessType.FIELD) |
| * public class Customer { |
| * @XmlPath("address[1]") |
| * private Address billingAddress; |
| * |
| * @XmlPath("address[2]") |
| * private Address shippingAddress; |
| * } |
| * </pre> |
| * This will produce XML like: |
| * <pre>{@code |
| * <xmp> |
| * <customer> |
| * <address> |
| * <street>1 Billing Street</street> |
| * </address> |
| * <address> |
| * <street>2 Shipping Road</street> |
| * </address> |
| * </customer> |
| * </xmp>} |
| * </pre> |
| * <b>Example 3 - Using {@code @XmlPath} to Map Two Objects to the Same Node</b> |
| * <p>We have seen how {@code @XmlPath} can be used to expand the structure by |
| * adding a grouping element. {@code @XmlPath} can also be used to collapse the |
| * structure by mapping two objects to the same node.</p> |
| * <pre> |
| * import jakarta.xml.bind.annotation.*; |
| * import org.eclipse.persistence.oxm.annotations.XmlPath; |
| * |
| * @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) |
| * public class Customer { |
| * @XmlPath(".") |
| * private Address billingAddress; |
| * |
| * private Address shippingAddress; |
| * } |
| * </pre> |
| * This will produce XML like: |
| * <pre>{@code |
| * <xmp> |
| * <customer> |
| * <street>1 Billing Street</street> |
| * <shippingAddress> |
| * <street>2 Shipping Road</street> |
| * </shippingAddress> |
| * </customer> |
| * </xmp>} |
| * </pre> |
| */ |
| @Target({ElementType.FIELD, ElementType.METHOD}) |
| @Retention(RetentionPolicy.RUNTIME) |
| public @interface XmlPath { |
| |
| /** |
| * <p>The XPath for this property. A subset of the XPath specification may be |
| * used to specify mappings. The following concepts are supported:</p> |
| * <ul> |
| * <li>Attribute - "@id"</li> |
| * <li>Element - "address"</li> |
| * <li>Element by Position - "address[1]"</li> |
| * <li>Element by Predicate - "address[@type='mailing']"</li> |
| * <li>Element Text - "name/text()"</li> |
| * <li>Text - "text()"</li> |
| * <li>Self - "."</li> |
| * <li>Combination - "personal-info/name[2]/text()"</li> |
| * </ul> |
| * <p>For namespace qualified nodes, the prefixes defined in the XmlNs |
| * annotations can be used to qualify the XPath fragments. Unqualified |
| * fragments will assumed to be in the namespace specified using |
| * @XmlSchema.</p> |
| * <b>Example</b> |
| * <p>Assuming the following namespace information has been set up using the |
| * @XmlSchema annotation:</p> |
| * <pre> |
| * @XmlSchema(namespace = "http://www.example.org/FOO", |
| * xmlns = {@XmlNs(prefix="ns", namespaceURI="http://www.example.com/BAR")}, |
| * elementFormDefault = XmlNsForm.QUALIFIED) |
| * package org.example; |
| * |
| * import jakarta.xml.bind.annotation.*; |
| * </pre> |
| * <p>Then the following XPath:</p> |
| * <pre> |
| * @XmlPath("contact-info/ns:address/@id") |
| * </pre> |
| * <p>Will be qualified as:</p> |
| * <ul> |
| * <li>contact-info - in "http://www.example.org/FOO" namespace.</li> |
| * <li>address - in "http://www.example.com/BAR" namespace.</li> |
| * <li>@id - in no namespace.</li> |
| * </ul> |
| * @see jakarta.xml.bind.annotation.XmlSchema |
| * @see jakarta.xml.bind.annotation.XmlNs |
| */ |
| String value(); |
| |
| } |