1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.dsmlv2;
21
22
23 import java.util.Arrays;
24 import java.util.Collection;
25
26 import javax.xml.transform.Transformer;
27 import javax.xml.transform.TransformerConfigurationException;
28 import javax.xml.transform.TransformerException;
29 import javax.xml.transform.TransformerFactory;
30 import javax.xml.transform.stream.StreamSource;
31
32 import org.apache.directory.api.dsmlv2.actions.ReadSoapHeader;
33 import org.apache.directory.api.dsmlv2.request.BatchRequestDsml;
34 import org.apache.directory.api.dsmlv2.request.BatchRequestDsml.Processing;
35 import org.apache.directory.api.dsmlv2.request.BatchRequestDsml.ResponseOrder;
36 import org.apache.directory.api.i18n.I18n;
37 import org.apache.directory.api.ldap.codec.api.CodecControl;
38 import org.apache.directory.api.ldap.codec.api.LdapApiService;
39 import org.apache.directory.api.ldap.model.entry.BinaryValue;
40 import org.apache.directory.api.ldap.model.entry.StringValue;
41 import org.apache.directory.api.ldap.model.ldif.LdifUtils;
42 import org.apache.directory.api.ldap.model.message.Control;
43 import org.apache.directory.api.util.Base64;
44 import org.apache.directory.api.util.Strings;
45 import org.dom4j.Document;
46 import org.dom4j.Element;
47 import org.dom4j.Namespace;
48 import org.dom4j.QName;
49 import org.dom4j.io.DocumentResult;
50 import org.dom4j.io.DocumentSource;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53 import org.xmlpull.v1.XmlPullParser;
54 import org.xmlpull.v1.XmlPullParserException;
55
56
57
58
59
60
61
62 public final class ParserUtils
63 {
64
65 public static final String XML_SCHEMA_URI = "http://www.w3.org/2001/XMLSchema";
66
67
68 public static final String XML_SCHEMA_INSTANCE_URI = "http://www.w3.org/2001/XMLSchema-instance";
69
70
71 public static final String BASE64BINARY = "base64Binary";
72
73
74 public static final String XSI = "xsi";
75
76
77 public static final String XSD = "xsd";
78
79
80 public static final Namespace DSML_NAMESPACE = new Namespace( null, "urn:oasis:names:tc:DSML:2:0:core" );
81
82
83 public static final Namespace XSD_NAMESPACE = new Namespace( XSD, XML_SCHEMA_URI );
84
85
86 public static final Namespace XSI_NAMESPACE = new Namespace( XSI, XML_SCHEMA_INSTANCE_URI );
87
88
89 private static final Logger LOG = LoggerFactory.getLogger( ParserUtils.class );
90
91
92 private ParserUtils()
93 {
94 }
95
96
97
98
99
100
101
102
103 public static String getXsiTypeAttributeValue( XmlPullParser xpp )
104 {
105 String type = null;
106 int nbAttributes = xpp.getAttributeCount();
107
108 for ( int i = 0; i < nbAttributes; i++ )
109 {
110
111 if ( xpp.getAttributeName( i ).equals( "type" )
112 && xpp.getNamespace( xpp.getAttributePrefix( i ) ).equals( XML_SCHEMA_INSTANCE_URI ) )
113 {
114 type = xpp.getAttributeValue( i );
115 break;
116 }
117 }
118
119 return type;
120 }
121
122
123
124
125
126
127
128
129
130 public static boolean isBase64BinaryValue( XmlPullParser parser, String attrValue )
131 {
132 if ( attrValue == null )
133 {
134 return false;
135 }
136
137
138
139 String[] splitedString = attrValue.split( ":" );
140
141 return ( splitedString.length == 2 ) && ( XML_SCHEMA_URI.equals( parser.getNamespace( splitedString[0] ) ) )
142 && ( BASE64BINARY.equals( splitedString[1] ) );
143 }
144
145
146
147
148
149
150
151
152 public static boolean needsBase64Encoding( Object value )
153 {
154 if ( value instanceof StringValue )
155 {
156 return false;
157 }
158 else if ( value instanceof BinaryValue )
159 {
160 return false;
161 }
162 else if ( value instanceof byte[] )
163 {
164 return true;
165 }
166 else if ( value instanceof String )
167 {
168 return !LdifUtils.isLDIFSafe( ( String ) value );
169 }
170
171 return true;
172 }
173
174
175
176
177
178
179
180
181 public static String base64Encode( Object value )
182 {
183 if ( value instanceof byte[] )
184 {
185 return new String( Base64.encode( ( byte[] ) value ) );
186 }
187 else if ( value instanceof String )
188 {
189 return new String( Base64.encode( Strings.getBytesUtf8( ( String ) value ) ) );
190 }
191
192 return "";
193 }
194
195
196
197
198
199
200
201
202
203
204 public static int parseAndVerifyRequestID( String attributeValue, XmlPullParser xpp ) throws XmlPullParserException
205 {
206 try
207 {
208 int requestID = Integer.parseInt( attributeValue );
209
210 if ( requestID < 0 )
211 {
212 throw new XmlPullParserException( I18n.err( I18n.ERR_03038, requestID ), xpp, null );
213 }
214
215 return requestID;
216 }
217 catch ( NumberFormatException nfe )
218 {
219 throw new XmlPullParserException( I18n.err( I18n.ERR_03039 ), xpp, nfe );
220 }
221 }
222
223
224
225
226
227
228
229
230
231 public static void addControls( LdapApiService codec, Element element, Collection<Control> controls )
232 {
233 if ( controls != null )
234 {
235 for ( Control control : controls )
236 {
237 Element controlElement = element.addElement( "control" );
238
239 if ( control.getOid() != null )
240 {
241 controlElement.addAttribute( "type", control.getOid() );
242 }
243
244 if ( control.isCritical() )
245 {
246 controlElement.addAttribute( "criticality", "true" );
247 }
248
249 byte[] value;
250
251 if ( control instanceof CodecControl<?> )
252 {
253 value = ( ( org.apache.directory.api.ldap.codec.api.CodecControl<?> ) control ).getValue();
254 }
255 else
256 {
257 value = codec.newControl( control ).getValue();
258 }
259
260 if ( value != null )
261 {
262 if ( ParserUtils.needsBase64Encoding( value ) )
263 {
264 element.getDocument().getRootElement().add( XSD_NAMESPACE );
265 element.getDocument().getRootElement().add( XSI_NAMESPACE );
266
267 Element valueElement = controlElement.addElement( "controlValue" ).addText(
268 ParserUtils.base64Encode( value ) );
269 valueElement.addAttribute( new QName( "type", XSI_NAMESPACE ), ParserUtils.XSD + ":"
270 + ParserUtils.BASE64BINARY );
271 }
272 else
273 {
274 controlElement.addElement( "controlValue" ).setText( Arrays.toString( value ) );
275 }
276 }
277 }
278 }
279 }
280
281
282
283
284
285
286
287
288
289 public static boolean isRequestIdNeeded( Dsmlv2Container container ) throws XmlPullParserException
290 {
291 BatchRequestDsml batchRequest = container.getBatchRequest();
292
293 if ( batchRequest == null )
294 {
295 throw new XmlPullParserException( I18n.err( I18n.ERR_03040 ), container.getParser(), null );
296 }
297
298 return ( ( batchRequest.getProcessing() == Processing.PARALLEL ) && ( batchRequest.getResponseOrder() == ResponseOrder.UNORDERED ) );
299 }
300
301
302
303
304
305
306
307
308 public static Document styleDocument( Document document )
309 {
310
311 TransformerFactory factory = TransformerFactory.newInstance();
312 Transformer transformer = null;
313
314 try
315 {
316 transformer = factory.newTransformer( new StreamSource( ParserUtils.class
317 .getResourceAsStream( "/org/apache/directory/shared/dsmlv2/DSMLv2.xslt" ) ) );
318 }
319 catch ( TransformerConfigurationException e1 )
320 {
321 LOG.warn( "Failed to create the XSLT transformer", e1 );
322
323 return document;
324 }
325
326
327 DocumentSource source = new DocumentSource( document );
328 DocumentResult result = new DocumentResult();
329
330 try
331 {
332 transformer.transform( source, result );
333 }
334 catch ( TransformerException e )
335 {
336
337 return document;
338 }
339
340
341 Document transformedDoc = result.getDocument();
342 return transformedDoc;
343 }
344
345
346
347
348 public static final GrammarAction READ_SOAP_HEADER = new ReadSoapHeader();
349 }