public abstract class Source extends Object
The starting point isFilefile = newFile(dir, name); assert name.endsWith(".java") : "Imagine 'c:\\sources\\Example.java' file";Sourcesource =Source.newBuilder(file).build(); assert file.getName().equals(source.getName()); assert file.getPath().equals(source.getPath()); assert file.toURI().equals(source.getURI()); assert "text/x-java".equals(source.getMimeType());
Source.newBuilder(java.io.File) method.
Source.newBuilder(java.net.URL)
factory: Each URL source is represented as a canonical object, indexed by the URL. Contents are read eagerly once theURLresource = relativeClass.getResource("sample.js");Sourcesource =Source.newBuilder(resource) .name("sample.js") .build(); assert resource.toExternalForm().equals(source.getPath()); assert "sample.js".equals(source.getName()); assert "application/javascript".equals(source.getMimeType()); assert resource.toURI().equals(source.getURI());
Source.Builder.build() method is called.
Source.newBuilder(java.lang.String) factory method: the createdSourcesource =Source.newBuilder("function() {\n" + " return 'Hi';\n" + "}\n") .name("hi.js") .mimeType("application/javascript") .build(); assert "hi.js".equals(source.getName()); assert "application/javascript".equals(source.getMimeType());
Source doesn't have associated mime type. One has to
explicitly attach via Source.Builder.mimeType(java.lang.String) method. The created
Source doesn't have associated name, one has to attach it via
Source.Builder.name(java.lang.String) method.
Reader one can convert its content into a Source via
Source.newBuilder(java.io.Reader) method: the content is read eagerly once theReaderstream = newInputStreamReader( relativeClass.getResourceAsStream("sample.js") );Sourcesource =Source.newBuilder(stream) .name("sample.js") .mimeType("application/javascript") .build(); assert "sample.js".equals(source.getName()); assert "application/javascript".equals(source.getMimeType());
Source.Builder.build() method is called. It
doesn't have associated mime type and Source.getName(). Both values have
to be explicitly provided by Source.Builder.name(java.lang.String) and
Source.Builder.mimeType(java.lang.String) methods otherwise MissingMIMETypeException
and/or MissingNameException are thrown.
Source
Source is an immutable object - once (lazily) loaded, it remains the same. The source
object can be associated with various attributes like Source.getName() , (),
Source.getMimeType() and these are immutable as well. The system makes the best effort to
derive values of these attributes from the location and/or content of the Source object.
However, to give the user that creates the source control over these attributes, the API offers
an easy way to alter values of these attributes by creating clones of the source via
Source.Builder.mimeType(java.lang.String), Source.Builder.name(java.lang.String),
Source.Builder.uri(java.net.URI) methods.
While Source is immutable, the world around it is changing. The content of a file from
which a source has been read may change few seconds
later. How can we balance the immutability with ability to see real state of the world? In this
case, one can load of a new version of the source for the
same file. The newly loaded Source will be different than the previous one, however it
will have the same attributes (Source.getName(), presumably also Source.getMimeType(), etc.).
There isn't much to do about this - just keep in mind that there can be multiple different
Source objects representing the same source origin.
| Modifier and Type | Class and Description |
|---|---|
class |
Source.Builder<E1 extends Exception,E2 extends Exception,E3 extends Exception>
|
| Modifier and Type | Method and Description |
|---|---|
SourceSection |
createSection(int lineNumber)
Creates a representation of a line of text in the source identified only by line number, from
which the character information will be computed.
|
SourceSection |
createSection(int charIndex,
int length)
Creates a representation of a contiguous region of text in the source.
|
SourceSection |
createSection(int startLine,
int startColumn,
int length)
Creates a representation of a contiguous region of text in the source.
|
SourceSection |
createUnavailableSection()
Returns an unavailable source section indicating that the source location is not available.
|
String |
getCode()
Returns the complete text of the code.
|
String |
getCode(int lineNumber)
Gets the text (not including a possible terminating newline) in a (1-based) numbered line.
|
String |
getCode(int charIndex,
int charLength)
Returns a subsection of the code test.
|
int |
getColumnNumber(int offset)
Given a 0-based character offset, return the 1-based number of the column at the position.
|
InputStream |
getInputStream()
Access to the source contents.
|
int |
getLength()
Gets the number of characters in the source.
|
int |
getLineCount()
The number of text lines in the source, including empty lines; characters at the end of the
source without a terminating newline count as a line.
|
int |
getLineLength(int lineNumber)
The number of characters (not counting a possible terminating newline) in a (1-based)
numbered line.
|
int |
getLineNumber(int offset)
Given a 0-based character offset, return the 1-based number of the line that includes the
position.
|
int |
getLineStartOffset(int lineNumber)
Given a 1-based line number, return the 0-based offset of the first character in the line.
|
String |
getMimeType()
MIME type that is associated with this source.
|
String |
getName()
Returns the name of this resource holding a guest language program.
|
String |
getPath()
The fully qualified name of the source.
|
Reader |
getReader()
Access to the source contents.
|
URI |
getURI()
Get URI of the source.
|
URL |
getURL()
The URL if the source is retrieved via URL.
|
boolean |
isInteractive()
Check whether this source has been marked as interactive.
|
boolean |
isInternal()
Check whether this source has been marked as internal, meaning that it has been
provided by the infrastructure, language implementation, or system library.
|
static Source.Builder<IOException,RuntimeException,RuntimeException> |
newBuilder(File file)
Creates new
Source builder for specified file. |
static Source.Builder<IOException,MissingMIMETypeException,MissingNameException> |
newBuilder(Reader reader)
Creates a new source whose content will be read once it is
constructed. |
static Source.Builder<RuntimeException,MissingMIMETypeException,MissingNameException> |
newBuilder(String text)
Builds new
source from a provided text. |
static Source.Builder<IOException,RuntimeException,RuntimeException> |
newBuilder(URL url)
Creates a new source whose content will be read from the provided URL once it is
constructed. |
Source |
subSource(int baseCharIndex,
int length)
|
public static Source.Builder<IOException,RuntimeException,RuntimeException> newBuilder(File file)
Source builder for specified file. Once the source is built
the name will become File.getName() and the
Source.getCode() will be loaded from the file, unless
redefined on the builder. Sample usage:
Filefile = newFile(dir, name); assert name.endsWith(".java") : "Imagine 'c:\\sources\\Example.java' file";Sourcesource =Source.newBuilder(file).build(); assert file.getName().equals(source.getName()); assert file.getPath().equals(source.getPath()); assert file.toURI().equals(source.getURI()); assert "text/x-java".equals(source.getMimeType());
The system tries to deduce appropriate Source.getMimeType() by consulting registered
file type detectors.
file - the location of the file to load content frompublic static Source.Builder<RuntimeException,MissingMIMETypeException,MissingNameException> newBuilder(String text)
source from a provided text. One needs to specify a
Source.Builder.mimeType(java.lang.String), possibly a Source.Builder.name(java.lang.String)
and other attributes and then can Source.Builder.build() a new instance of the source.
Sample usage:
Sourcesource =Source.newBuilder("function() {\n" + " return 'Hi';\n" + "}\n") .name("hi.js") .mimeType("application/javascript") .build(); assert "hi.js".equals(source.getName()); assert "application/javascript".equals(source.getMimeType());
text - the text to be returned by Source.getCode()public Source subSource(int baseCharIndex, int length)
baseCharIndex - 0-based index of the first character of the sub-rangelength - the number of characters in the sub-rangeIllegalArgumentException - if the specified sub-range is not contained in the basepublic static Source.Builder<IOException,RuntimeException,RuntimeException> newBuilder(URL url)
constructed. Example:
URLresource = relativeClass.getResource("sample.js");Sourcesource =Source.newBuilder(resource) .name("sample.js") .build(); assert resource.toExternalForm().equals(source.getPath()); assert "sample.js".equals(source.getName()); assert "application/javascript".equals(source.getMimeType()); assert resource.toURI().equals(source.getURI());
public static Source.Builder<IOException,MissingMIMETypeException,MissingNameException> newBuilder(Reader reader)
constructed. Multiple Source instances constructed by a single Source.Builder
instance share the content, read only once. When building source from reader, it is essential
to specify MIME type. Example follows:
Readerstream = newInputStreamReader( relativeClass.getResourceAsStream("sample.js") );Sourcesource =Source.newBuilder(stream) .name("sample.js") .mimeType("application/javascript") .build(); assert "sample.js".equals(source.getName()); assert "application/javascript".equals(source.getMimeType());
public String getName()
Source.getPath().public String getPath()
File,
then the default path is the normalized, canonical path.public boolean isInternal()
On the other hand, tools should be free to make internal sources visible in (possibly privileged) modes that are useful for language implementors.
One can specify whether a source is internal when building it.
public boolean isInteractive()
Depending on language interactive capability, when interactive sources are executed, the
appropriate result could be passed directly to the polyglot engine
output stream
or error stream
and polyglot engine
input stream can
be used to read user input during the execution, to clarify the execution behavior by asking
questions for instance. Non-interactive languages are expected to ignore this property.
One can specify whether a source is interactive when building
it.
public URL getURL()
nullpublic URI getURI()
URI, which can be used as a
persistent identification of the source. For example one can
register a breakpoint using a URI to a source that isn't loaded yet and it will be activated
when the source is
evaluated. The URI returned by this method should be as unique as possible, yet it
can happen that different sources return the same Source.getURI() - for
example when content of a file on a disk changes and
is re-loaded.nullpublic Reader getReader()
public final InputStream getInputStream()
public final int getLength()
public String getCode()
public String getCode(int charIndex, int charLength)
public final String getCode(int lineNumber)
public final int getLineCount()
public final int getLineNumber(int offset)
throws IllegalArgumentException
IllegalArgumentException - if the offset is outside the text contentspublic final int getColumnNumber(int offset)
throws IllegalArgumentException
IllegalArgumentException - if the offset is outside the text contentspublic final int getLineStartOffset(int lineNumber)
throws IllegalArgumentException
IllegalArgumentException - if there is no such line in the textpublic final int getLineLength(int lineNumber)
throws IllegalArgumentException
IllegalArgumentException - if there is no such line in the textpublic final SourceSection createUnavailableSection()
0, but returns false for
SourceSection.isAvailable().SourceSection.isAvailable()public final SourceSection createSection(int lineNumber)
code of this source to be loaded.lineNumber - 1-based line number of the first character in the sectionIllegalArgumentException - if the given lineNumber does not exist the sourcepublic final SourceSection createSection(int charIndex, int length)
code of this source to be
loaded if assertions enabled. The bounds of the source section are only verified if
assertions (-ea) are enabled in the host system. An IllegalArgumentException is
thrown if the given indices are out of bounds of the source bounds.charIndex - 0-based position of the first character in the sectionlength - the number of characters in the sectionIllegalArgumentException - if charIndex < 0 or length < 0; in case assertions are
enabled also if the given bounds are out of the source bounds.public final SourceSection createSection(int startLine, int startColumn, int length)
charIndex value by building a text map of lines in the source. Please note that
calling this method does cause the code of this source to be loaded.startLine - 1-based line number of the first character in the sectionstartColumn - 1-based column number of the first character in the sectionlength - the number of characters in the sectionIllegalArgumentException - if arguments are outside the text of the source boundsSource.createSection(int, int)public String getMimeType()
FileTypeDetector classes), yet
one can directly provide a MIME type to each
source.null, if unknown