/** * Copyright (c) 2009 - 2012 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package org.candlepin.swagger; import com.fasterxml.jackson.databind.introspect.AnnotatedMember; import io.swagger.models.Xml; import io.swagger.models.properties.ArrayProperty; import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.ObjectProperty; import io.swagger.models.properties.Property; import io.swagger.models.properties.RefProperty; import org.apache.commons.lang3.StringUtils; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; /** * The <code>JAXBAnnotationsHelper</code> class defines helper methods for * applying JAXB annotations to property definitions. */ class JAXBAnnotationsHelper { private static final String JAXB_DEFAULT = "##default"; private JAXBAnnotationsHelper() { } /** * Applies annotations to property's {@link Xml} definition. * * @param member annotations provider * @param property property instance to be updated */ public static void apply(AnnotatedMember member, Property property) { if (member.hasAnnotation(XmlElementWrapper.class) || member.hasAnnotation(XmlElement.class)) { applyElement(member, property); } else if (member.hasAnnotation(XmlAttribute.class) && isAttributeAllowed(property)) { applyAttribute(member, property); } } /** * Puts definitions for XML element. * * @param member annotations provider * @param property property instance to be updated */ private static void applyElement(AnnotatedMember member, Property property) { final XmlElementWrapper wrapper = member.getAnnotation(XmlElementWrapper.class); if (wrapper != null) { final Xml xml = getXml(property); xml.setWrapped(true); if (!"##default".equals(wrapper.name()) && !wrapper.name().isEmpty()) { xml.setName(wrapper.name()); } } final XmlElement element = member.getAnnotation(XmlElement.class); if (element != null) { setName(element.namespace(), element.name(), property); } } /** * Puts definitions for XML attribute. * * @param member annotations provider * @param property property instance to be updated */ private static void applyAttribute(AnnotatedMember member, Property property) { final XmlAttribute attribute = member.getAnnotation(XmlAttribute.class); if (attribute != null) { final Xml xml = getXml(property); xml.setAttribute(true); setName(attribute.namespace(), attribute.name(), property); } } private static Xml getXml(Property property) { final Xml existing = property.getXml(); if (existing != null) { return existing; } final Xml created = new Xml(); property.setXml(created); return created; } /** * Puts name space and name for XML node or attribute. * * @param ns name space * @param name name * @param property property instance to be updated * @return <code>true</code> if name space and name have been set */ private static boolean setName(String ns, String name, Property property) { boolean apply = false; final String cleanName = StringUtils.trimToNull(name); final String useName; if (!isEmpty(cleanName) && !cleanName.equals(property.getName())) { useName = cleanName; apply = true; } else { useName = null; } final String cleanNS = StringUtils.trimToNull(ns); final String useNS; if (!isEmpty(cleanNS)) { useNS = cleanNS; apply = true; } else { useNS = null; } // Set everything or nothing if (apply) { getXml(property).name(useName).namespace(useNS); } return apply; } /** * Checks whether the passed property can be represented as node attribute. * * @param property property instance to be checked * @return <code>true</code> if the passed property can be represented as * node attribute */ private static boolean isAttributeAllowed(Property property) { for (Class<?> item : new Class<?>[]{ ArrayProperty.class, MapProperty.class, ObjectProperty.class, RefProperty.class}) { if (item.isInstance(property)) { return false; } } return true; } private static boolean isEmpty(String name) { return StringUtils.isEmpty(name) || JAXB_DEFAULT.equals(name); } }