Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/hexidec/ekit/component/ExtendedHTMLEditorKit.java


1   /*
2   GNU Lesser General Public License
3   
4   ExtendedHTMLEditorKit
5   Copyright (C) 2001-2002  Frits Jalvingh & Howard A Kistler
6   
7   This library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public
9   License as published by the Free Software Foundation; either
10  version 2.1 of the License, or (at your option) any later version.
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  
22  package com.hexidec.ekit.component;
23  
24  import javax.swing.text.*;
25  import java.io.*;
26  import javax.swing.text.Element;
27  import javax.swing.text.StyleConstants;
28  import javax.swing.text.View;
29  import javax.swing.text.ViewFactory;
30  import javax.swing.text.html.HTMLEditorKit;
31  import javax.swing.text.html.*;
32  
33  /**
34    * This class extends HTMLEditorKit so that it can provide other renderer classes
35    * instead of the defaults. Most important is the part which renders relative
36    * image paths.
37    *
38    * @author <a href="mailto:jal@grimor.com">Frits Jalvingh</a>
39    * @version 1.0
40    */
41  
42  public class ExtendedHTMLEditorKit extends HTMLEditorKit
43  {
44      
45      
46           // --- variables ------------------------------------------
47          
48  
49          private static Parser defaultParser = null;
50      
51    /** Constructor
52      */
53    public ExtendedHTMLEditorKit()
54    {
55    }
56          
57        
58          
59          public HTMLEditorKit.Parser getParser(){
60              if (defaultParser == null) {
61                  try {
62                      Class c = Class.forName("com.hexidec.ekit.component.parser.ParserDelegator");
63                      defaultParser = (Parser) c.newInstance();
64                  } catch (Throwable e) {
65                      System.out.println("Error:"+e);
66                  }
67              }
68           
69              return defaultParser;
70          }
71    
72          
73    /** Method for returning a ViewFactory which handles the image rendering.
74      */
75    public ViewFactory getViewFactory()
76    {
77      return new HTMLFactoryExtended();
78    }
79  
80          
81          public Document createDefaultDocument() {
82              StyleSheet styles = getStyleSheet();
83              StyleSheet ss = new StyleSheet();
84  
85              ss.addStyleSheet(styles);
86  
87              // New Reader..
88              HTMLDocument doc = new ExtendedHTMLDocument(ss);
89              doc.setParser(getParser());
90              doc.setAsynchronousLoadPriority(4);
91              doc.setTokenThreshold(100);
92              return doc;
93          }
94          
95          
96  
97          /**
98           * Inserts content from the given stream. If <code>doc</code> is
99           * an instance of HTMLDocument, this will read
100          * HTML 3.2 text. Inserting HTML into a non-empty document must be inside
101          * the body Element, if you do not insert into the body an exception will
102          * be thrown. When inserting into a non-empty document all tags outside
103          * of the body (head, title) will be dropped.
104          *
105          * @param in  the stream to read from
106          * @param doc the destination for the insertion
107          * @param pos the location in the document to place the
108          *   content
109          * @exception IOException on any I/O error
110          * @exception BadLocationException if pos represents an invalid
111          *   location within the document
112          * @exception RuntimeException (will eventually be a BadLocationException)
113          *            if pos is invalid
114          */
115         public void read(Reader in, Document doc, int pos) throws IOException, BadLocationException {
116             
117             if (doc instanceof HTMLDocument) {
118                 HTMLDocument hdoc = (HTMLDocument) doc;
119                 Parser p = getParser();
120                 if (p == null) {
121                     throw new IOException("Can't load parser");
122                 }
123                 if (pos > doc.getLength()) {
124                     throw new BadLocationException("Invalid location", pos);
125                 }
126                 
127                 ParserCallback receiver = hdoc.getReader(pos);
128                 Boolean ignoreCharset = (Boolean)doc.getProperty("IgnoreCharsetDirective");
129                 p.parse(in, receiver, (ignoreCharset == null) ? false : ignoreCharset.booleanValue());
130                 receiver.flush();
131             } else {
132                 super.read(in, doc, pos);
133             }
134         }
135         
136         /**
137          * Inserts HTML into an existing document.
138          *
139          * @param doc       the document to insert into
140          * @param offset    the offset to insert HTML at
141          * @param popDepth  the number of ElementSpec.EndTagTypes to generate before
142          *        inserting
143          * @param pushDepth the number of ElementSpec.StartTagTypes with a direction
144          *        of ElementSpec.JoinNextDirection that should be generated
145          *        before inserting, but after the end tags have been generated
146          * @param insertTag the first tag to start inserting into document
147          * @exception RuntimeException (will eventually be a BadLocationException)
148          *            if pos is invalid
149          */
150     /**    public void insertHTML(HTMLDocument doc, int offset, String html,
151         int popDepth, int pushDepth,
152         HTML.Tag insertTag) throws
153         BadLocationException, IOException {
154             Parser p = getParser();
155             if (p == null) {
156                 throw new IOException("Can't load parser");
157             }
158             if (offset > doc.getLength()) {
159                 throw new BadLocationException("Invalid location", offset);
160             }
161             
162             ParserCallback receiver = doc.getReader(offset, popDepth, pushDepth,
163             insertTag);
164             Boolean ignoreCharset = (Boolean)doc.getProperty
165             ("IgnoreCharsetDirective");
166             p.parse(new StringReader(html), receiver, (ignoreCharset == null) ?
167             false : ignoreCharset.booleanValue());
168             receiver.flush();
169         }
170         
171         /**
172          * Write content from a document to the given stream
173          * in a format appropriate for this kind of content handler.
174          *
175          * @param out  the stream to write to
176          * @param doc  the source for the write
177          * @param pos  the location in the document to fetch the
178          *   content
179          * @param len  the amount to write out
180          * @exception IOException on any I/O error
181          * @exception BadLocationException if pos represents an invalid
182          *   location within the document
183          */
184        
185         
186         public void write(Writer out, Document doc, int pos, int len)
187         throws IOException, BadLocationException {
188             
189             if (doc instanceof HTMLDocument) {
190                 ExtendedHTMLWriter w = new ExtendedHTMLWriter(out, (HTMLDocument)doc, pos, len);
191                 w.write();
192             } else if (doc instanceof StyledDocument) {
193                 MinimalHTMLWriter w = new MinimalHTMLWriter(out, (StyledDocument)doc, pos, len);
194                 w.write();
195             } else {
196                 super.write(out, doc, pos, len);
197             }
198         }
199         
200         
201  
202         /**
203          * Copies the key/values in <code>element</code>s AttributeSet into
204          * <code>set</code>. This does not copy component, icon, or element
205          * names attributes. Subclasses may wish to refine what is and what
206          * isn't copied here. But be sure to first remove all the attributes that
207          * are in <code>set</code>.<p>
208          * This is called anytime the caret moves over a different location.
209          *
210          */
211         public void createInputAttributes(Element element,
212         MutableAttributeSet set) {
213             
214             set.removeAttributes(set);
215             set.addAttributes(element.getAttributes());
216             set.removeAttribute(StyleConstants.ComposedTextAttribute);
217             
218             Object o = set.getAttribute(StyleConstants.NameAttribute);
219             if (o instanceof HTML.Tag) {
220                 HTML.Tag tag = (HTML.Tag)o;
221                 // PENDING: we need a better way to express what shouldn't be
222                 // copied when editing...
223                 if(tag == HTML.Tag.IMG) {
224                     // Remove the related image attributes, src, width, height
225                     set.removeAttribute(HTML.Attribute.SRC);
226                     set.removeAttribute(HTML.Attribute.HEIGHT);
227                     set.removeAttribute(HTML.Attribute.WIDTH);
228                     set.addAttribute(StyleConstants.NameAttribute,
229                     HTML.Tag.CONTENT);
230                 }
231                 else if (tag == HTML.Tag.HR || tag == HTML.Tag.BR) {
232                     // Don't copy HRs or BRs either.
233                     set.addAttribute(StyleConstants.NameAttribute,
234                     HTML.Tag.CONTENT);
235                 }
236                 else if (tag == HTML.Tag.COMMENT) {
237                     // Don't copy COMMENTs either
238                     set.addAttribute(StyleConstants.NameAttribute,
239                     HTML.Tag.CONTENT);
240                     set.removeAttribute(HTML.Attribute.COMMENT);
241                 }
242                 else if (tag == HTML.Tag.INPUT) {
243                     // or INPUT either
244                     set.addAttribute(StyleConstants.NameAttribute,
245                     HTML.Tag.CONTENT);
246                     set.removeAttribute(HTML.Tag.INPUT);
247                 }
248                 else if (tag instanceof HTML.UnknownTag) {
249                     // Don't copy unknowns either:(
250                     set.addAttribute(StyleConstants.NameAttribute,
251                     HTML.Tag.CONTENT);
252                     set.removeAttribute(HTML.Attribute.ENDTAG);
253                 }
254             }
255         }
256         
257         
258         /**
259          * Creates a copy of the editor kit.
260          *
261          * @return the copy
262          */
263         public Object clone() {
264             ExtendedHTMLEditorKit o = (ExtendedHTMLEditorKit)super.clone();
265             return o;
266         }
267         
268         
269        
270 
271         /**
272          * Interface to be supported by the parser.  This enables
273          * providing a different parser while reusing some of the
274          * implementation provided by this editor kit.
275          */
276         
277        
278        /* public class Parser {
279             
280             /**
281              * Parse the given stream and drive the given callback
282              * with the results of the parse.  This method should
283              * be implemented to be thread-safe.*/
284              /**
285             public void parse(Reader r, ParserCallback cb, boolean ignoreCharSet) throws IOException;
286             
287         }
288         
289         */
290          
291     
292 
293 
294         
295         
296         
297         
298         
299         
300         
301         
302 /* Inner Classes --------------------------------------------- */
303 
304   /** Class that replaces the default ViewFactory and supports
305     * the proper rendering of both URL-based and local images.
306     */
307   public static class HTMLFactoryExtended extends HTMLFactory implements ViewFactory
308   {
309     /** Constructor
310       */
311     public HTMLFactoryExtended()
312     {
313     }
314 
315     /** Method to handle IMG tags and
316       * invoke the image loader.
317       */
318     public View create(Element elem)
319     {
320       Object obj = elem.getAttributes().getAttribute(StyleConstants.NameAttribute);
321       if(obj instanceof HTML.Tag)
322       {
323         HTML.Tag tagType = (HTML.Tag)obj;
324         if(tagType == HTML.Tag.IMG)
325         {
326           return new RelativeImageView(elem);
327         }
328       }
329       return super.create(elem);
330     }
331   }
332                 
333 }