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-2000 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.java.codegen;

import java.lang.ref.*;
import java.io.IOException;
import java.util.*;

import javax.swing.text.BadLocationException;
import javax.swing.text.Position;
import javax.swing.text.StyledDocument;
import javax.swing.undo.UndoableEdit;

import org.openide.awt.UndoRedo;
import org.openide.src.*;
import org.openide.text.CloneableEditorSupport;
import org.openide.text.NbDocument;
import org.openide.text.PositionBounds;
import org.openide.text.PositionRef;
import org.openide.ErrorManager;

import org.netbeans.modules.java.bridge.Binding;
import org.netbeans.modules.java.bridge.BindingFactory;
import org.netbeans.modules.java.bridge.ImportElement;

/**
 * Source is not, in fact, a Binding, but provides context to the editing operations.
 * It should manage locking, interactions with the outside environment and protection
 * management.

* * @author Svatopluk Dedic * @version 0.1 */ public class SourceText implements DocumentBinding { /** True, if runAtomics should be, in fact, runAtomicAsUser. */ int isAtomicAsUser; /** Support for editing documents. */ CloneableEditorSupport editSupport; /** * Undo manager to register undo events with. */ Env environment; /** * Yes/no flag whether the whole generator is enabled. Parser updater, for example, * disables the code generator while it updates the source model, so the discovered * changes are not reflected back to the text. */ boolean generatorEnabled; /** * An object used to lock tree of javax.swing.text.Elements or Bindings during * updates & reads. */ Object treeLock; /** * Binding of the SourceElement, held by a WeakReference. Since the binding * is held exclusively by SourceElement.Impl implementation, it may be freed along * with the implementation (or according to the implementation memory policy). */ Reference refSourceRoot; Map bindingMap; public SourceText(Env sourceEnvironment) { this.environment = sourceEnvironment; treeLock = new Object(); } public Element getElement() { return null; } protected SourceB getRoot() { synchronized (this) { if (refSourceRoot == null) return null; Object r = refSourceRoot.get(); if (r == null) refSourceRoot = null; return (SourceB)r; } } public CloneableEditorSupport getEditorSupport() { if (editSupport == null) editSupport = environment.findEditorSupport(); return editSupport; } protected synchronized void registerBinding(Element el, ElementBinding b) { if (bindingMap == null) { bindingMap = new WeakHashMap(37); } bindingMap.put(el, new WeakReference(b)); } /** * Enters or leaves user-mode of document editing. If the document contains * some user-protected text, all changes to the text will be disallowed in * the user mode. */ public void enableAtomicAsUser(boolean enable) { if (enable) isAtomicAsUser++; else isAtomicAsUser--; } public void enableGenerator(boolean enable) { generatorEnabled = enable; } public boolean isGeneratorEnabled() { return generatorEnabled; } /** * Retrieves a document for the I/O operations. The method can throw * IOException wrapped into a SourceException, if the operation fails. */ public StyledDocument getDocument() throws SourceException { try { return getEditorSupport().openDocument(); } catch (IOException ex) { rethrowException(ex); } return null; } public Element findElement(int position) { SourceB sb = getRoot(); if (sb == null) return null; synchronized (getTreeLock()) { ElementBinding b = sb.findBindingAt(position); if (b == null) return null; return b.getElement(); } } public boolean isAtomicAsUser() { return this.isAtomicAsUser > 0; } public void runAtomic(final Runnable r) throws SourceException { runAtomic(null, r); } private void checkWritable(Element el) throws IOException { environment.takeLock(); } private void runAtomic(Element el, final Runnable r) throws SourceException { final Exception[] exc = new Exception[1]; try { checkWritable(el); if (isAtomicAsUser()) { NbDocument.runAtomicAsUser(getDocument(), r); } else { NbDocument.runAtomic(getDocument(), r); } } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { exc[0] = ex; } rethrowException(el, exc[0]); } public void updateBindings(Runnable r) { synchronized (getTreeLock()) { r.run(); } } protected Object getTreeLock() { return treeLock; } protected static void rethrowException(Exception ex) throws SourceException { rethrowException(null, ex); } protected static void rethrowException(Element el, Exception ex) throws SourceException { if (ex == null) return; ErrorManager man = ErrorManager.getDefault(); SourceException x; if (ex instanceof BadLocationException) { x = new SourceException.Protection(el); man.annotate(x, ErrorManager.USER, null, ex.getLocalizedMessage(), ex, null); } else if (ex instanceof IOException) { x = new SourceException.IO((IOException)ex); man.annotate(x, ErrorManager.USER, null, ex.getLocalizedMessage(), ex, null); } else if (ex instanceof SourceException) { x = (SourceException)ex; } else { // PENDING: annotate the exception with the old one! x = new SourceException(); man.annotate(x, ex); } throw x; } public void runAtomic(final Element el, final ExceptionRunnable r) throws SourceException { final Exception[] exc = new Exception[1]; try { checkWritable(el); } catch (IOException ex) { rethrowException(el, ex); } Runnable r2 = new Runnable() { public void run() { //environment.notifyBeginEdit(); try { r.run(); } catch (Exception ex) { exc[0] = ex; throw new IllegalStateException(); } finally { //environment.notifyEndEdit(); } } }; StyledDocument doc = getDocument(); if (isAtomicAsUser()) { try { NbDocument.runAtomicAsUser(doc, r2); } catch (BadLocationException ex) { exc[0] = ex; } catch (IllegalStateException ex) { } } else { try { NbDocument.runAtomic(doc, r2); } catch (IllegalStateException ex) { // swallow - rethrow the runnable's exception instead. } } rethrowException(el, exc[0]); } protected PositionRef createPos(int offset, Position.Bias bias) { return getEditorSupport().createPositionRef(offset, bias); } protected synchronized ElementBinding findBinding(Element e) { if (bindingMap == null) return null; Reference r = (Reference)bindingMap.get(e); if (r == null) return null; return (ElementBinding)r.get(); } protected boolean canWriteInside(PositionBounds bounds) { return environment.findFreePosition(bounds) != null; } protected PositionRef findFreePosition(PositionBounds bounds) { return environment.findFreePosition(bounds); } public Binding.Field bindField(FieldElement impl) { return new FieldB(impl, this); } public Binding.Method bindMethod(MethodElement impl) { return new Method(impl, this); } public Binding.Method bindConstructor(ConstructorElement impl) { return new Method(impl, this); } public Binding.Class bindClass(ClassElement impl) { return new Clazz(impl, this); } public Binding.Initializer bindInitializer(InitializerElement impl) { return new Initializer(impl, this); } public Binding.Import bindImport(ImportElement impl) { return new ImportB(impl, this); } public Binding.Source bindSource(SourceElement impl) { SourceB sb = new SourceB(impl, this); this.refSourceRoot = new WeakReference(sb); return sb; } public void dumpDocument() { System.err.println("Document dump:"); // NOI18N final StyledDocument doc = getEditorSupport().getDocument(); doc.render(new Runnable() { public void run() { try { String s = doc.getText(0, doc.getLength()); System.err.println(s); } catch (Exception ex) { } } }); } }

... 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.