summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorcremet <cremet@epfl.ch>2004-04-13 10:36:10 +0000
committercremet <cremet@epfl.ch>2004-04-13 10:36:10 +0000
commit118ba73f3a8cc2209c690b0012750261a9ecced2 (patch)
tree44da86a13278864bae7f975a8aaf2e5451c42184 /sources
parent70c6897197370531b4626ec7a0bee4ab71be3b22 (diff)
downloadscala-118ba73f3a8cc2209c690b0012750261a9ecced2.tar.gz
scala-118ba73f3a8cc2209c690b0012750261a9ecced2.tar.bz2
scala-118ba73f3a8cc2209c690b0012750261a9ecced2.zip
- I modified Scaladoc so that it does not gener...
- I modified Scaladoc so that it does not generate any HTML file when launched as server. Instead it generates web pages on the fly when needed.
Diffstat (limited to 'sources')
-rw-r--r--sources/scala/tools/scaladoc/HTMLGenerator.java945
-rwxr-xr-xsources/scala/tools/scaladoc/HTTPServer.java11
-rw-r--r--sources/scala/tools/scaladoc/Location.java127
-rw-r--r--sources/scala/tools/scaladoc/Page.java121
-rw-r--r--sources/scala/tools/scaladoc/SymbolTablePrinterFactory.java6
5 files changed, 685 insertions, 525 deletions
diff --git a/sources/scala/tools/scaladoc/HTMLGenerator.java b/sources/scala/tools/scaladoc/HTMLGenerator.java
index 23b6e1315d..cb435e1913 100644
--- a/sources/scala/tools/scaladoc/HTMLGenerator.java
+++ b/sources/scala/tools/scaladoc/HTMLGenerator.java
@@ -10,6 +10,8 @@ package scala.tools.scaladoc;
import java.io.Writer;
import java.io.BufferedWriter;
+import java.io.Reader;
+import java.io.InputStreamReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
@@ -60,11 +62,11 @@ import scalac.util.ScalaProgramArgumentParser;
public abstract class HTMLGenerator {
/*
- * Names of predefined page names.
+ * Names of predefined page names and page sections.
*/
protected final String FRAME_PAGE = "index.html";
protected final String ROOT_PAGE = Location.ROOT_NAME + ".html";
- protected final String PACKAGE_LIST_PAGE = "package-list-page.html";
+ protected final String PACKAGE_INDEX_PAGE = "package-index-page.html";
protected final String HELP_PAGE = "help-page.html";
protected final String SEARCH_SECTION = "search-section";
protected final String INDEX_PAGE = "index-page.html";
@@ -247,6 +249,10 @@ public abstract class HTMLGenerator {
*/
public abstract TypeIsomorphism newTypeIso(Global global);
+ /** Page promises: Map[String, Promise].
+ */
+ public Map promises;
+
/**
* Creates a new instance.
*
@@ -256,6 +262,7 @@ public abstract class HTMLGenerator {
this.global = global;
this.root = global.definitions.ROOT_CLASS;
this.uri = Location.makeURI(".");
+ this.promises = new HashMap();
assert global.args instanceof HTMLGeneratorCommand;
HTMLGeneratorCommand args = (HTMLGeneratorCommand) global.args;
@@ -285,14 +292,35 @@ public abstract class HTMLGenerator {
};
}
- /** Relative URL of the definition of the given symbol.
+ /**
+ * Adapt the URI to the use context. If the usage context is the
+ * server, then the URI for the page <code>index.html</code> has
+ * the following shape: <pre>pageServlet?page=index.html</pre>. If
+ * the usage context is a static page, then the URI is given
+ * relative to the given page: <pre>../../index.html</pre>
+ */
+ public URI adaptURI(URI uri, URI pageUri) {
+ if (launchServer)
+ return Location.mkURI(PAGE_SERVLET_NAME + "?" +"page=" + uri.getPath() + "#" + uri.getFragment());
+ else
+ return Location.asSeenFrom(uri, pageUri);
+ }
+
+ /**
+ * Compute the URI for a symbol page. The URI is expressed
+ * relatively to the given page.
*/
- protected String definitionURL(Symbol sym, Page page) {
- return page.rel(Location.get(sym));
+ protected URI definitionURI(Symbol sym, Page page) {
+ URI defUri = Location.getURI(sym);
+ return adaptURI(defUri, page.uri);
}
- protected String definitionURL(Symbol sym) {
- return definitionURL(sym, page);
+ /**
+ * Compute the URI for a symbol page. The URI is expressed
+ * relatively to the current page.
+ */
+ protected URI definitionURI(Symbol sym) {
+ return definitionURI(sym, page);
}
/** Get the list pf packages to be documented.
@@ -311,9 +339,9 @@ public abstract class HTMLGenerator {
/** Get a file writer to a page.
*/
- protected static Writer fileWriter(File rootDirectory, URI uri) {
+ protected static Writer fileWriter(File rootDirectory, String uri) {
try {
- File f = new File(rootDirectory, uri.toString());
+ File f = new File(rootDirectory, uri);
f.getParentFile().mkdirs();
return new BufferedWriter(new FileWriter(f));
} catch(IOException e) { throw Debug.abort(e); }
@@ -324,15 +352,16 @@ public abstract class HTMLGenerator {
* @param uri URL of the page
* @param title Title of the page
*/
- protected void createPrinters(URI uri, String title, String destinationFrame) {
+ protected void createPrinters(Writer writer, URI uri, String title, String destinationFrame) {
stack.push(page);
stack.push(symtab);
// Create a new page.
- page = new Page(fileWriter(directory, uri), uri, destinationFrame,
+ page = new Page(writer, uri, destinationFrame,
title, representation,
- stylesheet/*, script*/);
+ adaptURI(Location.mkURI(HTMLPrinter.DEFAULT_STYLESHEET), uri).toString(),
+ adaptURI(Location.mkURI(HTMLPrinter.DEFAULT_JAVASCRIPT), uri).toString());
// Create a printer to print symbols and types.
- symtab = SymbolTablePrinterFactory.makeHTML(page, isDocumented);
+ symtab = SymbolTablePrinterFactory.makeHTML(this, page, isDocumented);
page.open();
}
@@ -340,7 +369,7 @@ public abstract class HTMLGenerator {
* Close the current page.
*/
protected void closePrinters() {
- page.close();
+ //page.close();
symtab = (MySymbolTablePrinter) stack.pop();
page = (Page) stack.pop();
}
@@ -368,27 +397,32 @@ public abstract class HTMLGenerator {
}
/**
- * Generates the HTML pages.
+ * Main function.
*/
public void apply() {
- if (! checkOutpath())
- return;
+ if (!launchServer) {
+ if (! checkOutpath())
+ return;
+ }
this.xhtml = new HTMLValidator(getResourceURL(HTML_DTD[0]));
- // page with list of packages
- createPackageIndexPage();
+ // Page with list of packages
+ Promise packageIndexPage = new PackageIndexPromise();
+ promises.put(packageIndexPage.name(), packageIndexPage);
- // class and object pages
+ // Class and object pages
ScalaSearch.foreach(root,
new ScalaSearch.SymFun() {
public void apply(Symbol sym) {
if (ScalaSearch.isContainer(sym) &&
isDocumented.apply(sym)) {
- createPages(sym);
+ Promise containerPage = new ContainerPromise(sym);
+ promises.put(containerPage.name(), containerPage);
if (sym.isPackage() || sym.isPackageClass()) {
- createContainerIndexPage(sym);
+ Promise containerIndexPage = new ContainerIndexPromise(sym);
+ promises.put(containerIndexPage.name(), containerIndexPage);
}
}
}
@@ -396,46 +430,72 @@ public abstract class HTMLGenerator {
);
if (!noindex) {
- // page with index of Scala documented entities.
- createIndexPage();
+ // Page with index of Scala documented entities
+ Promise indexPage = new IndexPromise();
+ promises.put(indexPage.name(), indexPage);
}
- createHelpPage();
+ // Help page
+ Promise helpPage = new HelpPromise();
+ promises.put(helpPage.name(), helpPage);
- // frame description page
- createFramePage();
+ // Frame description page
+ Promise framePage = new FramePromise();
+ promises.put(framePage.name(), framePage);
- // style sheet
- createResource(HTMLPrinter.DEFAULT_STYLESHEET, null);
+ // Style sheet
+ Promise styleSheetPage = new ResourcePromise(HTMLPrinter.DEFAULT_STYLESHEET, null);
+ promises.put(styleSheetPage.name(), styleSheetPage);
- // script
- createResource(HTMLPrinter.DEFAULT_JAVASCRIPT, null);
+ // Script
+ Promise javaScriptPage = new ResourcePromise(HTMLPrinter.DEFAULT_JAVASCRIPT, null);
+ promises.put(javaScriptPage.name(), javaScriptPage);
- // launch HTTP server
if (launchServer) {
- Servlet servlet = new ScaladocServlet();
- Servlet[] servlets = new Servlet[]{ servlet };
- // File directory = new File(global.outpath);
- try {
- HTTPServer webServer = new HTTPServer(directory, port, servlets);
- webServer.start();
- }
- catch (IOException e) {
- System.out.println("Server could not start because of an "
- + e.getClass());
- System.out.println(e);
- }
- // to prevent going to the next phase (implies checking
- // errors when parsing a type after RefCheck)
- try {
- synchronized(this) { wait(); }
- }
- catch(InterruptedException e) {
- System.err.println("Error while waiting.");
- System.exit(0);
+ // Launch HTTP server
+ launchServer();
+ }
+ else {
+ // Generate statically all the pages
+ Iterator i = promises.values().iterator();
+ while(i.hasNext()) {
+ Promise pagePromise = (Promise) i.next();
+ Writer writer = fileWriter(directory, pagePromise.name());
+ pagePromise.writeOn(writer);
+ try {
+ writer.close();
+ } catch(IOException e) {
+ e.printStackTrace();
+ }
}
}
+ }
+ /**
+ * Launch the HTTP server.
+ */
+ protected void launchServer() {
+ Servlet pageServlet = new PageServlet();
+ Servlet searchServlet = new SearchServlet();
+ Servlet[] servlets = new Servlet[]{ pageServlet, searchServlet };
+ try {
+ HTTPServer webServer = new HTTPServer(directory, port, servlets);
+ webServer.start();
+ }
+ catch (IOException e) {
+ System.out.println("Server could not start because of an "
+ + e.getClass());
+ System.out.println(e);
+ }
+ // to prevent going to the next phase (implies checking
+ // errors when parsing a type after RefCheck)
+ try {
+ synchronized(this) { wait(); }
+ }
+ catch(InterruptedException e) {
+ System.err.println("Error while waiting.");
+ System.exit(0);
+ }
}
/**
@@ -491,45 +551,56 @@ public abstract class HTMLGenerator {
/**
* Generates a HTML page for a class or object definition.
*/
- protected void createPages(Symbol sym) {
- String title = Location.getName(sym);
- createPrinters(Location.getURI(sym), title, SELF_FRAME);
- page.printHeader(ATTRS_META, getGenerator());
- page.printOpenBody();
+ class ContainerPromise extends Promise {
- if (sym.isRoot())
- addNavigationBar(ROOT_NAV_CONTEXT);
- else
- addNavigationBar(CONTAINER_NAV_CONTEXT);
- page.printlnHLine();
-
- addTitle(sym);
- addDocumentationComment(sym);
- page.printlnHLine();
-
- String[] titles = new String[]{ "Field", "Method", "Object",
- "Trait", "Class", "Package" }; // "Constructor"
- String[] inherited = new String[]{ "Fields", "Methods", "Objects",
- "Traits", "Classes", "Packages" };
- Symbol[][] members =
- ScalaSearch.splitMembers(ScalaSearch.members(sym, isDocumented));
- for (int i = 0; i < members.length; i++) {
- addMemberSummary(members[i], titles[i] + " Summary");
- if (i == 1) addInheritedMembers(sym, inherited[i]);
+ protected Symbol sym;
+
+ public ContainerPromise(Symbol sym) {
+ this.sym = sym;
}
- for (int i = 0; i < titles.length; i++)
- addMemberDetail(members[i], titles[i] + " Detail");
- page.printlnHLine();
- if (sym.isRoot())
- addNavigationBar(ROOT_NAV_CONTEXT);
- else
- addNavigationBar(CONTAINER_NAV_CONTEXT);
- if (validate)
- addValidationBar();
+ public String name() { return Location.getURI(sym).toString(); }
+
+ public void writeOn(Writer writer) {
+ String title = Location.getName(sym);
+ createPrinters(writer, Location.getURI(sym), title, SELF_FRAME);
+ page.printHeader(ATTRS_META, getGenerator());
+ page.printOpenBody();
+
+ if (sym.isRoot())
+ addNavigationBar(ROOT_NAV_CONTEXT);
+ else
+ addNavigationBar(CONTAINER_NAV_CONTEXT);
+ page.printlnHLine();
+
+ addTitle(sym);
+ addDocumentationComment(sym);
+ page.printlnHLine();
+
+ String[] titles = new String[]{ "Field", "Method", "Object",
+ "Trait", "Class", "Package" }; // "Constructor"
+ String[] inherited = new String[]{ "Fields", "Methods", "Objects",
+ "Traits", "Classes", "Packages" };
+ Symbol[][] members =
+ ScalaSearch.splitMembers(ScalaSearch.members(sym, isDocumented));
+ for (int i = 0; i < members.length; i++) {
+ addMemberSummary(members[i], titles[i] + " Summary");
+ if (i == 1) addInheritedMembers(sym, inherited[i]);
+ }
+ for (int i = 0; i < titles.length; i++)
+ addMemberDetail(members[i], titles[i] + " Detail");
+
+ page.printlnHLine();
+ if (sym.isRoot())
+ addNavigationBar(ROOT_NAV_CONTEXT);
+ else
+ addNavigationBar(CONTAINER_NAV_CONTEXT);
+ if (validate)
+ addValidationBar();
- page.printFootpage();
- closePrinters();
+ page.printFootpage();
+ closePrinters();
+ }
}
/**
@@ -549,7 +620,7 @@ public abstract class HTMLGenerator {
protected void addSearchSection(Page page) {
page.printlnOTag("form", new XMLAttribute[] {
- new XMLAttribute("action", "/" + SERVLET_NAME),
+ new XMLAttribute("action", "/" + SEARCH_SERVLET_NAME),
new XMLAttribute("method", "get") }).indent();
page.printlnOTag("table", new XMLAttribute[] {
@@ -618,9 +689,9 @@ public abstract class HTMLGenerator {
*/
protected void addNavigationBar(int navigationContext, Page page) {
try {
- String overviewLink = page.rel(ROOT_PAGE);
- String indexLink = page.rel(INDEX_PAGE);
- String helpLink = page.rel(HELP_PAGE);
+ String overviewLink = adaptURI(Location.mkURI(ROOT_PAGE), page.uri).toString();
+ String indexLink = adaptURI(Location.mkURI(INDEX_PAGE), page.uri).toString();
+ String helpLink = adaptURI(Location.mkURI(HELP_PAGE), page.uri).toString();
page.printlnOTag("table", ATTRS_NAVIGATION).indent();
page.printlnOTag("tr").indent();
@@ -878,7 +949,8 @@ public abstract class HTMLGenerator {
*/
protected void addMemberDetail(Symbol sym) {
// title with label
- page.printlnAname(Page.asSeenFrom(Location.getURI(sym), uri).getFragment(), "");
+ // page.printlnAname(Page.asSeenFrom(Location.getURI(sym), uri).getFragment(), "");
+ page.printlnAname(Location.getURI(sym).getFragment(), "");
page.printTag("h3", sym.nameString());
// signature
@@ -996,37 +1068,43 @@ public abstract class HTMLGenerator {
*
* @param title The page title
*/
- protected void createFramePage() {
- createPrinters(Location.makeURI(FRAME_PAGE), windowtitle, "");
- page.printHeader(ATTRS_META, getGenerator());
-
- page.printlnOTag("frameset", new XMLAttribute[] {
- new XMLAttribute("cols", "25%, 75%")}).indent();
- page.printlnOTag("frameset", new XMLAttribute[] {
- new XMLAttribute("rows", "50%, 50%")}).indent();
-
- page.printlnOTag("frame", new XMLAttribute[] {
- new XMLAttribute("src", PACKAGE_LIST_PAGE),
- new XMLAttribute("name", PACKAGES_FRAME)});
- page.printlnOTag("frame", new XMLAttribute[] {
- new XMLAttribute("src", PACKAGE_PAGE),
- new XMLAttribute("name", CLASSES_FRAME)}).undent();
- page.printlnCTag("frameset");
- page.printlnOTag("frame", new XMLAttribute[] {
- new XMLAttribute("src", ROOT_PAGE),
- new XMLAttribute("name", ROOT_FRAME)});
-
- page.printlnOTag("noframes").indent();
- page.printlnSTag("p");
- page.print("Here is the ");
- page.printAhref(ROOT_PAGE, "non-frame based version");
- page.println(" of the documentation.").undent();
- page.printlnCTag("noframes").undent();
-
- page.printlnCTag("frameset");
- page.printlnCTag("html");
-
- closePrinters();
+ class FramePromise extends Promise {
+
+ public String name() { return FRAME_PAGE; }
+
+ public void writeOn(Writer writer) {
+ createPrinters(writer, Location.makeURI(FRAME_PAGE), windowtitle, "");
+ page.printHeader(ATTRS_META, getGenerator());
+
+ page.printlnOTag("frameset", new XMLAttribute[] {
+ new XMLAttribute("cols", "25%, 75%")}).indent();
+ page.printlnOTag("frameset", new XMLAttribute[] {
+ new XMLAttribute("rows", "50%, 50%")}).indent();
+
+ page.printlnOTag("frame", new XMLAttribute[] {
+ new XMLAttribute("src", adaptURI(Location.mkURI(PACKAGE_INDEX_PAGE), page.uri).toString()),
+ new XMLAttribute("name", PACKAGES_FRAME)});
+ page.printlnOTag("frame", new XMLAttribute[] {
+ new XMLAttribute("src", adaptURI(Location.mkURI(PACKAGE_PAGE), page.uri).toString()),
+ new XMLAttribute("name", CLASSES_FRAME)}).undent();
+ page.printlnCTag("frameset");
+ page.printlnOTag("frame", new XMLAttribute[] {
+ new XMLAttribute("src", adaptURI(Location.mkURI(ROOT_PAGE), page.uri).toString()),
+ new XMLAttribute("name", ROOT_FRAME)});
+
+ page.printlnOTag("noframes").indent();
+ page.printlnSTag("p");
+ page.print("Here is the ");
+ page.printAhref(adaptURI(Location.mkURI(ROOT_PAGE), page.uri).toString(),
+ "non-frame based version");
+ page.println(" of the documentation.").undent();
+ page.printlnCTag("noframes").undent();
+
+ page.printlnCTag("frameset");
+ page.printlnCTag("html");
+
+ closePrinters();
+ }
}
/**
@@ -1037,7 +1115,6 @@ public abstract class HTMLGenerator {
String rsc = HTMLGenerator.class
.getResource("resources/" + name)
.toString();
- // System.out.println("Some used resource: " + rsc);
return rsc;
}
@@ -1046,35 +1123,39 @@ public abstract class HTMLGenerator {
*
* @param name The name of the resource file
*/
- protected void createResource(String name, String dir) {
- File dest;
- if (dir == null)
- dest = new File(directory, name);
- else {
- File f = new File(directory, dir);
- f.mkdirs();
- dest = new File(f, name);
+ class ResourcePromise extends Promise {
+
+ protected String name;
+
+ protected String dir;
+
+ ResourcePromise(String name, String dir) {
+ this.name = name;
+ this.dir = dir;
}
- String rsrcName = "resources/" + name;
- InputStream in = HTMLGenerator.class.getResourceAsStream(rsrcName);
- if (in == null)
- throw Debug.abort("Resource file \"" + rsrcName + "\" not found");
- try {
- FileOutputStream out = new FileOutputStream(dest);
-
- byte[] buf = new byte[1024];
- int len;
- while (true) {
- len = in.read(buf, 0, buf.length);
- if (len <= 0) break;
- out.write(buf, 0, len);
- }
- in.close();
- out.close();
- } catch (IOException exception) {
- throw Debug.abort(exception); // !!! reporting an error would be wiser
- }
+ public String name() { return name; }
+
+ public void writeOn(Writer writer) {
+ String rsrcName = "resources/" + name;
+ Reader reader = new InputStreamReader(HTMLGenerator.class.getResourceAsStream(rsrcName));
+ if (reader == null)
+ throw Debug.abort("Resource file \"" + rsrcName + "\" not found");
+ try {
+ char[] buf = new char[1024];
+ int len;
+ while (true) {
+ len = reader.read(buf, 0, buf.length);
+ if (len <= 0) break;
+ writer.write(buf, 0, len);
+ }
+
+ reader.close();
+ // writer.close();
+ } catch (IOException exception) {
+ throw Debug.abort(exception); // !!! reporting an error would be wiser
+ }
+ }
}
private String removeHtmlSuffix(String url) {
@@ -1107,7 +1188,7 @@ public abstract class HTMLGenerator {
for (int i = 1; i < syms.length; i++) {
Symbol sym = syms[i];
page.printAhref(
- packageSummaryPage(sym),
+ adaptURI(Location.mkURI(packageSummaryPage(sym)), page.uri).toString(),
CLASSES_FRAME,
removeHtmlSuffix(Location.getURI(sym).toString()));
page.printlnSTag("br");
@@ -1138,10 +1219,10 @@ public abstract class HTMLGenerator {
if (! sym.isRoot()) {
String name = sym.nameString();
if (sym.isPackage() || sym.isPackageClass())
- page.printAhref(definitionURL(sym), CLASSES_FRAME, name);
+ page.printAhref(definitionURI(sym).toString(), CLASSES_FRAME, name);
else {
Symbol user = (useFullName) ? global.definitions.ROOT_CLASS : Symbol.NONE;
- page.printAhref(definitionURL(sym), ROOT_FRAME, name);
+ page.printAhref(definitionURI(sym).toString(), ROOT_FRAME, name);
}
page.printlnSTag("br");
}
@@ -1159,23 +1240,29 @@ public abstract class HTMLGenerator {
*
* @param title
*/
- protected void createPackageIndexPage() {
- createPrinters(Location.makeURI(PACKAGE_LIST_PAGE), "List of packages", CLASSES_FRAME);
- page.printHeader(ATTRS_META, getGenerator());
- page.printOpenBody();
+ class PackageIndexPromise extends Promise {
+
+ public String name() { return PACKAGE_INDEX_PAGE; }
- Symbol[] packages = ScalaSearch.getSortedPackageList(root, isDocumented);
+ public void writeOn(Writer writer) {
+ createPrinters(writer, Location.makeURI(PACKAGE_INDEX_PAGE), "List of packages", CLASSES_FRAME);
+ page.printHeader(ATTRS_META, getGenerator());
+ page.printOpenBody();
- addDocumentationTitle(new XMLAttribute[]{
- new XMLAttribute("class", "doctitle-larger")});
- page.printAhref(PACKAGE_PAGE, CLASSES_FRAME, "All objects, traits and classes");
- page.printlnSTag("p");
- printPackagesTable(packages, "Packages");
- if (validate)
- addValidationBar();
+ Symbol[] packages = ScalaSearch.getSortedPackageList(root, isDocumented);
- page.printFootpage();
- closePrinters();
+ addDocumentationTitle(new XMLAttribute[]{
+ new XMLAttribute("class", "doctitle-larger")});
+ page.printAhref(adaptURI(Location.mkURI(PACKAGE_PAGE), page.uri).toString(),
+ CLASSES_FRAME, "All objects, traits and classes");
+ page.printlnSTag("p");
+ printPackagesTable(packages, "Packages");
+ if (validate)
+ addValidationBar();
+
+ page.printFootpage();
+ closePrinters();
+ }
}
/**
@@ -1183,38 +1270,49 @@ public abstract class HTMLGenerator {
*
* @param sym
*/
- protected void createContainerIndexPage(Symbol sym) {
- createPrinters(Location.makeURI(packageSummaryPage(sym)), Location.getName(sym), ROOT_FRAME);
- page.printHeader(ATTRS_META, getGenerator());
- page.printOpenBody();
+ class ContainerIndexPromise extends Promise {
- page.printlnOTag("table", ATTRS_NAVIGATION).indent();
- page.printlnOTag("tr").indent();
- page.printlnOTag("td", ATTRS_NAVIGATION_LINKS).indent();
- printPath(sym, ROOT_FRAME);
- page.printlnCTag("td");
- page.printlnCTag("tr");
- page.printlnCTag("table");
- page.printlnSTag("p");
-
- String[] titles = new String[]{ "Objects", "Traits", "Classes" };
- if (sym.isRoot()) {
- Symbol[][] members = ScalaSearch.getSubContainerMembers(root, isDocumented);
- for (int i = 0; i < titles.length; i++)
- addSymbolTable(members[i], "All " + titles[i], true);
- } else {
- Symbol[][] members = ScalaSearch.splitMembers(ScalaSearch.members(sym, isDocumented));
- for (int i = 0; i < titles.length; i++) {
- Arrays.sort(members[i + 2], ScalaSearch.symAlphaOrder);
- addSymbolTable(members[i + 2], titles[i], false);
+ protected Symbol sym;
+
+ ContainerIndexPromise(Symbol sym) {
+ this.sym = sym;
+ }
+
+ public String name() { return packageSummaryPage(sym); }
+
+ public void writeOn(Writer writer) {
+ createPrinters(writer, Location.makeURI(packageSummaryPage(sym)), Location.getName(sym), ROOT_FRAME);
+ page.printHeader(ATTRS_META, getGenerator());
+ page.printOpenBody();
+
+ page.printlnOTag("table", ATTRS_NAVIGATION).indent();
+ page.printlnOTag("tr").indent();
+ page.printlnOTag("td", ATTRS_NAVIGATION_LINKS).indent();
+ printPath(sym, ROOT_FRAME);
+ page.printlnCTag("td");
+ page.printlnCTag("tr");
+ page.printlnCTag("table");
+ page.printlnSTag("p");
+
+ String[] titles = new String[]{ "Objects", "Traits", "Classes" };
+ if (sym.isRoot()) {
+ Symbol[][] members = ScalaSearch.getSubContainerMembers(root, isDocumented);
+ for (int i = 0; i < titles.length; i++)
+ addSymbolTable(members[i], "All " + titles[i], true);
+ } else {
+ Symbol[][] members = ScalaSearch.splitMembers(ScalaSearch.members(sym, isDocumented));
+ for (int i = 0; i < titles.length; i++) {
+ Arrays.sort(members[i + 2], ScalaSearch.symAlphaOrder);
+ addSymbolTable(members[i + 2], titles[i], false);
+ }
}
- }
- if (validate)
- addValidationBar();
+ if (validate)
+ addValidationBar();
- page.printFootpage();
- closePrinters();
+ page.printFootpage();
+ closePrinters();
+ }
}
/**
@@ -1222,54 +1320,59 @@ public abstract class HTMLGenerator {
*
* @param title The page title
*/
- protected void createIndexPage() {
- String title = "Scala Library Index";
- createPrinters(Location.makeURI(INDEX_PAGE), title, SELF_FRAME);
- page.printHeader(ATTRS_META, getGenerator());
- page.printOpenBody();
+ class IndexPromise extends Promise {
- addNavigationBar(INDEX_NAV_CONTEXT);
- page.printlnHLine();
+ public String name() { return INDEX_PAGE; }
- page.printlnOTag("table", ATTRS_MEMBER).indent();
- page.printlnOTag("tr").indent();
- page.printlnOTag("td", ATTRS_MEMBER_TITLE).indent();
- page.println("Index").undent();
- page.printlnCTag("td").undent();
- page.printlnCTag("tr").undent();
- page.printlnCTag("table");
- page.printlnSTag("br");
-
- Pair index = ScalaSearch.index(root, isDocumented);
- Character[] chars = (Character[]) index.fst;
- Map map = (Map) index.snd;
- for (int i = 0; i < chars.length; i++)
- page.printlnAhref("#" + i, SELF_FRAME, HTMLPrinter.encode(chars[i]));
- page.printlnHLine();
- for (int i = 0; i < chars.length; i++) {
- Character car = chars[i];
- page.printlnAname(String.valueOf(i), "");
- page.printlnOTag("h2");
- page.printBold(HTMLPrinter.encode(car));
- page.printlnCTag("h2");
- page.printlnOTag("dl").indent();
- Symbol[] syms = (Symbol[]) map.get(car);
- for (int j = 0; j < syms.length; j++) {
- page.printOTag("dt");
- addIndexEntry(syms[j]);
- page.printlnCTag("dt");
- page.printlnTag("dd", firstSentence(getComment(syms[j])));
- }
- page.undent().printlnCTag("dl");
- }
+ public void writeOn(Writer writer) {
+ String title = "Scala Library Index";
+ createPrinters(writer, Location.makeURI(INDEX_PAGE), title, SELF_FRAME);
+ page.printHeader(ATTRS_META, getGenerator());
+ page.printOpenBody();
+
+ addNavigationBar(INDEX_NAV_CONTEXT);
+ page.printlnHLine();
+
+ page.printlnOTag("table", ATTRS_MEMBER).indent();
+ page.printlnOTag("tr").indent();
+ page.printlnOTag("td", ATTRS_MEMBER_TITLE).indent();
+ page.println("Index").undent();
+ page.printlnCTag("td").undent();
+ page.printlnCTag("tr").undent();
+ page.printlnCTag("table");
+ page.printlnSTag("br");
- page.printlnHLine();
- addNavigationBar(INDEX_NAV_CONTEXT);
- if (validate)
- addValidationBar();
+ Pair index = ScalaSearch.index(root, isDocumented);
+ Character[] chars = (Character[]) index.fst;
+ Map map = (Map) index.snd;
+ for (int i = 0; i < chars.length; i++)
+ page.printlnAhref("#" + i, SELF_FRAME, HTMLPrinter.encode(chars[i]));
+ page.printlnHLine();
+ for (int i = 0; i < chars.length; i++) {
+ Character car = chars[i];
+ page.printlnAname(String.valueOf(i), "");
+ page.printlnOTag("h2");
+ page.printBold(HTMLPrinter.encode(car));
+ page.printlnCTag("h2");
+ page.printlnOTag("dl").indent();
+ Symbol[] syms = (Symbol[]) map.get(car);
+ for (int j = 0; j < syms.length; j++) {
+ page.printOTag("dt");
+ addIndexEntry(syms[j]);
+ page.printlnCTag("dt");
+ page.printlnTag("dd", firstSentence(getComment(syms[j])));
+ }
+ page.undent().printlnCTag("dl");
+ }
+
+ page.printlnHLine();
+ addNavigationBar(INDEX_NAV_CONTEXT);
+ if (validate)
+ addValidationBar();
- page.printFootpage();
- closePrinters();
+ page.printFootpage();
+ closePrinters();
+ }
}
/**
@@ -1277,168 +1380,173 @@ public abstract class HTMLGenerator {
*
* @param title The page title
*/
- protected void createHelpPage() {
- String title = "API Help";
- createPrinters(Location.makeURI(HELP_PAGE), title, ROOT_PAGE);
- page.printHeader(ATTRS_META, getGenerator());
- page.printOpenBody();
+ class HelpPromise extends Promise {
- addNavigationBar(HELP_NAV_CONTEXT);
- page.printlnHLine();
+ public String name() { return HELP_PAGE; }
- XMLAttribute[] h3 = new XMLAttribute[]{
- new XMLAttribute("style", "margin:15px 0px 0px 0px; "
- + "font-size:large; font-weight: bold;")
- };
- XMLAttribute[] em = new XMLAttribute[]{
- new XMLAttribute("style", "margin:15px 0px 15px 0px; "
- + "font-size:small; font-style: italic;")
- };
- page.printlnTag("div", ATTRS_PAGE_TITLE, "How This API Document Is Organized");
- page.println("This API (Application Programming Interface) document "
- + "has pages corresponding to the items in the navigation bar, "
- + "described as follows.");
-
- page.printlnTag("div", h3, "Overview");
- page.printlnOTag("blockquote").indent();
- page.print("The ");
- page.printAhref(ROOT_PAGE, SELF_FRAME, "Overview");
- page.println(" page is the front page of this API document and "
- + "provides a list of all top-level packages, classes, traits "
- + "and objects with a summary for each. "
- + "This page can also contain an overall description of the "
- + "set of packages.").undent();
- page.printlnCTag("blockquote");
-
- page.printlnTag("div", h3, "Package");
- page.printlnOTag("blockquote").indent();
- page.println("Each package has a page that contains a list of "
- + "its objects, traits and classes, with a summary for each. "
- + "This page can contain three categories:");
- page.printlnOTag("ul").indent();
- page.printlnTag("li", "Objects");
- page.printlnTag("li", "Traits");
- page.printlnTag("li", "Classes").undent();
- page.printlnCTag("ul").undent();
- page.printlnCTag("blockquote");
-
- page.printlnTag("div", h3, "Object/Trait/Class");
- page.printlnOTag("blockquote").indent();
- page.println("Each object, trait, class, nested object, nested "
- + "trait and nested class has its own separate page. Each "
- + "of these pages has three sections consisting of a object"
- + "/trait/class description, summary tables, and detailed "
- + "member descriptions:");
- page.printlnOTag("ul").indent();
- page.printlnTag("li", "Class inheritance diagram");
- page.printlnTag("li", "Direct Subclasses");
- page.printlnTag("li", "All Known Subinterfaces");
- page.printlnTag("li", "All Known Implementing Classes");
- page.printlnTag("li", "Class/interface declaration");
- page.printlnTag("li", "Class/interface description<p/>");
- page.printlnTag("li", "Nested Class Summary");
- page.printlnTag("li", "Field Summary");
- page.printlnTag("li", "Constructor Summary");
- page.printlnTag("li", "Method Summary<p/>");
- page.printlnTag("li", "Field Detail");
- page.printlnTag("li", "Constructor Detail");
- page.printlnTag("li", "Method Detail").undent();
- page.printlnCTag("ul").undent();
- page.println("Each summary entry contains the first sentence from "
- + "the detailed description for that item. The summary entries "
- + "are alphabetical, while the detailed descriptions are in "
- + "the order they appear in the source code. This preserves "
- + "the logical groupings established by the programmer.");
- page.printlnCTag("blockquote");
-
-
- page.printlnTag("div", h3, "Index");
- page.printlnOTag("blockquote").indent();
- page.print("The ");
- page.printAhref(INDEX_PAGE, SELF_FRAME, "Index");
- page.print(" contains an alphabetic list of all classes, interfaces, "
- + "constructors, methods, and fields.");
- page.printlnCTag("blockquote");
+ public void writeOn(Writer writer) {
+ String title = "API Help";
+ createPrinters(writer, Location.makeURI(HELP_PAGE), title, ROOT_PAGE);
+ page.printHeader(ATTRS_META, getGenerator());
+ page.printOpenBody();
- if (launchServer) {
- page.printlnTag("div", h3, "Searching a definition");
+ addNavigationBar(HELP_NAV_CONTEXT);
+ page.printlnHLine();
+
+ XMLAttribute[] h3 = new XMLAttribute[]{
+ new XMLAttribute("style", "margin:15px 0px 0px 0px; "
+ + "font-size:large; font-weight: bold;")
+ };
+ XMLAttribute[] em = new XMLAttribute[]{
+ new XMLAttribute("style", "margin:15px 0px 15px 0px; "
+ + "font-size:small; font-style: italic;")
+ };
+ page.printlnTag("div", ATTRS_PAGE_TITLE, "How This API Document Is Organized");
+ page.println("This API (Application Programming Interface) document "
+ + "has pages corresponding to the items in the navigation bar, "
+ + "described as follows.");
+
+ page.printlnTag("div", h3, "Overview");
page.printlnOTag("blockquote").indent();
- page.printlnSTag("a",
- new XMLAttribute[] {
- new XMLAttribute("name", SEARCH_SECTION) });
- page.printlnOTag("p");
- page.println("At the top and and at the bottom of each page, there is a form that "
- + "allows to search the definition of a <em>symbol</em> (field, method, "
- + "package, object, type, trait or class).");
- page.printlnCTag("p");
-
- page.printlnOTag("p");
- page.println("There are three ways of specifying the symbols of interest:");
- page.printlnOTag("dl");
- page.printOTag("dt");
- page.printlnTag("b", "By name");
- page.printOTag("dd");
- page.println("The search string must be a ");
- page.printlnTag("a",
- new XMLAttribute[] {
- new XMLAttribute("href",
- "http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html") },
- "regular expression");
- page.print(" that has to match a substring in the name of the searched symbol.");
- page.printOTag("dt");
- page.printlnTag("b", "By comment");
- page.printOTag("dd");
- page.println("The search string must be a ");
- page.printlnTag("a",
- new XMLAttribute[] {
- new XMLAttribute("href",
- "http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html") },
- "regular expression");
- page.print(" that has to match a substring in the comments associated to the searched symbol.");
- page.printOTag("dt");
- page.printlnTag("b", "By type");
- page.printOTag("dd");
- page.println("The search string must represent a Scala type. Any string ");
- page.printlnTag("code", "S");
- page.println(" such that ");
- page.printlnTag("pre", "def foo S;");
- page.println(" is a valid function definition is accepted. Here are some examples:");
- page.printlnOTag("ul");
- page.printOTag("li");
- page.printlnTag("code", ": int => int");
- page.printOTag("li");
- page.printlnTag("code", "[a,b]: List[a] => (a => b) => List[b]");
- page.printOTag("li");
- page.printlnTag("code", "(x: int, y: int): unit");
- page.printlnCTag("ul");
- page.println("The searched symbols must conform to the entered type modulo ");
- page.printlnTag("a",
- new XMLAttribute[] {
- new XMLAttribute("href",
- "http://www.pps.jussieu.fr/~dicosmo/Publications/ISObook.html") },
- "type isomorphism");
- page.println(". This concept allows to unify types that differ by their exact "
- + "representation but not by their meaning. The order of parameters is "
- + "for instance irrelevant when looking for a function. Note finally that "
- + "methods of classes are interpreted as functions that would take an "
- + "extra argument of the type of the class.");
- page.printlnCTag("dl");
- page.printlnCTag("p");
+ page.print("The ");
+ page.printAhref(adaptURI(Location.mkURI(ROOT_PAGE), page.uri).toString(), SELF_FRAME, "Overview");
+ page.println(" page is the front page of this API document and "
+ + "provides a list of all top-level packages, classes, traits "
+ + "and objects with a summary for each. "
+ + "This page can also contain an overall description of the "
+ + "set of packages.").undent();
page.printlnCTag("blockquote");
- }
- page.printlnOTag("div", em);
- page.println("This help file applies to API documentation generated "
- + "using the standard doclet.");
- page.printlnCTag("div");
+ page.printlnTag("div", h3, "Package");
+ page.printlnOTag("blockquote").indent();
+ page.println("Each package has a page that contains a list of "
+ + "its objects, traits and classes, with a summary for each. "
+ + "This page can contain three categories:");
+ page.printlnOTag("ul").indent();
+ page.printlnTag("li", "Objects");
+ page.printlnTag("li", "Traits");
+ page.printlnTag("li", "Classes").undent();
+ page.printlnCTag("ul").undent();
+ page.printlnCTag("blockquote");
+
+ page.printlnTag("div", h3, "Object/Trait/Class");
+ page.printlnOTag("blockquote").indent();
+ page.println("Each object, trait, class, nested object, nested "
+ + "trait and nested class has its own separate page. Each "
+ + "of these pages has three sections consisting of a object"
+ + "/trait/class description, summary tables, and detailed "
+ + "member descriptions:");
+ page.printlnOTag("ul").indent();
+ page.printlnTag("li", "Class inheritance diagram");
+ page.printlnTag("li", "Direct Subclasses");
+ page.printlnTag("li", "All Known Subinterfaces");
+ page.printlnTag("li", "All Known Implementing Classes");
+ page.printlnTag("li", "Class/interface declaration");
+ page.printlnTag("li", "Class/interface description<p/>");
+ page.printlnTag("li", "Nested Class Summary");
+ page.printlnTag("li", "Field Summary");
+ page.printlnTag("li", "Constructor Summary");
+ page.printlnTag("li", "Method Summary<p/>");
+ page.printlnTag("li", "Field Detail");
+ page.printlnTag("li", "Constructor Detail");
+ page.printlnTag("li", "Method Detail").undent();
+ page.printlnCTag("ul").undent();
+ page.println("Each summary entry contains the first sentence from "
+ + "the detailed description for that item. The summary entries "
+ + "are alphabetical, while the detailed descriptions are in "
+ + "the order they appear in the source code. This preserves "
+ + "the logical groupings established by the programmer.");
+ page.printlnCTag("blockquote");
+
+
+ page.printlnTag("div", h3, "Index");
+ page.printlnOTag("blockquote").indent();
+ page.print("The ");
+ page.printAhref(adaptURI(Location.mkURI(INDEX_PAGE), page.uri).toString(), SELF_FRAME, "Index");
+ page.print(" contains an alphabetic list of all classes, interfaces, "
+ + "constructors, methods, and fields.");
+ page.printlnCTag("blockquote");
+
+ if (launchServer) {
+ page.printlnTag("div", h3, "Searching a definition");
+ page.printlnOTag("blockquote").indent();
+ page.printlnSTag("a",
+ new XMLAttribute[] {
+ new XMLAttribute("name", SEARCH_SECTION) });
+ page.printlnOTag("p");
+ page.println("At the top and and at the bottom of each page, there is a form that "
+ + "allows to search the definition of a <em>symbol</em> (field, method, "
+ + "package, object, type, trait or class).");
+ page.printlnCTag("p");
+
+ page.printlnOTag("p");
+ page.println("There are three ways of specifying the symbols of interest:");
+ page.printlnOTag("dl");
+ page.printOTag("dt");
+ page.printlnTag("b", "By name");
+ page.printOTag("dd");
+ page.println("The search string must be a ");
+ page.printlnTag("a",
+ new XMLAttribute[] {
+ new XMLAttribute("href",
+ "http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html") },
+ "regular expression");
+ page.print(" that has to match a substring in the name of the searched symbol.");
+ page.printOTag("dt");
+ page.printlnTag("b", "By comment");
+ page.printOTag("dd");
+ page.println("The search string must be a ");
+ page.printlnTag("a",
+ new XMLAttribute[] {
+ new XMLAttribute("href",
+ "http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html") },
+ "regular expression");
+ page.print(" that has to match a substring in the comments associated to the searched symbol.");
+ page.printOTag("dt");
+ page.printlnTag("b", "By type");
+ page.printOTag("dd");
+ page.println("The search string must represent a Scala type. Any string ");
+ page.printlnTag("code", "S");
+ page.println(" such that ");
+ page.printlnTag("pre", "def foo S;");
+ page.println(" is a valid function definition is accepted. Here are some examples:");
+ page.printlnOTag("ul");
+ page.printOTag("li");
+ page.printlnTag("code", ": int => int");
+ page.printOTag("li");
+ page.printlnTag("code", "[a,b]: List[a] => (a => b) => List[b]");
+ page.printOTag("li");
+ page.printlnTag("code", "(x: int, y: int): unit");
+ page.printlnCTag("ul");
+ page.println("The searched symbols must conform to the entered type modulo ");
+ page.printlnTag("a",
+ new XMLAttribute[] {
+ new XMLAttribute("href",
+ "http://www.pps.jussieu.fr/~dicosmo/Publications/ISObook.html") },
+ "type isomorphism");
+ page.println(". This concept allows to unify types that differ by their exact "
+ + "representation but not by their meaning. The order of parameters is "
+ + "for instance irrelevant when looking for a function. Note finally that "
+ + "methods of classes are interpreted as functions that would take an "
+ + "extra argument of the type of the class.");
+ page.printlnCTag("dl");
+ page.printlnCTag("p");
+ page.printlnCTag("blockquote");
+ }
+
+ page.printlnOTag("div", em);
+ page.println("This help file applies to API documentation generated "
+ + "using the standard doclet.");
+ page.printlnCTag("div");
- page.printlnHLine();
- addNavigationBar(HELP_NAV_CONTEXT);
- if (validate)
- addValidationBar();
+ page.printlnHLine();
+ addNavigationBar(HELP_NAV_CONTEXT);
+ if (validate)
+ addValidationBar();
- page.printFootpage();
- closePrinters();
+ page.printFootpage();
+ closePrinters();
+ }
}
/**
@@ -1448,7 +1556,7 @@ public abstract class HTMLGenerator {
protected void printPath(Symbol sym, String destinationFrame, Page page) {
String name = removeHtmlSuffix(Location.getURI(sym).toString());
if (isDocumented.apply(sym)) {
- String target = definitionURL(sym, page);
+ String target = definitionURI(sym, page).toString();
page.printlnAhref(target, destinationFrame, name);
}
else
@@ -1552,7 +1660,7 @@ public abstract class HTMLGenerator {
}
else {
String labl = label.equals("") ? sym.nameString() : label;
- return ahref(definitionURL(sym), ROOT_FRAME, labl);
+ return ahref(definitionURI(sym).toString(), ROOT_FRAME, labl);
}
default:
throw Debug.abort("illegal case", tag);
@@ -1795,12 +1903,13 @@ public abstract class HTMLGenerator {
page.printCTag("p");
}
- public static String SERVLET_NAME = "scaladocServlet";
+ public static String SEARCH_SERVLET_NAME = "scaladocServlet";
+ public static String PAGE_SERVLET_NAME = "pageServlet";
- public class ScaladocServlet extends Servlet {
+ public class SearchServlet extends Servlet {
public String name() {
- return SERVLET_NAME;
+ return SEARCH_SERVLET_NAME;
}
public void apply(Map req, Writer out) {
@@ -1811,8 +1920,11 @@ public abstract class HTMLGenerator {
String title = pagename;
final Page page = new Page(out, uri, destinationFrame,
- title, representation,
- stylesheet/*, script*/);
+ title, representation,
+ HTMLGenerator.this.adaptURI(Location.mkURI(HTMLPrinter.DEFAULT_STYLESHEET),
+ uri).toString(),
+ HTMLGenerator.this.adaptURI(Location.mkURI(HTMLPrinter.DEFAULT_JAVASCRIPT),
+ uri).toString());
page.open();
page.printHeader(ATTRS_META, getGenerator());
page.printOpenBody();
@@ -1821,7 +1933,7 @@ public abstract class HTMLGenerator {
// create symbol printer
final MySymbolTablePrinter symtab =
- SymbolTablePrinterFactory.makeHTML(page, isDocumented);
+ SymbolTablePrinterFactory.makeHTML(HTMLGenerator.this, page, isDocumented);
// analyze the request
String searchKind = (String) req.get("searchKind");
@@ -1957,6 +2069,24 @@ public abstract class HTMLGenerator {
// already done by the HTTP server when closing connection
}
}
+
+ /**
+ * A servlet that accepts requests for web pages registered in the
+ * hastable <code>promises</code>.
+ */
+ public class PageServlet extends Servlet {
+
+ public String name() {
+ return PAGE_SERVLET_NAME;
+ }
+
+ public void apply(Map req, Writer out) {
+ // analyze the request
+ String pageName = (String) req.get("page");
+ Promise promise = (Promise) promises.get(pageName);
+ promise.writeOn(out);
+ }
+ }
}
public class SearchResult {
@@ -1975,3 +2105,14 @@ public class SearchResult {
}
}
+/**
+ * This class represents a web page not yet printed.
+ */
+public abstract class Promise {
+
+ /** Name of the web page. */
+ public abstract String name();
+
+ /** Print the web page on the given writer. */
+ public abstract void writeOn(Writer writer);
+}
diff --git a/sources/scala/tools/scaladoc/HTTPServer.java b/sources/scala/tools/scaladoc/HTTPServer.java
index 951e748913..6c91c6de4c 100755
--- a/sources/scala/tools/scaladoc/HTTPServer.java
+++ b/sources/scala/tools/scaladoc/HTTPServer.java
@@ -74,11 +74,15 @@ public class HTTPServer extends Thread {
int port,
String indexFileName) throws IOException {
- if (!documentRootDirectory.isDirectory()) {
- throw new IOException(documentRootDirectory
+ this.documentRootDirectory =
+ documentRootDirectory == null ?
+ new File(".") :
+ documentRootDirectory;
+
+ if (!this.documentRootDirectory.isDirectory()) {
+ throw new IOException(this.documentRootDirectory
+ " does not exist as a directory");
}
- this.documentRootDirectory = documentRootDirectory;
this.indexFileName = indexFileName;
this.server = new ServerSocket(port);
}
@@ -294,6 +298,7 @@ class RequestProcessor implements Runnable {
URI uri = new URI(filename);
String resource = uri.getPath();
Servlet servlet = (Servlet) servletNamed.get(resource);
+
if (servlet != null) { // servlet invokation
String query = uri.getRawQuery();
Map map =
diff --git a/sources/scala/tools/scaladoc/Location.java b/sources/scala/tools/scaladoc/Location.java
index cc7cfcccab..5a9efa95e3 100644
--- a/sources/scala/tools/scaladoc/Location.java
+++ b/sources/scala/tools/scaladoc/Location.java
@@ -34,6 +34,23 @@ public class Location {
}
/** Returns the URI of a given symbol. */
static private final Map/*<Symbol, URI>*/ uris = new HashMap();
+// static public URI getURI(Symbol sym) {
+// if (uris.get(sym) == null) {
+// URI uri;
+// try {
+// if (sym.isModuleClass())
+// uri = getURI(sym.module());
+// else if (sym.isRoot() || sym.isClass() || sym.isModule() || sym.isPackage() || sym.isPackageClass())
+// uri = new URI(getPath(sym).toString() + HTML_SUFFIX);
+// else if (sym.isParameter())
+// uri = getURI(sym.classOwner());
+// else
+// uri = new URI(getURI(sym.owner()).toString() + "#" + nextFreeId(sym.owner()));
+// uris.put(sym, uri);
+// } catch(Exception e) { throw Debug.abort(sym.defString()); }
+// }
+// return (URI) uris.get(sym);
+// }
static public URI getURI(Symbol sym) {
if (uris.get(sym) == null) {
URI uri;
@@ -86,4 +103,114 @@ public class Location {
return new URI(uri);
} catch(Exception e) { throw Debug.abort(e); }
}
+
+ /////////////////// AS SEEN FROM //////////////////////
+
+ /**
+ * Returns a representation of the URL u1 relative to u2.
+ * Examples:
+ * "A/B/C" as seen from "A" is "A/B/C"
+ * "A" as seen from "A/B/C" is "../../A"
+ * "A/B#R" as seen from "A" is "A/B#R"
+ */
+
+ static public URI asSeenFrom(URI u, URI v) {
+ File f_u = new File(u.getPath());
+ File f_v = new File(v.getPath());
+ try {
+ return
+ new URI(asSeenFrom(f_u, f_v).getPath()
+ + (u.getFragment() != null ? "#" + u.getFragment() : ""))
+ .normalize();
+ } catch(Exception e) { return null; }
+ }
+ // where
+ /** f must be of the form ('.' | ['.' '/' ] A/...) */
+ static private File pathToRoot(File f) {
+ if (f.equals(hereFile) || f.getParentFile() == null)
+ return new File(".");
+ else
+ return new File(pathToRoot(f.getParentFile()), "..");
+ }
+ // where
+ /*
+ // where
+ static private File asSeenFrom(File f1, File f2) {
+ return new File(pathToRoot(f2), f1.getPath());
+ }
+ */
+ /** Compute the minimal path from one file to another.
+ * f1 and f2 should be of the form (A/...)
+ */
+ static private File asSeenFrom(File f1, File f2) {
+ if (f1.equals(f2))
+ return new File(f1.getName());
+ else {
+ File lcp = longestCommonPrefix(f1, f2);
+ File relf1 = subtractPrefix(lcp, f1);
+ File relf2 = subtractPrefix(lcp, f2);
+ return new File(pathToRoot(relf2), relf1.getPath());
+ }
+ }
+ // where
+ /** p and q should be of the form (A/...) */
+ static private File longestCommonPrefix(File p, File q) {
+ if (prefixes(p, q))
+ return p;
+ else if (p.getParentFile() == null)
+ return new File(".");
+ else
+ return longestCommonPrefix(p.getParentFile(), q);
+ }
+ // where
+ /** Test if p is a prefix of q.
+ * p and q should be of the form (A/...)
+ */
+ static private boolean prefixes(File p, File q) {
+ if (p.equals(q))
+ return true;
+ else if (q.getParentFile() == null)
+ return false;
+ else
+ return prefixes(p, q.getParentFile());
+ }
+ // and
+ static private File hereFile = new File(".");
+ static private File subtractPrefix(File p, File f) {
+ if (p.equals(hereFile))
+ return f;
+ else
+ return subtractPrefix(p, f, hereFile);
+ }
+ static private File subtractPrefix(File p, File f, File acc) {
+ if (p.equals(f))
+ return acc;
+ else if (f.getParentFile() == null)
+ return null;
+ else
+ return subtractPrefix(p, f.getParentFile(),
+ (acc.equals(hereFile) ?
+ new File(f.getName()) :
+ new File(f.getName(), acc.getPath())));
+ }
+
+ static protected URI mkURI(String uri) {
+ try {
+ return new URI(uri);
+ } catch(Exception e) { throw Debug.abort(e); }
+ }
+
+ public static void main(String[] args) {
+ File p = new File("A", "B");
+ File q = new File("A", new File("B", "C").getPath());
+ File r = new File("C");
+ System.out.println("" + longestCommonPrefix(p, q));
+ System.out.println("" + longestCommonPrefix(p, r));
+ System.out.println("" + subtractPrefix(longestCommonPrefix(p, r), p));
+
+ System.out.println("" + asSeenFrom(q, p));
+ System.out.println("" + asSeenFrom(p, r));
+ }
+
}
+
diff --git a/sources/scala/tools/scaladoc/Page.java b/sources/scala/tools/scaladoc/Page.java
index 41bcd659de..c9d4d2005c 100644
--- a/sources/scala/tools/scaladoc/Page.java
+++ b/sources/scala/tools/scaladoc/Page.java
@@ -30,7 +30,7 @@ class Page extends HTMLPrinter {
/** Page URL relative to the root directory.
*/
- protected URI uri;
+ URI uri;
/** Frame where to print the contents of links that appear on the
* page.
@@ -41,9 +41,8 @@ class Page extends HTMLPrinter {
*/
public Page(Writer writer, URI uri, String destinationFrame,
String title, HTMLRepresentation representation,
- String stylesheet/*, String script*/) {
- super(writer, title, representation,
- asSeenFrom(mkURI(stylesheet), uri).toString()/*, script*/);
+ String stylesheet, String script) {
+ super(writer, title, representation, stylesheet, script);
this.uri = uri;
this.destinationFrame = destinationFrame;
}
@@ -61,118 +60,4 @@ class Page extends HTMLPrinter {
throw Debug.abort(e);
}
}
-
- /** Compute a relative link.
- */
- public String rel(String url) {
- return asSeenFrom(mkURI(url), uri).toString();
- }
-
- /////////////////// AS SEEN FROM //////////////////////
-
- /**
- * Returns a representation of the URL u1 relative to u2.
- * Examples:
- * "A/B/C" as seen from "A" is "A/B/C"
- * "A" as seen from "A/B/C" is "../../A"
- * "A/B#R" as seen from "A" is "A/B#R"
- */
-
- static public URI asSeenFrom(URI u, URI v) {
- File f_u = new File(u.getPath());
- File f_v = new File(v.getPath());
- try {
- return
- new URI(asSeenFrom(f_u, f_v).getPath()
- + (u.getFragment() != null ? "#" + u.getFragment() : ""))
- .normalize();
- } catch(Exception e) { return null; }
- }
- // where
- /** f must be of the form ('.' | ['.' '/' ] A/...) */
- static private File pathToRoot(File f) {
- if (f.equals(hereFile) || f.getParentFile() == null)
- return new File(".");
- else
- return new File(pathToRoot(f.getParentFile()), "..");
- }
- // where
- /*
- // where
- static private File asSeenFrom(File f1, File f2) {
- return new File(pathToRoot(f2), f1.getPath());
- }
- */
- /** Compute the minimal path from one file to another.
- * f1 and f2 should be of the form (A/...)
- */
- static private File asSeenFrom(File f1, File f2) {
- if (f1.equals(f2))
- return new File(f1.getName());
- else {
- File lcp = longestCommonPrefix(f1, f2);
- File relf1 = subtractPrefix(lcp, f1);
- File relf2 = subtractPrefix(lcp, f2);
- return new File(pathToRoot(relf2), relf1.getPath());
- }
- }
- // where
- /** p and q should be of the form (A/...) */
- static private File longestCommonPrefix(File p, File q) {
- if (prefixes(p, q))
- return p;
- else if (p.getParentFile() == null)
- return new File(".");
- else
- return longestCommonPrefix(p.getParentFile(), q);
- }
- // where
- /** Test if p is a prefix of q.
- * p and q should be of the form (A/...)
- */
- static private boolean prefixes(File p, File q) {
- if (p.equals(q))
- return true;
- else if (q.getParentFile() == null)
- return false;
- else
- return prefixes(p, q.getParentFile());
- }
- // and
- static private File hereFile = new File(".");
- static private File subtractPrefix(File p, File f) {
- if (p.equals(hereFile))
- return f;
- else
- return subtractPrefix(p, f, hereFile);
- }
- static private File subtractPrefix(File p, File f, File acc) {
- if (p.equals(f))
- return acc;
- else if (f.getParentFile() == null)
- return null;
- else
- return subtractPrefix(p, f.getParentFile(),
- (acc.equals(hereFile) ?
- new File(f.getName()) :
- new File(f.getName(), acc.getPath())));
- }
-
- static protected URI mkURI(String uri) {
- try {
- return new URI(uri);
- } catch(Exception e) { throw Debug.abort(e); }
- }
-
- public static void main(String[] args) {
- File p = new File("A", "B");
- File q = new File("A", new File("B", "C").getPath());
- File r = new File("C");
- System.out.println("" + longestCommonPrefix(p, q));
- System.out.println("" + longestCommonPrefix(p, r));
- System.out.println("" + subtractPrefix(longestCommonPrefix(p, r), p));
-
- System.out.println("" + asSeenFrom(q, p));
- System.out.println("" + asSeenFrom(p, r));
- }
}
diff --git a/sources/scala/tools/scaladoc/SymbolTablePrinterFactory.java b/sources/scala/tools/scaladoc/SymbolTablePrinterFactory.java
index bf427f9965..ad78902dad 100644
--- a/sources/scala/tools/scaladoc/SymbolTablePrinterFactory.java
+++ b/sources/scala/tools/scaladoc/SymbolTablePrinterFactory.java
@@ -25,7 +25,9 @@ import SymbolBooleanFunction;
class SymbolTablePrinterFactory {
- public static MySymbolTablePrinter makeHTML(final Page page, final SymbolBooleanFunction isDocumented) {
+ public static MySymbolTablePrinter makeHTML(final HTMLGenerator htmlGenerator,
+ final Page page,
+ final SymbolBooleanFunction isDocumented) {
return new MySymbolTablePrinter(page.getCodePrinter()) {
@@ -34,7 +36,7 @@ class SymbolTablePrinterFactory {
if (global.debug) name = sym.name.toString();
if (isDocumented.apply(sym))
if (addLink)
- page.printAhref(page.rel(Location.get(sym)),
+ page.printAhref(htmlGenerator.definitionURI(sym, page).toString(),
page.destinationFrame, name);
else {
page.printOTag("em");