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

package org.netbeans.modules.java.bridge;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.netbeans.api.mdr.MDRepository;
import org.netbeans.jmi.javamodel.Resource;
import org.netbeans.modules.java.JavaDataObject;
import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
import org.openide.nodes.Node;
import org.openide.src.*;
import org.openide.util.Task;

public class SrcElementImpl implements SourceElement.Impl, Node.Cookie, PropertyChangeListener {
        
    private static final ClassElement[] NO_CLASSES = new ClassElement[0];
    
    /**
     * PropertyChangeListeners attached to the SourceElement.
     */
    LinkedList              listeners;
    
    /**
     * The Element representing this proxy/impl. Once set, the element cannot be
     * changed.
     */
    SourceElement           srcElement = null;
        
    private transient int status = SourceElement.STATUS_OK;
    
    private transient DefaultLangModel model;
    
    private transient WeakReference delegate;
    
    private JavaDataObject javaDataObject;
    
    private static final long serialVersionUID = 3120888788645227532L;
    
    
    // init .....................................................................
    
    public SrcElementImpl(JavaDataObject javaObject) {
        javaDataObject = javaObject;
        model = javaDataObject.getModel ();
    }

    private SourceElementImpl getDelegate() {
        SourceElementImpl impl = (delegate != null) ? (SourceElementImpl) delegate.get() : null;
        if (impl == null || !impl.isResourceValid()) {
            MDRepository repo = JavaMetamodel.getDefaultRepository();
            repo.beginTrans(false);
            try {
                FileObject fileObj = javaDataObject.getPrimaryFile();
                Resource resource = JavaMetamodel.getManager().getResource (fileObj);
                if (resource != null) {
                    status = SourceElement.STATUS_OK;
                    impl = new SourceElementImpl (model, resource, javaDataObject);
                    impl.attachedToElement(srcElement);
                    delegate = new WeakReference (impl);
                }
            } finally {
                repo.endTrans(false);
            }
        }
        return impl;
    }
    
    public void invalidateDelegate() {
        delegate = null;
    }
    
    /*
    String getRelativeName(FileObject root, JavaDataObject resource) {
       String rootName = root.getPackageNameExt('/', '.');
       String resName = resource.getPrimaryFile().getPackageNameExt('/', '.');
       if ("".equals(rootName))
           return resName;
        return resName.substring(rootName.length() + 1).replace('/', '.');
    }
     */
    
    /**
     * Returns the SourceElement representing the hierarchy.
     */
    protected SourceElement getElement() {
        return this.srcElement;
    }
    
    /**
     * OpenAPI callback; called when the SourceElement is constructed. This implementation
     * only records the reference
     */
    public void attachedToElement(Element el) {
        this.srcElement = (SourceElement)el;
    }

    /**
     * Retrieves the status of the parsing operation. Delegates to ParsingSupport.
     */
    public int getStatus() {
        return status;
    }
    
    /**
     * Implementation of OpenAPI prepare() call.
     */
    public Task prepare() {   
        return Task.EMPTY;
    }
    
    /**
     * Implementation of setPackage(). Retrieves the real implementation and
     * delegates to it. Throws SourceException if the source cannot be parsed.
     */
    public void setPackage(Identifier id) throws SourceException {
        SourceElementImpl del = getDelegate();
        if (del != null)
            del.setPackage(id);
    }
    
    public Identifier getPackage() {        
        SourceElementImpl del = getDelegate();
        if (del != null)
            return del.getPackage();
        else
            return Identifier.create ("");
    }
    
    public Import[] getImports() {        
        SourceElementImpl del = getDelegate();
        if (del != null)
            return del.getImports();
        else
            return new Import[0];
    }
    
    public void changeImports(Import[] elems, int action) throws SourceException {
        SourceElementImpl del = getDelegate();
        if (del != null)
            del.changeImports(elems, action);
    }
    
    public void changeClasses(ClassElement[] elems, int action) throws SourceException {
        SourceElementImpl del = getDelegate();
        if (del != null)
            del.changeClasses(elems, action);
    }
    
    public ClassElement[] getClasses() {
        SourceElementImpl del = getDelegate();
        if (del != null)
            return del.getClasses();
        else
            return NO_CLASSES;
    }
    
    public ClassElement getClass(Identifier name) {        
        SourceElementImpl del = getDelegate();
        if (del != null)
            return del.getClass(name);
        else
            return null;
    }
    
    public ClassElement[] getAllClasses() {
        SourceElementImpl del = getDelegate();
        if (del != null)
            return del.getAllClasses();
        else
            return NO_CLASSES;
    }
    
    /**
     * Implementation of getCookie(). The implementation fakes cookies of all interfaces
     * on this object; if the cookie is not available, it asks the environment to
     * provide the cookie and IF the cookie descends from the implementation hierarchy
     * passes the request on to the real SourceElement's implementation, optionally
     * parsing it from the source.
     */
    public Node.Cookie getCookie(Class type) {
        if (type.isAssignableFrom(getClass()))
            return this;
        if (type.isAssignableFrom(DataObject.class)) 
            return javaDataObject.getCookie (type);
        SourceElementImpl del = getDelegate();
        if (del != null)
            return del.getCookie(type);
        else
            return javaDataObject.getCookie (type);
    }
    
    /**
     * No effect on SourceElements, there's only one of them in a source :-)
     */
    public void markCurrent(boolean beforeAfter) {
    }
    
    /**
     * Exclusively locks the model for the execution of the Runnable object. Note that
     * the implementation does *NOT* lock the document! Also, do *NOT* call the
     * method if you have already locked the document for writing unless you
     * _REALLY_ know what you are doing.
     */
    public void runAtomic(final Runnable run) {
        getDelegate().runAtomic (run);
        /*
        final StyledDocument doc;
        try {
            doc = supp.docBinding.getEditorSupport().openDocument();
        } catch (java.io.IOException ex) {
            return;
        }
        try {
            model.runAtomic(new Runnable() {
                public void run() {
                    try {
                        supp.docBinding.enableAtomicAsUser(true);
                        NbDocument.runAtomic(doc, run);
                    } finally {
                        supp.docBinding.enableAtomicAsUser(false);
                    }
                }
            });
        } catch (SourceException ex) {
        }
         */
    }
    /**
     * Creates an atomic transaction, that respects the guarded sections inside
     * the document, over the model. Again, this does *NOT* lock the document.
     */
    public void runAtomicAsUser(final Runnable run) throws SourceException {
        getDelegate().runAtomicAsUser (run);
        /*
        final StyledDocument doc;
        try {
            doc = supp.docBinding.getEditorSupport().openDocument();
        } catch (java.io.IOException ex) {
            throw new SourceException.IO(ex);
        }
        model.runAtomic(new Runnable() {
            public void run() {
                try {
                    supp.docBinding.enableAtomicAsUser(true);
                    NbDocument.runAtomic(doc, run);
                } finally {
                    supp.docBinding.enableAtomicAsUser(false);
                }
            }
        });
         */
    }

    /**
     * Adds a PropertyChangeListener
     */
    public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
        if (listeners == null) {
            listeners = new LinkedList();
        }
        boolean attach = listeners.isEmpty();
        listeners.add(l);
                
        if (attach) {
            SourceElementImpl del = getDelegate();
            if (del != null)
                del.addPropertyChangeListener(this);
        }
    }
    
    public synchronized void removePropertyChangeListener(PropertyChangeListener l) {
        if (listeners == null)
            return;
        listeners.remove(l);
        if (listeners.isEmpty()) {
            SourceElementImpl del = getDelegate();
            if (del != null)
                del.removePropertyChangeListener(this);
        }
    }
    
    public Object readResolve() {
        return null;
    }
    
    /**
     * PropertyChangeListener implementation that refires all property changes
     * to the listeners attached to a SourceElement.
     */
    public void propertyChange(PropertyChangeEvent evt) {
        List l;
        synchronized (this) {
            if (listeners == null)
                return;
            l = new java.util.ArrayList(listeners);
        }
        // remap the event so that it appears to be fired from the source element.
        evt = new PropertyChangeEvent(
            srcElement, evt.getPropertyName(), 
            evt.getOldValue(), evt.getNewValue());
        
        for (Iterator it = l.iterator(); it.hasNext(); ) {
            PropertyChangeListener ll = (PropertyChangeListener)it.next();
            ll.propertyChange(evt);
        }
    }
    
}
... 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.