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

Category support #540

Open dkirrane opened 8 years ago

dkirrane commented 8 years ago

Setting categories doesn't seem to work

            EmailMessage msg;
            msg = new EmailMessage(exchangeService);
            msg.setCategories(new StringList("Blue Category"));

Also, there doesn't seem to be a way to create a new category

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.

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();
    }

}
markporter commented 7 years ago

In case anyone else is having issues setting categories on an Item:

StringList needs to be either an iterable of Strings or you need manually add categories:

StringList newCategories = new StringList();
newCategories.add("Alert");
newCategories.add("TempSensor");
// "item" is a item from a a previus FindResults, or Item.bind()
// you need to update this or nothing interesting will happen
item.setCategories(newCategories)
item.update(ConflictResolutionMode.AlwaysOverwrite)
dhavalgada11 commented 1 year ago

@gaby44541 Can you share the structure for Category.java as well. EWS API doesn't have implementation for it by default.