Skip to content

Commit 1c7bd98

Browse files
committed
1 parent 06d90d1 commit 1c7bd98

File tree

15 files changed

+436
-56
lines changed

15 files changed

+436
-56
lines changed

src/main/java/org/apache/ibatis/builder/annotation/MapperAnnotationBuilder.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.apache.ibatis.builder.annotation;
22

33
import java.io.IOException;
4-
import java.io.Reader;
4+
import java.io.InputStream;
55
import java.lang.annotation.Annotation;
66
import java.lang.reflect.Method;
77
import java.lang.reflect.ParameterizedType;
@@ -104,14 +104,14 @@ public void parse() {
104104

105105
private void loadXmlResource() {
106106
String xmlResource = type.getName().replace('.', '/') + ".xml";
107-
Reader xmlReader = null;
107+
InputStream inputStream = null;
108108
try {
109-
xmlReader = Resources.getResourceAsReader(type.getClassLoader(), xmlResource);
109+
inputStream = Resources.getResourceAsStream(type.getClassLoader(), xmlResource);
110110
} catch (IOException e) {
111111
// ignore, resource is not required
112112
}
113-
if (xmlReader != null) {
114-
XMLMapperBuilder xmlParser = new XMLMapperBuilder(xmlReader, assistant.getConfiguration(), xmlResource, configuration.getSqlFragments(), type.getName());
113+
if (inputStream != null) {
114+
XMLMapperBuilder xmlParser = new XMLMapperBuilder(inputStream, assistant.getConfiguration(), xmlResource, configuration.getSqlFragments(), type.getName());
115115
xmlParser.parse();
116116
}
117117
}

src/main/java/org/apache/ibatis/builder/xml/XMLConfigBuilder.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package org.apache.ibatis.builder.xml;
22

3+
import java.io.InputStream;
4+
import java.io.Reader;
5+
import java.util.Properties;
6+
37
import org.apache.ibatis.builder.BaseBuilder;
48
import org.apache.ibatis.builder.BuilderException;
59
import org.apache.ibatis.datasource.DataSourceFactory;
610
import org.apache.ibatis.executor.ErrorContext;
11+
import org.apache.ibatis.io.ReaderInputStream;
712
import org.apache.ibatis.io.Resources;
813
import org.apache.ibatis.mapping.Environment;
914
import org.apache.ibatis.parsing.XNode;
@@ -12,15 +17,12 @@
1217
import org.apache.ibatis.reflection.MetaClass;
1318
import org.apache.ibatis.reflection.factory.ObjectFactory;
1419
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
20+
import org.apache.ibatis.session.AutoMappingBehavior;
1521
import org.apache.ibatis.session.Configuration;
1622
import org.apache.ibatis.session.ExecutorType;
17-
import org.apache.ibatis.session.AutoMappingBehavior;
1823
import org.apache.ibatis.transaction.TransactionFactory;
1924
import org.apache.ibatis.type.TypeHandler;
2025

21-
import java.io.Reader;
22-
import java.util.Properties;
23-
2426
public class XMLConfigBuilder extends BaseBuilder {
2527

2628
private boolean parsed;
@@ -30,18 +32,30 @@ public class XMLConfigBuilder extends BaseBuilder {
3032
public XMLConfigBuilder(Reader reader) {
3133
this(reader, null, null);
3234
}
33-
35+
3436
public XMLConfigBuilder(Reader reader, String environment) {
3537
this(reader, environment, null);
3638
}
3739

3840
public XMLConfigBuilder(Reader reader, String environment, Properties props) {
41+
this(new ReaderInputStream(reader), environment, props);
42+
}
43+
44+
public XMLConfigBuilder(InputStream inputStream) {
45+
this(inputStream, null, null);
46+
}
47+
48+
public XMLConfigBuilder(InputStream inputStream, String environment) {
49+
this(inputStream, environment, null);
50+
}
51+
52+
public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
3953
super(new Configuration());
4054
ErrorContext.instance().resource("SQL Mapper Configuration");
4155
this.configuration.setVariables(props);
4256
this.parsed = false;
4357
this.environment = environment;
44-
this.parser = new XPathParser(reader, true, props, new XMLMapperEntityResolver());
58+
this.parser = new XPathParser(inputStream, true, props, new XMLMapperEntityResolver());
4559
}
4660

4761
public Configuration parse() {
@@ -230,16 +244,16 @@ private void mapperElement(XNode parent) throws Exception {
230244
for (XNode child : parent.getChildren()) {
231245
String resource = child.getStringAttribute("resource");
232246
String url = child.getStringAttribute("url");
233-
Reader reader;
247+
InputStream inputStream;
234248
if (resource != null && url == null) {
235249
ErrorContext.instance().resource(resource);
236-
reader = Resources.getResourceAsReader(resource);
237-
XMLMapperBuilder mapperParser = new XMLMapperBuilder(reader, configuration, resource, configuration.getSqlFragments());
250+
inputStream = Resources.getResourceAsStream(resource);
251+
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
238252
mapperParser.parse();
239253
} else if (url != null && resource == null) {
240254
ErrorContext.instance().resource(url);
241-
reader = Resources.getUrlAsReader(url);
242-
XMLMapperBuilder mapperParser = new XMLMapperBuilder(reader, configuration, url, configuration.getSqlFragments());
255+
inputStream = Resources.getUrlAsStream(url);
256+
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
243257
mapperParser.parse();
244258
} else {
245259
throw new BuilderException("A mapper element may only specify a url or resource, but not both.");

src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.apache.ibatis.builder.xml;
22

3+
import java.io.InputStream;
34
import java.io.Reader;
45
import java.util.ArrayList;
56
import java.util.Collections;
@@ -12,6 +13,7 @@
1213
import org.apache.ibatis.builder.MapperBuilderAssistant;
1314
import org.apache.ibatis.cache.Cache;
1415
import org.apache.ibatis.executor.ErrorContext;
16+
import org.apache.ibatis.io.ReaderInputStream;
1517
import org.apache.ibatis.io.Resources;
1618
import org.apache.ibatis.mapping.Discriminator;
1719
import org.apache.ibatis.mapping.ParameterMapping;
@@ -33,14 +35,22 @@ public class XMLMapperBuilder extends BaseBuilder {
3335
private String resource;
3436

3537
public XMLMapperBuilder(Reader reader, Configuration configuration, String resource, Map<String, XNode> sqlFragments, String namespace) {
36-
this(reader, configuration, resource, sqlFragments);
37-
this.builderAssistant.setCurrentNamespace(namespace);
38+
this(new ReaderInputStream(reader), configuration, resource, sqlFragments, namespace);
3839
}
3940

4041
public XMLMapperBuilder(Reader reader, Configuration configuration, String resource, Map<String, XNode> sqlFragments) {
42+
this(new ReaderInputStream(reader), configuration, resource, sqlFragments);
43+
}
44+
45+
public XMLMapperBuilder(InputStream inputStream, Configuration configuration, String resource, Map<String, XNode> sqlFragments, String namespace) {
46+
this(inputStream, configuration, resource, sqlFragments);
47+
this.builderAssistant.setCurrentNamespace(namespace);
48+
}
49+
50+
public XMLMapperBuilder(InputStream inputStream, Configuration configuration, String resource, Map<String, XNode> sqlFragments) {
4151
super(configuration);
4252
this.builderAssistant = new MapperBuilderAssistant(configuration, resource);
43-
this.parser = new XPathParser(reader, true, configuration.getVariables(), new XMLMapperEntityResolver());
53+
this.parser = new XPathParser(inputStream, true, configuration.getVariables(), new XMLMapperEntityResolver());
4454
this.sqlFragments = sqlFragments;
4555
this.resource = resource;
4656
}
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
package org.apache.ibatis.io;
2+
3+
import java.io.IOException;
4+
import java.io.InputStream;
5+
import java.io.Reader;
6+
7+
/**
8+
* Adapts a <code>Reader</code> as an <code>InputStream</code>.
9+
* Adapted from <CODE>StringInputStream</CODE>.
10+
*
11+
*/
12+
public class ReaderInputStream extends InputStream {
13+
14+
/** Source Reader */
15+
private Reader in;
16+
17+
private String encoding = System.getProperty("file.encoding");
18+
19+
private byte[] slack;
20+
21+
private int begin;
22+
23+
/**
24+
* Construct a <CODE>ReaderInputStream</CODE>
25+
* for the specified <CODE>Reader</CODE>.
26+
*
27+
* @param reader <CODE>Reader</CODE>. Must not be <code>null</code>.
28+
*/
29+
public ReaderInputStream(Reader reader) {
30+
in = reader;
31+
}
32+
33+
/**
34+
* Construct a <CODE>ReaderInputStream</CODE>
35+
* for the specified <CODE>Reader</CODE>,
36+
* with the specified encoding.
37+
*
38+
* @param reader non-null <CODE>Reader</CODE>.
39+
* @param encoding non-null <CODE>String</CODE> encoding.
40+
*/
41+
public ReaderInputStream(Reader reader, String encoding) {
42+
this(reader);
43+
if (encoding == null) {
44+
throw new IllegalArgumentException("encoding must not be null");
45+
} else {
46+
this.encoding = encoding;
47+
}
48+
}
49+
50+
/**
51+
* Reads from the <CODE>Reader</CODE>, returning the same value.
52+
*
53+
* @return the value of the next character in the <CODE>Reader</CODE>.
54+
*
55+
* @exception IOException if the original <code>Reader</code> fails to be read
56+
*/
57+
public synchronized int read() throws IOException {
58+
if (in == null) {
59+
throw new IOException("Stream Closed");
60+
}
61+
62+
byte result;
63+
if (slack != null && begin < slack.length) {
64+
result = slack[begin];
65+
if (++begin == slack.length) {
66+
slack = null;
67+
}
68+
} else {
69+
byte[] buf = new byte[1];
70+
if (read(buf, 0, 1) <= 0) {
71+
result = -1;
72+
}
73+
result = buf[0];
74+
}
75+
76+
if (result < -1) {
77+
result += 256;
78+
}
79+
80+
return result;
81+
}
82+
83+
/**
84+
* Reads from the <code>Reader</code> into a byte array
85+
*
86+
* @param b the byte array to read into
87+
* @param off the offset in the byte array
88+
* @param len the length in the byte array to fill
89+
* @return the actual number read into the byte array, -1 at
90+
* the end of the stream
91+
* @exception IOException if an error occurs
92+
*/
93+
public synchronized int read(byte[] b, int off, int len) throws IOException {
94+
if (in == null) {
95+
throw new IOException("Stream Closed");
96+
}
97+
98+
while (slack == null) {
99+
char[] buf = new char[len]; // might read too much
100+
int n = in.read(buf);
101+
if (n == -1) {
102+
return -1;
103+
}
104+
if (n > 0) {
105+
slack = new String(buf, 0, n).getBytes(encoding);
106+
begin = 0;
107+
}
108+
}
109+
110+
if (len > slack.length - begin) {
111+
len = slack.length - begin;
112+
}
113+
114+
System.arraycopy(slack, begin, b, off, len);
115+
116+
if ((begin += len) >= slack.length) {
117+
slack = null;
118+
}
119+
120+
return len;
121+
}
122+
123+
/**
124+
* Marks the read limit of the StringReader.
125+
*
126+
* @param limit the maximum limit of bytes that can be read before the
127+
* mark position becomes invalid
128+
*/
129+
public synchronized void mark(final int limit) {
130+
try {
131+
in.mark(limit);
132+
} catch (IOException ioe) {
133+
throw new RuntimeException(ioe.getMessage());
134+
}
135+
}
136+
137+
/**
138+
* @return the current number of bytes ready for reading
139+
* @exception IOException if an error occurs
140+
*/
141+
public synchronized int available() throws IOException {
142+
if (in == null) {
143+
throw new IOException("Stream Closed");
144+
}
145+
if (slack != null) {
146+
return slack.length - begin;
147+
}
148+
if (in.ready()) {
149+
return 1;
150+
} else {
151+
return 0;
152+
}
153+
}
154+
155+
/**
156+
* @return false - mark is not supported
157+
*/
158+
public boolean markSupported() {
159+
return false; // would be imprecise
160+
}
161+
162+
/**
163+
* Resets the StringReader.
164+
*
165+
* @exception IOException if the StringReader fails to be reset
166+
*/
167+
public synchronized void reset() throws IOException {
168+
if (in == null) {
169+
throw new IOException("Stream Closed");
170+
}
171+
slack = null;
172+
in.reset();
173+
}
174+
175+
/**
176+
* Closes the Stringreader.
177+
*
178+
* @exception IOException if the original StringReader fails to be closed
179+
*/
180+
public synchronized void close() throws IOException {
181+
if (in != null) {
182+
in.close();
183+
slack = null;
184+
in = null;
185+
}
186+
}
187+
}

src/main/java/org/apache/ibatis/io/Resources.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,13 @@ public static InputStream getUrlAsStream(String urlString) throws IOException {
200200
* @throws java.io.IOException If the resource cannot be found or read
201201
*/
202202
public static Reader getUrlAsReader(String urlString) throws IOException {
203-
return new InputStreamReader(getUrlAsStream(urlString));
203+
Reader reader;
204+
if (charset == null) {
205+
reader = new InputStreamReader(getUrlAsStream(urlString));
206+
} else {
207+
reader = new InputStreamReader(getUrlAsStream(urlString), charset);
208+
}
209+
return reader;
204210
}
205211

206212
/**

0 commit comments

Comments
 (0)