OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / tools / gnu / classpath / tools / appletviewer / TagParser.java
1 /* TagParser.java -- a parser for applet tags
2    Copyright (C) 2006  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38 package gnu.classpath.tools.appletviewer;
39
40 import gnu.javax.swing.text.html.parser.HTML_401F;
41
42 import gnu.xml.dom.DomNode;
43 import gnu.xml.dom.html2.DomHTMLAppletElement;
44 import gnu.xml.dom.html2.DomHTMLDocument;
45 import gnu.xml.dom.html2.DomHTMLEmbedElement;
46 import gnu.xml.dom.html2.DomHTMLObjectElement;
47 import gnu.xml.dom.html2.DomHTMLParamElement;
48 import gnu.xml.dom.html2.DomHTMLParser;
49
50 import java.io.File;
51 import java.io.InputStreamReader;
52 import java.io.IOException;
53 import java.io.Reader;
54
55 import java.net.MalformedURLException;
56 import java.net.URL;
57
58 import java.util.ArrayList;
59 import java.util.StringTokenizer;
60 import java.util.Vector;
61
62 import org.w3c.dom.NodeList;
63
64
65 public class TagParser
66 {
67     
68   /**
69    * Parsed document.
70    */
71   DomHTMLDocument document;
72   
73   /**
74    * The document base of this applet.
75    */
76   URL documentbase;
77   
78   /**
79    * The document base of all the applets.
80    */
81   static URL db;
82   
83   /** 
84    * The tags in the document.
85    */
86   Vector tags = new Vector();
87   
88   /**
89    * Default constructor.
90    */
91   TagParser()
92   {
93     // Do nothing.
94   }
95
96   /**
97    * Constructs and parses document using the given location.
98    * 
99    * @param location - location of applet
100    */
101   TagParser(String location) throws IOException
102   {
103     documentbase = getLocationToURL(location);
104     db = documentbase;
105     InputStreamReader in = new InputStreamReader(documentbase.openStream());
106     document = (DomHTMLDocument) (new DomHTMLParser(HTML_401F.getInstance()).parseDocument(in));
107   }
108
109   /**
110    * Constructs and parses document.
111    * 
112    * @param in - Reader to parse document from.
113    * @param documentBase - the URL of the applet
114    * @throws IOException - is thrown if any IO error occurs.
115    */
116   TagParser(Reader in, URL documentBase) throws IOException
117   {
118     documentbase = documentBase;
119     db = documentbase;
120     document = (DomHTMLDocument) (new DomHTMLParser(HTML_401F.getInstance()).parseDocument(in));
121   }
122   
123   /**
124    * Parses all applet tags in document.
125    * 
126    * @return a list of AppletTag objects representing the applet tags
127    * in document
128    */
129   ArrayList parseAppletTags()
130   {    
131     ArrayList allTags = new ArrayList();
132     if (document == null)
133       return null;;
134     
135     recurseDocument(document.getChildNodes());
136
137     int sz = tags.size();
138     for (int j = 0; j < sz; j++)
139       {
140         Object curr = tags.get(j);
141         // Order of checking is important here.
142         // Must check embed element before applet element
143         // because DomHTMLEmbedElement extends DomHTMLAppletElement
144         AppletTag a = null;
145         if (curr instanceof DomHTMLEmbedElement)
146           a = new AppletTag((DomHTMLEmbedElement) curr);
147         else if (curr instanceof DomHTMLAppletElement)
148           a = new AppletTag((DomHTMLAppletElement) curr);
149         else if (curr instanceof DomHTMLObjectElement)
150           a = new AppletTag((DomHTMLObjectElement) curr);
151         a.documentbase = documentbase;
152         allTags.add(a);
153       }
154     
155     return allTags;
156   }
157   
158   /**
159    * Recurses the document in search for the appropriate tags.
160    * 
161    * @param list - the Node list.
162    */
163   private void recurseDocument(NodeList list)
164   {
165     // Recurse and store all APPLET, OBJECT and EMBED tags.
166     int length = list.getLength();
167     for (int i = 0; i < length; i++)
168       {
169         DomNode curr = (DomNode) list.item(i);
170         if ((curr instanceof DomHTMLEmbedElement) || 
171             (curr instanceof DomHTMLAppletElement) ||
172             (curr instanceof DomHTMLObjectElement))
173           tags.add(curr);
174         recurseDocument(curr.getChildNodes());
175       }
176   }
177   
178   /**
179    * Parses the param elements for a given node.
180    * 
181    * @param node - the node element to parse.
182    */
183   static void parseParams(DomNode node, AppletTag t)
184   {
185     boolean ja = false;
186     boolean jb = false;
187     boolean jc = false;
188     NodeList l = node.getChildNodes();
189     int size = l.getLength();
190     
191     if (size != 0)
192       for (int i = 0; i < size; i++)
193         {
194           Object c = l.item(i);
195           if (! (c instanceof DomHTMLParamElement))
196             continue;
197           DomHTMLParamElement curr = (DomHTMLParamElement) c;
198           String key = curr.getName();
199           String val = curr.getValue();
200           
201           if (key.equals("java_code"))
202             {
203               jc = true;
204               t.code = val;
205             }
206           else if (key.equals("java_codebase"))
207             {
208               jb = true;
209               t.codebase = val;
210             }
211           else if (!jc && key.equals("code"))
212             t.code = val;
213           else if (!jc && key.equals("classid"))
214             {
215               int x = val.indexOf(":");
216               if (x != -1)
217                 val = val.substring(x + 1);
218               t.code = val;
219             }
220           else if (!jb && key.equals("codebase"))
221             t.codebase = val;
222           else if (key.equals("java_archive"))
223             {
224               ja = true;
225               t.archives = parseArchives(val, t);
226               val = t.archives.toString();
227             }
228           else if (!ja && key.equals("archive"))
229             {
230               t.archives = parseArchives(val, t);
231               val = t.archives.toString();
232             }
233           val = unescapeString(val);
234           t.parameters.put(key.toLowerCase(), val);
235         }
236   }
237   
238   /**
239    * This method does the same thing as the g_strcompress function in glib.
240    * 
241    * @param value
242    * @return value in its original one-byte equivalence.
243    */
244   private static String unescapeString(String value)
245   {
246     String unescVal = "";
247     for (int i = 0; i < value.length(); i++)
248       {
249         if (i == value.length() - 1)
250           {
251             unescVal = unescVal.concat(value.substring(i));
252             break;
253           }
254         if (value.charAt(i) == '\\')
255           {
256             switch (value.charAt(i + 1))
257               {
258               case 'b':
259                 unescVal = unescVal.concat("\b");
260                 break;
261               case 'f':
262                 unescVal = unescVal.concat("\f");
263                 break;
264               case 'n':
265                 unescVal = unescVal.concat("\n");
266                 break;
267               case 'r':
268                 unescVal = unescVal.concat("\r");
269                 break;
270               case 't':
271                 unescVal = unescVal.concat("\t");
272                 break;
273               case '\\':
274                 unescVal = unescVal.concat("\\");
275                 break;
276               case '\"':
277                 unescVal = unescVal.concat("\"");
278                 break;
279               default:
280                 unescVal = unescVal.concat("\\");
281                 unescVal = unescVal.concat(value.substring(i + 1, i + 2));
282                 break;
283               }
284             i++;
285           }
286         else
287           unescVal = unescVal.concat(value.substring(i, i + 1));
288       }
289     return unescVal;
290   }
291   
292   /**
293    * Parses the archive string and returns a list.
294    * 
295    * @param the list of archives (comma-separated) in a String.
296    */
297   static ArrayList parseArchives(String arcs, AppletTag t)
298   {
299     try
300       {
301         ArrayList list = new ArrayList();
302
303         StringTokenizer tagTokenizer = new StringTokenizer(arcs, ",");
304         while (tagTokenizer.hasMoreTokens())
305           list.add(t.prependCodeBase(tagTokenizer.nextToken().trim()));
306
307         return list;
308       }
309     catch (MalformedURLException e)
310       {
311       }
312     return null;
313   }
314   
315   /**
316    * Gets the location to the URL, given a location.
317    * 
318    * @param location - the given location.
319    * @return the URL.
320    */
321   static URL getLocationToURL(String location) throws IOException
322   {
323     URL tmpDocumentBase = null;
324
325     try
326       {        
327         // Try parsing location as a URL.
328         tmpDocumentBase = new URL(location);
329         
330         // If no file was specified in the URL the assume the user
331         // meant the root page.
332         String f = tmpDocumentBase.getFile();
333         if (f.indexOf(".") == -1 && !f.endsWith(File.separator))
334           if (new File(tmpDocumentBase.getFile()).isDirectory())
335             tmpDocumentBase = new URL(location.concat(File.separator));
336       }
337     catch (MalformedURLException e)
338       {
339         // location is not a URL.  See if it is an HTML file.
340         String path;
341
342         if (location.startsWith(File.separator))
343           path = new File(location).getCanonicalPath();
344         else
345           path = new File(System.getProperty("user.dir") + File.separator
346                           + location).getCanonicalPath();
347
348         tmpDocumentBase = new URL("file", "", path);
349         
350         if (new File(tmpDocumentBase.getFile()).isDirectory())
351           tmpDocumentBase = new URL("file", "", path + File.separator);
352       }
353     
354     return tmpDocumentBase;
355   }
356 }