KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > htmlparser > PrototypicalNodeFactory


1 // HTMLParser Library $Name: v1_5_20050313 $ - A java-based parser for HTML
2
// http://sourceforge.org/projects/htmlparser
3
// Copyright (C) 2003 Derrick Oswald
4
//
5
// Revision Control Information
6
//
7
// $Source: /cvsroot/htmlparser/htmlparser/src/org/htmlparser/PrototypicalNodeFactory.java,v $
8
// $Author: derrickoswald $
9
// $Date: 2004/07/31 16:42:35 $
10
// $Revision: 1.13 $
11
//
12
// This library is free software; you can redistribute it and/or
13
// modify it under the terms of the GNU Lesser General Public
14
// License as published by the Free Software Foundation; either
15
// version 2.1 of the License, or (at your option) any later version.
16
//
17
// This library is distributed in the hope that it will be useful,
18
// but WITHOUT ANY WARRANTY; without even the implied warranty of
19
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
// Lesser General Public License for more details.
21
//
22
// You should have received a copy of the GNU Lesser General Public
23
// License along with this library; if not, write to the Free Software
24
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
//
26

27 package org.htmlparser;
28
29 import java.io.Serializable JavaDoc;
30 import java.util.Hashtable JavaDoc;
31 import java.util.Locale JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.Set JavaDoc;
34 import java.util.Vector JavaDoc;
35
36 import org.htmlparser.Attribute;
37 import org.htmlparser.NodeFactory;
38 import org.htmlparser.Remark;
39 import org.htmlparser.Tag;
40 import org.htmlparser.Text;
41 import org.htmlparser.lexer.Page;
42 import org.htmlparser.nodes.AbstractNode;
43 import org.htmlparser.nodes.TextNode;
44 import org.htmlparser.nodes.RemarkNode;
45 import org.htmlparser.nodes.TagNode;
46 import org.htmlparser.tags.AppletTag;
47 import org.htmlparser.tags.BaseHrefTag;
48 import org.htmlparser.tags.BodyTag;
49 import org.htmlparser.tags.Bullet;
50 import org.htmlparser.tags.BulletList;
51 import org.htmlparser.tags.Div;
52 import org.htmlparser.tags.DoctypeTag;
53 import org.htmlparser.tags.FormTag;
54 import org.htmlparser.tags.FrameSetTag;
55 import org.htmlparser.tags.FrameTag;
56 import org.htmlparser.tags.HeadTag;
57 import org.htmlparser.tags.Html;
58 import org.htmlparser.tags.ImageTag;
59 import org.htmlparser.tags.InputTag;
60 import org.htmlparser.tags.JspTag;
61 import org.htmlparser.tags.LabelTag;
62 import org.htmlparser.tags.LinkTag;
63 import org.htmlparser.tags.MetaTag;
64 import org.htmlparser.tags.ObjectTag;
65 import org.htmlparser.tags.OptionTag;
66 import org.htmlparser.tags.ScriptTag;
67 import org.htmlparser.tags.SelectTag;
68 import org.htmlparser.tags.Span;
69 import org.htmlparser.tags.StyleTag;
70 import org.htmlparser.tags.TableColumn;
71 import org.htmlparser.tags.TableHeader;
72 import org.htmlparser.tags.TableRow;
73 import org.htmlparser.tags.TableTag;
74 import org.htmlparser.tags.TextareaTag;
75 import org.htmlparser.tags.TitleTag;
76 import org.htmlparser.util.ParserException;
77
78 /**
79  * A node factory based on the prototype pattern.
80  * This factory uses the prototype pattern to generate new nodes.
81  * It generates generic text and remark nodes from prototypes accessed
82  * via the textPrototype and remarkPrototype properties respectively.
83  * These are cloned as needed to form new {@link Text} and {@link Remark} nodes.
84  * Prototype tags, in the form of undifferentiated tags are held in a hash
85  * table. On a request for a tag, the attributes are examined for the name
86  * of the tag and if a prototype of that name is registered, it is cloned
87  * and the clone is given the characteristics
88  * {@link Attribute Attributes}, start and end position) of the requested tag.
89  * If no tag is registered under the needed name, a generic tag is created.
90  * Note that in all casses, the {@link Page} property is only set if the node
91  * is a subclass of {@link AbstractNode}.
92  */

93 public class PrototypicalNodeFactory
94     implements
95         Serializable JavaDoc,
96         NodeFactory
97 {
98     /**
99      * The prototypical text node.
100      */

101     protected Text mText;
102
103     /**
104      * The prototypical remark node.
105      */

106     protected Remark mRemark;
107
108     /**
109      * The prototypical tag node.
110      */

111     protected Tag mTag;
112
113     /**
114      * The list of tags to return.
115      * The list is keyed by tag name.
116      */

117     protected Map JavaDoc mBlastocyst;
118
119     /**
120      * Create a new factory with all tags registered.
121      */

122     public PrototypicalNodeFactory ()
123     {
124         this (false);
125     }
126
127     /**
128      * Create a new factory with no registered tags.
129      * @param empty If <code>true</code>, creates an empty factory,
130      * otherwise is equivalent to {@link #PrototypicalNodeFactory()}.
131      */

132     public PrototypicalNodeFactory (boolean empty)
133     {
134         clear ();
135         mText = new TextNode (null, 0, 0);
136         mRemark = new RemarkNode (null, 0, 0);
137         mTag = new TagNode (null, 0, 0, null);
138         if (!empty)
139             registerTags ();
140     }
141
142     /**
143      * Create a new factory with the given tag as the only registered tag.
144      * @param tag The single tag to register in the otherwise empty factory.
145      */

146     public PrototypicalNodeFactory (Tag tag)
147     {
148         this (true);
149         registerTag (tag);
150     }
151
152     /**
153      * Create a new factory with the given tags registered.
154      * @param tags The tags to register in the otherwise empty factory.
155      */

156     public PrototypicalNodeFactory (Tag[] tags)
157     {
158         this (true);
159         for (int i = 0; i < tags.length; i++)
160             registerTag (tags[i]);
161     }
162
163     /**
164      * Adds a tag to the registry.
165      * @param id The name under which to register the tag.
166      * @param tag The tag to be returned from a {@link #createTagNode} call.
167      * @return The tag previously registered with that id if any,
168      * or <code>null</code> if none.
169      */

170     public Tag put (String JavaDoc id, Tag tag)
171     {
172         return ((Tag)mBlastocyst.put (id, tag));
173     }
174
175     /**
176      * Gets a tag from the registry.
177      * @param id The name of the tag to return.
178      * @return The tag registered under the <code>id</code> name or <code>null</code> if none.
179      */

180     public Tag get (String JavaDoc id)
181     {
182         return ((Tag)mBlastocyst.get (id));
183     }
184
185     /**
186      * Remove a tag from the registry.
187      * @param id The name of the tag to remove.
188      * @return The tag that was registered with that <code>id</code>.
189      */

190     public Tag remove (String JavaDoc id)
191     {
192         return ((Tag)mBlastocyst.remove (id));
193     }
194
195     /**
196      * Clean out the registry.
197      */

198     public void clear ()
199     {
200         mBlastocyst = new Hashtable JavaDoc ();
201     }
202
203     /**
204      * Get the list of tag names.
205      * @return The names of the tags currently registered.
206      */

207     public Set JavaDoc getTagNames ()
208     {
209         return (mBlastocyst.keySet ());
210     }
211
212     /**
213      * Register a tag.
214      * Registers the given tag under every id the tag has.
215      * @param tag The tag to register (subclass of
216      * {@link Tag}).
217      */

218     public void registerTag (Tag tag)
219     {
220         String JavaDoc ids[];
221         
222         ids = tag.getIds ();
223         for (int i = 0; i < ids.length; i++)
224             put (ids[i], tag);
225     }
226
227     /**
228      * Unregister a tag.
229      * Unregisters the given tag from every id the tag has.
230      * @param tag The tag to unregister (subclass of
231      * {@link Tag}).
232      */

233     public void unregisterTag (Tag tag)
234     {
235         String JavaDoc ids[];
236         
237         ids = tag.getIds ();
238         for (int i = 0; i < ids.length; i++)
239             remove (ids[i]);
240     }
241
242     /**
243      * Register all known tags in the tag package.
244      * Registers tags from the {@link org.htmlparser.tags tag package} by
245      * calling {@link #registerTag(Tag) registerTag()}.
246      * @return 'this' nodefactory as a convenience.
247      */

248     public PrototypicalNodeFactory registerTags ()
249     {
250         registerTag (new AppletTag ());
251         registerTag (new BaseHrefTag ());
252         registerTag (new Bullet ());
253         registerTag (new BulletList ());
254         registerTag (new DoctypeTag ());
255         registerTag (new FormTag ());
256         registerTag (new FrameSetTag ());
257         registerTag (new FrameTag ());
258         registerTag (new ImageTag ());
259         registerTag (new InputTag ());
260         registerTag (new JspTag ());
261         registerTag (new LabelTag ());
262         registerTag (new LinkTag ());
263         registerTag (new MetaTag ());
264         registerTag (new ObjectTag ());
265         registerTag (new OptionTag ());
266         registerTag (new ScriptTag ());
267         registerTag (new SelectTag ());
268         registerTag (new StyleTag ());
269         registerTag (new TableColumn ());
270         registerTag (new TableHeader ());
271         registerTag (new TableRow ());
272         registerTag (new TableTag ());
273         registerTag (new TextareaTag ());
274         registerTag (new TitleTag ());
275         registerTag (new Div ());
276         registerTag (new Span ());
277         registerTag (new BodyTag ());
278         registerTag (new HeadTag ());
279         registerTag (new Html ());
280         
281         return (this);
282     }
283
284     /**
285      * Get the object being used to generate text nodes.
286      * @return The prototype for {@link Text} nodes.
287      */

288     public Text getTextPrototype ()
289     {
290         return (mText);
291     }
292
293     /**
294      * Set the object to be used to generate text nodes.
295      * @param text The prototype for {@link Text} nodes.
296      */

297     public void setTextPrototype (Text text)
298     {
299         if (null == text)
300             throw new IllegalArgumentException JavaDoc ("text prototype node cannot be null");
301         else
302             mText = text;
303     }
304
305     /**
306      * Get the object being used to generate remark nodes.
307      * @return The prototype for {@link Remark} nodes.
308      */

309     public Remark getRemarkPrototype ()
310     {
311         return (mRemark);
312     }
313
314     /**
315      * Set the object to be used to generate remark nodes.
316      * @param remark The prototype for {@link Remark} nodes.
317      */

318     public void setRemarkPrototype (Remark remark)
319     {
320         if (null == remark)
321             throw new IllegalArgumentException JavaDoc ("remark prototype node cannot be null");
322         else
323             mRemark = remark;
324     }
325
326     /**
327      * Get the object being used to generate generic tag nodes.
328      * These are returned from {@link #createTagNode} when no specific tag
329      * is found in the registered tag list.
330      * @return The prototype for {@link Tag} nodes.
331      */

332     public Tag getTagPrototype ()
333     {
334         return (mTag);
335     }
336
337     /**
338      * Set the object to be used to generate tag nodes.
339      * These are returned from {@link #createTagNode} when no specific tag
340      * is found in the registered tag list.
341      * @param tag The prototype for {@link Tag} nodes.
342      */

343     public void setTagPrototype (Tag tag)
344     {
345         if (null == tag)
346             throw new IllegalArgumentException JavaDoc ("tag prototype node cannot be null");
347         else
348             mTag = tag;
349     }
350
351     //
352
// NodeFactory interface
353
//
354

355     /**
356      * Create a new string node.
357      * @param page The page the node is on.
358      * @param start The beginning position of the string.
359      * @param end The ending position of the string.
360      */

361     public Text createStringNode (Page page, int start, int end)
362     {
363         Text ret;
364
365         try
366         {
367             ret = (Text)(getTextPrototype ().clone ());
368             ret.setPage (page);
369             ret.setStartPosition (start);
370             ret.setEndPosition (end);
371         }
372         catch (CloneNotSupportedException JavaDoc cnse)
373         {
374             ret = new TextNode (page, start, end);
375         }
376
377         return (ret);
378     }
379
380     /**
381      * Create a new remark node.
382      * @param page The page the node is on.
383      * @param start The beginning position of the remark.
384      * @param end The ending positiong of the remark.
385      */

386     public Remark createRemarkNode (Page page, int start, int end)
387     {
388         Remark ret;
389         
390         try
391         {
392             ret = (Remark)(getRemarkPrototype ().clone ());
393             ret.setPage (page);
394             ret.setStartPosition (start);
395             ret.setEndPosition (end);
396         }
397         catch (CloneNotSupportedException JavaDoc cnse)
398         {
399             ret = new RemarkNode (page, start, end);
400         }
401
402         return (ret);
403     }
404
405     /**
406      * Create a new tag node.
407      * Note that the attributes vector contains at least one element,
408      * which is the tag name (standalone attribute) at position zero.
409      * This can be used to decide which type of node to create, or
410      * gate other processing that may be appropriate.
411      * @param page The page the node is on.
412      * @param start The beginning position of the tag.
413      * @param end The ending positiong of the tag.
414      * @param attributes The attributes contained in this tag.
415      */

416     public Tag createTagNode (Page page, int start, int end, Vector JavaDoc attributes)
417         throws
418             ParserException
419     {
420         Attribute attribute;
421         String JavaDoc id;
422         Tag prototype;
423         Tag ret;
424
425         ret = null;
426
427         if (0 != attributes.size ())
428         {
429             attribute = (Attribute)attributes.elementAt (0);
430             id = attribute.getName ();
431             if (null != id)
432             {
433                 try
434                 {
435                     id = id.toUpperCase (Locale.ENGLISH);
436                     if (!id.startsWith ("/"))
437                     {
438                         if (id.endsWith ("/"))
439                             id = id.substring (0, id.length () - 1);
440                         prototype = (Tag)mBlastocyst.get (id);
441                         if (null != prototype)
442                         {
443                             ret = (Tag)prototype.clone ();
444                             ret.setPage (page);
445                             ret.setStartPosition (start);
446                             ret.setEndPosition (end);
447                             ret.setAttributesEx (attributes);
448                         }
449                     }
450                 }
451                 catch (CloneNotSupportedException JavaDoc cnse)
452                 {
453                     // default to creating a new one
454
}
455             }
456         }
457         if (null == ret)
458         { // generate a generic node
459
try
460             {
461                 ret = (Tag)getTagPrototype ().clone ();
462                 ret.setPage (page);
463                 ret.setStartPosition (start);
464                 ret.setEndPosition (end);
465                 ret.setAttributesEx (attributes);
466             }
467             catch (CloneNotSupportedException JavaDoc cnse)
468             {
469                 ret = new TagNode (page, start, end, attributes);
470             }
471         }
472
473         return (ret);
474     }
475 }
476
Popular Tags