AT&T 2.0.19 Code drop, stage 1
[aaf/authz.git] / misc / env / src / main / java / org / onap / aaf / misc / env / jaxb / JAXBmar.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21
22 /**
23  * JAXBumar.java
24  *
25  * Created on: Apr 10, 2009
26  * Created by: Jonathan
27  *
28  * Revamped to do away with ThreadLocal 5/27/2011, JG1555
29  *
30  * (c) 2009 SBC Knowledge Ventures, L.P. All rights reserved.
31  ******************************************************************* 
32  * RESTRICTED - PROPRIETARY INFORMATION The Information contained 
33  * herein is for use only by authorized employees of AT&T Services, 
34  * Inc., and authorized Affiliates of AT&T Services, Inc., and is 
35  * not for general distribution within or outside the respective 
36  * companies. 
37  *******************************************************************
38  */
39 package org.onap.aaf.misc.env.jaxb;
40
41 import java.io.OutputStream;
42 import java.io.StringWriter;
43 import java.io.Writer;
44 import java.util.HashMap;
45 import java.util.Map;
46
47 import javax.xml.bind.JAXBContext;
48 import javax.xml.bind.JAXBElement;
49 import javax.xml.bind.JAXBException;
50 import javax.xml.bind.Marshaller;
51 import javax.xml.namespace.QName;
52
53 import org.onap.aaf.misc.env.APIException;
54 import org.onap.aaf.misc.env.LogTarget;
55 import org.onap.aaf.misc.env.util.Pool;
56 import org.onap.aaf.misc.env.util.Pool.Pooled;
57
58 /**
59  * JAXBmar classes are inexpensive for going in and out of scope
60  * and have been made thread safe via Pooling
61
62  * @author Jonathan
63  *
64  */
65 public class JAXBmar {
66         // Need to store off possible JAXBContexts based on Class, which will be stored in Creator
67         private static Map<Class<?>[],Pool<PMarshaller>> pools = new HashMap<Class<?>[], Pool<PMarshaller>>();
68
69         // Handle Marshaller class setting of properties only when needed
70         private class PMarshaller {
71                 private Marshaller m;
72                 private boolean p;
73                 private boolean f;
74                 
75                 public PMarshaller(Marshaller marshaller) throws JAXBException {
76                         m = marshaller;
77                 m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
78                 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, p = false);
79                 m.setProperty(Marshaller.JAXB_FRAGMENT, f = false);
80                 }
81                 
82                 public Marshaller get(boolean pretty, boolean fragment) throws JAXBException {
83                         if(pretty != p) {
84                         m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, p = pretty);
85                         }
86                         if(fragment != f) {
87                         m.setProperty(Marshaller.JAXB_FRAGMENT, f = fragment);
88                         }
89                         return m;
90                 }
91         }
92         
93         private class Creator implements Pool.Creator<PMarshaller> {
94                 private JAXBContext jc;
95                 private String name;
96                 public Creator(Class<?>[] classes) throws JAXBException {
97                         jc = JAXBContext.newInstance(classes);
98                         name = "JAXBmar: " + classes[0].getName();
99                 }
100                 
101                 // @Override
102                 public PMarshaller create() throws APIException {
103                         try {
104                                 return new PMarshaller(jc.createMarshaller());
105                         } catch (JAXBException e) {
106                                 throw new APIException(e);
107                         }
108                 }
109
110                 public String toString() {
111                         return name;
112                 }
113
114                 // @Override
115                 public void reuse(PMarshaller pm) {
116                         // Nothing to do
117                 }
118                 
119                 // @Override
120                 public void destroy(PMarshaller pm) {
121                         // Nothing to do
122                 }
123
124                 // @Override
125                 public boolean isValid(PMarshaller t) {
126                         return true; 
127                 }
128         }
129
130         //TODO isn't UTF-8 a standard string somewhere for encoding?
131         private boolean fragment= false;
132         private boolean pretty=false;
133         private QName qname;
134         
135         private Pool<PMarshaller> mpool; // specific Pool associated with constructed Classes
136         private Class<?> cls;
137         
138         private Pool<PMarshaller> getPool(Class<?> ... classes) throws JAXBException {
139                 Pool<PMarshaller> mp;
140                 synchronized(pools) {
141                         mp = pools.get(classes);
142                         if(mp==null) {
143                                 pools.put(classes,mp = new Pool<PMarshaller>(new Creator(classes)));
144                         }
145                 }               
146                 return mp;
147         }
148         
149         public JAXBmar(Class<?>... classes) throws JAXBException {
150                 cls = classes[0];
151                 mpool = getPool(classes);
152                 qname = null;
153         }
154
155         public JAXBmar(QName theQname, Class<?>... classes) throws JAXBException {
156                 cls = classes[0];
157                 mpool = getPool(classes);
158                 qname = theQname;
159         }
160
161         @SuppressWarnings("unchecked")
162         public<O> O marshal(LogTarget lt,O o, Writer writer, boolean ... options) throws JAXBException, APIException {
163                 boolean pretty, fragment;
164                 pretty = options.length>0?options[0]:this.pretty;
165                 fragment = options.length>1?options[1]:this.fragment;
166                 Pooled<PMarshaller> m = mpool.get(lt);
167                 try {
168                         if(qname==null) {
169                                 m.content.get(pretty,fragment).marshal(o, writer);
170                         } else {
171                                 m.content.get(pretty,fragment).marshal(
172                                         new JAXBElement<O>(qname, (Class<O>)cls, o ),
173                                         writer);
174                         }
175                         return o;
176                 } finally {
177                         m.done();
178                 }
179         }
180
181         @SuppressWarnings("unchecked")
182         public<O> O marshal(LogTarget lt, O o, OutputStream os, boolean ... options) throws JAXBException, APIException {
183                 boolean pretty, fragment;
184                 pretty = options.length>0?options[0]:this.pretty;
185                 fragment = options.length>1?options[1]:this.fragment;
186                 Pooled<PMarshaller> m = mpool.get(lt);
187                 try {
188                         if(qname==null) {
189                                 m.content.get(pretty,fragment).marshal(o, os);
190                         } else {
191                                 m.content.get(pretty,fragment).marshal(
192                                         new JAXBElement<O>(qname, (Class<O>)cls, o ),os);
193                         }
194                         return o;
195                 } finally {
196                         m.done();
197                 }
198         }
199         
200         public<O> O marshal(LogTarget lt, O o, Writer writer, Class<O> clss) throws JAXBException, APIException {
201                 Pooled<PMarshaller> m = mpool.get(lt);
202                 try {
203                         if(qname==null) {
204                                 m.content.get(pretty,fragment).marshal(o, writer);
205                         } else {
206                                 m.content.get(pretty,fragment).marshal(
207                                         new JAXBElement<O>(qname, clss, o),writer);
208                         }
209                         return o;
210                 } finally {
211                         m.done();
212                 }
213                         
214         }
215
216         public<O> O marshal(LogTarget lt, O o, OutputStream os, Class<O> clss) throws JAXBException, APIException {
217                 Pooled<PMarshaller> m = mpool.get(lt);
218                 try {
219                         if(qname==null) { 
220                                 m.content.get(pretty,fragment).marshal(o, os);
221                         } else {
222                                 m.content.get(pretty,fragment).marshal(
223                                         new JAXBElement<O>(qname, clss, o ),os);
224                         }
225                         return o;
226                 } finally {
227                         m.done();
228                 }
229         }
230
231         /**
232          * @return
233          */
234         public Class<?> getMarshalClass() {
235                 return cls;
236         }
237
238         public<O> String stringify(LogTarget lt, O o) throws JAXBException, APIException {
239                 StringWriter sw = new StringWriter();
240                 marshal(lt,o,sw);
241                 return sw.toString();
242         }
243
244         public JAXBmar pretty(boolean pretty) {
245                 this.pretty = pretty;
246                 return this;
247         }
248         
249         public JAXBmar asFragment(boolean fragment) {
250                 this.fragment = fragment;
251                 return this;
252         }
253 }