1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 package org.openoffice.netbeans.editor;
24 
25 import java.io.*;
26 import java.awt.event.KeyEvent;
27 import java.awt.event.InputEvent;
28 import java.awt.event.ActionEvent;
29 import java.net.URL;
30 import java.text.MessageFormat;
31 
32 import java.util.Map;
33 import java.util.List;
34 import java.util.ResourceBundle;
35 import java.util.MissingResourceException;
36 import javax.swing.KeyStroke;
37 import javax.swing.JEditorPane;
38 import javax.swing.JMenuItem;
39 import javax.swing.Action;
40 import javax.swing.text.Document;
41 import javax.swing.text.JTextComponent;
42 import javax.swing.text.TextAction;
43 import javax.swing.text.BadLocationException;
44 import org.netbeans.editor.*;
45 import org.netbeans.editor.ext.*;
46 import org.netbeans.editor.ext.java.*;
47 
48 /**
49 * Java editor kit with appropriate document
50 *
51 * @author Miloslav Metelka
52 * @version 1.00
53 */
54 
55 /* This class is based on the JavaKit class in the demosrc directory of
56  * the editor module of the NetBeans project: http://www.netbeans.org
57  *
58  * The class sets up an EditorKit for syntax highlighting and code completion
59  * of Java syntax
60  */
61 
62 public class JavaKit extends ExtKit {
63 
64     public static final String JAVA_MIME_TYPE = "text/x-java"; // NOI18N
65 
66     static final long serialVersionUID =-5445829962533684922L;
67 
68     static {
Settings.addInitializer( new JavaSettingsInitializer( JavaKit.class ) )69         Settings.addInitializer( new JavaSettingsInitializer( JavaKit.class ) );
Settings.reset()70         Settings.reset();
71 
72         URL skeleton = null, body = null;
73         skeleton = JavaKit.class.getResource("OOo.jcs");
74         body     = JavaKit.class.getResource("OOo.jcb");
75 
76         if (skeleton != null && body != null) {
77             DAFileProvider provider = new DAFileProvider(
78                 new URLAccessor(skeleton),
79                 new URLAccessor(body));
80 
81             JCBaseFinder finder = new JCBaseFinder();
82             finder.append( provider );
83             JavaCompletion.setFinder( finder );
84         }
85     }
86 
getContentType()87     public String getContentType() {
88         return JAVA_MIME_TYPE;
89     }
90 
91     /** Create new instance of syntax coloring scanner
92     * @param doc document to operate on. It can be null in the cases the syntax
93     *   creation is not related to the particular document
94     */
createSyntax(Document doc)95     public Syntax createSyntax(Document doc) {
96         return new JavaSyntax();
97     }
98 
99     /** Create syntax support */
createSyntaxSupport(BaseDocument doc)100     public SyntaxSupport createSyntaxSupport(BaseDocument doc) {
101         return new JavaSyntaxSupport(doc);
102     }
103 
createCompletion(ExtEditorUI extEditorUI)104     public Completion createCompletion(ExtEditorUI extEditorUI) {
105         return new JavaCompletion(extEditorUI);
106     }
107 
108     /** Create the formatter appropriate for this kit */
createFormatter()109     public Formatter createFormatter() {
110         return new JavaFormatter(this.getClass());
111     }
112 
createEditorUI()113     protected EditorUI createEditorUI() {
114         return new ExtEditorUI();
115     }
116 
initDocument(BaseDocument doc)117     protected void initDocument(BaseDocument doc) {
118         doc.addLayer(new JavaDrawLayerFactory.JavaLayer(),
119                 JavaDrawLayerFactory.JAVA_LAYER_VISIBILITY);
120         doc.addDocumentListener(new JavaDrawLayerFactory.LParenWatcher());
121     }
122 
123     /**
124      *   DataAccessor for parser DB files via URL streams
125      *
126      *   @author  Petr Nejedly
127      */
128     public static class URLAccessor implements DataAccessor {
129 
130         URL url;
131         InputStream stream;
132         int streamOff;
133         int actOff;
134 
URLAccessor(URL url)135         public URLAccessor(URL url) {
136             this.url = url;
137         }
138 
139         /** Not implemented
140          */
append(byte[] buffer, int off, int len)141         public void append(byte[] buffer, int off, int len)
142             throws IOException
143         {
144             throw new IllegalArgumentException("read only!");
145         }
146 
147         /**
148          * Reads exactly <code>len</code> bytes from this file resource
149          * into the byte array, starting at the current file pointer.
150          * This method reads repeatedly from the file until the requested
151          * number of bytes are read. This method blocks until the requested
152          * number of bytes are read, the end of the inputStream is detected,
153          * or an exception is thrown.
154          *
155          * @param      buffer     the buffer into which the data is read.
156          * @param      off        the start offset of the data.
157          * @param      len        the number of bytes to read.
158          */
read(byte[] buffer, int off, int len)159         public void read(byte[] buffer, int off, int len) throws IOException {
160             InputStream str = getStream(actOff);
161             while (len > 0) {
162                 int count = str.read(buffer, off, len);
163                 streamOff += count;
164                 off += count;
165                 len -= count;
166             }
167         }
168 
169         /** Opens DataAccessor file resource
170          *  @param requestWrite if true, file is opened for read/write
171          */
open(boolean requestWrite)172         public void open(boolean requestWrite) throws IOException {
173             if(requestWrite)
174                 throw new IllegalArgumentException("read only!");
175         }
176 
177         /** Closes DataAccessor file resource  */
close()178         public void close() throws IOException {
179             if (stream != null) {
180                 stream.close();
181                 stream = null;
182             }
183         }
184 
185         /**
186          * Returns the current offset in this file.
187          *
188          * @return     the offset from the beginning of the file, in bytes,
189          *             at which the next read or write occurs.
190          */
getFilePointer()191         public long getFilePointer() throws IOException {
192            return actOff;
193         }
194 
195         /** Clears the file and sets the offset to 0 */
resetFile()196         public void resetFile() throws IOException {
197             throw new IllegalArgumentException("read only!");
198         }
199 
200         /**
201          * Sets the file-pointer offset, measured from the beginning of this
202          * file, at which the next read or write occurs.
203          */
seek(long pos)204         public void seek(long pos) throws IOException {
205             actOff = (int)pos;
206         }
207 
208         /** Gets InputStream prepared for reading from <code>off</code>
209          *  offset position
210          */
getStream(int off)211         private InputStream getStream(int off) throws IOException {
212             if (streamOff > off && stream != null) {
213                 stream.close();
214                 stream = null;
215             }
216 
217             if(stream == null) {
218                 stream = url.openStream();
219                 streamOff = 0;
220             }
221 
222             while (streamOff < off) {
223                 long len = stream.skip(off - streamOff);
224                 streamOff += (int)len;
225                 if (len == 0) throw new IOException("EOF");
226             }
227 
228             return stream;
229         }
230 
getFileLength()231         public int getFileLength() {
232             try {
233                 int l =  url.openConnection().getContentLength();
234                 return l;
235             } catch (IOException e) {
236                 return 0;
237             }
238         }
239 
toString()240         public String toString() {
241             return url.toString();
242         }
243     }
244 }
245