1+ // ------------------------------------------------------------------------------
2+ // Copyright (c) 2017 Microsoft Corporation
3+ //
4+ // Permission is hereby granted, free of charge, to any person obtaining a copy
5+ // of this software and associated documentation files (the "Software"), to deal
6+ // in the Software without restriction, including without limitation the rights
7+ // to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
8+ // copies of the Software, and to permit persons to whom the Software is
9+ // furnished to do so, subject to the following conditions:
10+ //
11+ // The above copyright notice and this permission notice shall be included in
12+ // all copies or substantial portions of the Software.
13+ //
14+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ // THE SOFTWARE.
21+ // ------------------------------------------------------------------------------
22+
23+ package com .microsoft .graph .serializer ;
24+
25+ import java .lang .reflect .InvocationTargetException ;
26+ import java .lang .reflect .Type ;
27+ import java .util .ArrayList ;
28+ import java .util .Arrays ;
29+ import java .util .List ;
30+
31+ import com .google .gson .JsonArray ;
32+ import com .google .gson .JsonElement ;
33+ import com .google .gson .JsonObject ;
34+ import com .google .gson .JsonParseException ;
35+ import com .google .gson .JsonParser ;
36+ import com .google .common .reflect .TypeToken ;
37+ import com .microsoft .graph .http .BaseCollectionPage ;
38+ import com .microsoft .graph .http .IRequestBuilder ;
39+ import com .microsoft .graph .logger .ILogger ;
40+
41+ // keep these imports: even though they are not used, it's a good way to call
42+ // for maintainer's attention en the event code generation naming conventions
43+ // change. If the name change, these import will build at build time rather than
44+ // reflection building at run time.
45+ import com .microsoft .graph .models .extensions .Attachment ;
46+ import com .microsoft .graph .requests .extensions .AttachmentCollectionPage ;
47+ import com .microsoft .graph .requests .extensions .AttachmentCollectionResponse ;
48+ import com .microsoft .graph .requests .extensions .IAttachmentCollectionRequestBuilder ;
49+
50+ public class CollectionPageSerializer {
51+
52+ private static DefaultSerializer serializer ;
53+ /** length of the word "page" */
54+ private final static Integer pageLength = 4 ;
55+ /** length of the word "collection" */
56+ private final static Integer collectionLength = 10 ;
57+ /** length of the work "response" */
58+ private final static Integer responseLength = 8 ;
59+ /** the extensions segment in the package name of target classes */
60+ private final static String extensionsPath = "extensions." ;
61+
62+ /**
63+ * Not available for instantiation
64+ */
65+ private CollectionPageSerializer () {
66+ }
67+
68+ /**
69+ * Serializes an CollectionPage
70+ *
71+ * @param src the CollectionPage variable for serialization
72+ * @param logger the logger
73+ * @return JsonElement of CollectionPage
74+ */
75+ public static <T1 , T2 extends IRequestBuilder > JsonElement serialize (final BaseCollectionPage <T1 , T2 > src , final ILogger logger ) {
76+ if (src == null ) {
77+ return null ;
78+ }
79+ JsonArray jsonArray = new JsonArray ();
80+ List <T1 > items = src .getCurrentPage ();
81+ serializer = new DefaultSerializer (logger );
82+ for (T1 item : items ) {
83+ final String json = serializer .serializeObject (item );
84+ final JsonElement element = JsonParser .parseString (json );
85+ if (element != null && element .isJsonObject ()) {
86+ final JsonObject jsonObject = element .getAsJsonObject ();
87+ jsonArray .add (jsonObject );
88+ }
89+ }
90+ return jsonArray ;
91+ }
92+
93+ /**
94+ * Deserializes the JsonElement
95+ *
96+ * @param json the source CollectionPage's Json
97+ * @param typeOfT The type of the CollectionPage to deserialize to
98+ * @param logger the logger
99+ * @throws JsonParseException the parse exception
100+ * @return the deserialized CollectionPage
101+ */
102+ @ SuppressWarnings ("unchecked" )
103+ public static <T1 , T2 extends IRequestBuilder > BaseCollectionPage <T1 , T2 > deserialize (final JsonElement json , Type typeOfT , final ILogger logger ) throws JsonParseException {
104+ if (json == null ) {
105+ return null ;
106+ }
107+ serializer = new DefaultSerializer (logger );
108+ final JsonObject [] sourceArray = serializer .deserializeObject (json .toString (), JsonObject [].class );
109+ final ArrayList <T1 > list = new ArrayList <T1 >(sourceArray .length );
110+ /** eg: com.microsoft.graph.requests.extensions.AttachmentCollectionPage */
111+ final String collectionPageClassCanonicalName = typeOfT .getTypeName ();
112+ /** eg: com.microsoft.graph.models.extensions.Attachment */
113+ final String baseEntityClassCanonicalName = collectionPageClassCanonicalName
114+ .substring (0 , collectionPageClassCanonicalName .length () - pageLength - collectionLength )
115+ .replace ("requests" , "models" );
116+ try {
117+ final Class <?> baseEntityClass = Class .forName (baseEntityClassCanonicalName );
118+ for (JsonObject sourceObject : sourceArray ) {
119+ Class <?> entityClass = serializer .getDerivedClass (sourceObject , baseEntityClass );
120+ if (entityClass == null )
121+ entityClass = baseEntityClass ;
122+ final T1 targetObject = (T1 )serializer .deserializeObject (sourceObject .toString (), entityClass );
123+ ((IJsonBackedObject )targetObject ).setRawObject (serializer , sourceObject );
124+ list .add (targetObject );
125+ }
126+ /** eg: com.microsoft.graph.requests.extensions.AttachmentCollectionResponse */
127+ final String responseClassCanonicalName = collectionPageClassCanonicalName
128+ .substring (0 , collectionPageClassCanonicalName .length () - pageLength ) + "Response" ;
129+ final Class <?> responseClass = Class .forName (responseClassCanonicalName );
130+ final Object response = responseClass .getConstructor ().newInstance ();
131+ responseClass .getField ("value" ).set (response , list );
132+ final Class <?> collectionPageClass = Class .forName (collectionPageClassCanonicalName );
133+ /** eg: com.microsoft.graph.requests.extensions.IAttachmentCollectionRequestBuilder */
134+ final String responseBuilderInterfaceCanonicalName = responseClassCanonicalName
135+ .substring (0 , responseClassCanonicalName .length () - responseLength )
136+ .replace (extensionsPath , extensionsPath + "I" ) + "RequestBuilder" ;
137+ final Class <?> responseBuilderInterfaceClass = Class .forName (responseBuilderInterfaceCanonicalName );
138+ return (BaseCollectionPage <T1 , T2 >)collectionPageClass .getConstructor (responseClass , responseBuilderInterfaceClass ).newInstance (response , null );
139+ } catch (ClassNotFoundException ex ) {
140+ logger .logError ("Could not find class during deserialization" , ex );
141+ } catch (NoSuchMethodException | InstantiationException | InvocationTargetException ex ) {
142+ logger .logError ("Could not instanciate type during deserialization" , ex );
143+ } catch (NoSuchFieldException | IllegalAccessException ex ) {
144+ logger .logError ("Unable to set field value during deserialization" , ex );
145+ }
146+ return null ;
147+ }
148+ }
0 commit comments