Index: src/gnu/gcjwebplugin/AppletTag.java =================================================================== RCS file: /sources/gcjwebplugin/gcjwebplugin/src/gnu/gcjwebplugin/AppletTag.java,v retrieving revision 1.23 diff -u -r1.23 AppletTag.java --- src/gnu/gcjwebplugin/AppletTag.java 5 Sep 2005 18:58:17 -0000 1.23 +++ src/gnu/gcjwebplugin/AppletTag.java 11 Apr 2006 17:58:46 -0000 @@ -1,5 +1,6 @@ /* AppletTag.java - representation of an HTML APPLET tag - Copyright (C) 2003, 2004, 2005 Thomas Fitzsimmons
+ Copyright (C) 2003, 2004, 2005, 2006 Thomas Fitzsimmons + Lillian Angel This file is part of GCJ Applet Viewer. @@ -20,848 +21,559 @@ package gnu.gcjwebplugin; +import gnu.javax.swing.text.html.parser.HTML_401F; + +import gnu.xml.dom.DomNode; +import gnu.xml.dom.html2.DomHTMLAppletElement; +import gnu.xml.dom.html2.DomHTMLDocument; +import gnu.xml.dom.html2.DomHTMLEmbedElement; +import gnu.xml.dom.html2.DomHTMLObjectElement; +import gnu.xml.dom.html2.DomHTMLParamElement; +import gnu.xml.dom.html2.DomHTMLParser; + import java.awt.Dimension; + import java.io.File; -import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; -import java.io.StreamTokenizer; +import java.io.IOException; +import java.io.Reader; + import java.net.MalformedURLException; import java.net.URL; + import java.text.NumberFormat; import java.text.ParseException; + import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.StringTokenizer; +import java.util.Vector; + +import org.w3c.dom.NodeList; + class AppletTag { + + /** + * Parsed document. + */ + DomHTMLDocument document; + + /** + * The document base of the applet. + */ + URL documentbase; + + /** + * name of applet tag. + */ String name = ""; + + /** + * code of applet tag. + */ String code = ""; + + /** + * codebase of applet tag. + */ String codebase = ""; - String archivesList = ""; - ArrayList archives = new ArrayList(); + + /** + * The object of the applet tag. + */ + String object = ""; + + /** + * The Elements that may be in the document. + */ + DomHTMLAppletElement appElement; + DomHTMLObjectElement objElement; + DomHTMLEmbedElement embElement; + Vector paramElements = new Vector(); + + /** + * The archives. + */ + static ArrayList archives = new ArrayList(); + + /** + * The parameters. + */ HashMap parameters = new HashMap(); - - // documentbase is not specified in an applet tag but we keep it - // here anyway, for convenience. - URL documentbase; - - // Same goes for the HTML file's character encoding. - String encoding; - - // Default constructor needed by derived classes. + + /** + * Default constructor. + */ AppletTag() { + // Nothing to do here. } - - // Construct an applet tag object from a .class file and the user's - // current directory. - AppletTag(String code, String archives, List parameters, - Dimension dimensions, String encoding) - throws MalformedURLException, IOException - { - this.encoding = encoding; - // Calculate code. - this.code = - code.substring(code.lastIndexOf(File.separatorChar) + 1, code.length()); - - // When a class file is given on the command line, codebase is - // always set to the empty string and documentbase is the - // directory in which the class file resides. - String tmpCodeBase = - code.substring(0, code.lastIndexOf(File.separatorChar) + 1); - if (tmpCodeBase.startsWith(File.separator)) - this.documentbase = new URL("file", "", tmpCodeBase); - else - // documentbase is the current working directory. - this.documentbase = - new URL("file", "", - System.getProperty("user.dir") + File.separator + tmpCodeBase); - - archivesList = archives; - // Parse archives. - parseArchives(); - - // Parse parameters, a list of comma-delimited key-value pairs. - Iterator pairs = parameters.iterator(); - while (pairs.hasNext()) - { - StringTokenizer paramTokenizer = - new StringTokenizer((String) pairs.next(), ","); - this.parameters.put(paramTokenizer.nextToken().trim().toLowerCase(), - paramTokenizer.nextToken().trim()); - } - this.parameters.put("width", Integer.toString(dimensions.width)); - this.parameters.put("height", Integer.toString(dimensions.height)); - } - - // Construct an applet tag object from an HTML stream. - AppletTag(StreamTokenizer tagTokenizer, URL documentbase, String encoding) - throws IOException - { - this.documentbase = documentbase; - this.encoding = encoding; - - while (tagTokenizer.nextToken() != '>') - { - if (tagTokenizer.ttype == StreamTokenizer.TT_EOF) - break; - - if (tagTokenizer.ttype == StreamTokenizer.TT_WORD) - { - if (tagTokenizer.sval.equals("name")) - { - name = parseAttributeString(tagTokenizer); - this.parameters.put("name", name); - } - else if (tagTokenizer.sval.equals("code")) - code = parseAttributeString(tagTokenizer); - else if (tagTokenizer.sval.equals("codebase")) - codebase = parseAttributeString(tagTokenizer); - else if (tagTokenizer.sval.equals("archive")) - archivesList = parseAttributeString(tagTokenizer); - else if (tagTokenizer.sval.equals("width")) - { - tagTokenizer.nextToken(); - tagTokenizer.nextToken(); - if (tagTokenizer.ttype == StreamTokenizer.TT_NUMBER) - this.parameters.put("width", - Integer.toString((int) tagTokenizer.nval)); - else - this.parameters.put("width", tagTokenizer.sval); - } - else if (tagTokenizer.sval.equals("height")) - { - tagTokenizer.nextToken(); - tagTokenizer.nextToken(); - if (tagTokenizer.ttype == StreamTokenizer.TT_NUMBER) - this.parameters.put("height", - Integer.toString((int) tagTokenizer.nval)); - else - this.parameters.put("height", tagTokenizer.sval); - } - } - } - } - - // Parse a case-sensitive element. - static String parseAttributeString(StreamTokenizer tagTokenizer) - throws IOException - { - String value = ""; - - // Read "=". - tagTokenizer.nextToken(); - - // Read non-alphabetic characters that may appear in file names as - // word characters so that an unquoted file name is parsed as a - // single token. - tagTokenizer.wordChars('!', '!'); - tagTokenizer.wordChars('#', '&'); - tagTokenizer.wordChars('(', '/'); - tagTokenizer.wordChars('{', '~'); - tagTokenizer.wordChars('[', '^'); - - tagTokenizer.lowerCaseMode(false); - - tagTokenizer.nextToken(); - value = new String(tagTokenizer.sval); - - // Reset character meanings. - tagTokenizer.ordinaryChar('!'); - tagTokenizer.ordinaryChars('#', '&'); - tagTokenizer.ordinaryChars('(', '/'); - tagTokenizer.ordinaryChars('{', '~'); - tagTokenizer.ordinaryChars('[', '^'); - - tagTokenizer.lowerCaseMode(true); - return value; - } - - // Parse a comma-delimited list of archives. - void parseArchives() throws IOException - { - StringTokenizer tagTokenizer = new StringTokenizer(archivesList, ","); - - while (tagTokenizer.hasMoreTokens()) - archives.add(prependCodebase(tagTokenizer.nextToken().trim())); - } - - // Prepend the full codebase to basename and return a URL object - // representing the result. The full codebase is the codebase - // appended to the documentbase. - URL prependCodebase(String basename) throws MalformedURLException + + /** + * Constructs an applet with the given parameters. + * + * @param code - the code for the applet. + * @param archive - the archive for the applet. + * @param parameters - the parameters for the applet. + * @param dim - the dimensions for the applet. + */ + AppletTag(String code, String archives, List parameters, Dimension dims) { - URL fullcodebase; - - // If no codebase was specified default to documentbase. + this.code = code; + parseArchives(archives); + + int size = parameters.size(); + if (size != 0) + for (int i = 0; i < size; i++) + { + DomHTMLParamElement curr = (DomHTMLParamElement) parameters.get(i); + name = curr.getName(); + if (name.startsWith("java_")) + name = name.substring(5); + this.parameters.put(name, curr.getValue()); + } + this.parameters.put("width", Integer.toString(dims.width)); + this.parameters.put("height", Integer.toString(dims.height)); + } + + /** + * Constructs and parses document using the given location. + * + * @param loc - location of applet + */ + AppletTag(String location) throws IOException + { + documentbase = getLocationToURL(location); + InputStreamReader in = new InputStreamReader(documentbase.openStream()); + document = (DomHTMLDocument) (new DomHTMLParser(HTML_401F.getInstance()).parseDocument(in)); + } + + /** + * Constructs and parses document. + * + * @param in - Reader to parse document from. + * @param documentBase - the URL of the applet + * @throws IOException - is thrown if any IO error occurs. + */ + AppletTag(Reader in, URL documentBase) throws IOException + { + this.documentbase = documentBase; + document = (DomHTMLDocument) (new DomHTMLParser(HTML_401F.getInstance()).parseDocument(in)); + } + + /** + * Creates the applet using the parsed document. + * + * @return the Applet created. + */ + void createApplet() + { + recurseDocument(document.getChildNodes()); + + if (appElement != null) + parseAppletTag(); + else if (objElement != null) + parseObjectTag(); + else if (embElement != null) + parseEmbedTag(); + + int size = paramElements.size(); + if (size != 0) + for (int i = 0; i < size; i++) + { + DomHTMLParamElement curr = (DomHTMLParamElement) paramElements.get(i); + name = curr.getName(); + if (name.startsWith("java_")) + name = name.substring(5); + parameters.put(name, curr.getValue()); + } + } + + /** + * Recurses the document in search for the appropriate tags. + * + * @param list - the Node list. + */ + private void recurseDocument(NodeList list) + { + // Recurse and store all APPLET, OBJECT and EMBED tags. + int length = list.getLength(); + for (int i = 0; i < length; i++) + { + DomNode curr = (DomNode) list.item(i); + // Order of checking is important here. + // Must check embed element before applet element + // because DomHTMLEmbedElement extends DomHTMLAppletElement + if (curr instanceof DomHTMLEmbedElement) + embElement = (DomHTMLEmbedElement) curr; + else if (curr instanceof DomHTMLAppletElement) + appElement = (DomHTMLAppletElement) curr; + else if (curr instanceof DomHTMLObjectElement) + objElement = (DomHTMLObjectElement) curr; + else if (curr instanceof DomHTMLParamElement) + paramElements.add((DomHTMLParamElement) curr); + recurseDocument(curr.getChildNodes()); + } + } + + /** + * Parses the embed tag. + */ + private void parseEmbedTag() + { + // In an EMBED tag, a parameter is any non-standard attribute. This + // is a problem for applets that take parameters named "code", + // "codebase", "archive", "object", or "type". The solution is to + // allow the same attributes, prefixed by "java_". The presence of + // a "java_" attribute indicates that the non-prefixed attribute + // should be interpreted as a parameter. For example if "java_code" + // and "code" attributes are present in the EMBED tag then the + // "code" attribute is interpreted as a parameter. + + name = embElement.getName(); + parameters.put("name", name); + + object = embElement.getObject(); + if (object.equals("")) + object = embElement.getJavaObject(); + parameters.put("object", object); + + code = embElement.getCode(); + if (code.equals("")) + code = embElement.getJavaCode(); + parameters.put("code", code); + + archives = parseArchives(embElement.getArchive()); + if (archives.equals("")) + archives = parseArchives(embElement.getJavaArchive()); + parameters.put("archive", archives); + + codebase = embElement.getCodeBase(); if (codebase.equals("")) - { - if (documentbase.getFile().endsWith(File.separator)) - fullcodebase = documentbase; - else - { - String dirname = documentbase.getFile(); - - // Determine dirname for file by stripping everything - // past the last file separator. - dirname = - dirname.substring(0, dirname.lastIndexOf(File.separatorChar) + 1); - - fullcodebase = - new URL(documentbase.getProtocol(), documentbase.getHost(), - documentbase.getPort(), dirname); - } - } - else - { - // codebase was specified - URL codebaseURL = new URL(documentbase, codebase); - - if ("file".equals(codebaseURL.getProtocol())) - { - if (new File(codebaseURL.getFile()).isDirectory()) - fullcodebase = new URL(documentbase, codebase + File.separator); - else - fullcodebase = new URL(documentbase, codebase); - } - else if (codebase.endsWith(File.separator)) - fullcodebase = new URL(documentbase, codebase); - else - fullcodebase = new URL(documentbase, codebase + File.separator); - } - - return new URL(fullcodebase, basename); - } - - // Parse an applet parameter. - void parseParam(StreamTokenizer tagTokenizer) throws IOException - { - String key = null; - String value = null; - - while (tagTokenizer.nextToken() != '>') - { - if (tagTokenizer.ttype == StreamTokenizer.TT_WORD) - { - if (tagTokenizer.sval.equals("name")) - { - tagTokenizer.nextToken(); - tagTokenizer.nextToken(); - key = new String(tagTokenizer.sval).toLowerCase(); - } - else if (tagTokenizer.sval.equals("value")) - value = parseParamValue(tagTokenizer); - } - - if (key != null && value != null) - parameters.put(key, value); - } - } - - // Parse the value of a parameter. - static String parseParamValue(StreamTokenizer tagTokenizer) - throws IOException - { - String value = ""; - - // Read "=". - tagTokenizer.nextToken(); - - // Read non-alphabetic characters that may appear in - // file names as word characters so that an unquoted - // file name is parsed as a single token. - tagTokenizer.wordChars('!', '!'); - tagTokenizer.wordChars('#', '&'); - tagTokenizer.wordChars('(', '/'); - tagTokenizer.wordChars('{', '~'); - tagTokenizer.wordChars('[', '^'); - - tagTokenizer.lowerCaseMode(false); - - tagTokenizer.nextToken(); - if (tagTokenizer.ttype == StreamTokenizer.TT_NUMBER) - { - // Remove nval's scale. - int unscaled_nval = (int) tagTokenizer.nval; - - // See if nval represents an integer value. - if (Double.compare(tagTokenizer.nval, (double) unscaled_nval) == 0) - value = Integer.toString(unscaled_nval); - else - value = Double.toString(tagTokenizer.nval); - } - else - value = new String(tagTokenizer.sval); - - // Reset character meanings. - tagTokenizer.ordinaryChar('!'); - tagTokenizer.ordinaryChars('#', '&'); - tagTokenizer.ordinaryChars('(', '/'); - tagTokenizer.ordinaryChars('{', '~'); - tagTokenizer.ordinaryChars('[', '^'); - - tagTokenizer.lowerCaseMode(true); - - return value; + codebase = embElement.getJavaCodeBase(); + + parameters.put("codebase", codebase); + parameters.put("width", embElement.getWidth()); + parameters.put("height", embElement.getHeight()); + parameters.put("align", embElement.getAlign()); + parameters.put("alt", embElement.getAlt()); + parameters.put("hspace", Integer.toString(embElement.getHspace())); + parameters.put("mayscript", embElement.getMayscript()); + parameters.put("pluginspage", embElement.getPluginsPage()); + parameters.put("title", embElement.getTitle()); + parameters.put("type", embElement.getType()); + parameters.put("java_type", embElement.getJavaType()); + parameters.put("vspace", Integer.toString(embElement.getVspace())); + } + + /** + * Parses the Object tag. + */ + private void parseObjectTag() + { + // In an OBJECT tag, a parameter is any non-standard attribute. This + // is a problem for applets that take parameters named "code", + // "codebase", "archive", "object", or "type". The solution is to + // allow the same attributes, prefixed by "java_". The presence of + // a "java_" attribute indicates that the non-prefixed attribute + // should be interpreted as a parameter. For example if "java_code" + // and "code" attributes are present in the OBJECT tag then the + // "code" attribute is interpreted as a parameter. + + name = objElement.getName(); + parameters.put("name", name); + + code = objElement.getCode(); + if (code.equals("")) + code = objElement.getJavaCode(); + parameters.put("code", code); + + object = objElement.getObject(); + if (object.equals("")) + object = objElement.getJavaObject(); + parameters.put("object", object); + + archives = parseArchives(objElement.getArchive()); + if (archives.equals("")) + archives = parseArchives(objElement.getJavaArchive()); + parameters.put("archive", archives); + + codebase = objElement.getCodeBase(); + if (codebase.equals("")) + codebase = objElement.getJavaCodeBase(); + parameters.put("codebase", codebase); + + parameters.put("type", objElement.getType()); + parameters.put("java_type", objElement.getJavaType()); + parameters.put("align", objElement.getAlign()); + parameters.put("codetype", objElement.getCodeType()); + parameters.put("data", objElement.getData()); + parameters.put("declare", Boolean.toString(objElement.getDeclare())); + parameters.put("height", objElement.getHeight()); + parameters.put("hspace", Integer.toString(objElement.getHspace())); + parameters.put("border", objElement.getBorder()); + parameters.put("standby", objElement.getStandby()); + parameters.put("tabindex", Integer.toString(objElement.getTabIndex())); + parameters.put("usemap", objElement.getUseMap()); + parameters.put("vspace", Integer.toString(objElement.getVspace())); + parameters.put("width", objElement.getWidth()); + parameters.put("mayscript", objElement.getMayscript()); + parameters.put("scriptable", objElement.getScriptable()); } - - static URL locationToURL(String location) throws IOException + + private void parseAppletTag() { - URL tmpDocumentBase = null; + name = appElement.getName(); + parameters.put("name", name); + + object = appElement.getObject(); + parameters.put("object", object); + + archives = parseArchives(appElement.getArchive()); + parameters.put("archive", archives); + code = appElement.getCode(); + parameters.put("code", code); + + codebase = appElement.getCodeBase(); + parameters.put("codebase", codebase); + + parameters.put("align", appElement.getAlign()); + parameters.put("alt", appElement.getAlt()); + parameters.put("height", appElement.getHeight()); + parameters.put("hspace", Integer.toString(appElement.getHspace())); + parameters.put("vspace", Integer.toString(appElement.getVspace())); + parameters.put("width", appElement.getWidth()); + parameters.put("class", appElement.getCls()); + parameters.put("src", appElement.getSrc()); + } + + /** + * Parses the archive string and returns a list. + * + * @param the list of archives (comma-separated) in a String. + */ + private ArrayList parseArchives(String arcs) + { try { - // Try parsing location as a URL. - tmpDocumentBase = new URL(location); - - // If no file was specified in the URL the assume the user - // meant the root page. - if (tmpDocumentBase.getFile().equals("")) - tmpDocumentBase = new URL(location.concat(File.separator)); - } - catch (MalformedURLException e) - { - // location is not a URL. See if it is an HTML file. - String path; + ArrayList list = new ArrayList(); - if (location.startsWith(File.separator)) - path = new File(location).getCanonicalPath(); - else - path = - new File(System.getProperty("user.dir") + File.separator - + location).getCanonicalPath(); + StringTokenizer tagTokenizer = new StringTokenizer(arcs, ","); + while (tagTokenizer.hasMoreTokens()) + list.add(prependCodeBase(tagTokenizer.nextToken().trim())); - tmpDocumentBase = new URL("file", "", path); + return list; } - return tmpDocumentBase; - } - - // Return a list of applet tag objects representing the applet tags - // that appear in the file or URL "location." - static List parseAppletTags(String location, String encoding) - throws IOException - { - ArrayList tags = new ArrayList(); - URL tmpDocumentBase = locationToURL(location); - InputStream input = tmpDocumentBase.openStream(); - StreamTokenizer tagTokenizer = - new StreamTokenizer(new InputStreamReader(input)); - AppletTag currentTag = - parseNextTag(tagTokenizer, tmpDocumentBase, encoding); - - while (currentTag != null) - { - tags.add(currentTag); - currentTag = parseNextTag(tagTokenizer, tmpDocumentBase, encoding); - } - - return tags; - } - - // Parse the next applet tag in the tagTokenizer stream. - static AppletTag parseNextTag(StreamTokenizer tagTokenizer, - URL documentbase, String encoding) - throws IOException - { - AppletTag currentTag = null; - int token; - - tagTokenizer.lowerCaseMode(true); - tagTokenizer.ordinaryChar('/'); - tagTokenizer.wordChars('_', '_'); - - token = tagTokenizer.nextToken(); - while (token != StreamTokenizer.TT_EOF) - { - // Start of an HTML tag. - if (token == '<') - { - token = tagTokenizer.nextToken(); - if (token == StreamTokenizer.TT_WORD) - { - // An APPLET tag. - if (tagTokenizer.sval.equals("applet")) - currentTag = - new AppletTag(tagTokenizer, documentbase, encoding); - else if (tagTokenizer.sval.equals("embed")) - currentTag = - new EmbedTag(tagTokenizer, documentbase, encoding); - else if (tagTokenizer.sval.equals("object")) - currentTag = - new ObjectTag(tagTokenizer, documentbase, encoding); - else if (tagTokenizer.sval.equals("app")) - currentTag = - new AppTag(tagTokenizer, documentbase, encoding); - else if (tagTokenizer.sval.equals("param")) - { - // Parse APPLET parameters only. - if (currentTag != null - && ! (currentTag instanceof EmbedTag)) - currentTag.parseParam(tagTokenizer); - } - } - else - { - if (token == '/') - { - token = tagTokenizer.nextToken(); - - if (token == StreamTokenizer.TT_WORD) - { - if (currentTag instanceof AppletTag) - { - if (tagTokenizer.sval.equals("applet") - || tagTokenizer.sval.equals("embed") - || tagTokenizer.sval.equals("object") - || tagTokenizer.sval.equals("app")) - { - // Parse archives at this point so - // that we can generate full archive - // URLs using the documentbase and - // codebase fields. - currentTag.parseArchives(); - return currentTag; - } - } - } - } - } - } - token = tagTokenizer.nextToken(); - } - - // If we hit EOF, just go ahead with whatever we've got. Some - // pages don't properly terminate; besides which our parser is a - // bit bogus anyway. - if (currentTag != null) + catch (MalformedURLException e) { - currentTag.parseArchives(); - return currentTag; + return null; } - - return null; } - + + /** + * String representation of the tag. + * + * @return the string representation. + */ public String toString() { return (" name=" + name + "\n" + " code=" + code + "\n" + " codebase=" - + codebase + "\n" + " archive=" + archives + "\n" - + " parameters=" + parameters + "\n" + " documentbase=" - + documentbase + "\n"); - } - - public static Dimension getSize (AppletTag tag) + + codebase + "\n" + " archives=" + archives + "\n" + " parameters=" + + parameters + "\n" + " documentbase=" + documentbase + + " object=" + object + "\n"); + } + + /** + * Returns the size of the applet. + * + * @return the size. + */ + Dimension getSize() { NumberFormat numberFormat; Dimension size = new Dimension(320, 200); try { - String widthStr = (String) tag.parameters.get("width"); + String widthStr = (String) parameters.get("width"); - if (widthStr != null) - { - if (widthStr.charAt(widthStr.length() - 1) == '%') - numberFormat = NumberFormat.getPercentInstance(Locale.US); - else - numberFormat = NumberFormat.getInstance(Locale.US); - - // FIXME: Handle percentage somehow. - size.width = numberFormat.parse(widthStr).intValue(); - } + if (widthStr != null) + { + if (widthStr.charAt(widthStr.length() - 1) == '%') + numberFormat = NumberFormat.getPercentInstance(Locale.US); + else + numberFormat = NumberFormat.getInstance(Locale.US); + + // FIXME: Handle percentage somehow. + size.width = numberFormat.parse(widthStr).intValue(); + } } catch (ParseException e) { - // Use default. + // Use default. } try { - String heightStr = (String) tag.parameters.get("height"); + String heightStr = (String) parameters.get("height"); - if (heightStr != null) - { - if (heightStr.charAt(heightStr.length() - 1) == '%') - numberFormat = NumberFormat.getPercentInstance(Locale.US); - else - numberFormat = NumberFormat.getInstance(Locale.US); - - // FIXME: Handle percentage somehow. - size.height = numberFormat.parse(heightStr).intValue(); - } + if (heightStr != null) + { + if (heightStr.charAt(heightStr.length() - 1) == '%') + numberFormat = NumberFormat.getPercentInstance(Locale.US); + else + numberFormat = NumberFormat.getInstance(Locale.US); + + // FIXME: Handle percentage somehow. + size.height = numberFormat.parse(heightStr).intValue(); + } } catch (ParseException e) { - // Use default. + // Use default. } return size; } -} - - -class EmbedTag extends AppletTag -{ - EmbedTag(StreamTokenizer tagTokenizer, URL documentbase, String encoding) - throws IOException + + /** + * Gets the code base. + * + * @return the codebase. + */ + String getCodeBase() + { + return codebase; + } + + /** + * Gets the archive list. + * + * @return the archive list. + */ + ArrayList getArchives() + { + return archives; + } + + /** + * Prepends the base to the codebase. + * + * @return the new URL. + */ + URL prependCodeBase(String base) throws MalformedURLException { - this.documentbase = documentbase; - this.encoding = encoding; - - // In an EMBED tag, a parameter is any non-standard attribute. This - // is a problem for applets that take parameters named "code", - // "codebase", "archive", "object", or "type". The solution is to - // allow the same attributes, prefixed by "java_". The presence of - // a "java_" attribute indicates that the non-prefixed attribute - // should be interpreted as a parameter. For example if "java_code" - // and "code" attributes are present in the EMBED tag then the - // "code" attribute is interpreted as a parameter. - boolean codeSet = false; - boolean codebaseSet = false; - boolean archiveSet = false; - boolean objectSet = false; - - boolean javaCodeSet = false; - boolean javaCodebaseSet = false; - boolean javaArchiveSet = false; - boolean javaObjectSet = false; - - while (tagTokenizer.nextToken() != '>') - { - if (tagTokenizer.ttype == StreamTokenizer.TT_WORD) - { - if (tagTokenizer.sval.equals("name")) - { - name = parseAttributeString(tagTokenizer); - parameters.put("name", name); - } - else if (tagTokenizer.sval.equals("code")) - { - if (javaCodeSet) - { - // Interpret non-prefixed attribute as a parameter. - String key = new String(tagTokenizer.sval); - String value = AppletTag.parseParamValue(tagTokenizer); - - parameters.put(key, value); - } - else - { - code = parseAttributeString(tagTokenizer); - codeSet = true; - } - } - else if (tagTokenizer.sval.equals("java_code")) - { - if (codeSet) - parameters.put("code", code); - code = parseAttributeString(tagTokenizer); - javaCodeSet = true; - } - else if (tagTokenizer.sval.equals("object")) - { - if (javaObjectSet) - { - // Interpret non-prefixed attribute as a parameter. - String key = new String(tagTokenizer.sval); - String value = AppletTag.parseParamValue(tagTokenizer); - - parameters.put(key, value); - } - else - { - code = parseAttributeString(tagTokenizer); - objectSet = true; - } - } - else if (tagTokenizer.sval.equals("java_object")) - { - if (objectSet) - parameters.put("object", code); - code = parseAttributeString(tagTokenizer); - javaObjectSet = true; - } - else if (tagTokenizer.sval.equals("codebase")) - { - if (javaCodebaseSet) - { - // Interpret non-prefixed attribute as a parameter. - String key = new String(tagTokenizer.sval); - String value = AppletTag.parseParamValue(tagTokenizer); - - parameters.put(key, value); - } - else - { - codebase = parseAttributeString(tagTokenizer); - codebaseSet = true; - } - } - else if (tagTokenizer.sval.equals("java_codebase")) - { - if (codebaseSet) - parameters.put("codebase", codebase); - codebase = parseAttributeString(tagTokenizer); - javaCodebaseSet = true; - } - else if (tagTokenizer.sval.equals("archive")) - { - if (javaArchiveSet) - { - // Interpret non-prefixed attribute as a parameter. - String key = new String(tagTokenizer.sval); - String value = AppletTag.parseParamValue(tagTokenizer); - - parameters.put(key, value); - } - else - { - archivesList = parseAttributeString(tagTokenizer); - archiveSet = true; - } - } - else if (tagTokenizer.sval.equals("java_archive")) - { - if (archiveSet) - parameters.put("archive", archivesList); - archivesList = parseAttributeString(tagTokenizer); - javaArchiveSet = true; - } - else if (tagTokenizer.sval.equals("width")) - { - tagTokenizer.nextToken(); - tagTokenizer.nextToken(); - if (tagTokenizer.ttype == StreamTokenizer.TT_NUMBER) - this.parameters.put("width", - Integer.toString((int) tagTokenizer.nval)); - else - this.parameters.put("width", tagTokenizer.sval); - } - else if (tagTokenizer.sval.equals("height")) - { - tagTokenizer.nextToken(); - tagTokenizer.nextToken(); - if (tagTokenizer.ttype == StreamTokenizer.TT_NUMBER) - this.parameters.put("height", - Integer.toString((int) tagTokenizer.nval)); - else - this.parameters.put("height", tagTokenizer.sval); - } - else if (! tagTokenizer.sval.equals("align") - && ! tagTokenizer.sval.equals("alt") - && ! tagTokenizer.sval.equals("hspace") - && ! tagTokenizer.sval.equals("mayscript") - && ! tagTokenizer.sval.equals("pluginspage") - && ! tagTokenizer.sval.equals("title") - && ! tagTokenizer.sval.equals("type") - && ! tagTokenizer.sval.equals("java_type") - && ! tagTokenizer.sval.equals("vspace")) - { - // Interpret this unknown attribute as a parameter. - String key = new String(tagTokenizer.sval).toLowerCase(); - String value = AppletTag.parseParamValue(tagTokenizer); - parameters.put(key, value); - } - } + URL fullcodebase; + + //If no codebase was specified, default to documentbase. + if (codebase.equals("")) + { + if (documentbase.getFile().endsWith(File.separator)) + fullcodebase = documentbase; + else + { + String dirname = documentbase.getFile(); + + // Determine dirname for file by strippint everything + // past the last file separator. + dirname = dirname.substring(0, + dirname.lastIndexOf(File.separatorChar) + 1); + + fullcodebase = new URL(documentbase.getProtocol(), + documentbase.getHost(), + documentbase.getPort(), dirname); + } + } + else + { + // codebase was specified. + URL codebaseURL = new URL(documentbase, codebase); + + if ("file".equals(codebaseURL.getProtocol())) + { + if (new File(codebaseURL.getFile()).isDirectory()) + fullcodebase = new URL(documentbase, codebase + File.separator); + else + fullcodebase = new URL(documentbase, codebase); + } + else if (codebase.endsWith(File.separator)) + fullcodebase = new URL(documentbase, codebase); + else + fullcodebase = new URL(documentbase, codebase + File.separator); } + + return new URL(fullcodebase, base); } -} + + /** + * Gets the code. + * + * @return the code. + */ + String getCode() + { + return code; + } + + /** + * Gets the document base. + * + * @return the document base. + */ + URL getDocumentBase() + { + return documentbase; + } + + /** + * Gets the specified parameter. + * + * @param name - the specified parameter. + * @return the parameter. + */ + String getParameter(String name) + { + return (String) parameters.get(name.toLowerCase()); + } + + /** + * Gets the location to the URL, given a location. + * + * @param location - the given location. + * @return the URL. + */ + static URL getLocationToURL(String location) throws IOException + { + URL tmpDocumentBase = null; + try + { + // Try parsing location as a URL. + tmpDocumentBase = new URL(location); -class ObjectTag extends AppletTag -{ - // See comment in EmbedTag for an explanation of these fields. - boolean codeSet; - boolean codebaseSet; - boolean archiveSet; - boolean objectSet; - boolean javaCodeSet; - boolean javaCodebaseSet; - boolean javaArchiveSet; - boolean javaObjectSet; - - ObjectTag(StreamTokenizer tagTokenizer, URL documentbase, String encoding) - throws IOException - { - this.documentbase = documentbase; - this.encoding = encoding; - - while (tagTokenizer.nextToken() != '>') - { - if (tagTokenizer.ttype == StreamTokenizer.TT_WORD) - { - if (tagTokenizer.sval.equals("name")) - name = parseAttributeString(tagTokenizer); - - if (tagTokenizer.sval.equals("width")) - { - tagTokenizer.nextToken(); - tagTokenizer.nextToken(); - if (tagTokenizer.ttype == StreamTokenizer.TT_NUMBER) - this.parameters.put("width", - Integer.toString((int) tagTokenizer.nval)); - else - this.parameters.put("width", tagTokenizer.sval); - } - else if (tagTokenizer.sval.equals("height")) - { - tagTokenizer.nextToken(); - tagTokenizer.nextToken(); - if (tagTokenizer.ttype == StreamTokenizer.TT_NUMBER) - this.parameters.put("height", - Integer.toString((int) tagTokenizer.nval)); - else - this.parameters.put("height", tagTokenizer.sval); - } - } - } - } - - // Parse an applet parameter. - void parseParam(StreamTokenizer tagTokenizer) throws IOException - { - String paramName = null; - String value = null; - - while (tagTokenizer.nextToken() != '>') - { - if (tagTokenizer.ttype == StreamTokenizer.TT_WORD) - { - if (tagTokenizer.sval.equals("name")) - { - tagTokenizer.nextToken(); - tagTokenizer.nextToken(); - paramName = new String(tagTokenizer.sval).toLowerCase(); - } - else if (tagTokenizer.sval.equals("value")) - value = parseParamValue(tagTokenizer); - } - - if (paramName != null && value != null) - { - if (paramName.equals("code")) - { - if (javaCodeSet) - // Interpret non-prefixed attribute as a parameter. - parameters.put(paramName, value); - else - { - code = value; - codeSet = true; - } - } - else if (paramName.equals("java_code")) - { - if (codeSet) - parameters.put("code", code); - code = value; - javaCodeSet = true; - } - else if (paramName.equals("object")) - { - if (javaObjectSet) - parameters.put(paramName, value); - else - { - code = value; - objectSet = true; - } - } - else if (paramName.equals("java_object")) - { - if (objectSet) - parameters.put("object", code); - code = value; - javaObjectSet = true; - } - else if (paramName.equals("codebase")) - { - if (javaCodebaseSet) - parameters.put(paramName, value); - else - { - codebase = value; - codebaseSet = true; - } - } - else if (paramName.equals("java_codebase")) - { - if (codebaseSet) - parameters.put("codebase", codebase); - codebase = value; - javaCodebaseSet = true; - } - else if (paramName.equals("archive")) - { - if (javaArchiveSet) - parameters.put(paramName, value); - else - { - // Save the archive list for later processing. - archivesList = value; - archiveSet = true; - } - } - else if (paramName.equals("java_archive")) - { - if (archiveSet) - parameters.put("archive", archivesList); - archivesList = value; - javaArchiveSet = true; - } - else if (! paramName.equals("type") - && ! paramName.equals("java_type") - && ! paramName.equals("mayscript") - && ! paramName.equals("scriptable")) - parameters.put(paramName, value); - } + // If no file was specified in the URL the assume the user + // meant the root page. + if (tmpDocumentBase.getFile().equals("")) + tmpDocumentBase = new URL(location.concat(File.separator)); } - } -} - + catch (MalformedURLException e) + { + // location is not a URL. See if it is an HTML file. + String path; -class AppTag extends AppletTag -{ - AppTag(StreamTokenizer tagTokenizer, URL documentbase, String encoding) - throws IOException - { - this.documentbase = documentbase; - this.encoding = encoding; + if (location.startsWith(File.separator)) + path = new File(location).getCanonicalPath(); + else + path = new File(System.getProperty("user.dir") + File.separator + + location).getCanonicalPath(); - while (tagTokenizer.nextToken() != '>') - { - if (tagTokenizer.ttype == StreamTokenizer.TT_WORD) - { - if (tagTokenizer.sval.equals("class")) - code = parseAttributeString(tagTokenizer); - else if (tagTokenizer.sval.equals("src")) - codebase = parseAttributeString(tagTokenizer); - else if (tagTokenizer.sval.equals("width")) - { - tagTokenizer.nextToken(); - tagTokenizer.nextToken(); - if (tagTokenizer.ttype == StreamTokenizer.TT_NUMBER) - this.parameters.put("width", - Integer.toString((int) tagTokenizer.nval)); - else - this.parameters.put("width", tagTokenizer.sval); - } - else if (tagTokenizer.sval.equals("height")) - { - tagTokenizer.nextToken(); - tagTokenizer.nextToken(); - if (tagTokenizer.ttype == StreamTokenizer.TT_NUMBER) - this.parameters.put("height", - Integer.toString((int) tagTokenizer.nval)); - else - this.parameters.put("height", tagTokenizer.sval); - } - } + tmpDocumentBase = new URL("file", "", path); } + return tmpDocumentBase; } -} +} \ No newline at end of file Index: src/gnu/gcjwebplugin/AppletViewer.java =================================================================== RCS file: /sources/gcjwebplugin/gcjwebplugin/src/gnu/gcjwebplugin/AppletViewer.java,v retrieving revision 1.42 diff -u -r1.42 AppletViewer.java --- src/gnu/gcjwebplugin/AppletViewer.java 5 Apr 2006 19:45:44 -0000 1.42 +++ src/gnu/gcjwebplugin/AppletViewer.java 11 Apr 2006 17:58:46 -0000 @@ -78,9 +78,10 @@ try { - ClassLoader loader = getClassLoader(tag.prependCodebase (""), - tag.archives); - String code = tag.code; + tag.createApplet(); + ClassLoader loader = getClassLoader(tag.prependCodeBase(""), + tag.getArchives()); + String code = tag.getCode(); if (code.endsWith(".class")) code = code.substring(0, code.length() - 6).replace('/', '.'); @@ -283,6 +284,6 @@ new StandaloneAppletViewer(code, codebase, archives, parameters, dimensions, widthGiven, heightGiven, codeGiven, verbose, args, opts, - opts.getOptind(), encoding); + opts.getOptind()); } } Index: src/gnu/gcjwebplugin/CommonAppletStub.java =================================================================== RCS file: /sources/gcjwebplugin/gcjwebplugin/src/gnu/gcjwebplugin/CommonAppletStub.java,v retrieving revision 1.6 diff -u -r1.6 CommonAppletStub.java --- src/gnu/gcjwebplugin/CommonAppletStub.java 9 Aug 2004 03:48:13 -0000 1.6 +++ src/gnu/gcjwebplugin/CommonAppletStub.java 11 Apr 2006 17:58:46 -0000 @@ -65,7 +65,7 @@ */ public URL getDocumentBase() { - return tag.documentbase; + return tag.getDocumentBase(); } /** @@ -77,11 +77,11 @@ { try { - return tag.prependCodebase(""); + return tag.prependCodeBase(""); } catch (MalformedURLException e) { - throw new RuntimeException("unknown codebase"); + throw new RuntimeException("unknown codebase"); } } @@ -95,7 +95,7 @@ */ public String getParameter(String name) { - return (String) tag.parameters.get(name.toLowerCase()); + return (String) tag.getParameter(name.toLowerCase()); } /** Index: src/gnu/gcjwebplugin/PluginAppletViewer.java =================================================================== RCS file: /sources/gcjwebplugin/gcjwebplugin/src/gnu/gcjwebplugin/PluginAppletViewer.java,v retrieving revision 1.24 diff -u -r1.24 PluginAppletViewer.java --- src/gnu/gcjwebplugin/PluginAppletViewer.java 5 Apr 2006 19:45:44 -0000 1.24 +++ src/gnu/gcjwebplugin/PluginAppletViewer.java 11 Apr 2006 17:58:46 -0000 @@ -80,9 +80,8 @@ { int pos = message.indexOf(' ', 4); String documentbase = message.substring(4, pos); - String tag = message.substring(pos + 1); - - currentWindow.setTag(tag, documentbase, "UTF8"); + String tag = message.substring(pos + 1); + currentWindow.setTag(tag, documentbase); } else if (message.startsWith("handle")) { Index: src/gnu/gcjwebplugin/PluginAppletWindow.java =================================================================== RCS file: /sources/gcjwebplugin/gcjwebplugin/src/gnu/gcjwebplugin/PluginAppletWindow.java,v retrieving revision 1.23 diff -u -r1.23 PluginAppletWindow.java --- src/gnu/gcjwebplugin/PluginAppletWindow.java 7 Apr 2006 18:19:55 -0000 1.23 +++ src/gnu/gcjwebplugin/PluginAppletWindow.java 11 Apr 2006 17:58:46 -0000 @@ -38,7 +38,7 @@ import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.io.IOException; -import java.io.StreamTokenizer; +import java.io.InputStreamReader; import java.io.StringReader; import java.net.MalformedURLException; import java.net.URL; @@ -379,23 +379,20 @@ } } - void setTag(String tag, String documentbase, String encoding) - throws MalformedURLException, IOException + void setTag(String tag, String documentbase) throws MalformedURLException, IOException { - StringReader reader = new StringReader(tag); - URL documentbaseURL = AppletTag.locationToURL(documentbase); - this.tag = - AppletTag.parseNextTag(new StreamTokenizer(reader), documentbaseURL, - encoding); + URL documentbaseURL = AppletTag.getLocationToURL(documentbase); + StringReader in = new StringReader(tag); + this.tag = new AppletTag(in, documentbaseURL); } - /////////////////////////////////// - ////// EmbeddedWindow Method ////// - /////////////////////////////////// + // ///////////////////////////////// + // //// EmbeddedWindow Method ////// + // ///////////////////////////////// /** * Set the native handle of the window system to embed the window in. - * + * * @param handle the native handle. */ public void setHandle(long handle) @@ -405,8 +402,8 @@ applet = AppletViewer.createApplet(tag); - if (contexts.get(tag.codebase) == null) - contexts.put(tag.codebase, new PluginAppletContext()); + if (contexts.get(tag.getCodeBase()) == null) + contexts.put(tag.getCodeBase(), new PluginAppletContext()); int result = AppletWarning.show(); @@ -416,12 +413,12 @@ isActive = true; add(applet); - AppletContext context = (AppletContext) contexts.get(tag.codebase); + AppletContext context = (AppletContext) contexts.get(tag.getCodeBase()); ((PluginAppletContext) context).addApplet(applet); applet.setStub(new CommonAppletStub(tag, context, applet)); - Dimension size = AppletTag.getSize (tag); + Dimension size = tag.getSize (); setSize (size.width, size.height); applet.setSize (size); Index: src/gnu/gcjwebplugin/StandaloneAppletViewer.java =================================================================== RCS file: /sources/gcjwebplugin/gcjwebplugin/src/gnu/gcjwebplugin/StandaloneAppletViewer.java,v retrieving revision 1.11 diff -u -r1.11 StandaloneAppletViewer.java --- src/gnu/gcjwebplugin/StandaloneAppletViewer.java 12 Feb 2006 10:02:00 -0000 1.11 +++ src/gnu/gcjwebplugin/StandaloneAppletViewer.java 11 Apr 2006 17:58:46 -0000 @@ -49,7 +49,7 @@ boolean widthGiven, boolean heightGiven, boolean codeGiven, boolean verbose, String[] args, Getopt opts, - int firstNonOptIndex, String encoding) + int firstNonOptIndex) throws MalformedURLException, IOException { boolean classFileGiven = false; @@ -78,7 +78,7 @@ classFileGiven = true; appletTags.add(new AppletTag(args[i], archives, parameters, - dimensions, encoding)); + dimensions)); // Process only the first .class file we encounter on the // command line. break; @@ -96,7 +96,11 @@ // Handle each file specified on the command line. for (int i = opts.getOptind(); i < args.length; i++) - appletTags.addAll(AppletTag.parseAppletTags(args[i], encoding)); + { + AppletTag t = new AppletTag(args[i]); + t.createApplet(); + appletTags.add(t); + } // Handle --code option, if it was given. if (! code.equals("")) @@ -131,9 +135,10 @@ StringReader reader = new StringReader(tagString); String path = System.getProperty("user.dir") + File.separator; - appletTags.add(AppletTag.parseNextTag(new StreamTokenizer(reader), - new URL("file", "", path), - encoding)); + AppletTag tg = new AppletTag(reader, + new URL("file", "", path)); + tg.createApplet(); + appletTags.add(tg); } if (verbose) @@ -168,7 +173,7 @@ for (int i = 0; i < appletTags.size(); i++) { AppletTag tag = (AppletTag) appletTags.get(i); - + // Create a StandaloneAppletWindow and add it to the // appletWindows list. new StandaloneAppletWindow(tag, appletWindows); Index: src/gnu/gcjwebplugin/StandaloneAppletWindow.java =================================================================== RCS file: /sources/gcjwebplugin/gcjwebplugin/src/gnu/gcjwebplugin/StandaloneAppletWindow.java,v retrieving revision 1.27 diff -u -r1.27 StandaloneAppletWindow.java --- src/gnu/gcjwebplugin/StandaloneAppletWindow.java 7 Apr 2006 18:19:55 -0000 1.27 +++ src/gnu/gcjwebplugin/StandaloneAppletWindow.java 11 Apr 2006 17:58:46 -0000 @@ -22,17 +22,14 @@ import java.applet.Applet; import java.applet.AppletContext; -import java.awt.AWTEvent; import java.awt.BorderLayout; import java.awt.Dimension; -import java.awt.Event; import java.awt.Frame; import java.awt.Insets; import java.awt.Label; import java.awt.Menu; import java.awt.MenuBar; import java.awt.MenuItem; -import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentEvent; @@ -105,7 +102,7 @@ System.exit(0); } }); - + addContainerListener(this); addComponentListener(this); addMouseListener(this); @@ -185,7 +182,6 @@ menuApplet.add(closeItem); menuApplet.add(quitItem); setMenuBar(menuBar); - setTitle("GCJ Applet Viewer: " + tag.code); AppletContext context = (AppletContext) contexts.get(tag.codebase); @@ -195,14 +191,14 @@ String testWindowCountProperty = System.getProperty("gnu.gcjwebplugin.test.windowCount"); - + if (testWindowCountProperty == null) { // Create the frame's peer. Otherwise getPreferredSize will read // its insets as 0. addNotify(); Insets i = getInsets (); - Dimension size = AppletTag.getSize (tag); + Dimension size = tag.getSize(); setSize(i.left + size.width + i.right, i.top + size.height + status.getPreferredSize ().height + i.bottom); @@ -231,7 +227,6 @@ applet.invalidate(); applet.validate(); applet.repaint(); - if (++StandaloneAppletWindow.testWindowCount == Integer.decode(testWindowCountProperty).intValue()) System.exit(0); }