OfficeDev / ews-java-api

A java client library to access Exchange web services. The API works against Office 365 Exchange Online as well as on premises Exchange.
MIT License
869 stars 560 forks source link

Unable to update CategoryList #114

Open aglueck opened 9 years ago

aglueck commented 9 years ago

Hello,

I'm trying to update the CategoryList but I can not get further because the UserConfiguration's setter for XmlData wants me to set a Base64 encoded ByteArray. Unfortunately a subsequent request returns a Base64 encoded ByteArray, but I'm expecting a plain XML just as in the first call.

Can you tell me, if there's something wrong? I'm accessing an Exchange 2010.

Here's the sample code I've written:

    UserConfiguration configuration = UserConfiguration.bind(service, "CategoryList", 
    WellKnownFolderName.Calendar, UserConfigurationProperties.XmlData);

    JAXBContext jaxbContext = JAXBContext.newInstance(Categories.class);
    Unmarshaller unmarshaller =  jaxbContext.createUnmarshaller();

    ByteArrayInputStream bais = new ByteArrayInputStream(configuration.getXmlData());
    Categories c = (Categories) unmarshaller.unmarshal(bais);

    Category newCat = new Category();
    newCat.setName("New Category");
    newCat.setColor(24);
    newCat.setKeyboardShortcut(0);
    newCat.setGuid(UUID.randomUUID().toString());
    newCat.setLastSessionUsed(0);

    c.getCategory().add(newCat);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    Marshaller marshaller = jaxbContext.createMarshaller();
    marshaller.marshal(c, baos);

    byte[] content = baos.toByteArray();

    configuration.setXmlData(Base64.encodeBase64(content));
    configuration.update();

Thanks in advance,

Adam

wwahmed commented 8 years ago

Hello @aglueck

First of all - thank you for asking your question in detail. It gave me some tips on how to get the Category List as I was unable to find a high level API method for this. Sadly, it seems like we have to get the raw XML and parse categories ourselves.

Can you please confirm whether you were able to get around this problem or are you still unable to add/update categories?

Thanks

gaby44541 commented 7 years ago

Unfortunately, EWS Java API doesn't manage properly categories. But we can manage categories ourself : indeed, we can get the xml containing all categories. By coding methods, we can read this xml, update nodes, and rewrite to Exchange. You have to adapt the code.

To get the XML :

           UserConfiguration config = UserConfiguration.bind(ExchangeManager.getService(), "CategoryList", WellKnownFolderName.Calendar,
                                       UserConfigurationProperties.XmlData);
            String s = new String(config.getXmlData(),"UTF-8");
            System.err.println("Categories (XML) : "+s);

To read the XML and put each categories in an ArrayList of Category (you have to create the class Category)

  private static void readXML(byte[] documentoXml){
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(new ByteArrayInputStream(documentoXml));
            doc.getDocumentElement().normalize();
            CategoryManager.categories = new ArrayList<Category>();

            NodeList nList = doc.getElementsByTagName("category");
            for (int temp = 0; temp < nList.getLength(); temp++) {
                Node nNode = nList.item(temp);
                if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element eElement = (Element) nNode;

                    boolean renameOnFirstUse = "1".equals(eElement.getAttribute("renameOnFirstUse")) ? true : false;
                    String name = eElement.getAttribute("name");
                    int color = Integer.parseInt(eElement.getAttribute("color"));
                    int keyboardShortcut = Integer.parseInt(eElement.getAttribute("keyboardShortcut"));
                    String guid = eElement.getAttribute("guid");
                    categories.add(new Category(renameOnFirstUse,name,color,keyboardShortcut,guid,isIXBat));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

To write the ArrayList in XML

    private static byte[] updateXML(byte[] documentoXml){
        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(new ByteArrayInputStream(documentoXml));

            // Get the root element
            //Node categories = doc.getFirstChild();

            NodeList nList = doc.getElementsByTagName("category");
            for (int temp = 0; temp < nList.getLength(); temp++) {    
                Node category = doc.getElementsByTagName("category").item(temp);

                Category cat = findCategory(((Element)category).getAttribute("guid"));
                System.err.println("> " + cat);

                // maj category attribute
                NamedNodeMap attr = category.getAttributes();

                Node nodeAttrName = attr.getNamedItem("name");
                nodeAttrName.setTextContent(cat.getNom());

                Node nodeAttrColor = attr.getNamedItem("color");
                nodeAttrColor.setTextContent(cat.getCodeCouleur()+"");                    

            }

            // write the content into xml file
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(doc);

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            StreamResult result = new StreamResult(bos);
            transformer.transform(source, result);

            return bos.toByteArray();

        } catch (ParserConfigurationException pce) {
            pce.printStackTrace();
        } catch (TransformerException tfe) {
            tfe.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (SAXException sae) {
            sae.printStackTrace();
        }
        return null;
    }

To send the XML to Exchange :

public static void updateCategoriesToExchange(){
    try {
        UserConfiguration config =
            UserConfiguration.bind(ExchangeManager.getService(), "CategoryList", WellKnownFolderName.Calendar,
                                   UserConfigurationProperties.XmlData);
        byte[] nvXml = CategoryManager.updateXML(config.getXmlData());

        System.err.println(new String(nvXml));
        config.setXmlData(nvXml);
        config.update();
    } catch (Exception e) {
        e.printStackTrace();
    }

}