KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > au > id > jericho > lib > html > Cache


1 // Jericho HTML Parser - Java based library for analysing and manipulating HTML
2
// Version 2.2
3
// Copyright (C) 2006 Martin Jericho
4
// http://sourceforge.net/projects/jerichohtml/
5
//
6
// This library is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU Lesser General Public
8
// License as published by the Free Software Foundation; either
9
// version 2.1 of the License, or (at your option) any later version.
10
// http://www.gnu.org/copyleft/lesser.html
11
//
12
// This library is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
// Lesser General Public License for more details.
16
//
17
// You should have received a copy of the GNU Lesser General Public
18
// License along with this library; if not, write to the Free Software
19
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20

21 package au.id.jericho.lib.html;
22
23 import java.util.*;
24
25 /**
26  * Represents a cached map of character positions to tags.
27  * The allTagTypesSubCache object is used to cache all tags.
28  * Additional subcaches are used to cache single tag types, which increases the performance when searching for those tag types.
29  * A list of tag types to be cached separately is specified in the SeparatelyCachedTagTypes property.
30  * The standard implementation caches only COMMENT tag types separately, as these tag types are searched extensively
31  * in the process of ensuring that every non-server tag is not located inside a comment.
32  */

33 final class Cache {
34     public final Source source;
35     private final SubCache allTagTypesSubCache;
36     private final SubCache[] subCaches; // contains allTagTypesSubCache plus a SubCache object for each separately cached tag type
37

38     public Cache(final Source source) {
39         this.source=source;
40         allTagTypesSubCache=new SubCache(this,null);
41         TagType[] separatelyCachedTagTypes=getSeparatelyCachedTagTypes();
42         subCaches=new SubCache[separatelyCachedTagTypes.length+1];
43         subCaches[0]=allTagTypesSubCache;
44         for (int i=0; i<separatelyCachedTagTypes.length; i++)
45             subCaches[i+1]=new SubCache(this,separatelyCachedTagTypes[i]);
46     }
47
48     public void clear() {
49         for (int i=0; i<subCaches.length; i++) subCaches[i].clear();
50     }
51
52     public Tag getTagAt(final int pos) {
53         return source.useAllTypesCache
54             ? allTagTypesSubCache.getTagAt(pos)
55             : Tag.getTagAtUncached(source,pos);
56     }
57
58     public Tag findPreviousOrNextTag(final int pos, final boolean previous) {
59         // returns null if pos is out of range.
60
return allTagTypesSubCache.findPreviousOrNextTag(pos,previous);
61     }
62
63     public Tag findPreviousOrNextTag(final int pos, final TagType tagType, final boolean previous) {
64         // returns null if pos is out of range.
65
for (int i=source.useAllTypesCache ? 0 : 1; i<subCaches.length; i++)
66             if (tagType==subCaches[i].tagType) return subCaches[i].findPreviousOrNextTag(pos,previous);
67         return Tag.findPreviousOrNextTagUncached(source,pos,tagType,previous,ParseText.NO_BREAK);
68     }
69
70     public Tag addTagAt(final int pos) {
71         final Tag tag=Tag.getTagAtUncached(source,pos);
72         allTagTypesSubCache.addTagAt(pos,tag);
73         if (tag==null) return tag;
74         final TagType tagType=tag.getTagType();
75         for (int i=1; i<subCaches.length; i++) {
76             if (tagType==subCaches[i].tagType) {
77                 subCaches[i].addTagAt(pos,tag);
78                 return tag;
79             }
80         }
81         return tag;
82     }
83
84     public int getTagCount() {
85         return allTagTypesSubCache.size()-2;
86     }
87
88     public Iterator getTagIterator() {
89         return allTagTypesSubCache.getTagIterator();
90     }
91
92     public void loadAllTags(final List tags, final Tag[] allRegisteredTags, final StartTag[] allRegisteredStartTags) {
93         // assumes the tags list implements RandomAccess
94
final int tagCount=tags.size();
95         allTagTypesSubCache.bulkLoad_Init(tagCount);
96         int registeredTagIndex=0;
97         int registeredStartTagIndex=0;
98         for (int i=0; i<tagCount; i++) {
99             Tag tag=(Tag)tags.get(i);
100             if (!tag.isUnregistered()) {
101                 allRegisteredTags[registeredTagIndex++]=tag;
102                 if (tag instanceof StartTag) allRegisteredStartTags[registeredStartTagIndex++]=(StartTag)tag;
103             }
104             allTagTypesSubCache.bulkLoad_Set(i,tag);
105             for (int x=1; x<subCaches.length; x++) {
106                 if (tag.getTagType()==subCaches[x].tagType) {
107                     subCaches[x].bulkLoad_AddToTypeSpecificCache(tag);
108                     break;
109                 }
110             }
111         }
112         for (int x=1; x<subCaches.length; x++)
113             subCaches[x].bulkLoad_FinaliseTypeSpecificCache();
114     }
115
116     public String JavaDoc toString() {
117         StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
118         for (int i=0; i<subCaches.length; i++) subCaches[i].appendTo(sb);
119         return sb.toString();
120     }
121
122     protected int getSourceLength() {
123         return source.end;
124     }
125     
126     private static TagType[] getSeparatelyCachedTagTypes() {
127         return TagType.getTagTypesIgnoringEnclosedMarkup();
128     }
129 }
130
Popular Tags