File: Jdbc4SQLXML.java

package info (click to toggle)
libpgjava 8.4-701-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 3,532 kB
  • ctags: 4,162
  • sloc: java: 33,948; xml: 3,158; makefile: 14; sh: 10
file content (297 lines) | stat: -rw-r--r-- 10,787 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
package org.postgresql.jdbc4;

import org.postgresql.util.GT;
import org.postgresql.util.PSQLState;
import org.postgresql.util.PSQLException;
import org.postgresql.core.BaseConnection;

import java.io.*;
import java.sql.SQLXML;
import java.sql.SQLException;
import javax.xml.transform.Source;
import javax.xml.transform.Result;

import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.dom.DOMResult;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;

import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXResult;
import org.xml.sax.InputSource;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXParseException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;

import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;

import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stax.StAXResult;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.stream.XMLStreamException;

public class Jdbc4SQLXML implements SQLXML {

    private final BaseConnection _conn;
    private String _data;           // The actual data contained.
    private boolean _initialized;   // Has someone assigned the data for this object?
    private boolean _active;        // Is anyone in the process of loading data into us?
    private boolean _freed;

    private ByteArrayOutputStream _byteArrayOutputStream;
    private StringWriter _stringWriter;
    private DOMResult _domResult;

    public Jdbc4SQLXML(BaseConnection conn)
    {
        this(conn, null, false);
    }

    public Jdbc4SQLXML(BaseConnection conn, String data)
    {
        this(conn, data, true);
    }

    private Jdbc4SQLXML(BaseConnection conn, String data, boolean initialized)
    {
        _conn = conn;
        _data = data;
        _initialized = initialized;
        _active = false;
        _freed = false;
    }

    public synchronized void free()
    {
        _freed = true;
        _data = null;
    }

    public synchronized InputStream getBinaryStream() throws SQLException
    {
        checkFreed();
        ensureInitialized();

        if (_data == null)
            return null;

        try {
            return new ByteArrayInputStream(_conn.getEncoding().encode(_data));
        } catch (IOException ioe) {
            // This should be a can't happen exception.  We just
            // decoded this data, so it would be surprising that
            // we couldn't encode it.
            // For this reason don't make it translatable.
            throw new PSQLException("Failed to re-encode xml data.", PSQLState.DATA_ERROR, ioe);
        }
    }

    public synchronized Reader getCharacterStream() throws SQLException
    {
        checkFreed();
        ensureInitialized();

        if (_data == null)
            return null;

        return new StringReader(_data);
    }

    // We must implement this unsafely because that's what the
    // interface requires.  Because it says we're returning T
    // which is unknown, none of the return values can satisfy it
    // as Java isn't going to understand the if statements that
    // ensure they are the same.
    //
    public synchronized Source getSource(Class sourceClass) throws SQLException
    {
        checkFreed();
        ensureInitialized();

        if (_data == null)
            return null;

        try {
            if (sourceClass == null || DOMSource.class.equals(sourceClass))
            {
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = factory.newDocumentBuilder();
                builder.setErrorHandler(new NonPrintingErrorHandler());
                InputSource input = new InputSource(new StringReader(_data));
                return new DOMSource(builder.parse(input));
            }
            else if (SAXSource.class.equals(sourceClass))
            {
                InputSource is = new InputSource(new StringReader(_data));
                return new SAXSource(is);
            }
            else if (StreamSource.class.equals(sourceClass))
            {
                return new StreamSource(new StringReader(_data));
            }
            else if (StAXSource.class.equals(sourceClass))
            {
                XMLInputFactory xif = XMLInputFactory.newInstance();
                XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(_data));
                return new StAXSource(xsr);
            }
        } catch (Exception e) {
            throw new PSQLException(GT.tr("Unable to decode xml data."), PSQLState.DATA_ERROR, e);
        }

        throw new PSQLException(GT.tr("Unknown XML Source class: {0}", sourceClass), PSQLState.INVALID_PARAMETER_TYPE);
    }

    public synchronized String getString() throws SQLException
    {
        checkFreed();
        ensureInitialized();
        return _data;
    }

    public synchronized OutputStream setBinaryStream() throws SQLException
    {
        checkFreed();
        initialize();
        _active = true;
        _byteArrayOutputStream = new ByteArrayOutputStream();
        return _byteArrayOutputStream;
    }

    public synchronized Writer setCharacterStream() throws SQLException
    {
        checkFreed();
        initialize();
        _stringWriter = new StringWriter();
        return _stringWriter;
    }

    public synchronized Result setResult(Class resultClass) throws SQLException
    {
        checkFreed();
        initialize();

        if (resultClass == null || DOMResult.class.equals(resultClass)) {
            _domResult = new DOMResult();
            _active = true;
            return _domResult;
        } else if (SAXResult.class.equals(resultClass)) {
            try {
                SAXTransformerFactory transformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
                TransformerHandler transformerHandler = transformerFactory.newTransformerHandler();
                _stringWriter = new StringWriter();
                transformerHandler.setResult(new StreamResult(_stringWriter));
                _active = true;
                return new SAXResult(transformerHandler);
            } catch (TransformerException te) {
                throw new PSQLException(GT.tr("Unable to create SAXResult for SQLXML."), PSQLState.UNEXPECTED_ERROR, te);
            }
        } else if (StreamResult.class.equals(resultClass)) {
            _stringWriter = new StringWriter();
            _active = true;
            return new StreamResult(_stringWriter);
        } else if (StAXResult.class.equals(resultClass)) {
            _stringWriter = new StringWriter();
            try {
                XMLOutputFactory xof = XMLOutputFactory.newInstance();
                XMLStreamWriter xsw = xof.createXMLStreamWriter(_stringWriter);
                _active = true;
                return new StAXResult(xsw);
            } catch (XMLStreamException xse) {
                throw new PSQLException(GT.tr("Unable to create StAXResult for SQLXML"), PSQLState.UNEXPECTED_ERROR, xse);
            }
        }

        throw new PSQLException(GT.tr("Unknown XML Result class: {0}", resultClass), PSQLState.INVALID_PARAMETER_TYPE);
    }

    public synchronized void setString(String value) throws SQLException
    {
        checkFreed();
        initialize();
        _data = value;
    }

    private void checkFreed() throws SQLException
    {
        if (_freed) {
            throw new PSQLException(GT.tr("This SQLXML object has already been freed."), PSQLState.OBJECT_NOT_IN_STATE);
        }
    }

    private void ensureInitialized() throws SQLException
    {
        if (!_initialized) {
            throw new PSQLException(GT.tr("This SQLXML object has not been initialized, so you cannot retrieve data from it."), PSQLState.OBJECT_NOT_IN_STATE);
        }

        // Is anyone loading data into us at the moment?
        if (!_active)
            return;

        if (_byteArrayOutputStream != null) {
            try {
                _data = _conn.getEncoding().decode(_byteArrayOutputStream.toByteArray());
            } catch (IOException ioe) {
                throw new PSQLException(GT.tr("Failed to convert binary xml data to encoding: {0}.", _conn.getEncoding().name()), PSQLState.DATA_ERROR, ioe);
            } finally {
                _byteArrayOutputStream = null;
                _active = false;
            }
        } else if (_stringWriter != null) {
            // This is also handling the work for Stream, SAX, and StAX Results
            // as they will use the same underlying stringwriter variable.
            //
            _data = _stringWriter.toString();
            _stringWriter = null;
            _active = false;
        } else if (_domResult != null) {
            // Copy the content from the result to a source
            // and use the identify transform to get it into a
            // friendlier result format.
            try {
                TransformerFactory factory = TransformerFactory.newInstance();
                Transformer transformer = factory.newTransformer();
                DOMSource domSource = new DOMSource(_domResult.getNode());
                StringWriter stringWriter = new StringWriter();
                StreamResult streamResult = new StreamResult(stringWriter);
                transformer.transform(domSource, streamResult);
                _data = stringWriter.toString();
            } catch (TransformerException te) {
                throw new PSQLException(GT.tr("Unable to convert DOMResult SQLXML data to a string."), PSQLState.DATA_ERROR, te);
            }
            finally {
                _domResult = null;
                _active = false;
            }
        }
    }


    private void initialize() throws SQLException
    {
        if (_initialized) {
            throw new PSQLException(GT.tr("This SQLXML object has already been initialized, so you cannot manipulate it further."), PSQLState.OBJECT_NOT_IN_STATE);
        }
        _initialized = true;
    }

    // Don't clutter System.err with errors the user can't silence.
    // If something bad really happens an exception will be thrown.
    static class NonPrintingErrorHandler implements ErrorHandler
    {
        public void error(SAXParseException e) { }
        public void fatalError(SAXParseException e) { }
        public void warning(SAXParseException e) { }
    }

}