1 |
This document specifies the format of a .japi file, version 0.9.7. The actual |
2 |
implementations of japize, japifix and japicompat may not honor this spec |
3 |
exactly. If they do not, it is generally a bug or missing feature in the tool; |
4 |
this spec notes such bugs when they are known. |
5 |
|
6 |
Types |
7 |
----- |
8 |
|
9 |
Types in a japi file get represented in different ways, depending on where they |
10 |
appear. This spec identifies which representation should be used for each |
11 |
item. The possible representations are: |
12 |
- Java Language representation: Can only be used to represent classes and |
13 |
interfaces. The format is simply the format of a fully-qualified class name |
14 |
in the Java language, eg "java.lang.Exception". This format is used when |
15 |
only classes and interfaces can appear, eg in superclasses or exceptions. |
16 |
Inner classes are represented using the name that the compiler gives them: |
17 |
the name of the outer class followed by a "$" followed by the inner |
18 |
class name, eg "java.util.Map$Entry". |
19 |
XXXX insert discussion of generic types in JL representation |
20 |
- Type Signature representation: Can represent any Java type, including |
21 |
primitive types and arrays. This is the format used in type signatures |
22 |
internally within the Java virtual machine. The format looks like this: |
23 |
- Primitive types are represented as single letter codes, specifically: |
24 |
boolean=Z, byte=B, char=C, short=S, int=I, long=J, float=F, double=D, void=V |
25 |
- Classes and interfaces are represented as the letter L, followed by the |
26 |
fully-qualified classname with periods replaced by slashes, followed by a |
27 |
semicolon. The class generally known as java.io.Writer would be represented |
28 |
as "Ljava/io/Writer;". Inner classes are represented by the name the |
29 |
compiler gives them, just as above. |
30 |
- Array types are represented by the character "[" followed by the type |
31 |
of elements in the array. For example, an array of java.util.Dates would |
32 |
be represented as "[Ljava/util/Date;" and a two-dimensional array of |
33 |
ints (an array of arrays of ints) would be "[[I". |
34 |
- In the special case of a method which takes a variable number of arguments |
35 |
(which Java implements internally as an array parameter), the leading "[" |
36 |
should be replaced by a ".". For example, a method taking a variable number |
37 |
of int arguments would be represented as ".I" and a variable number of |
38 |
arrays of strings would be ".[Ljava/lang/String;". Note that a special |
39 |
rule applies for ordering methods with this kind of parameter - see |
40 |
"Ordering", below. |
41 |
- XXXX insert discussion of generic types in TS representation |
42 |
- Japi sortable representation: Designed to make it easy to sort a japi file |
43 |
into a convenient order. The format is: |
44 |
<pkg>,<class>[$<innerclass>]. |
45 |
In this format, <pkg> is the package that the class appears in (dot separated, |
46 |
eg "java.util"), <class> is the full name of the outer class (eg "Map") and |
47 |
<innerclass> is the name of the inner class (eg "Entry"), if applicable. The |
48 |
$ is omitted for top-level classes. Note that it is theoretically possible for |
49 |
a class to have a $ in its name without being an inner class: the $ in that |
50 |
case should be \u escaped (see "Escaping", below; note that this is not yet |
51 |
implemented by any of the japitools programs). Multiple levels of inner- |
52 |
classness are represented the obvious way. So the class java.util.Map is |
53 |
represented as "java.util,Map", and its Entry inner class is represented as |
54 |
"java.util,Map$Entry". No special consideration applies to generic types |
55 |
in this representation: they never appear here. |
56 |
|
57 |
|
58 |
Escaping |
59 |
-------- |
60 |
Note: Much of this section is not yet implemented by any existing japitools |
61 |
program. |
62 |
|
63 |
The Java language is a fully unicode-enabled language with support for multibyte |
64 |
characters at every level of the language. However, the japi file format is |
65 |
strictly 7-bit ASCII, for ease of processing in (for example) older versions of |
66 |
perl, which are not unicode-capable. To support this, characters outside the |
67 |
normal ASCII ranges are escaped. Characters are escaped as follows: The newline |
68 |
character is escaped to "\n", the backslash character is escaped to "\\", and |
69 |
all other characters are escaped as "\uXXXX", where XXXX is the lowercase |
70 |
hexadecimal rendition of the integer value of the "char" type in java. |
71 |
|
72 |
In class names, all characters should be escaped except for A-Z, a-z, 0-9, _ and |
73 |
any metacharacters that have meaning in the particular representation being |
74 |
used. In Java Language representation, the metacharacters are ".$"; in Type |
75 |
Signature representation, they are "/$;"; and in Japi Sortable representation |
76 |
they are ".,$". |
77 |
|
78 |
In field and method names, all characters should be escaped except for A-Z, a-z, |
79 |
0-9 and _. |
80 |
|
81 |
In constant strings, all characters outside the range from " " to "~" in ASCII |
82 |
value should be escaped, along with the backslash ("\") character. |
83 |
|
84 |
Existing implementations only escape backslash and newline, and only do so in |
85 |
constant strings. This covers the vast majority of what will actually arise. |
86 |
|
87 |
|
88 |
Inclusion |
89 |
--------- |
90 |
|
91 |
Japi files may be created for any set of classes and interfaces, although |
92 |
typically they will be made for particular complete packages that make up a |
93 |
public API. However, it is not permitted to create a japi file for only part of |
94 |
a class. Only public and protected classes and interfaces can be included in |
95 |
a japi file. |
96 |
|
97 |
For each class and/or interface that is included, all its public and protected |
98 |
fields, methods and constructors must be included. This includes fields and |
99 |
methods (but not constructors!) inherited from public or protected superclasses. |
100 |
|
101 |
|
102 |
Ordering |
103 |
-------- |
104 |
|
105 |
In order to allow efficient comparison of japi files, the items in the file are |
106 |
required to be in a strict order. The items are sorted first by package, then |
107 |
by class (or interface), then by member. |
108 |
|
109 |
Packages are sorted alphabetically by name, except that java.lang and all its |
110 |
subpackages (eg java.lang.reflect and java.lang.ref) are placed first. Classes |
111 |
and interfaces are sorted by name, with inner classes coming after the |
112 |
corresponding outer class, except for java.lang.Object which sorts first of |
113 |
everything. |
114 |
|
115 |
Within a class or interface, the class (or interface) itself comes first, |
116 |
followed by its fields (in alphabetical order by name), followed by its |
117 |
constructors (in alphabetical order by argument types), followed by its methods |
118 |
(in alphabetical order by name and argument types). "By argument types" here |
119 |
means by the result of concatenating all the types of the arguments, comma |
120 |
separated, in type signature format, EXCEPT that any generic types should be |
121 |
replaced by the real type and the leading "." of a vararg array should be |
122 |
replaced with "[" for the purposes of this comparison. |
123 |
|
124 |
If any package, class or member names include any escaped characters, it is the |
125 |
escaped string that is compared, rather than the original. |
126 |
|
127 |
|
128 |
File Format: Compression |
129 |
------------------------ |
130 |
|
131 |
Japi files may optionally be compressed by gzip. A compressed japi file should |
132 |
be named *.japi.gz; an uncompressed one should be named *.japi. Tools for |
133 |
reading japi files may rely on this naming convention; tools for creating japi |
134 |
files should enforce it where possible. |
135 |
|
136 |
|
137 |
File Format: First Line |
138 |
----------------------- |
139 |
|
140 |
The first line of a japi file indicates the file format version. This line is |
141 |
guaranteed to follow the same format for all future releases. Thus, this section |
142 |
(only!) of the spec covers all japi file format versions, past and future. With |
143 |
this information you can identify whether a file is a japi file, and which |
144 |
version it is. However, this spec does not provide any information about the |
145 |
content of the rest of the file for any version other than 0.9.7. Both past and |
146 |
future versions can be assumed to be entirely incompatible with this spec from |
147 |
the second line onwards. |
148 |
|
149 |
The first line of any japi file since version 0.8.1 is as follows: |
150 |
%%japi <version>[ <info>] |
151 |
<version> indicates the version number of the japi file format. While this |
152 |
version number vaguely correlates with the version number of japitools releases, |
153 |
it is not the same number. Often japitools releases do not require a file format |
154 |
change, and sometimes I mess with the file version number for other reasons, |
155 |
with mixed results. The contents of <info> may vary from version to version, |
156 |
or it and its leading space may be omitted altogether; implementations should |
157 |
parse and ignore it (if present) except when the file format version indicates |
158 |
they can understand it. |
159 |
|
160 |
For completeness, I should mention file format versions prior to 0.8.1. Version |
161 |
0.7 can be recognized by the following regular expression: |
162 |
/^[^ ]+#[^ ]* (public|protected) (abstract|concrete) (static|instance) (final|nonfinal) / |
163 |
Version 0.8 can be recognized by the following regular expression: |
164 |
/^[^ ]+#[^ ]* [Pp][ac][si][fn] / |
165 |
These version numbers were invented retroactively, of course :) |
166 |
|
167 |
|
168 |
File Format: File information |
169 |
----------------------------- |
170 |
|
171 |
The <info> field contains a list of space-separated name=value pairs. Unknown |
172 |
names should be ignored. Neither the name nor value may include spaces. The |
173 |
following names and values are permitted: |
174 |
date=yyyy/mm/dd_hh:mm:ss_TZ |
175 |
creator=<toolname> |
176 |
origver=<original japi file version that this was updated from> |
177 |
|
178 |
|
179 |
File Format: API Items |
180 |
---------------------- |
181 |
|
182 |
Every other line in a japi file represents an individual item in the API. |
183 |
These lines must appear in a specific order; see "Ordering" above for the |
184 |
specific requirements. |
185 |
The format of these lines is as follows: |
186 |
<plus><class>!<member> <modifiers> <typeinfo> |
187 |
|
188 |
<plus> is "++" for all members of java.lang.Object, "+" for all members of all |
189 |
classes in java.lang and its subpackages, or nothing ("") for all other API |
190 |
items. This allows java.lang.Object and java.lang to appear in the right |
191 |
places in a purely alphabetical sort. |
192 |
|
193 |
<class> is the name of the class, in Japi Sortable representation. |
194 |
|
195 |
<member> is one of the following depending on what type of API item is being |
196 |
represented: |
197 |
- The empty string, to refer to the class or interface itself. |
198 |
- #<fieldname>, to refer to a field. |
199 |
- (<argtypes>), to refer to a constructor. |
200 |
- <methodname>(<argtypes>), to refer to a method. |
201 |
<fieldname> and <methodname> are simply the name of the field or method, eg |
202 |
"toString". <argtypes> is a comma-separated list of argument types, with each |
203 |
one listed in Type Signature representation, eg "[B,I,I,Ljava/lang/String;". |
204 |
|
205 |
<modifiers> is a five-character string indicating the modifiers of the item: |
206 |
|
207 |
- The first character is either "P" for public or "p" for protected. |
208 |
Package-private (default access) and private items do not appear in japi |
209 |
files. |
210 |
|
211 |
- The second character is either "a" for abstract or "c" for concrete |
212 |
(non-abstract). Interfaces, and methods on interfaces, are always considered |
213 |
abstract regardless of whether they are explicitly set as such. |
214 |
|
215 |
- The third character is either "s" for static or "i" for instance (non-static). |
216 |
Top-level classes are always considered static. |
217 |
|
218 |
- The fourth character is either "f" for final, "n" for nonfinal, or "e" for |
219 |
the special fields that are the values of an "enum" type. Methods on final |
220 |
classes are always considered final regardless of whether they are explicitly |
221 |
set as such. |
222 |
|
223 |
- The fifth character is either "d" for deprecated, "u" for undeprecated, or |
224 |
"?" if the deprecation status is unknown. |
225 |
|
226 |
<typeinfo> is a catch-all for general information about the item. What exactly |
227 |
appears here depends on what type of item this is. |
228 |
XXXX Insert notes here about how annotations appear on each of the types of |
229 |
item and which annotations should appear (probably those that are @Documented). |
230 |
|
231 |
- For classes, the <typeinfo> field consists of the following parts: |
232 |
- The word "class" |
233 |
- If the class is serializable, the character "#" followed by the |
234 |
SerialVersionUID of the class, represented in decimal. If the class is |
235 |
not serializable, this section does not appear. |
236 |
- For each superclass, in order, the character ":" followed by the |
237 |
name of the superclass in Java Language representation. Superclasses that |
238 |
are neither public nor protected are omitted. In the case of |
239 |
java.lang.Object, which has no superclass, this section does not appear. |
240 |
- For each interface implemented by the class, in *any* order, the character |
241 |
"*" followed by the name of the interface in Java Language representation. |
242 |
Interfaces that are neither public nor protected are omitted. Note that |
243 |
interfaces implemented by superclasses, or by other interfaces, must also be |
244 |
included, even if the superclass that implements the interface isn't |
245 |
public or protected. |
246 |
For example, for the class java.util.ArrayList, the typeinfo would be |
247 |
something like: |
248 |
class#99999999999999:java.util.AbstractList:java.lang.AbstractCollection:java.lang.Object*java.io.Serializable*java.lang.Cloneable*java.util.List*java.util.Collection |
249 |
|
250 |
- For interfaces, the format is the same except that "interface" appears instead |
251 |
of "class", and the SerialVersionUID and superclasses are not applicable. |
252 |
|
253 |
- For enums, the format is identical to that of classes except that "enum" |
254 |
appears instead of "class". |
255 |
|
256 |
- For annotations, the format is identical to that of interfaces except that |
257 |
"annotation" appears instead of "interface". |
258 |
|
259 |
- For fields, the <typeinfo> field consists of the following parts: |
260 |
- The type of the field, in Type Signature format. |
261 |
- If the field is a constant value other than null, the character ":" followed |
262 |
by the value of the field. In the case of a char value, this is the integer |
263 |
value of the character; in the case of a string, it is the character '"' |
264 |
followed by the escaped string. For all other values it is the result of |
265 |
Java's default conversion of that type to a string. For float and double |
266 |
constants, the stringified value may be followed by "/" and the result of |
267 |
toHexString() called on the result of floatToRawIntBits() or |
268 |
doubleToRawLongBits(), respectively. This is unambigous since there is no |
269 |
way for the stringified value of a float or double to contain "/". This |
270 |
hex string is optional but it is recommended to include it if possible. |
271 |
|
272 |
- For constructors, the <typeinfo> field consists of the following parts: |
273 |
- The word "constructor". |
274 |
- For every exception type thrown by this constructor, the character "*" |
275 |
followed by the name of the exception type, in Java Language representation. |
276 |
These may appear in any order. Subclasses of java.lang.RuntimeException and |
277 |
java.lang.Error must be omitted, as must any exception that is a subclass of |
278 |
another exception that can be thrown (eg if both java.io.IOException and |
279 |
java.io.FileNotFoundException can be thrown, only java.io.IOException should |
280 |
be listed). |
281 |
|
282 |
- For methods, the <typeinfo> field consists of the following parts: |
283 |
- The return type of the method, in Type Signature format. |
284 |
- For every exception type thrown by this method, the character "*" followed |
285 |
by the name of the exception type, in Java Language representation. These |
286 |
may appear in any order. Subclasses of java.lang.RuntimeException and |
287 |
java.lang.Error must be omitted, as must any exception that is a subclass of |
288 |
another exception that can be thrown (eg if both java.io.IOException and |
289 |
java.io.FileNotFoundException can be thrown, only java.io.IOException should |
290 |
be listed). |
291 |
|
292 |
|
293 |
Conclusion |
294 |
---------- |
295 |
|
296 |
This specification should provide enough information to both read and write |
297 |
japi files. Any questions or comments, especially if anything in this spec is |
298 |
unclear, should be directed to stuart.a.ballard@gmail.com. |