Search in sources :

Example 96 with Element

use of com.zimbra.common.soap.Element in project zm-mailbox by Zimbra.

the class JaxbUtil method addChildElementFromJaxb.

public static Element addChildElementFromJaxb(Element parent, String name, String namespace, Object o) {
    Element.ElementFactory factory;
    if (parent instanceof XMLElement) {
        factory = XMLElement.mFactory;
    } else {
        factory = JSONElement.mFactory;
    }
    Element child = null;
    try {
        child = jaxbToNamedElement(name, namespace, o, factory);
    } catch (ServiceException e) {
        ZimbraLog.misc.info("JAXB Problem making " + name + " element", e);
    }
    parent.addElement(child);
    return child;
}
Also used : ServiceException(com.zimbra.common.service.ServiceException) Element(com.zimbra.common.soap.Element) JSONElement(com.zimbra.common.soap.Element.JSONElement) JAXBElement(javax.xml.bind.JAXBElement) XMLElement(com.zimbra.common.soap.Element.XMLElement) XMLElement(com.zimbra.common.soap.Element.XMLElement)

Example 97 with Element

use of com.zimbra.common.soap.Element in project zm-mailbox by Zimbra.

the class JaxbUtil method fixupStructureForJaxb.

/**
     * Manipulates a structure under {@link elem} which obeys Zimbra's SOAP XML structure rules to comply with more
     * stringent JAXB rules.
     * <ol>
     * <li>Zimbra allows attributes to be specified as elements.
     * <p>One scenario where this happens - {@link XMLElement}'s {@code getAttribute(String key, String defaultValue)}
     * will look for an attribute with "key" as the name.
     * If it fails to find that, it looks for an element with "key" as the name and returns the elements text.</p></li>
     * <li>Zimbra allows elements to be specified as attributes.
     * <p>One scenario where this happens.
     * <pre>
     *      elem.addAttribute("xml-elem-json-attr", "XML elem but JSON attribute", Element.Disposition.CONTENT);
     * </pre>
     * Will be serialized to this JSON (i.e. treated as an attribute in JSON) :
     * <pre>
     *       "xml-elem-json-attr": "XML elem but JSON attribute"
     * </pre>
     * or to this XML (i.e. treated as an element in XML) :
     * <pre>
     *       &lt;xml-elem-json-attr>XML elem but JSON attribute&lt;/xml-elem-json-attr>
     * </pre>
     * In JAXB, we typically use {@link XmlElement} for the associated field.  Round tripping from XML will result in
     * an element but round tripping from JSON will result in an attribute.
     * <li>Zimbra uses key/value pairs which serialize to JSON as:
     * <pre>
     *     "_attrs":{"anID":"val","anID2":"val2"}
     * </pre>
     * If this is read into a JSONElement structure and written out as XML, you get:
     * <pre>
     *     &lt;a n="anID">val&lt;/a>&lt;a n="anID2">val2&lt;/a>
     * </pre>
     * The element name "a" and the attribute name "n" are defaults - the actual expected values can be different - so
     * we query the JAXB classes to see what they should be.
     * </ol>
     * @param klass is the JAXB class for {@code elem} which must be under the "com.zimbra" package hierarchy.
     */
private static void fixupStructureForJaxb(org.w3c.dom.Element elem, Class<?> klass) {
    if (elem == null) {
        return;
    }
    if (klass == null) {
        LOG.debug("JAXB no class associated with " + elem.getLocalName());
        return;
    }
    if (!isJaxbType(klass)) {
        return;
    }
    JaxbInfo jaxbInfo = JaxbInfo.getFromCache(klass);
    NamedNodeMap attrs = elem.getAttributes();
    int numAttrs = attrs.getLength();
    List<String> orphanAttrs = null;
    // Process each attribute
    for (int i = 0; i < numAttrs; i++) {
        Attr attr = (Attr) attrs.item(i);
        // Get attribute name and value
        String attrName = attr.getNodeName();
        if (!jaxbInfo.hasAttribute(attrName) && jaxbInfo.hasElement(attrName)) {
            if (orphanAttrs == null) {
                orphanAttrs = Lists.newArrayList();
            }
            orphanAttrs.add(attrName);
            String attrValue = attr.getNodeValue();
            elem.getNamespaceURI();
            org.w3c.dom.Element newElem = elem.getOwnerDocument().createElementNS(elem.getNamespaceURI(), attrName);
            newElem.setTextContent(attrValue);
            elem.appendChild(newElem);
        }
    }
    if (orphanAttrs != null) {
        for (String orphan : orphanAttrs) {
            attrs.removeNamedItem(orphan);
        }
    }
    NodeList list = elem.getChildNodes();
    List<org.w3c.dom.Element> orphans = null;
    for (int i = 0; i < list.getLength(); i++) {
        Node subnode = list.item(i);
        if (subnode.getNodeType() == Node.ELEMENT_NODE) {
            org.w3c.dom.Element child = (org.w3c.dom.Element) subnode;
            String childName = child.getLocalName();
            if (jaxbInfo.hasWrapperElement(childName)) {
                NodeList wrappedList = child.getChildNodes();
                for (int j = 0; j < wrappedList.getLength(); j++) {
                    Node wSubnode = wrappedList.item(j);
                    if (wSubnode.getNodeType() == Node.ELEMENT_NODE) {
                        org.w3c.dom.Element wChild = (org.w3c.dom.Element) wSubnode;
                        fixupStructureForJaxb(wChild, jaxbInfo.getClassForWrappedElement(childName, wChild.getLocalName()));
                    }
                }
            } else if (jaxbInfo.hasElement(childName)) {
                fixupStructureForJaxb(child, jaxbInfo.getClassForElement(childName));
            } else if (jaxbInfo.hasAttribute(childName)) {
                elem.setAttribute(childName, child.getTextContent());
                // Don't remove pre-existing child until later pass to avoid changing the list of child elements
                if (orphans == null) {
                    orphans = Lists.newArrayList();
                }
                orphans.add(child);
            } else if (Element.XMLElement.E_ATTRIBUTE.equals(childName)) {
                // This might be a keyvaluepair, the Element code doesn't have access to JAXB info, so defaults
                // the element name to "a" and its attribute will be "n".  If this is what has happened, replace
                // it with a corrected equivalent using the JAXB object for reference.
                JaxbInfo.KeyValuePairXmlRepresentationInfo kvpXmlRep = jaxbInfo.getKeyValuePairElementInfo();
                if (kvpXmlRep != null) {
                    elem.getNamespaceURI();
                    org.w3c.dom.Element newElem = elem.getOwnerDocument().createElementNS(elem.getNamespaceURI(), kvpXmlRep.getXmlElementName());
                    newElem.setTextContent(child.getTextContent());
                    newElem.setAttribute(kvpXmlRep.getXmlAttributeName(), child.getAttribute(Element.XMLElement.A_ATTR_NAME));
                    elem.appendChild(newElem);
                    if (orphans == null) {
                        orphans = Lists.newArrayList();
                    }
                    orphans.add(child);
                }
            } else {
                LOG.debug("JAXB class " + klass.getName() + " does NOT recognise element named:" + childName);
            }
        }
    }
    // Prune the promoted elements from the list of children
    if (orphans != null) {
        for (org.w3c.dom.Element orphan : orphans) {
            elem.removeChild(orphan);
        }
    }
}
Also used : NamedNodeMap(org.w3c.dom.NamedNodeMap) NodeList(org.w3c.dom.NodeList) Element(com.zimbra.common.soap.Element) JSONElement(com.zimbra.common.soap.Element.JSONElement) JAXBElement(javax.xml.bind.JAXBElement) XMLElement(com.zimbra.common.soap.Element.XMLElement) Node(org.w3c.dom.Node) Attr(org.w3c.dom.Attr) JaxbInfo(com.zimbra.soap.util.JaxbInfo)

Example 98 with Element

use of com.zimbra.common.soap.Element in project zm-mailbox by Zimbra.

the class OctopusJaxbTest method checkDeviceStatusResponse.

/**
     * Validating that method used to create response in CheckDeviceStatus
     * should work.
     * @throws Exception
     */
@Test
public void checkDeviceStatusResponse() throws Exception {
    IdStatus idStatus = IdStatus.fromIdAndStatus("idString", "statusString");
    CheckDeviceStatusResponse resp = new CheckDeviceStatusResponse(idStatus);
    Element response = JaxbUtil.jaxbToElement(resp, XMLElement.mFactory);
    Assert.assertNotNull("response object", response);
    resp = JaxbUtil.elementToJaxb(response);
    Assert.assertEquals("round tripped id", "idString", resp.getDevice().getId());
    Assert.assertEquals("round tripped status", "statusString", resp.getDevice().getStatus());
}
Also used : XMLElement(com.zimbra.common.soap.Element.XMLElement) Element(com.zimbra.common.soap.Element) JSONElement(com.zimbra.common.soap.Element.JSONElement) IdStatus(com.zimbra.soap.mail.type.IdStatus) CheckDeviceStatusResponse(com.zimbra.soap.mail.message.CheckDeviceStatusResponse) Test(org.junit.Test)

Example 99 with Element

use of com.zimbra.common.soap.Element in project zm-mailbox by Zimbra.

the class OctopusJaxbTest method activityInfoForGetActivityStreamXml.

@Test
public void activityInfoForGetActivityStreamXml() throws Exception {
    Map<String, String> args = Maps.newHashMap();
    args.put("key1", "value1");
    args.put("key2", "value2");
    ActivityInfo ai = toActivityInfo("account", "op", 333L, "123-123-123:22", 44, "itemName", args);
    Element notify = XMLElement.create(SoapProtocol.Soap12, "pink");
    Element activityElem = JaxbUtil.addChildElementFromJaxb(notify, MailConstants.E_A, MailConstants.NAMESPACE_STR, ai);
    ai = JaxbUtil.elementToJaxb(activityElem, ActivityInfo.class);
    checkActivityInfo(ai, "XML round tripped ");
}
Also used : ActivityInfo(com.zimbra.soap.mail.type.ActivityInfo) XMLElement(com.zimbra.common.soap.Element.XMLElement) Element(com.zimbra.common.soap.Element) JSONElement(com.zimbra.common.soap.Element.JSONElement) Test(org.junit.Test)

Example 100 with Element

use of com.zimbra.common.soap.Element in project zm-mailbox by Zimbra.

the class ZimbraSoapUtils method invokeJaxb.

@SuppressWarnings("unchecked")
public static <T> T invokeJaxb(SoapHttpTransport transport, Object jaxbObject) throws ServiceException {
    Element req = JaxbUtil.jaxbToElement(jaxbObject);
    Element res = invoke(transport, req);
    return (T) JaxbUtil.elementToJaxb(res);
}
Also used : Element(com.zimbra.common.soap.Element)

Aggregations

Element (com.zimbra.common.soap.Element)980 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)315 XMLElement (com.zimbra.common.soap.Element.XMLElement)269 Account (com.zimbra.cs.account.Account)220 Test (org.junit.Test)175 JSONElement (com.zimbra.common.soap.Element.JSONElement)167 Provisioning (com.zimbra.cs.account.Provisioning)147 Mailbox (com.zimbra.cs.mailbox.Mailbox)138 ServiceException (com.zimbra.common.service.ServiceException)103 ItemId (com.zimbra.cs.service.util.ItemId)81 ArrayList (java.util.ArrayList)81 OperationContext (com.zimbra.cs.mailbox.OperationContext)80 HashMap (java.util.HashMap)77 ItemIdFormatter (com.zimbra.cs.service.util.ItemIdFormatter)56 SoapHttpTransport (com.zimbra.common.soap.SoapHttpTransport)54 Server (com.zimbra.cs.account.Server)49 FilterTest (com.zimbra.soap.mail.type.FilterTest)46 IOException (java.io.IOException)45 XmlAnyElement (javax.xml.bind.annotation.XmlAnyElement)44 XmlElement (javax.xml.bind.annotation.XmlElement)44