Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_langtools
提交
10e7c2c7
D
dragonwell8_langtools
项目概览
openanolis
/
dragonwell8_langtools
通知
0
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_langtools
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
10e7c2c7
编写于
12月 11, 2009
作者:
J
jjg
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6906175: bridge JSR199 and JSR 203 APIs
Reviewed-by: darcy, alanb
上级
980b6c24
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
1570 addition
and
313 deletion
+1570
-313
make/build.properties
make/build.properties
+17
-2
make/build.xml
make/build.xml
+3
-3
src/share/classes/com/sun/tools/javac/file/BaseFileObject.java
...hare/classes/com/sun/tools/javac/file/BaseFileObject.java
+3
-8
src/share/classes/com/sun/tools/javac/file/JavacFileManager.java
...re/classes/com/sun/tools/javac/file/JavacFileManager.java
+7
-295
src/share/classes/com/sun/tools/javac/file/Paths.java
src/share/classes/com/sun/tools/javac/file/Paths.java
+1
-1
src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java
...classes/com/sun/tools/javac/nio/JavacPathFileManager.java
+543
-0
src/share/classes/com/sun/tools/javac/nio/PathFileManager.java
...hare/classes/com/sun/tools/javac/nio/PathFileManager.java
+125
-0
src/share/classes/com/sun/tools/javac/nio/PathFileObject.java
...share/classes/com/sun/tools/javac/nio/PathFileObject.java
+319
-0
src/share/classes/com/sun/tools/javac/util/BaseFileManager.java
...are/classes/com/sun/tools/javac/util/BaseFileManager.java
+355
-0
src/share/classes/com/sun/tools/javac/util/CloseableURLClassLoader.java
...ses/com/sun/tools/javac/util/CloseableURLClassLoader.java
+4
-3
src/share/classes/javax/tools/StandardJavaFileManager.java
src/share/classes/javax/tools/StandardJavaFileManager.java
+0
-1
test/tools/javac/nio/compileTest/CompileTest.java
test/tools/javac/nio/compileTest/CompileTest.java
+165
-0
test/tools/javac/nio/compileTest/HelloPathWorld.java
test/tools/javac/nio/compileTest/HelloPathWorld.java
+28
-0
未找到文件。
make/build.properties
浏览文件 @
10e7c2c7
...
...
@@ -149,11 +149,26 @@ apt.tests = \
#
# The following files require the import JDK to be available
require.import.jdk.files
=
require.import.jdk.files
=
\
com/sun/tools/javac/nio/*.java
# The following files in the import jdk source directory are required
# in order to compile the files defined in ${require.import.jdk.files}
import.jdk.stub.files
=
#
# For NIO, the list of stub files is defined by the contents of the primary
# API packages, together with such types that may be required in order to
# compile the stubs. Some of these dependencies would go away if the stub
# generator were to be improved -- e.g. by removing unnecessary imports.
#
import.jdk.stub.files
=
\
java/io/File.java
\
java/nio/file/**.java
\
java/nio/file/attribute/**.java
\
java/nio/file/spi/**.java
\
java/nio/channels/AsynchronousChannel.java
\
java/nio/channels/AsynchronousFileChannel.java
\
java/nio/channels/CompletionHandler.java
\
java/nio/channels/SeekableByteChannel.java
# The following value is used by the main jtreg target.
# An empty value means all tests
...
...
make/build.xml
浏览文件 @
10e7c2c7
...
...
@@ -98,7 +98,7 @@
import.jdk should be unset, or set to jdk home (to use rt.jar)
or to jdk repo (to use src/share/classes).
Based on the value, if any, set up default values for javac's sourcepath,
classpath and bootclasspath. Note: the default values are overridden
classpath and bootclasspath. Note: the default values are overridden
in the build-bootstrap-classes macro. -->
<available
property=
"import.jdk.src.dir"
value=
"${import.jdk}/src/share/classes"
...
...
@@ -552,8 +552,8 @@
<compilerarg
line=
"${javac.version.opt}"
/>
<compilerarg
line=
"${javac.lint.opts}"
/>
</javac>
<copy
todir=
"@{classes.dir}"
>
<fileset
dir=
"${src.classes.dir}"
includes=
"@{includes}"
>
<copy
todir=
"@{classes.dir}"
includeemptydirs=
"false"
>
<fileset
dir=
"${src.classes.dir}"
includes=
"@{includes}"
excludes=
"@{excludes}"
>
<exclude
name=
"**/*.java"
/>
<exclude
name=
"**/*.properties"
/>
<exclude
name=
"**/*-template"
/>
...
...
src/share/classes/com/sun/tools/javac/file/BaseFileObject.java
浏览文件 @
10e7c2c7
...
...
@@ -39,6 +39,8 @@ import javax.tools.JavaFileObject;
import
static
javax
.
tools
.
JavaFileObject
.
Kind
.*;
import
com.sun.tools.javac.util.BaseFileManager
;
/**
* <p><b>This is NOT part of any API supported by Sun Microsystems.
* If you write code that depends on this, you do so at your own risk.
...
...
@@ -74,14 +76,7 @@ public abstract class BaseFileObject implements JavaFileObject {
protected
abstract
String
inferBinaryName
(
Iterable
<?
extends
File
>
path
);
protected
static
JavaFileObject
.
Kind
getKind
(
String
filename
)
{
if
(
filename
.
endsWith
(
CLASS
.
extension
))
return
CLASS
;
else
if
(
filename
.
endsWith
(
SOURCE
.
extension
))
return
SOURCE
;
else
if
(
filename
.
endsWith
(
HTML
.
extension
))
return
HTML
;
else
return
OTHER
;
return
BaseFileManager
.
getKind
(
filename
);
}
protected
static
String
removeExtension
(
String
fileName
)
{
...
...
src/share/classes/com/sun/tools/javac/file/JavacFileManager.java
浏览文件 @
10e7c2c7
...
...
@@ -26,29 +26,16 @@
package
com.sun.tools.javac.file
;
import
java.io.ByteArrayOutputStream
;
import
java.io.Closeable
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStreamWriter
;
import
java.lang.ref.SoftReference
;
import
java.lang.reflect.Constructor
;
import
java.net.MalformedURLException
;
import
java.net.URI
;
import
java.net.URISyntaxException
;
import
java.net.URL
;
import
java.net.URLClassLoader
;
import
java.nio.ByteBuffer
;
import
java.nio.CharBuffer
;
import
java.nio.channels.FileChannel
;
import
java.nio.charset.Charset
;
import
java.nio.charset.CharsetDecoder
;
import
java.nio.charset.CoderResult
;
import
java.nio.charset.CodingErrorAction
;
import
java.nio.charset.IllegalCharsetNameException
;
import
java.nio.charset.UnsupportedCharsetException
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
...
...
@@ -66,18 +53,13 @@ import javax.tools.JavaFileManager;
import
javax.tools.JavaFileObject
;
import
javax.tools.StandardJavaFileManager
;
import
com.sun.tools.javac.code.Source
;
import
com.sun.tools.javac.file.RelativePath.RelativeFile
;
import
com.sun.tools.javac.file.RelativePath.RelativeDirectory
;
import
com.sun.tools.javac.main.JavacOption
;
import
com.sun.tools.javac.main.OptionName
;
import
com.sun.tools.javac.
main.RecognizedOptions
;
import
com.sun.tools.javac.
util.BaseFileManager
;
import
com.sun.tools.javac.util.Context
;
import
com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition
;
import
com.sun.tools.javac.util.List
;
import
com.sun.tools.javac.util.ListBuffer
;
import
com.sun.tools.javac.util.Log
;
import
com.sun.tools.javac.util.Options
;
import
static
javax
.
tools
.
StandardLocation
.*;
import
static
com
.
sun
.
tools
.
javac
.
main
.
OptionName
.*;
...
...
@@ -91,7 +73,7 @@ import static com.sun.tools.javac.main.OptionName.*;
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public
class
JavacFileManager
implements
StandardJavaFileManager
{
public
class
JavacFileManager
extends
BaseFileManager
implements
StandardJavaFileManager
{
boolean
useZipFileIndex
;
...
...
@@ -102,17 +84,10 @@ public class JavacFileManager implements StandardJavaFileManager {
return
buffer
.
toString
().
toCharArray
();
}
/**
* The log to be used for error reporting.
*/
protected
Log
log
;
/** Encapsulates knowledge of paths
*/
private
Paths
paths
;
private
Options
options
;
private
FSInfo
fsInfo
;
private
final
File
uninited
=
new
File
(
"U N I N I T E D"
);
...
...
@@ -134,12 +109,6 @@ public class JavacFileManager implements StandardJavaFileManager {
protected
boolean
mmappedIO
;
protected
boolean
ignoreSymbolFile
;
protected
String
classLoaderClass
;
/**
* User provided charset (through javax.tools).
*/
protected
Charset
charset
;
/**
* Register a Context.Factory to create a JavacFileManager.
...
...
@@ -157,18 +126,18 @@ public class JavacFileManager implements StandardJavaFileManager {
* it as the JavaFileManager for that context.
*/
public
JavacFileManager
(
Context
context
,
boolean
register
,
Charset
charset
)
{
super
(
charset
);
if
(
register
)
context
.
put
(
JavaFileManager
.
class
,
this
);
byteBufferCache
=
new
ByteBufferCache
();
this
.
charset
=
charset
;
setContext
(
context
);
}
/**
* Set the context for JavacFileManager.
*/
@Override
public
void
setContext
(
Context
context
)
{
log
=
Log
.
instance
(
context
);
super
.
setContext
(
context
);
if
(
paths
==
null
)
{
paths
=
Paths
.
instance
(
context
);
}
else
{
...
...
@@ -177,14 +146,12 @@ public class JavacFileManager implements StandardJavaFileManager {
paths
.
setContext
(
context
);
}
options
=
Options
.
instance
(
context
);
fsInfo
=
FSInfo
.
instance
(
context
);
useZipFileIndex
=
System
.
getProperty
(
"useJavaUtilZip"
)
==
null
;
// TODO: options.get("useJavaUtilZip") == null;
mmappedIO
=
options
.
get
(
"mmappedIO"
)
!=
null
;
ignoreSymbolFile
=
options
.
get
(
"ignore.symbol.file"
)
!=
null
;
classLoaderClass
=
options
.
get
(
"procloader"
);
}
public
JavaFileObject
getFileForInput
(
String
name
)
{
...
...
@@ -214,17 +181,6 @@ public class JavacFileManager implements StandardJavaFileManager {
return
getJavaFileObjectsFromStrings
(
Arrays
.
asList
(
nullCheck
(
names
)));
}
protected
JavaFileObject
.
Kind
getKind
(
String
extension
)
{
if
(
extension
.
equals
(
JavaFileObject
.
Kind
.
CLASS
.
extension
))
return
JavaFileObject
.
Kind
.
CLASS
;
else
if
(
extension
.
equals
(
JavaFileObject
.
Kind
.
SOURCE
.
extension
))
return
JavaFileObject
.
Kind
.
SOURCE
;
else
if
(
extension
.
equals
(
JavaFileObject
.
Kind
.
HTML
.
extension
))
return
JavaFileObject
.
Kind
.
HTML
;
else
return
JavaFileObject
.
Kind
.
OTHER
;
}
private
static
boolean
isValidName
(
String
name
)
{
// Arguably, isValidName should reject keywords (such as in SourceVersion.isName() ),
// but the set of keywords depends on the source level, and we don't want
...
...
@@ -359,9 +315,7 @@ public class JavacFileManager implements StandardJavaFileManager {
}
private
boolean
isValidFile
(
String
s
,
Set
<
JavaFileObject
.
Kind
>
fileKinds
)
{
int
lastDot
=
s
.
lastIndexOf
(
"."
);
String
extn
=
(
lastDot
==
-
1
?
s
:
s
.
substring
(
lastDot
));
JavaFileObject
.
Kind
kind
=
getKind
(
extn
);
JavaFileObject
.
Kind
kind
=
getKind
(
s
);
return
fileKinds
.
contains
(
kind
);
}
...
...
@@ -564,18 +518,6 @@ public class JavacFileManager implements StandardJavaFileManager {
}
}
CharBuffer
getCachedContent
(
JavaFileObject
file
)
{
SoftReference
<
CharBuffer
>
r
=
contentCache
.
get
(
file
);
return
(
r
==
null
?
null
:
r
.
get
());
}
void
cache
(
JavaFileObject
file
,
CharBuffer
cb
)
{
contentCache
.
put
(
file
,
new
SoftReference
<
CharBuffer
>(
cb
));
}
private
final
Map
<
JavaFileObject
,
SoftReference
<
CharBuffer
>>
contentCache
=
new
HashMap
<
JavaFileObject
,
SoftReference
<
CharBuffer
>>();
private
String
defaultEncodingName
;
private
String
getDefaultEncodingName
()
{
if
(
defaultEncodingName
==
null
)
{
...
...
@@ -585,161 +527,6 @@ public class JavacFileManager implements StandardJavaFileManager {
return
defaultEncodingName
;
}
protected
String
getEncodingName
()
{
String
encName
=
options
.
get
(
OptionName
.
ENCODING
);
if
(
encName
==
null
)
return
getDefaultEncodingName
();
else
return
encName
;
}
protected
Source
getSource
()
{
String
sourceName
=
options
.
get
(
OptionName
.
SOURCE
);
Source
source
=
null
;
if
(
sourceName
!=
null
)
source
=
Source
.
lookup
(
sourceName
);
return
(
source
!=
null
?
source
:
Source
.
DEFAULT
);
}
/**
* Make a byte buffer from an input stream.
*/
ByteBuffer
makeByteBuffer
(
InputStream
in
)
throws
IOException
{
int
limit
=
in
.
available
();
if
(
mmappedIO
&&
in
instanceof
FileInputStream
)
{
// Experimental memory mapped I/O
FileInputStream
fin
=
(
FileInputStream
)
in
;
return
fin
.
getChannel
().
map
(
FileChannel
.
MapMode
.
READ_ONLY
,
0
,
limit
);
}
if
(
limit
<
1024
)
limit
=
1024
;
ByteBuffer
result
=
byteBufferCache
.
get
(
limit
);
int
position
=
0
;
while
(
in
.
available
()
!=
0
)
{
if
(
position
>=
limit
)
// expand buffer
result
=
ByteBuffer
.
allocate
(
limit
<<=
1
).
put
((
ByteBuffer
)
result
.
flip
());
int
count
=
in
.
read
(
result
.
array
(),
position
,
limit
-
position
);
if
(
count
<
0
)
break
;
result
.
position
(
position
+=
count
);
}
return
(
ByteBuffer
)
result
.
flip
();
}
void
recycleByteBuffer
(
ByteBuffer
bb
)
{
byteBufferCache
.
put
(
bb
);
}
/**
* A single-element cache of direct byte buffers.
*/
private
static
class
ByteBufferCache
{
private
ByteBuffer
cached
;
ByteBuffer
get
(
int
capacity
)
{
if
(
capacity
<
20480
)
capacity
=
20480
;
ByteBuffer
result
=
(
cached
!=
null
&&
cached
.
capacity
()
>=
capacity
)
?
(
ByteBuffer
)
cached
.
clear
()
:
ByteBuffer
.
allocate
(
capacity
+
capacity
>>
1
);
cached
=
null
;
return
result
;
}
void
put
(
ByteBuffer
x
)
{
cached
=
x
;
}
}
private
final
ByteBufferCache
byteBufferCache
;
CharsetDecoder
getDecoder
(
String
encodingName
,
boolean
ignoreEncodingErrors
)
{
Charset
cs
=
(
this
.
charset
==
null
)
?
Charset
.
forName
(
encodingName
)
:
this
.
charset
;
CharsetDecoder
decoder
=
cs
.
newDecoder
();
CodingErrorAction
action
;
if
(
ignoreEncodingErrors
)
action
=
CodingErrorAction
.
REPLACE
;
else
action
=
CodingErrorAction
.
REPORT
;
return
decoder
.
onMalformedInput
(
action
)
.
onUnmappableCharacter
(
action
);
}
/**
* Decode a ByteBuffer into a CharBuffer.
*/
CharBuffer
decode
(
ByteBuffer
inbuf
,
boolean
ignoreEncodingErrors
)
{
String
encodingName
=
getEncodingName
();
CharsetDecoder
decoder
;
try
{
decoder
=
getDecoder
(
encodingName
,
ignoreEncodingErrors
);
}
catch
(
IllegalCharsetNameException
e
)
{
log
.
error
(
"unsupported.encoding"
,
encodingName
);
return
(
CharBuffer
)
CharBuffer
.
allocate
(
1
).
flip
();
}
catch
(
UnsupportedCharsetException
e
)
{
log
.
error
(
"unsupported.encoding"
,
encodingName
);
return
(
CharBuffer
)
CharBuffer
.
allocate
(
1
).
flip
();
}
// slightly overestimate the buffer size to avoid reallocation.
float
factor
=
decoder
.
averageCharsPerByte
()
*
0.8f
+
decoder
.
maxCharsPerByte
()
*
0.2f
;
CharBuffer
dest
=
CharBuffer
.
allocate
(
10
+
(
int
)(
inbuf
.
remaining
()*
factor
));
while
(
true
)
{
CoderResult
result
=
decoder
.
decode
(
inbuf
,
dest
,
true
);
dest
.
flip
();
if
(
result
.
isUnderflow
())
{
// done reading
// make sure there is at least one extra character
if
(
dest
.
limit
()
==
dest
.
capacity
())
{
dest
=
CharBuffer
.
allocate
(
dest
.
capacity
()+
1
).
put
(
dest
);
dest
.
flip
();
}
return
dest
;
}
else
if
(
result
.
isOverflow
())
{
// buffer too small; expand
int
newCapacity
=
10
+
dest
.
capacity
()
+
(
int
)(
inbuf
.
remaining
()*
decoder
.
maxCharsPerByte
());
dest
=
CharBuffer
.
allocate
(
newCapacity
).
put
(
dest
);
}
else
if
(
result
.
isMalformed
()
||
result
.
isUnmappable
())
{
// bad character in input
// report coding error (warn only pre 1.5)
if
(!
getSource
().
allowEncodingErrors
())
{
log
.
error
(
new
SimpleDiagnosticPosition
(
dest
.
limit
()),
"illegal.char.for.encoding"
,
charset
==
null
?
encodingName
:
charset
.
name
());
}
else
{
log
.
warning
(
new
SimpleDiagnosticPosition
(
dest
.
limit
()),
"illegal.char.for.encoding"
,
charset
==
null
?
encodingName
:
charset
.
name
());
}
// skip past the coding error
inbuf
.
position
(
inbuf
.
position
()
+
result
.
length
());
// undo the flip() to prepare the output buffer
// for more translation
dest
.
position
(
dest
.
limit
());
dest
.
limit
(
dest
.
capacity
());
dest
.
put
((
char
)
0xfffd
);
// backward compatible
}
else
{
throw
new
AssertionError
(
result
);
}
}
// unreached
}
public
ClassLoader
getClassLoader
(
Location
location
)
{
nullCheck
(
location
);
Iterable
<?
extends
File
>
path
=
getLocation
(
location
);
...
...
@@ -754,39 +541,7 @@ public class JavacFileManager implements StandardJavaFileManager {
}
}
URL
[]
urls
=
lb
.
toArray
(
new
URL
[
lb
.
size
()]);
ClassLoader
thisClassLoader
=
getClass
().
getClassLoader
();
// Bug: 6558476
// Ideally, ClassLoader should be Closeable, but before JDK7 it is not.
// On older versions, try the following, to get a closeable classloader.
// 1: Allow client to specify the class to use via hidden option
if
(
classLoaderClass
!=
null
)
{
try
{
Class
<?
extends
ClassLoader
>
loader
=
Class
.
forName
(
classLoaderClass
).
asSubclass
(
ClassLoader
.
class
);
Class
<?>[]
constrArgTypes
=
{
URL
[].
class
,
ClassLoader
.
class
};
Constructor
<?
extends
ClassLoader
>
constr
=
loader
.
getConstructor
(
constrArgTypes
);
return
constr
.
newInstance
(
new
Object
[]
{
urls
,
thisClassLoader
});
}
catch
(
Throwable
t
)
{
// ignore errors loading user-provided class loader, fall through
}
}
// 2: If URLClassLoader implements Closeable, use that.
if
(
Closeable
.
class
.
isAssignableFrom
(
URLClassLoader
.
class
))
return
new
URLClassLoader
(
urls
,
thisClassLoader
);
// 3: Try using private reflection-based CloseableURLClassLoader
try
{
return
new
CloseableURLClassLoader
(
urls
,
thisClassLoader
);
}
catch
(
Throwable
t
)
{
// ignore errors loading workaround class loader, fall through
}
// 4: If all else fails, use plain old standard URLClassLoader
return
new
URLClassLoader
(
urls
,
thisClassLoader
);
return
getClassLoader
(
lb
.
toArray
(
new
URL
[
lb
.
size
()]));
}
public
Iterable
<
JavaFileObject
>
list
(
Location
location
,
...
...
@@ -836,38 +591,6 @@ public class JavacFileManager implements StandardJavaFileManager {
return
a
.
equals
(
b
);
}
public
boolean
handleOption
(
String
current
,
Iterator
<
String
>
remaining
)
{
for
(
JavacOption
o:
javacFileManagerOptions
)
{
if
(
o
.
matches
(
current
))
{
if
(
o
.
hasArg
())
{
if
(
remaining
.
hasNext
())
{
if
(!
o
.
process
(
options
,
current
,
remaining
.
next
()))
return
true
;
}
}
else
{
if
(!
o
.
process
(
options
,
current
))
return
true
;
}
// operand missing, or process returned false
throw
new
IllegalArgumentException
(
current
);
}
}
return
false
;
}
// where
private
static
JavacOption
[]
javacFileManagerOptions
=
RecognizedOptions
.
getJavacFileManagerOptions
(
new
RecognizedOptions
.
GrumpyHelper
());
public
int
isSupportedOption
(
String
option
)
{
for
(
JavacOption
o
:
javacFileManagerOptions
)
{
if
(
o
.
matches
(
option
))
return
o
.
hasArg
()
?
1
:
0
;
}
return
-
1
;
}
public
boolean
hasLocation
(
Location
location
)
{
return
getLocation
(
location
)
!=
null
;
}
...
...
@@ -1115,15 +838,4 @@ public class JavacFileManager implements StandardJavaFileManager {
}
throw
new
IllegalArgumentException
(
"Invalid relative path: "
+
file
);
}
private
static
<
T
>
T
nullCheck
(
T
o
)
{
o
.
getClass
();
// null check
return
o
;
}
private
static
<
T
>
Iterable
<
T
>
nullCheck
(
Iterable
<
T
>
it
)
{
for
(
T
t
:
it
)
t
.
getClass
();
// null check
return
it
;
}
}
src/share/classes/com/sun/tools/javac/file/Paths.java
浏览文件 @
10e7c2c7
...
...
@@ -66,7 +66,7 @@ public class Paths {
* @param context the context
* @return the Paths instance for this context
*/
static
Paths
instance
(
Context
context
)
{
public
static
Paths
instance
(
Context
context
)
{
Paths
instance
=
context
.
get
(
pathsKey
);
if
(
instance
==
null
)
instance
=
new
Paths
(
context
);
...
...
src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java
0 → 100644
浏览文件 @
10e7c2c7
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
com.sun.tools.javac.nio
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.net.MalformedURLException
;
import
java.net.URL
;
import
java.nio.charset.Charset
;
import
java.nio.file.Files
;
import
java.nio.file.FileSystem
;
import
java.nio.file.FileSystems
;
import
java.nio.file.FileVisitOption
;
import
java.nio.file.FileVisitResult
;
import
java.nio.file.Path
;
import
java.nio.file.SimpleFileVisitor
;
import
java.nio.file.attribute.Attributes
;
import
java.nio.file.attribute.BasicFileAttributes
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.EnumSet
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.LinkedHashSet
;
import
java.util.Map
;
import
java.util.Set
;
import
javax.lang.model.SourceVersion
;
import
javax.tools.FileObject
;
import
javax.tools.JavaFileManager
;
import
javax.tools.JavaFileObject
;
import
javax.tools.JavaFileObject.Kind
;
import
javax.tools.StandardLocation
;
import
static
java
.
nio
.
file
.
FileVisitOption
.*;
import
static
javax
.
tools
.
StandardLocation
.*;
import
com.sun.tools.javac.file.Paths
;
import
com.sun.tools.javac.util.BaseFileManager
;
import
com.sun.tools.javac.util.Context
;
import
com.sun.tools.javac.util.List
;
import
com.sun.tools.javac.util.ListBuffer
;
import
static
com
.
sun
.
tools
.
javac
.
main
.
OptionName
.*;
// NOTE the imports carefully for this compilation unit.
//
// Path: java.nio.file.Path -- the new NIO type for which this file manager exists
//
// Paths: com.sun.tools.javac.file.Paths -- legacy javac type for handling path options
// The other Paths (java.nio.file.Paths) is not used
// NOTE this and related classes depend on new API in JDK 7.
// This requires special handling while bootstrapping the JDK build,
// when these classes might not yet have been compiled. To workaround
// this, the build arranges to make stubs of these classes available
// when compiling this and related classes. The set of stub files
// is specified in make/build.properties.
/**
* Implementation of PathFileManager: a JavaFileManager based on the use
* of java.nio.file.Path.
*
* <p>Just as a Path is somewhat analagous to a File, so too is this
* JavacPathFileManager analogous to JavacFileManager, as it relates to the
* support of FileObjects based on File objects (i.e. just RegularFileObject,
* not ZipFileObject and its variants.)
*
* <p>The default values for the standard locations supported by this file
* manager are the same as the default values provided by JavacFileManager --
* i.e. as determined by the javac.file.Paths class. To override these values,
* call {@link #setLocation}.
*
* <p>To reduce confusion with Path objects, the locations such as "class path",
* "source path", etc, are generically referred to here as "search paths".
*
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
* you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public
class
JavacPathFileManager
extends
BaseFileManager
implements
PathFileManager
{
protected
FileSystem
defaultFileSystem
;
/**
* Create a JavacPathFileManager using a given context, optionally registering
* it as the JavaFileManager for that context.
*/
public
JavacPathFileManager
(
Context
context
,
boolean
register
,
Charset
charset
)
{
super
(
charset
);
if
(
register
)
context
.
put
(
JavaFileManager
.
class
,
this
);
pathsForLocation
=
new
HashMap
<
Location
,
PathsForLocation
>();
fileSystems
=
new
HashMap
<
Path
,
FileSystem
>();
setContext
(
context
);
}
/**
* Set the context for JavacPathFileManager.
*/
@Override
protected
void
setContext
(
Context
context
)
{
super
.
setContext
(
context
);
searchPaths
=
Paths
.
instance
(
context
);
}
@Override
public
FileSystem
getDefaultFileSystem
()
{
if
(
defaultFileSystem
==
null
)
defaultFileSystem
=
FileSystems
.
getDefault
();
return
defaultFileSystem
;
}
@Override
public
void
setDefaultFileSystem
(
FileSystem
fs
)
{
defaultFileSystem
=
fs
;
}
@Override
public
void
flush
()
throws
IOException
{
contentCache
.
clear
();
}
@Override
public
void
close
()
throws
IOException
{
for
(
FileSystem
fs:
fileSystems
.
values
())
fs
.
close
();
}
@Override
public
ClassLoader
getClassLoader
(
Location
location
)
{
nullCheck
(
location
);
Iterable
<?
extends
Path
>
path
=
getLocation
(
location
);
if
(
path
==
null
)
return
null
;
ListBuffer
<
URL
>
lb
=
new
ListBuffer
<
URL
>();
for
(
Path
p:
path
)
{
try
{
lb
.
append
(
p
.
toUri
().
toURL
());
}
catch
(
MalformedURLException
e
)
{
throw
new
AssertionError
(
e
);
}
}
return
getClassLoader
(
lb
.
toArray
(
new
URL
[
lb
.
size
()]));
}
// <editor-fold defaultstate="collapsed" desc="Location handling">
public
boolean
hasLocation
(
Location
location
)
{
return
(
getLocation
(
location
)
!=
null
);
}
public
Iterable
<?
extends
Path
>
getLocation
(
Location
location
)
{
nullCheck
(
location
);
lazyInitSearchPaths
();
PathsForLocation
path
=
pathsForLocation
.
get
(
location
);
if
(
path
==
null
&&
!
pathsForLocation
.
containsKey
(
location
))
{
setDefaultForLocation
(
location
);
path
=
pathsForLocation
.
get
(
location
);
}
return
path
;
}
private
Path
getOutputLocation
(
Location
location
)
{
Iterable
<?
extends
Path
>
paths
=
getLocation
(
location
);
return
(
paths
==
null
?
null
:
paths
.
iterator
().
next
());
}
public
void
setLocation
(
Location
location
,
Iterable
<?
extends
Path
>
searchPath
)
throws
IOException
{
nullCheck
(
location
);
lazyInitSearchPaths
();
if
(
searchPath
==
null
)
{
setDefaultForLocation
(
location
);
}
else
{
if
(
location
.
isOutputLocation
())
checkOutputPath
(
searchPath
);
PathsForLocation
pl
=
new
PathsForLocation
();
for
(
Path
p:
searchPath
)
pl
.
add
(
p
);
// TODO -Xlint:path warn if path not found
pathsForLocation
.
put
(
location
,
pl
);
}
}
private
void
checkOutputPath
(
Iterable
<?
extends
Path
>
searchPath
)
throws
IOException
{
Iterator
<?
extends
Path
>
pathIter
=
searchPath
.
iterator
();
if
(!
pathIter
.
hasNext
())
throw
new
IllegalArgumentException
(
"empty path for directory"
);
Path
path
=
pathIter
.
next
();
if
(
pathIter
.
hasNext
())
throw
new
IllegalArgumentException
(
"path too long for directory"
);
if
(!
path
.
exists
())
throw
new
FileNotFoundException
(
path
+
": does not exist"
);
else
if
(!
isDirectory
(
path
))
throw
new
IOException
(
path
+
": not a directory"
);
}
private
void
setDefaultForLocation
(
Location
locn
)
{
Collection
<
File
>
files
=
null
;
if
(
locn
instanceof
StandardLocation
)
{
switch
((
StandardLocation
)
locn
)
{
case
CLASS_PATH:
files
=
searchPaths
.
userClassPath
();
break
;
case
PLATFORM_CLASS_PATH:
files
=
searchPaths
.
bootClassPath
();
break
;
case
SOURCE_PATH:
files
=
searchPaths
.
sourcePath
();
break
;
case
CLASS_OUTPUT:
{
String
arg
=
options
.
get
(
D
);
files
=
(
arg
==
null
?
null
:
Collections
.
singleton
(
new
File
(
arg
)));
break
;
}
case
SOURCE_OUTPUT:
{
String
arg
=
options
.
get
(
S
);
files
=
(
arg
==
null
?
null
:
Collections
.
singleton
(
new
File
(
arg
)));
break
;
}
}
}
PathsForLocation
pl
=
new
PathsForLocation
();
if
(
files
!=
null
)
{
for
(
File
f:
files
)
pl
.
add
(
f
.
toPath
());
}
pathsForLocation
.
put
(
locn
,
pl
);
}
private
void
lazyInitSearchPaths
()
{
if
(!
inited
)
{
setDefaultForLocation
(
PLATFORM_CLASS_PATH
);
setDefaultForLocation
(
CLASS_PATH
);
setDefaultForLocation
(
SOURCE_PATH
);
inited
=
true
;
}
}
// where
private
boolean
inited
=
false
;
private
Map
<
Location
,
PathsForLocation
>
pathsForLocation
;
private
Paths
searchPaths
;
private
static
class
PathsForLocation
extends
LinkedHashSet
<
Path
>
{
private
static
final
long
serialVersionUID
=
6788510222394486733L
;
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="FileObject handling">
@Override
public
Path
getPath
(
FileObject
fo
)
{
nullCheck
(
fo
);
if
(!(
fo
instanceof
PathFileObject
))
throw
new
IllegalArgumentException
();
return
((
PathFileObject
)
fo
).
getPath
();
}
@Override
public
boolean
isSameFile
(
FileObject
a
,
FileObject
b
)
{
nullCheck
(
a
);
nullCheck
(
b
);
if
(!(
a
instanceof
PathFileObject
))
throw
new
IllegalArgumentException
(
"Not supported: "
+
a
);
if
(!(
b
instanceof
PathFileObject
))
throw
new
IllegalArgumentException
(
"Not supported: "
+
b
);
return
((
PathFileObject
)
a
).
isSameFile
((
PathFileObject
)
b
);
}
@Override
public
Iterable
<
JavaFileObject
>
list
(
Location
location
,
String
packageName
,
Set
<
Kind
>
kinds
,
boolean
recurse
)
throws
IOException
{
// validatePackageName(packageName);
nullCheck
(
packageName
);
nullCheck
(
kinds
);
Iterable
<?
extends
Path
>
paths
=
getLocation
(
location
);
if
(
paths
==
null
)
return
List
.
nil
();
ListBuffer
<
JavaFileObject
>
results
=
new
ListBuffer
<
JavaFileObject
>();
for
(
Path
path
:
paths
)
list
(
path
,
packageName
,
kinds
,
recurse
,
results
);
return
results
.
toList
();
}
private
void
list
(
Path
path
,
String
packageName
,
final
Set
<
Kind
>
kinds
,
boolean
recurse
,
final
ListBuffer
<
JavaFileObject
>
results
)
throws
IOException
{
if
(!
path
.
exists
())
return
;
final
Path
pathDir
;
if
(
isDirectory
(
path
))
pathDir
=
path
;
else
{
FileSystem
fs
=
getFileSystem
(
path
);
if
(
fs
==
null
)
return
;
pathDir
=
fs
.
getRootDirectories
().
iterator
().
next
();
}
String
sep
=
path
.
getFileSystem
().
getSeparator
();
Path
packageDir
=
packageName
.
isEmpty
()
?
pathDir
:
pathDir
.
resolve
(
packageName
.
replace
(
"."
,
sep
));
if
(!
packageDir
.
exists
())
return
;
/* Alternate impl of list, superceded by use of Files.walkFileTree */
// Deque<Path> queue = new LinkedList<Path>();
// queue.add(packageDir);
//
// Path dir;
// while ((dir = queue.poll()) != null) {
// DirectoryStream<Path> ds = dir.newDirectoryStream();
// try {
// for (Path p: ds) {
// String name = p.getName().toString();
// if (isDirectory(p)) {
// if (recurse && SourceVersion.isIdentifier(name)) {
// queue.add(p);
// }
// } else {
// if (kinds.contains(getKind(name))) {
// JavaFileObject fe =
// PathFileObject.createDirectoryPathFileObject(this, p, pathDir);
// results.append(fe);
// }
// }
// }
// } finally {
// ds.close();
// }
// }
int
maxDepth
=
(
recurse
?
Integer
.
MAX_VALUE
:
1
);
Set
<
FileVisitOption
>
opts
=
EnumSet
.
of
(
DETECT_CYCLES
,
FOLLOW_LINKS
);
Files
.
walkFileTree
(
packageDir
,
opts
,
maxDepth
,
new
SimpleFileVisitor
<
Path
>()
{
@Override
public
FileVisitResult
preVisitDirectory
(
Path
dir
)
{
if
(
SourceVersion
.
isIdentifier
(
dir
.
getName
().
toString
()))
// JSR 292?
return
FileVisitResult
.
CONTINUE
;
else
return
FileVisitResult
.
SKIP_SUBTREE
;
}
@Override
public
FileVisitResult
visitFile
(
Path
file
,
BasicFileAttributes
attrs
)
{
if
(
attrs
.
isRegularFile
()
&&
kinds
.
contains
(
getKind
(
file
.
getName
().
toString
())))
{
JavaFileObject
fe
=
PathFileObject
.
createDirectoryPathFileObject
(
JavacPathFileManager
.
this
,
file
,
pathDir
);
results
.
append
(
fe
);
}
return
FileVisitResult
.
CONTINUE
;
}
});
}
@Override
public
Iterable
<?
extends
JavaFileObject
>
getJavaFileObjectsFromPaths
(
Iterable
<?
extends
Path
>
paths
)
{
ArrayList
<
PathFileObject
>
result
;
if
(
paths
instanceof
Collection
<?>)
result
=
new
ArrayList
<
PathFileObject
>(((
Collection
<?>)
paths
).
size
());
else
result
=
new
ArrayList
<
PathFileObject
>();
for
(
Path
p:
paths
)
result
.
add
(
PathFileObject
.
createSimplePathFileObject
(
this
,
nullCheck
(
p
)));
return
result
;
}
@Override
public
Iterable
<?
extends
JavaFileObject
>
getJavaFileObjects
(
Path
...
paths
)
{
return
getJavaFileObjectsFromPaths
(
Arrays
.
asList
(
nullCheck
(
paths
)));
}
@Override
public
JavaFileObject
getJavaFileForInput
(
Location
location
,
String
className
,
Kind
kind
)
throws
IOException
{
return
getFileForInput
(
location
,
getRelativePath
(
className
,
kind
));
}
@Override
public
FileObject
getFileForInput
(
Location
location
,
String
packageName
,
String
relativeName
)
throws
IOException
{
return
getFileForInput
(
location
,
getRelativePath
(
packageName
,
relativeName
));
}
private
JavaFileObject
getFileForInput
(
Location
location
,
String
relativePath
)
throws
IOException
{
for
(
Path
p:
getLocation
(
location
))
{
if
(
isDirectory
(
p
))
{
Path
f
=
resolve
(
p
,
relativePath
);
if
(
f
.
exists
())
return
PathFileObject
.
createDirectoryPathFileObject
(
this
,
f
,
p
);
}
else
{
FileSystem
fs
=
getFileSystem
(
p
);
if
(
fs
!=
null
)
{
Path
file
=
getPath
(
fs
,
relativePath
);
if
(
file
.
exists
())
return
PathFileObject
.
createJarPathFileObject
(
this
,
file
);
}
}
}
return
null
;
}
@Override
public
JavaFileObject
getJavaFileForOutput
(
Location
location
,
String
className
,
Kind
kind
,
FileObject
sibling
)
throws
IOException
{
return
getFileForOutput
(
location
,
getRelativePath
(
className
,
kind
),
sibling
);
}
@Override
public
FileObject
getFileForOutput
(
Location
location
,
String
packageName
,
String
relativeName
,
FileObject
sibling
)
throws
IOException
{
return
getFileForOutput
(
location
,
getRelativePath
(
packageName
,
relativeName
),
sibling
);
}
private
JavaFileObject
getFileForOutput
(
Location
location
,
String
relativePath
,
FileObject
sibling
)
{
Path
dir
=
getOutputLocation
(
location
);
if
(
dir
==
null
)
{
if
(
location
==
CLASS_OUTPUT
)
{
Path
siblingDir
=
null
;
if
(
sibling
!=
null
&&
sibling
instanceof
PathFileObject
)
{
siblingDir
=
((
PathFileObject
)
sibling
).
getPath
().
getParent
();
}
return
PathFileObject
.
createSiblingPathFileObject
(
this
,
siblingDir
.
resolve
(
getBaseName
(
relativePath
)),
relativePath
);
}
else
if
(
location
==
SOURCE_OUTPUT
)
{
dir
=
getOutputLocation
(
CLASS_OUTPUT
);
}
}
Path
file
;
if
(
dir
!=
null
)
{
file
=
resolve
(
dir
,
relativePath
);
return
PathFileObject
.
createDirectoryPathFileObject
(
this
,
file
,
dir
);
}
else
{
file
=
getPath
(
getDefaultFileSystem
(),
relativePath
);
return
PathFileObject
.
createSimplePathFileObject
(
this
,
file
);
}
}
@Override
public
String
inferBinaryName
(
Location
location
,
JavaFileObject
fo
)
{
nullCheck
(
fo
);
// Need to match the path semantics of list(location, ...)
Iterable
<?
extends
Path
>
paths
=
getLocation
(
location
);
if
(
paths
==
null
)
{
return
null
;
}
if
(!(
fo
instanceof
PathFileObject
))
throw
new
IllegalArgumentException
(
fo
.
getClass
().
getName
());
return
((
PathFileObject
)
fo
).
inferBinaryName
(
paths
);
}
private
FileSystem
getFileSystem
(
Path
p
)
throws
IOException
{
FileSystem
fs
=
fileSystems
.
get
(
p
);
if
(
fs
==
null
)
{
fs
=
FileSystems
.
newFileSystem
(
p
,
Collections
.<
String
,
Void
>
emptyMap
(),
null
);
fileSystems
.
put
(
p
,
fs
);
}
return
fs
;
}
private
Map
<
Path
,
FileSystem
>
fileSystems
;
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Utility methods">
private
static
String
getRelativePath
(
String
className
,
Kind
kind
)
{
return
className
.
replace
(
"."
,
"/"
)
+
kind
.
extension
;
}
private
static
String
getRelativePath
(
String
packageName
,
String
relativeName
)
{
return
packageName
.
replace
(
"."
,
"/"
)
+
relativeName
;
}
private
static
String
getBaseName
(
String
relativePath
)
{
int
lastSep
=
relativePath
.
lastIndexOf
(
"/"
);
return
relativePath
.
substring
(
lastSep
+
1
);
// safe if "/" not found
}
private
static
boolean
isDirectory
(
Path
path
)
throws
IOException
{
BasicFileAttributes
attrs
=
Attributes
.
readBasicFileAttributes
(
path
);
return
attrs
.
isDirectory
();
}
private
static
Path
getPath
(
FileSystem
fs
,
String
relativePath
)
{
return
fs
.
getPath
(
relativePath
.
replace
(
"/"
,
fs
.
getSeparator
()));
}
private
static
Path
resolve
(
Path
base
,
String
relativePath
)
{
FileSystem
fs
=
base
.
getFileSystem
();
Path
rp
=
fs
.
getPath
(
relativePath
.
replace
(
"/"
,
fs
.
getSeparator
()));
return
base
.
resolve
(
rp
);
}
// </editor-fold>
}
src/share/classes/com/sun/tools/javac/nio/PathFileManager.java
0 → 100644
浏览文件 @
10e7c2c7
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
com.sun.tools.javac.nio
;
import
java.io.IOException
;
import
java.nio.file.FileSystem
;
import
java.nio.file.Path
;
import
javax.tools.FileObject
;
import
javax.tools.JavaFileManager
;
import
javax.tools.JavaFileObject
;
/**
* File manager based on {@linkplain File java.nio.file.Path}.
*
* Eventually, this should be moved to javax.tools.
* Also, JavaCompiler might reasonably provide a method getPathFileManager,
* similar to {@link javax.tools.JavaCompiler#getStandardFileManager
* getStandardFileManager}. However, would need to be handled carefully
* as another forward reference from langtools to jdk.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
* you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public
interface
PathFileManager
extends
JavaFileManager
{
/**
* Get the default file system used to create paths. If no value has been
* set, the default file system is {@link FileSystems#getDefault}.
*/
FileSystem
getDefaultFileSystem
();
/**
* Set the default file system used to create paths.
* @param fs the default file system used to create any new paths.
*/
void
setDefaultFileSystem
(
FileSystem
fs
);
/**
* Get file objects representing the given files.
*
* @param paths a list of paths
* @return a list of file objects
* @throws IllegalArgumentException if the list of paths includes
* a directory
*/
Iterable
<?
extends
JavaFileObject
>
getJavaFileObjectsFromPaths
(
Iterable
<?
extends
Path
>
paths
);
/**
* Get file objects representing the given paths.
* Convenience method equivalent to:
*
* <pre>
* getJavaFileObjectsFromPaths({@linkplain java.util.Arrays#asList Arrays.asList}(paths))
* </pre>
*
* @param paths an array of paths
* @return a list of file objects
* @throws IllegalArgumentException if the array of files includes
* a directory
* @throws NullPointerException if the given array contains null
* elements
*/
Iterable
<?
extends
JavaFileObject
>
getJavaFileObjects
(
Path
...
paths
);
/**
* Return the Path for a file object that has been obtained from this
* file manager.
*
* @param fo A file object that has been obtained from this file manager.
* @return The underlying Path object.
* @throws IllegalArgumentException is the file object was not obtained from
* from this file manager.
*/
Path
getPath
(
FileObject
fo
);
/**
* Get the search path associated with the given location.
*
* @param location a location
* @return a list of paths or {@code null} if this location has no
* associated search path
* @see #setLocation
*/
Iterable
<?
extends
Path
>
getLocation
(
Location
location
);
/**
* Associate the given search path with the given location. Any
* previous value will be discarded.
*
* @param location a location
* @param searchPath a list of files, if {@code null} use the default
* search path for this location
* @see #getLocation
* @throws IllegalArgumentException if location is an output
* location and searchpath does not contain exactly one element
* @throws IOException if location is an output location and searchpath
* does not represent an existing directory
*/
void
setLocation
(
Location
location
,
Iterable
<?
extends
Path
>
searchPath
)
throws
IOException
;
}
src/share/classes/com/sun/tools/javac/nio/PathFileObject.java
0 → 100644
浏览文件 @
10e7c2c7
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
com.sun.tools.javac.nio
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
java.io.OutputStream
;
import
java.io.OutputStreamWriter
;
import
java.io.Reader
;
import
java.io.Writer
;
import
java.net.URI
;
import
java.nio.ByteBuffer
;
import
java.nio.CharBuffer
;
import
java.nio.charset.CharsetDecoder
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.attribute.Attributes
;
import
java.nio.file.attribute.BasicFileAttributes
;
import
javax.lang.model.element.Modifier
;
import
javax.lang.model.element.NestingKind
;
import
javax.tools.JavaFileObject
;
import
com.sun.tools.javac.util.BaseFileManager
;
/**
* Implementation of JavaFileObject using java.nio.file API.
*
* <p>PathFileObjects are, for the most part, straightforward wrappers around
* Path objects. The primary complexity is the support for "inferBinaryName".
* This is left as an abstract method, implemented by each of a number of
* different factory methods, which compute the binary name based on
* information available at the time the file object is created.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
* you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
abstract
class
PathFileObject
implements
JavaFileObject
{
private
JavacPathFileManager
fileManager
;
private
Path
path
;
/**
* Create a PathFileObject within a directory, such that the binary name
* can be inferred from the relationship to the parent directory.
*/
static
PathFileObject
createDirectoryPathFileObject
(
JavacPathFileManager
fileManager
,
final
Path
path
,
final
Path
dir
)
{
return
new
PathFileObject
(
fileManager
,
path
)
{
@Override
String
inferBinaryName
(
Iterable
<?
extends
Path
>
paths
)
{
return
toBinaryName
(
dir
.
relativize
(
path
));
}
};
}
/**
* Create a PathFileObject in a file system such as a jar file, such that
* the binary name can be inferred from its position within the filesystem.
*/
static
PathFileObject
createJarPathFileObject
(
JavacPathFileManager
fileManager
,
final
Path
path
)
{
return
new
PathFileObject
(
fileManager
,
path
)
{
@Override
String
inferBinaryName
(
Iterable
<?
extends
Path
>
paths
)
{
return
toBinaryName
(
path
);
}
};
}
/**
* Create a PathFileObject whose binary name can be inferred from the
* relative path to a sibling.
*/
static
PathFileObject
createSiblingPathFileObject
(
JavacPathFileManager
fileManager
,
final
Path
path
,
final
String
relativePath
)
{
return
new
PathFileObject
(
fileManager
,
path
)
{
@Override
String
inferBinaryName
(
Iterable
<?
extends
Path
>
paths
)
{
return
toBinaryName
(
relativePath
,
"/"
);
}
};
}
/**
* Create a PathFileObject whose binary name might be inferred from its
* position on a search path.
*/
static
PathFileObject
createSimplePathFileObject
(
JavacPathFileManager
fileManager
,
final
Path
path
)
{
return
new
PathFileObject
(
fileManager
,
path
)
{
@Override
String
inferBinaryName
(
Iterable
<?
extends
Path
>
paths
)
{
Path
absPath
=
path
.
toAbsolutePath
();
for
(
Path
p:
paths
)
{
Path
ap
=
p
.
toAbsolutePath
();
if
(
absPath
.
startsWith
(
ap
))
{
try
{
Path
rp
=
ap
.
relativize
(
absPath
);
if
(
rp
!=
null
)
// maybe null if absPath same as ap
return
toBinaryName
(
rp
);
}
catch
(
IllegalArgumentException
e
)
{
// ignore this p if cannot relativize path to p
}
}
}
return
null
;
}
};
}
protected
PathFileObject
(
JavacPathFileManager
fileManager
,
Path
path
)
{
fileManager
.
getClass
();
// null check
path
.
getClass
();
// null check
this
.
fileManager
=
fileManager
;
this
.
path
=
path
;
}
abstract
String
inferBinaryName
(
Iterable
<?
extends
Path
>
paths
);
/**
* Return the Path for this object.
* @return the Path for this object.
*/
Path
getPath
()
{
return
path
;
}
@Override
public
Kind
getKind
()
{
return
BaseFileManager
.
getKind
(
path
.
getName
().
toString
());
}
@Override
public
boolean
isNameCompatible
(
String
simpleName
,
Kind
kind
)
{
simpleName
.
getClass
();
// null check
if
(
kind
==
Kind
.
OTHER
&&
getKind
()
!=
kind
)
{
return
false
;
}
String
sn
=
simpleName
+
kind
.
extension
;
String
pn
=
path
.
getName
().
toString
();
if
(
pn
.
equals
(
sn
))
{
return
true
;
}
if
(
pn
.
equalsIgnoreCase
(
sn
))
{
try
{
// allow for Windows
return
path
.
toRealPath
(
false
).
getName
().
toString
().
equals
(
sn
);
}
catch
(
IOException
e
)
{
}
}
return
false
;
}
@Override
public
NestingKind
getNestingKind
()
{
return
null
;
}
@Override
public
Modifier
getAccessLevel
()
{
return
null
;
}
@Override
public
URI
toUri
()
{
return
path
.
toUri
();
}
@Override
public
String
getName
()
{
return
path
.
toString
();
}
@Override
public
InputStream
openInputStream
()
throws
IOException
{
return
path
.
newInputStream
();
}
@Override
public
OutputStream
openOutputStream
()
throws
IOException
{
ensureParentDirectoriesExist
();
return
path
.
newOutputStream
();
}
@Override
public
Reader
openReader
(
boolean
ignoreEncodingErrors
)
throws
IOException
{
CharsetDecoder
decoder
=
fileManager
.
getDecoder
(
fileManager
.
getEncodingName
(),
ignoreEncodingErrors
);
return
new
InputStreamReader
(
openInputStream
(),
decoder
);
}
@Override
public
CharSequence
getCharContent
(
boolean
ignoreEncodingErrors
)
throws
IOException
{
CharBuffer
cb
=
fileManager
.
getCachedContent
(
this
);
if
(
cb
==
null
)
{
InputStream
in
=
openInputStream
();
try
{
ByteBuffer
bb
=
fileManager
.
makeByteBuffer
(
in
);
JavaFileObject
prev
=
fileManager
.
log
.
useSource
(
this
);
try
{
cb
=
fileManager
.
decode
(
bb
,
ignoreEncodingErrors
);
}
finally
{
fileManager
.
log
.
useSource
(
prev
);
}
fileManager
.
recycleByteBuffer
(
bb
);
if
(!
ignoreEncodingErrors
)
{
fileManager
.
cache
(
this
,
cb
);
}
}
finally
{
in
.
close
();
}
}
return
cb
;
}
@Override
public
Writer
openWriter
()
throws
IOException
{
ensureParentDirectoriesExist
();
return
new
OutputStreamWriter
(
path
.
newOutputStream
(),
fileManager
.
getEncodingName
());
}
@Override
public
long
getLastModified
()
{
try
{
BasicFileAttributes
attrs
=
Attributes
.
readBasicFileAttributes
(
path
);
return
attrs
.
lastModifiedTime
().
toMillis
();
}
catch
(
IOException
e
)
{
return
-
1
;
}
}
@Override
public
boolean
delete
()
{
try
{
path
.
delete
();
return
true
;
}
catch
(
IOException
e
)
{
return
false
;
}
}
public
boolean
isSameFile
(
PathFileObject
other
)
{
try
{
return
path
.
isSameFile
(
other
.
path
);
}
catch
(
IOException
e
)
{
return
false
;
}
}
@Override
public
boolean
equals
(
Object
other
)
{
return
(
other
instanceof
PathFileObject
&&
path
.
equals
(((
PathFileObject
)
other
).
path
));
}
@Override
public
int
hashCode
()
{
return
path
.
hashCode
();
}
@Override
public
String
toString
()
{
return
getClass
().
getSimpleName
()
+
"["
+
path
+
"]"
;
}
private
void
ensureParentDirectoriesExist
()
throws
IOException
{
Path
parent
=
path
.
getParent
();
if
(
parent
!=
null
)
Files
.
createDirectories
(
parent
);
}
private
long
size
()
{
try
{
BasicFileAttributes
attrs
=
Attributes
.
readBasicFileAttributes
(
path
);
return
attrs
.
size
();
}
catch
(
IOException
e
)
{
return
-
1
;
}
}
protected
static
String
toBinaryName
(
Path
relativePath
)
{
return
toBinaryName
(
relativePath
.
toString
(),
relativePath
.
getFileSystem
().
getSeparator
());
}
protected
static
String
toBinaryName
(
String
relativePath
,
String
sep
)
{
return
removeExtension
(
relativePath
).
replaceAll
(
sep
,
"."
);
}
protected
static
String
removeExtension
(
String
fileName
)
{
int
lastDot
=
fileName
.
lastIndexOf
(
"."
);
return
(
lastDot
==
-
1
?
fileName
:
fileName
.
substring
(
0
,
lastDot
));
}
}
src/share/classes/com/sun/tools/javac/util/BaseFileManager.java
0 → 100644
浏览文件 @
10e7c2c7
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
com.sun.tools.javac.util
;
import
com.sun.tools.javac.code.Source
;
import
com.sun.tools.javac.main.JavacOption
;
import
com.sun.tools.javac.main.OptionName
;
import
com.sun.tools.javac.main.RecognizedOptions
;
import
com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition
;
import
java.io.ByteArrayOutputStream
;
import
java.io.Closeable
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStreamWriter
;
import
java.lang.ref.SoftReference
;
import
java.lang.reflect.Constructor
;
import
java.net.URL
;
import
java.net.URLClassLoader
;
import
java.nio.ByteBuffer
;
import
java.nio.CharBuffer
;
import
java.nio.charset.Charset
;
import
java.nio.charset.CharsetDecoder
;
import
java.nio.charset.CoderResult
;
import
java.nio.charset.CodingErrorAction
;
import
java.nio.charset.IllegalCharsetNameException
;
import
java.nio.charset.UnsupportedCharsetException
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.Map
;
import
javax.tools.JavaFileObject
;
import
javax.tools.JavaFileObject.Kind
;
/**
* Utility methods for building a filemanager.
* There are no references here to file-system specific objects such as
* java.io.File or java.nio.file.Path.
*/
public
class
BaseFileManager
{
protected
BaseFileManager
(
Charset
charset
)
{
this
.
charset
=
charset
;
byteBufferCache
=
new
ByteBufferCache
();
}
/**
* Set the context for JavacPathFileManager.
*/
protected
void
setContext
(
Context
context
)
{
log
=
Log
.
instance
(
context
);
options
=
Options
.
instance
(
context
);
classLoaderClass
=
options
.
get
(
"procloader"
);
}
/**
* The log to be used for error reporting.
*/
public
Log
log
;
/**
* User provided charset (through javax.tools).
*/
protected
Charset
charset
;
protected
Options
options
;
protected
String
classLoaderClass
;
protected
Source
getSource
()
{
String
sourceName
=
options
.
get
(
OptionName
.
SOURCE
);
Source
source
=
null
;
if
(
sourceName
!=
null
)
source
=
Source
.
lookup
(
sourceName
);
return
(
source
!=
null
?
source
:
Source
.
DEFAULT
);
}
protected
ClassLoader
getClassLoader
(
URL
[]
urls
)
{
ClassLoader
thisClassLoader
=
getClass
().
getClassLoader
();
// Bug: 6558476
// Ideally, ClassLoader should be Closeable, but before JDK7 it is not.
// On older versions, try the following, to get a closeable classloader.
// 1: Allow client to specify the class to use via hidden option
if
(
classLoaderClass
!=
null
)
{
try
{
Class
<?
extends
ClassLoader
>
loader
=
Class
.
forName
(
classLoaderClass
).
asSubclass
(
ClassLoader
.
class
);
Class
<?>[]
constrArgTypes
=
{
URL
[].
class
,
ClassLoader
.
class
};
Constructor
<?
extends
ClassLoader
>
constr
=
loader
.
getConstructor
(
constrArgTypes
);
return
constr
.
newInstance
(
new
Object
[]
{
urls
,
thisClassLoader
});
}
catch
(
Throwable
t
)
{
// ignore errors loading user-provided class loader, fall through
}
}
// 2: If URLClassLoader implements Closeable, use that.
if
(
Closeable
.
class
.
isAssignableFrom
(
URLClassLoader
.
class
))
return
new
URLClassLoader
(
urls
,
thisClassLoader
);
// 3: Try using private reflection-based CloseableURLClassLoader
try
{
return
new
CloseableURLClassLoader
(
urls
,
thisClassLoader
);
}
catch
(
Throwable
t
)
{
// ignore errors loading workaround class loader, fall through
}
// 4: If all else fails, use plain old standard URLClassLoader
return
new
URLClassLoader
(
urls
,
thisClassLoader
);
}
// <editor-fold defaultstate="collapsed" desc="Option handling">
public
boolean
handleOption
(
String
current
,
Iterator
<
String
>
remaining
)
{
for
(
JavacOption
o:
javacFileManagerOptions
)
{
if
(
o
.
matches
(
current
))
{
if
(
o
.
hasArg
())
{
if
(
remaining
.
hasNext
())
{
if
(!
o
.
process
(
options
,
current
,
remaining
.
next
()))
return
true
;
}
}
else
{
if
(!
o
.
process
(
options
,
current
))
return
true
;
}
// operand missing, or process returned false
throw
new
IllegalArgumentException
(
current
);
}
}
return
false
;
}
// where
private
static
JavacOption
[]
javacFileManagerOptions
=
RecognizedOptions
.
getJavacFileManagerOptions
(
new
RecognizedOptions
.
GrumpyHelper
());
public
int
isSupportedOption
(
String
option
)
{
for
(
JavacOption
o
:
javacFileManagerOptions
)
{
if
(
o
.
matches
(
option
))
return
o
.
hasArg
()
?
1
:
0
;
}
return
-
1
;
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Encoding">
private
String
defaultEncodingName
;
private
String
getDefaultEncodingName
()
{
if
(
defaultEncodingName
==
null
)
{
defaultEncodingName
=
new
OutputStreamWriter
(
new
ByteArrayOutputStream
()).
getEncoding
();
}
return
defaultEncodingName
;
}
public
String
getEncodingName
()
{
String
encName
=
options
.
get
(
OptionName
.
ENCODING
);
if
(
encName
==
null
)
return
getDefaultEncodingName
();
else
return
encName
;
}
public
CharBuffer
decode
(
ByteBuffer
inbuf
,
boolean
ignoreEncodingErrors
)
{
String
encodingName
=
getEncodingName
();
CharsetDecoder
decoder
;
try
{
decoder
=
getDecoder
(
encodingName
,
ignoreEncodingErrors
);
}
catch
(
IllegalCharsetNameException
e
)
{
log
.
error
(
"unsupported.encoding"
,
encodingName
);
return
(
CharBuffer
)
CharBuffer
.
allocate
(
1
).
flip
();
}
catch
(
UnsupportedCharsetException
e
)
{
log
.
error
(
"unsupported.encoding"
,
encodingName
);
return
(
CharBuffer
)
CharBuffer
.
allocate
(
1
).
flip
();
}
// slightly overestimate the buffer size to avoid reallocation.
float
factor
=
decoder
.
averageCharsPerByte
()
*
0.8f
+
decoder
.
maxCharsPerByte
()
*
0.2f
;
CharBuffer
dest
=
CharBuffer
.
allocate
(
10
+
(
int
)(
inbuf
.
remaining
()*
factor
));
while
(
true
)
{
CoderResult
result
=
decoder
.
decode
(
inbuf
,
dest
,
true
);
dest
.
flip
();
if
(
result
.
isUnderflow
())
{
// done reading
// make sure there is at least one extra character
if
(
dest
.
limit
()
==
dest
.
capacity
())
{
dest
=
CharBuffer
.
allocate
(
dest
.
capacity
()+
1
).
put
(
dest
);
dest
.
flip
();
}
return
dest
;
}
else
if
(
result
.
isOverflow
())
{
// buffer too small; expand
int
newCapacity
=
10
+
dest
.
capacity
()
+
(
int
)(
inbuf
.
remaining
()*
decoder
.
maxCharsPerByte
());
dest
=
CharBuffer
.
allocate
(
newCapacity
).
put
(
dest
);
}
else
if
(
result
.
isMalformed
()
||
result
.
isUnmappable
())
{
// bad character in input
// report coding error (warn only pre 1.5)
if
(!
getSource
().
allowEncodingErrors
())
{
log
.
error
(
new
SimpleDiagnosticPosition
(
dest
.
limit
()),
"illegal.char.for.encoding"
,
charset
==
null
?
encodingName
:
charset
.
name
());
}
else
{
log
.
warning
(
new
SimpleDiagnosticPosition
(
dest
.
limit
()),
"illegal.char.for.encoding"
,
charset
==
null
?
encodingName
:
charset
.
name
());
}
// skip past the coding error
inbuf
.
position
(
inbuf
.
position
()
+
result
.
length
());
// undo the flip() to prepare the output buffer
// for more translation
dest
.
position
(
dest
.
limit
());
dest
.
limit
(
dest
.
capacity
());
dest
.
put
((
char
)
0xfffd
);
// backward compatible
}
else
{
throw
new
AssertionError
(
result
);
}
}
// unreached
}
public
CharsetDecoder
getDecoder
(
String
encodingName
,
boolean
ignoreEncodingErrors
)
{
Charset
cs
=
(
this
.
charset
==
null
)
?
Charset
.
forName
(
encodingName
)
:
this
.
charset
;
CharsetDecoder
decoder
=
cs
.
newDecoder
();
CodingErrorAction
action
;
if
(
ignoreEncodingErrors
)
action
=
CodingErrorAction
.
REPLACE
;
else
action
=
CodingErrorAction
.
REPORT
;
return
decoder
.
onMalformedInput
(
action
)
.
onUnmappableCharacter
(
action
);
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="ByteBuffers">
/**
* Make a byte buffer from an input stream.
*/
public
ByteBuffer
makeByteBuffer
(
InputStream
in
)
throws
IOException
{
int
limit
=
in
.
available
();
if
(
limit
<
1024
)
limit
=
1024
;
ByteBuffer
result
=
byteBufferCache
.
get
(
limit
);
int
position
=
0
;
while
(
in
.
available
()
!=
0
)
{
if
(
position
>=
limit
)
// expand buffer
result
=
ByteBuffer
.
allocate
(
limit
<<=
1
).
put
((
ByteBuffer
)
result
.
flip
());
int
count
=
in
.
read
(
result
.
array
(),
position
,
limit
-
position
);
if
(
count
<
0
)
break
;
result
.
position
(
position
+=
count
);
}
return
(
ByteBuffer
)
result
.
flip
();
}
public
void
recycleByteBuffer
(
ByteBuffer
bb
)
{
byteBufferCache
.
put
(
bb
);
}
/**
* A single-element cache of direct byte buffers.
*/
private
static
class
ByteBufferCache
{
private
ByteBuffer
cached
;
ByteBuffer
get
(
int
capacity
)
{
if
(
capacity
<
20480
)
capacity
=
20480
;
ByteBuffer
result
=
(
cached
!=
null
&&
cached
.
capacity
()
>=
capacity
)
?
(
ByteBuffer
)
cached
.
clear
()
:
ByteBuffer
.
allocate
(
capacity
+
capacity
>>
1
);
cached
=
null
;
return
result
;
}
void
put
(
ByteBuffer
x
)
{
cached
=
x
;
}
}
private
final
ByteBufferCache
byteBufferCache
;
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Content cache">
public
CharBuffer
getCachedContent
(
JavaFileObject
file
)
{
SoftReference
<
CharBuffer
>
r
=
contentCache
.
get
(
file
);
return
(
r
==
null
?
null
:
r
.
get
());
}
public
void
cache
(
JavaFileObject
file
,
CharBuffer
cb
)
{
contentCache
.
put
(
file
,
new
SoftReference
<
CharBuffer
>(
cb
));
}
protected
final
Map
<
JavaFileObject
,
SoftReference
<
CharBuffer
>>
contentCache
=
new
HashMap
<
JavaFileObject
,
SoftReference
<
CharBuffer
>>();
// </editor-fold>
public
static
Kind
getKind
(
String
name
)
{
if
(
name
.
endsWith
(
Kind
.
CLASS
.
extension
))
return
Kind
.
CLASS
;
else
if
(
name
.
endsWith
(
Kind
.
SOURCE
.
extension
))
return
Kind
.
SOURCE
;
else
if
(
name
.
endsWith
(
Kind
.
HTML
.
extension
))
return
Kind
.
HTML
;
else
return
Kind
.
OTHER
;
}
protected
static
<
T
>
T
nullCheck
(
T
o
)
{
o
.
getClass
();
// null check
return
o
;
}
protected
static
<
T
>
Collection
<
T
>
nullCheck
(
Collection
<
T
>
it
)
{
for
(
T
t
:
it
)
t
.
getClass
();
// null check
return
it
;
}
}
src/share/classes/com/sun/tools/javac/
file
/CloseableURLClassLoader.java
→
src/share/classes/com/sun/tools/javac/
util
/CloseableURLClassLoader.java
浏览文件 @
10e7c2c7
...
...
@@ -23,7 +23,7 @@
* have any questions.
*/
package
com.sun.tools.javac.
file
;
package
com.sun.tools.javac.
util
;
import
java.io.Closeable
;
import
java.io.IOException
;
...
...
@@ -45,9 +45,9 @@ import java.util.jar.JarFile;
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
class
CloseableURLClassLoader
public
class
CloseableURLClassLoader
extends
URLClassLoader
implements
Closeable
{
CloseableURLClassLoader
(
URL
[]
urls
,
ClassLoader
parent
)
throws
Error
{
public
CloseableURLClassLoader
(
URL
[]
urls
,
ClassLoader
parent
)
throws
Error
{
super
(
urls
,
parent
);
try
{
getLoaders
();
//proactive check that URLClassLoader is as expected
...
...
@@ -63,6 +63,7 @@ class CloseableURLClassLoader
* @throws java.io.IOException if the jar files cannot be found for any
* reson, or if closing the jar file itself causes an IOException.
*/
@Override
public
void
close
()
throws
IOException
{
try
{
for
(
Object
l:
getLoaders
())
{
...
...
src/share/classes/javax/tools/StandardJavaFileManager.java
浏览文件 @
10e7c2c7
...
...
@@ -28,7 +28,6 @@ package javax.tools;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.*
;
import
java.util.concurrent.*
;
/**
* File manager based on {@linkplain File java.io.File}. A common way
...
...
test/tools/javac/nio/compileTest/CompileTest.java
0 → 100644
浏览文件 @
10e7c2c7
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @compile HelloPathWorld.java
* @run main CompileTest
*/
import
java.io.*
;
import
java.nio.file.*
;
import
java.util.*
;
import
java.util.jar.*
;
import
javax.tools.*
;
import
com.sun.tools.javac.nio.*
;
import
com.sun.tools.javac.util.Context
;
import
java.nio.file.spi.FileSystemProvider
;
public
class
CompileTest
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
new
CompileTest
().
run
();
}
public
void
run
()
throws
Exception
{
File
rtDir
=
new
File
(
"rt.dir"
);
File
javaHome
=
new
File
(
System
.
getProperty
(
"java.home"
));
if
(
javaHome
.
getName
().
equals
(
"jre"
))
javaHome
=
javaHome
.
getParentFile
();
File
rtJar
=
new
File
(
new
File
(
new
File
(
javaHome
,
"jre"
),
"lib"
),
"rt.jar"
);
expand
(
rtJar
,
rtDir
);
String
[]
rtDir_opts
=
{
"-bootclasspath"
,
rtDir
.
toString
(),
"-classpath"
,
""
,
"-sourcepath"
,
""
,
"-extdirs"
,
""
};
test
(
rtDir_opts
,
"HelloPathWorld"
);
if
(
isJarFileSystemAvailable
())
{
String
[]
rtJar_opts
=
{
"-bootclasspath"
,
rtJar
.
toString
(),
"-classpath"
,
""
,
"-sourcepath"
,
""
,
"-extdirs"
,
""
};
test
(
rtJar_opts
,
"HelloPathWorld"
);
String
[]
default_opts
=
{
};
test
(
default_opts
,
"HelloPathWorld"
);
// finally, a non-trivial program
test
(
default_opts
,
"CompileTest"
);
}
else
System
.
err
.
println
(
"jar file system not available: test skipped"
);
}
void
test
(
String
[]
opts
,
String
className
)
throws
Exception
{
count
++;
System
.
err
.
println
(
"Test "
+
count
+
" "
+
Arrays
.
asList
(
opts
)
+
" "
+
className
);
Path
testSrcDir
=
Paths
.
get
(
System
.
getProperty
(
"test.src"
));
Path
testClassesDir
=
Paths
.
get
(
System
.
getProperty
(
"test.classes"
));
Path
classes
=
Paths
.
get
(
"classes."
+
count
);
classes
.
createDirectory
();
Context
ctx
=
new
Context
();
PathFileManager
fm
=
new
JavacPathFileManager
(
ctx
,
true
,
null
);
JavaCompiler
compiler
=
ToolProvider
.
getSystemJavaCompiler
();
List
<
String
>
options
=
new
ArrayList
<
String
>();
options
.
addAll
(
Arrays
.
asList
(
opts
));
options
.
addAll
(
Arrays
.
asList
(
"-verbose"
,
"-XDverboseCompilePolicy"
,
"-d"
,
classes
.
toString
()
));
Iterable
<?
extends
JavaFileObject
>
compilationUnits
=
fm
.
getJavaFileObjects
(
testSrcDir
.
resolve
(
className
+
".java"
));
StringWriter
sw
=
new
StringWriter
();
PrintWriter
out
=
new
PrintWriter
(
sw
);
JavaCompiler
.
CompilationTask
t
=
compiler
.
getTask
(
out
,
fm
,
null
,
options
,
null
,
compilationUnits
);
boolean
ok
=
t
.
call
();
System
.
err
.
println
(
sw
.
toString
());
if
(!
ok
)
{
throw
new
Exception
(
"compilation failed"
);
}
File
expect
=
new
File
(
"classes."
+
count
+
"/"
+
className
+
".class"
);
if
(!
expect
.
exists
())
throw
new
Exception
(
"expected file not found: "
+
expect
);
long
expectedSize
=
new
File
(
testClassesDir
.
toString
(),
className
+
".class"
).
length
();
long
actualSize
=
expect
.
length
();
if
(
expectedSize
!=
actualSize
)
throw
new
Exception
(
"wrong size found: "
+
actualSize
+
"; expected: "
+
expectedSize
);
}
boolean
isJarFileSystemAvailable
()
{
boolean
result
=
false
;
for
(
FileSystemProvider
fsp:
FileSystemProvider
.
installedProviders
())
{
String
scheme
=
fsp
.
getScheme
();
System
.
err
.
println
(
"Provider: "
+
scheme
+
" "
+
fsp
);
if
(
scheme
.
equalsIgnoreCase
(
"jar"
)
||
scheme
.
equalsIgnoreCase
(
"zip"
))
result
=
true
;
}
return
result
;
}
void
expand
(
File
jar
,
File
dir
)
throws
IOException
{
JarFile
jarFile
=
new
JarFile
(
jar
);
try
{
Enumeration
<
JarEntry
>
entries
=
jarFile
.
entries
();
while
(
entries
.
hasMoreElements
())
{
JarEntry
je
=
entries
.
nextElement
();
if
(!
je
.
isDirectory
())
{
copy
(
jarFile
.
getInputStream
(
je
),
new
File
(
dir
,
je
.
getName
()));
}
}
}
finally
{
jarFile
.
close
();
}
}
void
copy
(
InputStream
in
,
File
dest
)
throws
IOException
{
dest
.
getParentFile
().
mkdirs
();
OutputStream
out
=
new
BufferedOutputStream
(
new
FileOutputStream
(
dest
));
try
{
byte
[]
data
=
new
byte
[
8192
];
int
n
;
while
((
n
=
in
.
read
(
data
,
0
,
data
.
length
))
>
0
)
out
.
write
(
data
,
0
,
n
);
}
finally
{
out
.
close
();
in
.
close
();
}
}
void
error
(
String
message
)
{
System
.
err
.
println
(
"Error: "
+
message
);
errors
++;
}
int
errors
;
int
count
;
}
test/tools/javac/nio/compileTest/HelloPathWorld.java
0 → 100644
浏览文件 @
10e7c2c7
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
class
HelloPathWorld
{
public
static
void
main
(
String
...
args
)
{
System
.
out
.
println
(
"Hello World!"
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录