84502adef8e64aad98ff043508a8f4faa9f17e67
[aaf/authz.git] / misc / env / src / main / java / org / onap / aaf / misc / env / jaxb / JAXBData.java
1 /**\r
2  * ============LICENSE_START====================================================\r
3  * org.onap.aaf\r
4  * ===========================================================================\r
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.\r
6  * ===========================================================================\r
7  * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * you may not use this file except in compliance with the License.\r
9  * You may obtain a copy of the License at\r
10  * \r
11  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * \r
13  * Unless required by applicable law or agreed to in writing, software\r
14  * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * See the License for the specific language governing permissions and\r
17  * limitations under the License.\r
18  * ============LICENSE_END====================================================\r
19  *\r
20  */\r
21 \r
22 package org.onap.aaf.misc.env.jaxb;\r
23 \r
24 import java.io.ByteArrayInputStream;\r
25 import java.io.IOException;\r
26 import java.io.InputStream;\r
27 import java.io.OutputStream;\r
28 import java.io.Reader;\r
29 import java.io.Writer;\r
30 \r
31 import javax.xml.bind.JAXBException;\r
32 \r
33 import org.onap.aaf.misc.env.APIException;\r
34 import org.onap.aaf.misc.env.Data;\r
35 import org.onap.aaf.misc.env.Env;\r
36 import org.onap.aaf.misc.env.EnvJAXB;\r
37 import org.onap.aaf.misc.env.old.IOStringifier;\r
38 import org.onap.aaf.misc.env.old.Objectifier;\r
39 import org.onap.aaf.misc.env.old.Stringifier;\r
40 /**\r
41  * <H1>Data</H1>\r
42  * <i>Data</i> facilitates lazy marshaling of data with a pre-determined\r
43  * marshaling mechanism.<p>\r
44  * \r
45  * It stores either Object (defined by Generic {@literal <T>}) or String.<p>  \r
46  * \r
47  * On asking for Object of type {@literal <T>}, it will respond with the object\r
48  * if it exists, or unmarshal the string and pass the result back.<p>\r
49  * \r
50  * On asking for String, it will respond with the String\r
51  * if it exists, or marshal the String and pass the result back.<p>\r
52  * \r
53  * @author Jonathan\r
54  *\r
55  * @param <T>\r
56  */\r
57 public final class JAXBData<T> implements Data<T>{\r
58         private Stringifier<T> stringifier;\r
59         private Objectifier<T> objectifier;\r
60         private String dataAsString;\r
61         private T dataAsObject;\r
62         private Class<T> tclass;\r
63         private JAXBDF<T> df;\r
64         private Env creatingEnv;\r
65         private boolean options[] = new boolean[] {false, false};\r
66         \r
67         /**\r
68          * Construct a Data Object with an appropriate Stringifier, Objectifier and Class to support\r
69          * \r
70          * @param env\r
71          * @param strfr\r
72          * @param objfr\r
73          * @param text\r
74          * @param typeClass\r
75          */\r
76         JAXBData(Env env, JAXBDF<T> df, Stringifier<T> strfr, Objectifier<T> objfr, String text, Class<T> typeClass) {\r
77                 dataAsString = text;\r
78                 dataAsObject = null;\r
79                 stringifier = strfr;\r
80                 objectifier = objfr;\r
81                 tclass = typeClass;\r
82                 creatingEnv = env;\r
83                 this.df = df;\r
84         }\r
85         \r
86         \r
87         /**\r
88          * Construct a Data Object with an appropriate Stringifier, Objectifier and Object (which will\r
89          * yield it's class)\r
90          * \r
91          * @param env\r
92          * @param strfr\r
93          * @param objfr\r
94          * @param object\r
95          */\r
96         @SuppressWarnings("unchecked")\r
97         JAXBData(Env env, JAXBDF<T> df, Stringifier<T> strfr, Objectifier<T> objfr, T object) {\r
98                 dataAsString = null;\r
99                 dataAsObject = object;\r
100                 stringifier = strfr;\r
101                 objectifier = objfr;\r
102                 tclass = (Class<T>) object.getClass();\r
103                 creatingEnv = env;\r
104                 this.df = df;\r
105         }\r
106 \r
107         /**\r
108          * Respond with the String if it exists, or marshal the String and pass the result back.<p>\r
109          * \r
110          * Explicitly use a specific Env for logging purposes\r
111          * \r
112          * @param env\r
113          * @return String\r
114          * @throws APIException\r
115          */\r
116         public String asString(EnvJAXB env) throws APIException {\r
117                 if(dataAsString!=null) {\r
118                         return dataAsString;\r
119                 } else {\r
120                         return dataAsString = stringifier.stringify(env, dataAsObject);\r
121                 }\r
122         }\r
123 \r
124         /**\r
125          * Respond with the String if it exists, or marshal the String and pass the result back.\r
126          * \r
127          * However, use the Env the Data Object was created with.\r
128          * \r
129          * @return String\r
130          * @throws APIException\r
131          */\r
132         // @Override\r
133         public String asString() throws APIException {\r
134                 if(dataAsString!=null) {\r
135                         return dataAsString;\r
136                 } else {\r
137                         return dataAsString = stringifier.stringify(creatingEnv, dataAsObject,options);\r
138                 }\r
139         }\r
140         \r
141         public Data<T> to(OutputStream os) throws APIException, IOException {\r
142                 if(dataAsString!=null) {\r
143                         os.write(dataAsString.getBytes());\r
144                 } else if (stringifier instanceof IOStringifier){\r
145                         ((IOStringifier<T>)stringifier).stringify(creatingEnv, dataAsObject, os, options);\r
146                 } else {\r
147                         dataAsString = stringifier.stringify(creatingEnv, dataAsObject, options);\r
148                         os.write(dataAsString.getBytes());\r
149                 }\r
150                 return this;\r
151         }\r
152 \r
153 \r
154         // @Override\r
155         public JAXBData<T> to(Writer writer) throws APIException, IOException {\r
156                 if(dataAsString!=null) {\r
157                         writer.write(dataAsString);\r
158                 } else if (stringifier instanceof IOStringifier){\r
159                         ((IOStringifier<T>)stringifier).stringify(creatingEnv, dataAsObject, writer, options);\r
160                 } else {\r
161                         dataAsString = stringifier.stringify(creatingEnv, dataAsObject, options);\r
162                         writer.write(dataAsString);\r
163                 }\r
164                 return this;\r
165         }\r
166 \r
167 \r
168         public InputStream getInputStream() throws APIException {\r
169                 if(dataAsString==null) {\r
170                         dataAsString = stringifier.stringify(creatingEnv,dataAsObject,options);\r
171                 }\r
172                 return new ByteArrayInputStream(dataAsString.getBytes());\r
173         }\r
174         \r
175         /**\r
176          * Respond with the Object of type {@literal <T>} if it exists, or unmarshal from String \r
177          * and pass the result back.<p>\r
178          * \r
179          * Explicitly use a specific Env for logging purposes\r
180          * \r
181          * @param env\r
182          * @return T\r
183          * @throws APIException\r
184          */\r
185 \r
186         public T asObject(EnvJAXB env) throws APIException {\r
187                 if(dataAsObject !=null) {\r
188                         return dataAsObject;\r
189                 } else {\r
190                         // Some Java compilers need two statements here\r
191                         dataAsObject = objectifier.objectify(env, dataAsString);\r
192                         return dataAsObject;\r
193                 }\r
194         }\r
195 \r
196         /**\r
197          * Respond with the Object of type {@literal <T>} if it exists, or unmarshal from String \r
198          * and pass the result back.<p>\r
199          *\r
200          * However, use the Env the Data Object was created with.\r
201          * \r
202          * @return T\r
203          * @throws APIException\r
204          */\r
205         // @Override\r
206         public T asObject() throws APIException {\r
207                 if(dataAsObject !=null) {\r
208                         return dataAsObject;\r
209                 } else {\r
210                         // Some Java compilers need two statements here\r
211                         dataAsObject = objectifier.objectify(creatingEnv, dataAsString);\r
212                         return dataAsObject;\r
213                 }\r
214         }\r
215         \r
216 \r
217         /**\r
218          * Return the Class Type supported by this DataObject\r
219          * \r
220          * @return {@literal Class<T>}\r
221          */\r
222         // @Override\r
223         public Class<T> getTypeClass() {\r
224                 return tclass;\r
225         }\r
226         \r
227         \r
228         /**\r
229          * For Debugging Convenience, we marshal to String if possible.\r
230          * \r
231          * Behavior is essentially the same as asString(), except asString() throws\r
232          * an APIException.  <p>\r
233          * Since toString() must not throw exceptions, the function just catches and prints an\r
234          * error, which is probably not the behavior desired.<p>\r
235          *  \r
236          * Therefore, use "asString()" where possible in actual Transactional code. \r
237          * \r
238          * @see java.lang.Object#toString()\r
239          */\r
240         // @Override\r
241         public String toString() {\r
242                 if(dataAsString!=null) {\r
243                         return dataAsString;\r
244                 } else {\r
245                         try {\r
246                                 return dataAsString = stringifier.stringify(creatingEnv, dataAsObject);\r
247                         } catch (APIException e) {\r
248                                 return "ERROR - Can't Stringify from Object " + e.getLocalizedMessage();\r
249                         }\r
250                 }\r
251         }\r
252 \r
253         public Data<T> load(T t) throws APIException {\r
254                 dataAsObject = t;\r
255                 dataAsString = null;\r
256                 return this;\r
257         }\r
258 \r
259 \r
260         public Data<T> load(String str) throws APIException {\r
261                 dataAsObject = null;\r
262                 dataAsString = str;\r
263                 return this;\r
264         }\r
265 \r
266 \r
267         public Data<T> load(InputStream is) throws APIException {\r
268                 try {\r
269                         dataAsObject = df.jumar.unmarshal(creatingEnv.debug(),is);\r
270                         dataAsString = null;\r
271                 } catch (JAXBException e) {\r
272                         throw new APIException(e);\r
273                 }\r
274                 return this;\r
275         }\r
276 \r
277 \r
278         public Data<T> load(Reader rdr) throws APIException {\r
279                 try {\r
280                         dataAsObject = df.jumar.unmarshal(creatingEnv.debug(),rdr);\r
281                         dataAsString = null;\r
282                 } catch (JAXBException e) {\r
283                         throw new APIException(e);\r
284                 }\r
285                 return this;\r
286         }\r
287 \r
288 \r
289         // @Override\r
290         public void direct(InputStream input, OutputStream output) throws APIException, IOException {\r
291                 byte b[] = new byte[128];\r
292                 int count;\r
293                 do {\r
294                         count = input.read(b);\r
295                         if(count>0)output.write(b, 0, count);\r
296                 } while(count>=0);\r
297         }\r
298 \r
299 \r
300         // @Override\r
301         public Data<T> out(TYPE type) {\r
302                 // it's going to be XML regardless...\r
303                 return this;\r
304         }\r
305 \r
306 \r
307         // @Override\r
308         public Data<T> in(TYPE type) {\r
309                 // Not Supported... will still be XML\r
310                 return this;\r
311         }\r
312 \r
313 \r
314         // @Override\r
315         public Data<T> option(int option) {\r
316                 options[0] = (option&Data.PRETTY)==Data.PRETTY;\r
317                 options[1] = (option&Data.FRAGMENT)==Data.FRAGMENT;\r
318                 return this;\r
319         }\r
320         \r
321 }