View Javadoc
1   /*
2    * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
3    * Copyright (C) 2010  Mickael Guessant
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  
20  package davmail.exchange.graph;
21  
22  import davmail.exception.DavMailException;
23  import davmail.exchange.ews.Field;
24  import davmail.exchange.ews.FieldURI;
25  import davmail.util.StringUtil;
26  import org.codehaus.jettison.json.JSONArray;
27  import org.codehaus.jettison.json.JSONException;
28  import org.codehaus.jettison.json.JSONObject;
29  
30  import java.text.ParseException;
31  import java.text.SimpleDateFormat;
32  import java.util.Date;
33  import java.util.HashSet;
34  import java.util.ResourceBundle;
35  import java.util.TimeZone;
36  
37  /**
38   * Wrapper for Graph API JsonObject
39   */
40  public class GraphObject {
41      protected final JSONObject jsonObject;
42      protected int statusCode;
43  
44      public GraphObject(JSONObject jsonObject) {
45          this.jsonObject = jsonObject;
46      }
47  
48      public String optString(String key) {
49          String value = jsonObject.optString(key, null);
50          // special case for keywords/categories
51          if ("keywords".equals(key) || "categories".equals(key)) {
52              JSONArray categoriesArray = jsonObject.optJSONArray("categories");
53              HashSet<String> keywords = new HashSet<>();
54              for (int j = 0; j < categoriesArray.length(); j++) {
55                  keywords.add(categoriesArray.optString(j));
56              }
57              value = StringUtil.join(keywords, ",");
58          } else if ("changeKey".equals(key) && value == null) {
59              // tasks don't have an etag field, use @odata.etag
60              String odataEtag = optString("@odata.etag");
61              if (odataEtag != null && odataEtag.startsWith("W/\"") && odataEtag.endsWith("\"")) {
62                  value = odataEtag.substring(3, odataEtag.length()-1);
63              }
64              // try to fetch from expanded properties
65          } else if (value == null) {
66              key = Field.get(key).getGraphId();
67              // remapped attributes first
68              value = jsonObject.optString(key, null);
69              // check expanded properties
70              if (value == null) {
71                  JSONArray singleValueExtendedProperties = jsonObject.optJSONArray("singleValueExtendedProperties");
72                  if (singleValueExtendedProperties != null) {
73                      for (int i = 0; i < singleValueExtendedProperties.length(); i++) {
74                          JSONObject singleValueObject = singleValueExtendedProperties.optJSONObject(i);
75                          if (singleValueObject != null && key.equals(singleValueObject.optString("id"))) {
76                              value = singleValueObject.optString("value");
77                          }
78  
79                      }
80                  }
81              }
82          }
83          return value;
84      }
85  
86      public JSONArray optJSONArray(String key) {
87          return jsonObject.optJSONArray(key);
88      }
89  
90      public void put(String alias, String value) throws JSONException {
91          FieldURI field = Field.get(alias);
92          String key = field.getGraphId();
93          // assume all expanded properties have a space
94          if (key.contains(" ")) {
95              if (field.isNumber() && value == null) {
96                  value = "0";
97              }
98              getSingleValueExtendedProperties().put(new JSONObject().put("id", key).put("value", value == null?JSONObject.NULL:value));
99          } else {
100             jsonObject.put(key, value == null?JSONObject.NULL:value);
101         }
102     }
103 
104     public void put(String alias, boolean value) throws JSONException {
105         FieldURI field = Field.get(alias);
106         String key = field.getGraphId();
107         // assume all expanded properties have a space
108         if (key.contains(" ")) {
109             getSingleValueExtendedProperties().put(new JSONObject().put("id", key).put("value", value));
110         } else {
111             jsonObject.put(key, value);
112         }
113     }
114 
115     public void put(String key, JSONArray values) throws JSONException {
116         jsonObject.put(key, values);
117     }
118 
119     public void setCategories(String values) throws JSONException {
120         if (values != null) {
121             setCategories(values.split(","));
122         } else {
123             jsonObject.put("categories", new JSONArray());
124         }
125     }
126 
127     public void setCategories(String[] values) throws JSONException {
128         // assume all expanded properties have a space
129         JSONArray jsonValues = new JSONArray();
130         for (String singleValue : values) {
131             jsonValues.put(singleValue);
132         }
133         jsonObject.put("categories", jsonValues);
134     }
135 
136     public String toString(int indentFactor) throws JSONException {
137         return jsonObject.toString(indentFactor);
138     }
139 
140     protected JSONArray getSingleValueExtendedProperties() throws JSONException {
141         JSONArray singleValueExtendedProperties = jsonObject.optJSONArray("singleValueExtendedProperties");
142         if (singleValueExtendedProperties == null) {
143             singleValueExtendedProperties = new JSONArray();
144             jsonObject.put("singleValueExtendedProperties", singleValueExtendedProperties);
145         }
146         return singleValueExtendedProperties;
147     }
148 
149 
150     public String getString(String key) throws JSONException {
151         String value = optString(key);
152         if (value == null) {
153             throw new JSONException("JSONObject[" + key + "] not found.");
154         }
155         return value;
156     }
157 
158     public String optString(String section, String key) {
159         JSONObject sectionObject = jsonObject.optJSONObject(section);
160         // try to map with field
161         if (sectionObject == null) {
162             sectionObject = jsonObject.optJSONObject(Field.get(section).getGraphId());
163         }
164         if (sectionObject != null) {
165             return sectionObject.optString(key, null);
166         }
167         return null;
168     }
169 
170     public JSONObject optJSONObject(String key) {
171         return jsonObject.optJSONObject(key);
172     }
173 
174     public Date optDateTimeTimeZone(String key) throws DavMailException {
175         JSONObject sectionObject = jsonObject.optJSONObject(key);
176         if (sectionObject != null) {
177             String timeZone = sectionObject.optString("timeZone");
178             String dateTime = sectionObject.optString("dateTime");
179             if (timeZone != null && dateTime != null) {
180                 try {
181                     SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS");
182                     parser.setTimeZone(TimeZone.getTimeZone(timeZone));
183                     return parser.parse(dateTime);
184                 } catch (ParseException e) {
185                     throw new DavMailException("EXCEPTION_INVALID_DATE", dateTime);
186                 }
187             }
188         }
189         return null;
190     }
191 
192     public static String convertTimezoneFromExchange(String exchangeTimezone) {
193         ResourceBundle tzidsBundle = ResourceBundle.getBundle("stdtimezones");
194         if (tzidsBundle.containsKey(exchangeTimezone)) {
195             return tzidsBundle.getString(exchangeTimezone);
196         } else {
197             return exchangeTimezone;
198         }
199     }
200 }
201