alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.java;

import javax.swing.text.Document;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataObject;
import org.openide.loaders.ExtensionList;
import org.openide.text.IndentEngine;
import org.netbeans.modules.java.JavaEditor.GuardedReader;
import java.util.ResourceBundle;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Iterator;
import java.util.LinkedList;
import org.openide.cookies.SaveCookie;
import org.openide.ErrorManager;

import org.openide.text.NbDocument;
import org.openide.text.PositionRef;
import org.netbeans.modules.java.settings.JavaSettings;
import java.io.*;
import org.openide.util.SharedClassObject;
import java.lang.ref.WeakReference;
import java.lang.ref.ReferenceQueue;
import org.netbeans.modules.javacore.internalapi.JavaMetamodel;

import org.openide.src.SourceException;
import org.openide.util.NbBundle;

/** Miscellaneous utilities for Java data loader.
*
* @author Petr Hamernik, Ales Novak
*/
public final class Util extends Object {
    // ===================== i18n utilities ===========================

    /**
     * Instance of error manager used for annotating exceptions.
     */
    private static ErrorManager errorManager;
    
    static final String ATTR_FILE_ENCODING = "Content-Encoding"; // NOI18N

    /** Computes the localized string for the key.
    * @param key The key of the string.
    * @return the localized string.
    */
    static String getString(String key) {
        return NbBundle.getMessage(Util.class, key);
    }
    
    static ErrorManager getErrorManager() {
        if (errorManager != null)
            return errorManager;
        ErrorManager main = ErrorManager.getDefault();
        if (main == null) {
            System.err.println("WARNING: can't lookup error manager"); // NOI18N
            return null;
        }
        return errorManager = main;
    }
    
    static void annotateThrowable(Throwable t, Throwable nested) {
        getErrorManager().annotate(t, nested);
    }
    
    static void annotateThrowable(Throwable t, String localizedMessage, 
        boolean user) {
        if (user) {
            getErrorManager().annotate(t, ErrorManager.USER, null,
                localizedMessage, null, null);
        } else {
            getErrorManager().annotate(t, ErrorManager.EXCEPTION, null,
                localizedMessage, null, null);
        }
    }

    // ===================== loader utilities ===========================

    static FileObject findBrother(FileObject f, String extension) {
        return FileUtil.findBrother(f, extension);
    }

    private static FileObject findSibling(FileObject base, String name, Enumeration extlist) {
        FileObject ret;
        while (extlist.hasMoreElements()) {
            String ext = (String)extlist.nextElement();
            if (ext == null)
                continue;
            ret = base.getFileObject(name, ext);
            if (ret != null)
                return ret;
        }
        return null;
    }

    /** Notifies about an exception
    *
    * @param msg is ignored
    */
    private static void notifyException(Throwable t, String msg) {
        getErrorManager().notify(t);
    }


    // ===================== Indentation util ==============================

    /** Finds the appropriate indentation writer for the java sources.
    * @param doc The document where it will be inserted in
    * @param offset The position in the document
    * @param writer The encapsulated writer
    */
    static Writer findIndentWriter(Document doc, int offset, Writer writer) {
        IndentEngine engine = IndentEngine.find(doc); // NOI18N
        return engine.createWriter(doc, offset, writer);
    }

    // ===================== Advanced Task suppport =========================

    /** Invokes the runnable using NbDocument.runAtomic.
    * If BadLocationException occured inside, it will be thrown
    * the new SourceException.
    *
    */
    static void runAtomic(StyledDocument doc, ExceptionRunnable run) throws SourceException {
        RunnableSupport support = new RunnableSupport(run);
        NbDocument.runAtomic(doc, support);
        support.throwException();
    }
    
    /** This interface is used like runnable, but its method run
    * could throw BadLocationException.
    * @exception
    */
    interface ExceptionRunnable {
        public void run() throws Exception;
    }

    /** Encapsulation class for the ExceptionRunnable interface.
    * It implements Runnable, so it can be used everywhere is Runnable
    * accepted.
    */
    private static class RunnableSupport implements Runnable {
        /** Exception which occured in the e*/
        private Exception e;

        /** Encapsulated runnable */
        private ExceptionRunnable runnable;

        /** Creates new class */
        public RunnableSupport(ExceptionRunnable runnable) {
            this.runnable = runnable;
            e = null;
        }

        /** @return true if exception occured. */
        public boolean hasException() {
            return e != null;
        }

        /** @return the exception or null if no exception has occured. */
        public Exception getException() {
            return e;
        }

        /** If a bad position exception occured during running
        * the given ExceptionRunnable, it will be thrown new SourceException
        * with the same message. Otherwise throws nothing.
        */
        public void throwException() throws SourceException {
            if (e != null) {
                if (e instanceof SourceException) {
                    // already in the correct format
                    throw (SourceException)e;
                }
                
                SourceException wrapper = new SourceException(e.getMessage());
                // special translation for BadLocationException:
                if (e instanceof BadLocationException) {
                    // provide unified message about attempt to modify a guarded block:
                    ErrorManager.getDefault().annotate(
                        wrapper, ErrorManager.USER,
                        e.getMessage(),
                        e.getLocalizedMessage(),
                        e, null
                    );
                } else {
                    ErrorManager.getDefault().annotate(
                        wrapper, e
                    );
                }
                throw wrapper;
            }
        }

        /** Implementation of the Runnable interface. It calls the encapsulated
        * runnable passed in the constructor and catch the exceptions.
        */
        public void run() {
            try {
                runnable.run();
            }
            catch (Exception e) {
                this.e = e;
            }
        }
    }
    
    /**
     * Retrieves file's encoding. If the file does not specify any encoding,
     * null is returned. Note: an empty string is also a legal value, which also
     * means platform-default encoding.
     * @deprecated Disclaimer: this method is not an API method. It may not
     * be available in future releases.
     * @param someFile file object to retrieve encoding for
     * @return encoding string, or null if no explicit encoding is given.
     */
    public static String getFileEncoding0(FileObject someFile) {
        return (String)someFile.getAttribute(ATTR_FILE_ENCODING);
    }
    
    /**
     * Retrieves file's encoding. Returns the default encoding for java files,
     * if the file's specific encoding is not set.
     * @deprecated Disclaimer: this method is not an API method. It may not
     * be available in future releases.
     * @param someFile file object to retrieve encoding for
     * @return encoding string, or null if no explicit encoding is given in file's
     * or IDE's settings.
     */
    public static String getFileEncoding(FileObject someFile) {
        String enc = getFileEncoding0(someFile);
        if (enc == null) {
            enc = JavaSettings.getDefault().getDefaultEncoding();
        }
        if ("".equals(enc))
            return null;
        else
            return enc;
    }
    
    /**
     * Retrieves file's encoding. Returns the default encoding for java files,
     * if the file's specific encoding is not set.
     * This implementation stores the encoding information into file's extended
     * attributes (so it won't work on JARs).
     * @deprecated Disclaimer: this method is not an API method. It may not
     * be available in future releases.
     * @param someFile file object to set encoding for
     * @param enc encoding string. Null means revert to the default encoding.
     */
    public static void setFileEncoding(FileObject someFile, String enc) throws IOException {
        someFile.setAttribute(ATTR_FILE_ENCODING, enc);
    }
    
    static void throwException(String desc, String bundleKey) throws SourceException {
	throw (SourceException)getErrorManager().annotate(
	    new SourceException(desc),
	    getString(bundleKey)
	);
    }
    
    static SourceException wrapException(Exception ex) {
	SourceException x = new SourceException("Exception wrapper"); // NOI18N
	annotateThrowable(x, ex);
	return x;
    }

    public static char[] readContents(Reader r) throws IOException {
        int read = 0;
        int total = 0;
        int offset;
        char[] buffer;
        List buflist = new LinkedList();

        do {
            buffer = new char[2048];
            offset = 0;
            while (offset < buffer.length) {
                read = r.read(buffer, offset, buffer.length - offset);
                if (read == -1) break;
                offset += read;
            }
            if (offset > 0) buflist.add(buffer);
            total += offset;
        } while (read >= 0);
        r.close();

        buffer = new char[total];
        Iterator it = buflist.iterator();
        int offset2 = 0;
        while (it.hasNext()) {
            char[] buf = (char[])it.next();
            int size = (it.hasNext()) ? buf.length : total - offset2;
            System.arraycopy(buf, 0, buffer, offset2, size);
            offset2 += size;
        }
        return buffer;
    }
    
    private static String getDocumentText(FileObject fo, boolean save) throws IOException {
        DataObject obj = DataObject.find(fo);
        JavaEditor editor = null;

        if (obj instanceof JavaDataObject)
            editor = ((JavaDataObject) obj).getJavaEditor();

	final Document doc;
        if ((editor != null) && (doc = editor.getDocument()) != null) {
            // loading from the memory (Document)
            final String[] str = new String[1];
            // safely take the text from the document
            Runnable run = new Runnable() {
                               public void run() {
                                   try {
                                       str[0] = doc.getText(0, doc.getLength());
                                   }
                                   catch (BadLocationException e) {
                                       // impossible
                                   }
                               }
                           };
            if (save) {
                SaveCookie cookie = (SaveCookie) obj.getCookie(SaveCookie.class);
                if (cookie != null) {
                    cookie.save();
                }
            }
            JavaMetamodel.getDefaultRepository().beginTrans(false);
            try {
                doc.render(run);
            } finally {
                JavaMetamodel.getDefaultRepository().endTrans();
            }
            return str[0];
        } else {
            return null;
        }
    }
    
    /** Returns contents of fileobject fo. If the object is opened in the editor,
      the function returns current contents of the edited document. In that case,
      if save is true, the editor content is saved.
      If the file is not opened in a JavaEditor, it is read from the disk and 
      guarded sections are filtered out.
      @return contents of the file/editor document; guarded section markers are filtered out.
    */
    public static char[] getContent(FileObject fo, boolean save, boolean filter, String encoding) throws IOException {
        String text = getDocumentText(fo, save);
        if (text == null) {
            // loading from the file
            InputStream is = new BufferedInputStream(fo.getInputStream());
            Reader reader;
            if (filter) {
                reader = new GuardedReader(is, true, encoding);
            } else {
                if (encoding == null) {
                    reader = new InputStreamReader(is);
                } else {
                    reader = new InputStreamReader(is, encoding);
                }
            }
            return readContents(reader);
        } else {
            return text.toCharArray();
        }
    }
    
    public static InputStream createInputStream(FileObject fo, boolean save, boolean store) throws IOException {
        return createInputStream(fo, save,store, null);
    }

    /** Creates new input stream from the file object.
    * Finds the java data object, checks if the document is loaded and
    * and create the stream either from the file object either from the document.
    * @param fo fileobject with the source
    * @param store if there is required the building and storing the elements
    *              hierarchy
    * @exception IOException if any i/o problem occured during reading
      @deprecated ParserInputStream that is being created by this function does not
        fit well in I18N environments.
    */
    public static InputStream createInputStream(FileObject fo, boolean save, boolean store, String encoding) throws IOException {
        String text = getDocumentText(fo, save);
        
        if (text == null) {
            // loading from the file
            InputStream is = new BufferedInputStream(fo.getInputStream());
            if (store) {
                //PENDING - improve performance
                ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
                OutputStreamWriter outWriter = new OutputStreamWriter(byteStream);
                GuardedReader reader = new GuardedReader(is, true);
                try {
                    int c;
                    while ((c = reader.read()) != -1) {
                        outWriter.write(c);
                    }
                }
                finally {
                    outWriter.close();
                    is.close();
                }
                is = new ByteArrayInputStream(byteStream.toByteArray());
            }
            return new ParserInputStream(is);
        } else {
            return new ParserInputStream(text, encoding);
        }
    }
    
    /** The input stream which holds all data which are read in the StringBuffer.
     * @deprecated The class doesn't process character data in the stream and
     * is not very usable in I18N environments.
     */
    static class ParserInputStream extends InputStream {
        
        /** The underlaying stream.  */
        private InputStream stream;
        
        /** Whole text  */
        private String text;
        
        /** The string buffer which collect the data.  */
        private StringBuffer buffer;
        
        /** This flag determines if there is used the text field or buffer field.
         * The constructor set it
         */
        private boolean mode;
        
        /** The counter of read chars  */
        private int counter;
        
        /** Offset of the begins of the lines (e.g. offset of [line,col] is lines[line] + col - 1
         */
        private int[] lines = new int[200];
        
        /** Current line counter - it is used for filling the lines array in the read method
         */
        int lineCounter = 2;
        
        /** Length of the current line
         */
        int currentLineLength = 0;
        
        /** Creates the stream from the text.
         */
        ParserInputStream(String text) {
            this(text, null);
        }
        
        ParserInputStream(String text, String encoding) {
            this.text = text;
            counter = 0;
            mode = false;
            ByteArrayOutputStream outstm = new ByteArrayOutputStream(text.length());
            Writer wr = null;
            
            if (encoding != null) {
                try {
                    wr = new OutputStreamWriter(outstm, encoding);
                } catch (UnsupportedEncodingException ex) {
                }
            }
            if (wr == null) {
                wr = new OutputStreamWriter(outstm);
            }
            
            try {
                wr.write(text);
                wr.close();
            } catch (IOException ex) {
            }
            this.stream = new ByteArrayInputStream(outstm.toByteArray());
        }
        
        /** Creates the stream from the another stream.  */
        ParserInputStream(InputStream stream) {
            this.stream = stream;
            buffer = new StringBuffer();
            mode = true;
        }
        
        /** Gets the part of the text which was already read.
         * @param begin the begin index
         * @param end the end index
         */
        public String getString(int begin, int end) {
            return mode ? buffer.substring(begin, end) : text.substring(begin, end);
        }
        
        /** Gets the part of the text which was already read.
         * End is last position which was already read.
         * @param begin the begin index
         */
        public String getString(int begin) {
            if (mode) {
                return buffer.substring(begin);
            }
            else {
                int end = Math.min(counter - 1, text.length());
                return text.substring(begin, end);
            }
        }
        
        /** Read one character from the stream.  */
        public int read() throws IOException {
            int x = stream.read();
            if (mode && (x != -1)) {
                buffer.append((char)x);
                counter++;
            }
            
            // counting line's length
            if (x == (int)'\n') {
                if (lineCounter == lines.length - 1) {
                    int[] newLines = new int[lineCounter + lineCounter];
                    System.arraycopy(lines, 0, newLines, 0, lines.length);
                    lines = newLines;
                }
                lines[lineCounter] = lines[lineCounter - 1] + currentLineLength + 1;
                lineCounter++;
                currentLineLength = 0;
            }
            else {
                currentLineLength++;
            }
            
            return x;
        }
        
        /** Closes the stream  */
        public void close() throws IOException {
            stream.close();
        }
        
        /** Compute offset in the stream from line and column.
         * @return the offset
         */
        int getOffset(int line, int column) {
            return lines[line] + column - 1;
        }
        
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.