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