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 java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.*;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.jmi.javamodel.JavaClass;
import org.netbeans.jmi.javamodel.JavaModelPackage;
import org.netbeans.jmi.javamodel.Resource;
import org.netbeans.modules.java.bridge.DefaultLangModel;
import org.netbeans.modules.java.bridge.LangModel;
import org.netbeans.modules.java.bridge.SrcElementImpl;
import org.netbeans.modules.java.codesync.ModelEventAdapter;
import org.netbeans.modules.java.codesync.SourceConnectionSupport;
import org.netbeans.modules.java.codesync.SynchronizeCodeCookie;
import org.netbeans.modules.java.parser.JavaParser;
import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
import org.netbeans.modules.javacore.jmiimpl.javamodel.ResourceClassImpl;
import org.netbeans.modules.javacore.jmiimpl.javamodel.ResourceImpl;
import org.openide.ErrorManager;
import org.openide.actions.OpenAction;
import org.openide.cookies.*;
import org.openide.filesystems.*;
import org.openide.loaders.*;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.CookieSet;
import org.openide.nodes.Node;
import org.openide.src.*;
import org.openide.src.nodes.ElementNodeFactory;
import org.openide.src.nodes.FilterFactory;
import org.openide.text.CloneableEditorSupport;
import org.openide.text.EditorSupport;
import org.openide.util.*;

/**
 * Data object representing a Java source file.
 * May be subclassed (but please don't).
 */
public class JavaDataObject extends MultiDataObject implements CookieSet.Factory {
    /** generated Serialized Version UID */
    static final long serialVersionUID = -6035788991669336965L;

    public static final byte CONNECT_NOT = 0;
    public static final byte CONNECT_CONFIRM = 1;
    public static final byte CONNECT_AUTO = 2;

    public static final byte CONNECT_DEFAULT = CONNECT_CONFIRM;

    private static final String EA_CONNECTION = "SourceSync"; // NOI18N

    /*
     * @deprecated
     */
    public static final String EA_PRODUCTS = "Products"; // NOI18N

    private static final String[] SKIP_REGISTRATION_PREFIX = { "java.", "javax."}; // NOI18N

    /**
     * Holds a reference to editor support class. Lazy initialized from getJavaEditor,
     * or a getter for EditorSupport.class cookie.
     */
    transient private JavaEditor editorSupport;

    transient protected AbstractNode alteranteParent;

    /** WeakListener that intercepts external modification while the file is not
     *  opened in the Editor.
     */
    transient private FileChangeListener fileChangeListener;

    /** Hook to keep the WeakListener alive for the lifetime of the DataObject
     */
    transient private FileChangeListener fileChangeListenerHook;


    /** TEMPORARY: Filename of the primary file before it was changed (DO was
     * renamed or moved.
     */
    transient private String previousFileName;

    /** Lock for parsing and connection support
     */
    transient private Object lock;

    private transient boolean initialized;

    /**
     * Holds a reference to the glue between the parser and the dataobject.
     * Lazy initialized from {@link #initializeParsingSupport}
     */
    private transient JavaParserGlue   parserGlue;

    /**
     * Reference to an adapter and ConnectionSupport implementation, that
     * adapts model events to JavaConnection events.
     */
    private transient ModelEventAdapter connectionAdapter;
    
    private transient SourceElement source = null;

    public transient SourceConnectionSupport connectionManager;
    
    private transient DefaultLangModel model = null;

    static final String PROP_SYNCHRONIZATION_TYPE = "synchMode"; // NOI18N

    /** Create new data object.
    * @param pf primary file object for this data object (i.e. the source file)
    * @param loader the associated loader
    */
    public JavaDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException {
        super(pf, loader);
        init();
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        init();
    }

    private void init() {
        MultiDataObject.Entry entry = getPrimaryEntry();
        CookieSet cookies = getCookieSet();
        Class[] cookieClasses = new Class[] {
            JavaEditor.class,
            ConnectionCookie.class,
            JavaParser.class,
            SourceCookie.Editor.class,
            SynchronizeCodeCookie.class,
        };
        cookies.add(cookieClasses, this);

        PrimaryListener l = new PrimaryListener();
	addPropertyChangeListener(l);
        fileChangeListenerHook = l;
	fileChangeListener = WeakListener.fileChange(fileChangeListenerHook, entry.getFile());
        lock = new Object();
        addSourceChangeListener(null);
        initialized = true;
        // [TODO] the following code was comented out as it interfered with FileScanner during IDE startup
        // it should be uncommented after we figure out how to avoid the interference
//        try {
//            updateResource();
//        } catch (IOException ex) {
//            ErrorManager.getDefault().notify(ex);
//        }
    }
    
    public synchronized DefaultLangModel getModel () {
        if (model == null) {
            synchronized (lock) {
                if (model == null)
                    model = new DefaultLangModel (this);
            }
        }
        return model;
    }


    void firePropertyChange0(String s, Object v1, Object v2) {
        super.firePropertyChange(s, v1, v2);
    }

    /**
     * Creates a parsing support.
     */
    private JavaParser initializeParsingSupport() {
        if (parserGlue != null)
            return parserGlue.getParser();
        synchronized (lock) {
            if (parserGlue != null) {
                return parserGlue.getParser();
            }

            parserGlue = new JavaParserGlue(getPrimaryEntry());
            if (editorSupport != null) {
                parserGlue.cloneableSupportCreated(extractCloneableEditor(editorSupport));
            }

            // initialize connection support -- this can be delayed up to the first commit,
            // if needed, can be captured by a CommitListener.
 
            // LangModel m = parserGlue.getParser().getModel(); [PENDING]
            LangModel m = getModel ();
            if (connectionAdapter == null)
                initializeConnectionSupport(m);
            else
                connectionAdapter.attachToModel(m);

            // attach management of incoming dependencies.
            connectionManager = new PersistentConnectionSupport(
                getSource(), m);
            connectionManager.resume(false);
            if (isModified()) {
                connectionManager.syncConnections();
            }
        }
        return parserGlue.getParser();
    }

    /**
     * Initializes support for JavaConnections - if a parser is not yet created,
     * it begins its live unattached to any model.
     */
    private ConnectionSupport initializeConnectionSupport(LangModel m) {
        
        if (m == null)
            m = getModel ();
        
        if (connectionAdapter != null)
            return connectionAdapter;
        synchronized (lock) {
            if (connectionAdapter != null)
                return connectionAdapter;
            connectionAdapter = new ModelEventAdapter(getPrimaryEntry());
            if (m != null) {
                connectionAdapter.attachToModel(m);
            }
        }
        return connectionAdapter;
    }

    public void setValid(boolean v) throws PropertyVetoException {
        super.setValid(v);
        if (!v) {
            synchronized (this) {
                if (parserGlue != null) {
                    parserGlue.suspendDocumentChanges();
                    connectionAdapter.detachFromModel();
                    connectionManager.suspend();
                }
            }
        }
    }

    /**
     * Finds a cloneableEditorSupport that holds the displayable/parseable source. The implementation
     * currently uses a hack, that extract package-private member from the EditorSupport's
     * implementation.
     */
    protected CloneableEditorSupport findCloneableEditorSupport() {
        EditorSupport supp = (EditorSupport)getCookie(EditorSupport.class);
        return extractCloneableEditor(supp);
    }

    /**
     * Extract CloneableEditorSupport instance from the given EditorSupport.
     * The implementation is fragile as it uses package-private member and reflection.
     */
    private CloneableEditorSupport extractCloneableEditor(EditorSupport supp) {
        try {
            java.lang.reflect.Field f = EditorSupport.class.getDeclaredField("del"); // NOI18N
            f.setAccessible(true);
            return (CloneableEditorSupport)f.get(supp);
        } catch (Exception x) {
        }
        return null;
    }

    /** Attaches a file change listener to the primary (source) file.
     * Optionally removes the listener from previously used file object.
     * @param previousPrimary if not null, then the method removes change listener from this
     *        file object.
     */
    void addSourceChangeListener(FileObject previousPrimary) {
      if (previousPrimary != null) {
        previousPrimary.removeFileChangeListener(fileChangeListener);
      }
      getPrimaryEntry().getFile().addFileChangeListener(fileChangeListener);
    }

    // =================== Connections ====================================

    public byte getSynchronizationType() {
        Object o = getPrimaryFile().getAttribute(EA_CONNECTION);
        return ((o != null) && (o instanceof Byte)) ?
               ((Byte)o).byteValue() : CONNECT_DEFAULT;
    }

    public void setSynchronizationType(byte type) {
        FileObject fo = getPrimaryFile();
        try {
            if ((type != CONNECT_CONFIRM) && (type != CONNECT_NOT) && (type != CONNECT_AUTO))
                throw new IllegalArgumentException();
            fo.setAttribute(EA_CONNECTION, (type == CONNECT_DEFAULT) ? null : new Byte(type));
            firePropertyChange(PROP_SYNCHRONIZATION_TYPE, null, null);
        }
        catch (IOException e) {
        }
    }

    int getAllListenersMask() {
        //    System.out.println("getAllListenersMask()"+JavaConnections.SETTINGS.isEnabled()); // NOI18N
        if (!JavaConnections.SETTINGS.isEnabled()) // disabled
            return 0;

        Iterator it = getConnectionSupport().getRegisteredTypes().iterator();
        int mask = 0;
        while (it.hasNext()) {
            Object o = it.next();
            /*      System.out.println("nextType:"+o); // NOI18N
                  System.out.println("   first:"+o.getClass().getClassLoader()); // NOI18N
                  System.out.println("  second:"+JavaConnections.Type.class.getClassLoader());*/ // NOI18N
            if (o instanceof JavaConnections.Type) {
                mask |= ((JavaConnections.Type)o).getFilter();
            }

            // temporary-begin-------
            mask |= JavaConnections.IMPLEMENTS.getFilter();
            // end ------------------

        }
        return mask;
    }

    /**
     * @deprecated The method will be soon reimplemented in the new connection support
     * classes in the codesync package.
     */
    void startChangeProcessors(LinkedList changeProcessors) {
        if (changeProcessors.size() > 0) {
            if (getSynchronizationType() == CONNECT_AUTO) {
                Iterator it = changeProcessors.iterator();
                while (it.hasNext()) {
                    JavaConnections.ChangeProcessor p = (JavaConnections.ChangeProcessor) it.next();
                    try {
                        p.process();
                    } catch (SourceException e) {
                        // eat the exception
                        // TopManager.getDefault().notify(new NotifyDescriptor.Exception(e));
                    }
                }
            }
            else { // CONNECT_CONFIRM
                final byte oldSynch = getSynchronizationType();
                final JavaConnections.SyncRequest request =
                    JavaConnections.scheduleShowChangesDialog(changeProcessors, oldSynch);
                request.getTask().addTaskListener(new org.openide.util.TaskListener() {
                    public void taskFinished(Task t) {
                        byte newSynch = request.getSyncType();

                        t.removeTaskListener(this);
                        if (oldSynch != newSynch)
                            setSynchronizationType(newSynch);
                    }
                });
            }
        }
    }

    /**
     * @deprecated Please see the new implementation of the connections in
     * {@link org.netbeans.modules.java.codesync.SourceConnectionSupport} and related
     * classes.
     */
    protected boolean connectionNotify(ConnectionCookie.Event event, LinkedList changeProcessors) {

        if (event.getType().getEventClass().isAssignableFrom(JavaConnections.Event.class)) {
            // there are two main sources of notification: external notifications that something this source
            // depends on has changed, and explicit notifications that this source should check itself for changes.
            JavaConnections.Event evt = (JavaConnections.Event)event;
            boolean selfcheck = evt.getType().overlaps(new JavaConnections.Type(JavaConnections.TYPE_SOURCE_CHECK_DEEP | JavaConnections.TYPE_SOURCE_CHECK_SELF));
            if (selfcheck) {
                return InterfaceConnection.sourceCheck(changeProcessors, getSource());
            } else {
                return InterfaceConnection.synchronizeInterfaces((JavaConnections.Event) event, changeProcessors, getSource());
            }
        }

        return false;
    }

    /**
     * @deprecated The registration implementation was removed from the JavaDataObject.
     * See {@link org.netbeans.modules.java.codesync.SourceConnectionSupport} class for
     * the new implementation.
     */
    protected void registerForName(Identifier id, JavaConnections.Type type) {
        // do nothing
    }

    /**
     * @deprecated The registration implementation was removed from the JavaDataObject.
     * See {@link org.netbeans.modules.java.codesync.SourceConnectionSupport} class for
     * the new implementation.
     */
    protected void unregisterForName(Identifier id, JavaConnections.Type type) {
        // do nothing
    }

    /** Set whether this object is considered modified.
    * @param modif true to consider it modified
    */
    public void setModified(boolean modif) {
        boolean changed = isModified() != modif;
        super.setModified(modif);
        if (modif && this.connectionManager != null) {
            connectionManager.syncConnections();
        }
    }

    public void resumeSupports() {
        connectionAdapter.attachToModel(getModel());
        connectionManager.resume(false);
        parserGlue.resumeDocumentChanges();
    }

    public void suspendSupports() {
        // initialize support objects. If they were requested after this method,
        // they would be created in an active state.
        initializeConnectionSupport(null);
        initializeParsingSupport();
        // suspend everything that is bound to the model and document
        parserGlue.suspendDocumentChanges();
        connectionAdapter.detachFromModel();
        connectionManager.suspend();
    }

    boolean isJavaFileReadOnly() {
	FileObject primary = getPrimaryFile();
	if (!isValid() || !primary.isValid()) {
	    return true;
	}
	return primary.isReadOnly();
    }

    // ==================== Handle methods =======================

    protected DataObject handleCopy(DataFolder df) throws IOException {
        DataObject dob = super.handleCopy(df);
        if (!Repository.getDefault().getDefaultFileSystem().equals(dob.getPrimaryFile().getFileSystem())) {
            JavaMetamodel.getDefaultRepository().beginTrans(true);
            boolean fail = true;
            try {
                ClassPath cp = ClassPath.getClassPath(dob.getPrimaryFile(),ClassPath.SOURCE);
                if (cp!=null) {
                    JavaModelPackage model = JavaMetamodel.getManager().resolveJavaExtent(cp.findOwnerRoot(dob.getPrimaryFile()));
                    if (model == null) {
                        ErrorManager.getDefault().log(ErrorManager.WARNING, "JavaDataObject: Extent for " + dob.getName() + " not found");
                        fail = false;
                        return dob;
                    }
                    ResourceClassImpl resClass = (ResourceClassImpl) model.getResource();
                    String resourceName = cp.getResourceName(dob.getPrimaryFile());
                    Resource res = resClass.resolveResource(resourceName, true, false);
                
                    res.setPackageName(cp.getResourceName(df.getPrimaryFile()).replace('/','.'));
                    Iterator i = res.getClassifiers().iterator();
                    if (i.hasNext()) {
                        JavaClass clazz = (JavaClass) i.next();
                        clazz.setSimpleName(dob.getName());
                    }
                }
                fail = false;
            } finally {
                JavaMetamodel.getDefaultRepository().endTrans(fail);
            }
        }
        return dob;
    }
    
    /* Renames all entries and changes their files to new ones.
    */
    protected FileObject handleRename (String name) throws IOException {
        if (!Utilities.isJavaIdentifier(name))
            throw new IOException(NbBundle.getMessage(JavaDataObject.class, "FMT_Not_Valid_FileName", name));

        FileObject fo = super.handleRename(name);
        return fo;
    }

    /* Moves primary and secondary files to a new folder.
     * May ask for user confirmation before overwriting.
     * @param df the new folder
     * @return the moved primary file object
     * @throws IOException if there was a problem moving
     * @throws UserCancelException if the user cancelled the move
    */
    protected FileObject handleMove (DataFolder df) throws IOException {
        FileObject f = super.handleMove(df);
        SrcElementImpl src = (SrcElementImpl) getSource().getCookie(SrcElementImpl.class);
        src.invalidateDelegate();
        return f;
    }

    /* Creates new object from template.
    * @exception IOException
    */
    protected DataObject handleCreateFromTemplate (DataFolder df, String name) throws IOException {
        if (name == null) {
            // special case: name is null (unspecified or from one-parameter createFromTemplate)
            name = FileUtil.findFreeFileName(df.getPrimaryFile(),
                getPrimaryFile().getName(), "java"); // NOI18N
        } else if (!Utilities.isJavaIdentifier(name))
            throw new IOException(NbBundle.getMessage(JavaDataObject.class, "FMT_Not_Valid_FileName", name));

        IndentFileEntry entry = (IndentFileEntry)getPrimaryEntry();
        entry.initializeIndentEngine();
        JavaDataObject obj;

        boolean failed = true;
        JavaMetamodel.getDefaultRepository().beginTrans(true);
        try {
            obj = (JavaDataObject) super.handleCreateFromTemplate(df, name);
            String oldName = getPrimaryFile().getName();
            ClassPath cp = ClassPath.getClassPath(df.getPrimaryFile(),ClassPath.SOURCE);
                if (cp != null) {
                    String packageName = cp.getResourceName (df.getPrimaryFile(),'.',false);
                    assert packageName != null;
                    //if (isValidPackageName(packageName)) {
                      JavaModelPackage model = JavaMetamodel.getManager().resolveJavaExtent(cp.findOwnerRoot (obj.getPrimaryFile()));
                      ResourceClassImpl resClass = (ResourceClassImpl) model.getResource();
                      String resourceName = cp.getResourceName (obj.getPrimaryFile());
                      Resource res = resClass.resolveResource(resourceName, true, false);
                      res.setName(resourceName);
                      res.setPackageName(packageName);
                      Iterator i = res.getClassifiers().iterator();
                      if (i.hasNext()) {
                          JavaClass clazz = (JavaClass) i.next();
                          clazz.setSimpleName(name); 
                      }
                }
                else {
                    //Destnation folder is not in project
                    //Skeep update but log
                    //TODO: Remove logging
                    ErrorManager.getDefault().log ("Can not update source while creating from template, destination folder "+
                        df.getPrimaryFile().getPath()+" is not in any project."); // NOI18N
                }
            failed = false;
        } finally {
            JavaMetamodel.getDefaultRepository().endTrans(failed);
            entry.setIndentEngine(null);
        }
        return obj;
    }

    /** Create the editor support for this data object.
    * By default, creates a JavaEditor with the source file entry;
    * subclasses may override this.
    * @return the editor support
    */
    protected JavaEditor createJavaEditor () {
        JavaEditor je = new JavaEditor (getPrimaryEntry ());
        return je;
    }

    /** Provide node that should represent this data object.
    * This implementation creates and returns a {@link JavaNode}.
    * Subclasses may wish to return a specialized subclass of this node type.
    * You should probably make the default action be {@link OpenAction}.
    * @return the node representation for this data object
    */
    protected Node createNodeDelegate () {
        JavaNode node = new JavaNode (this);
        return node;
    }

    /** Get the parsed representation of this source file.
    * May not be fully parsed yet; the source element itself indicates its status.
    * @return the source element for this Java source file
    */
    public SourceElement getSource() {
        // return ((JavaParser)getCookie(JavaParser.class)).getSource();        
        if (source == null) {
            synchronized (lock) {
                if (source == null)
                    source = new SourceElement (new SrcElementImpl (this));
            }
        }
        return source;
    }

    /** Get the current editor support.
    * Ought not be subclasses; use {@link #createJavaEditor}.
    * @return the editor support
    */
    public JavaEditor getJavaEditor() {
        if (editorSupport == null) {
            synchronized (this) {
                editorSupport = createJavaEditor();
                if (parserGlue != null)
                    parserGlue.cloneableSupportCreated(extractCloneableEditor(editorSupport));
            }
        }
        return editorSupport;
    }

    public ConnectionSupport getConnectionSupport() {
        return initializeConnectionSupport(null);
    }

    // =============== The mechanism for regeisteing node factories ==============

    private static NodeFactoryPool explorerFactories;
    private static NodeFactoryPool browserFactories;
    private static ElementNodeFactory basicBrowser;

    /**
     * DO NOT USE THIS METHOD!!! 

* This method is intended to be called only during initialization of java * module-provided node factories from the installation layer. It won't * be maintained for compatibility reasons. */ synchronized static ElementNodeFactory createBasicExplorerFactory() { return JavaElementNodeFactory.DEFAULT; } /** * DO NOT USE THIS METHOD!!!

* This method is intended to be called only during initialization of java * module-provided node factories from the installation layer. It won't * be maintained for compatibility reasons. */ synchronized static ElementNodeFactory createBasicBrowserFactory() { if (basicBrowser == null) { basicBrowser = org.netbeans.modules.java.ui.nodes.SourceNodes.createElementNodeFactory( org.netbeans.modules.java.ui.nodes.SourceNodes.getBrowserFactory()); } return basicBrowser; } public static ElementNodeFactory getExplorerFactory() { NodeFactoryPool pool = createExplorerFactory(); ElementNodeFactory f = null; if (pool != null) f = pool.getHead(); if (f == null) f = createBasicExplorerFactory(); return f; } /** * * @deprecated */ public static ElementNodeFactory getBrowserFactory() { ErrorManager.getDefault().notify( ErrorManager.WARNING, new IllegalStateException("JavaDataObject.getBrowserFactory is deprecated. Use SourceNodes.getBrowserFactory() instead.") // NOI18N ); return createBasicBrowserFactory(); } static NodeFactoryPool createFactoryPool(String folderName, ElementNodeFactory def) { FileObject f = Repository.getDefault().getDefaultFileSystem().findResource(folderName); if (f == null) return null; try { DataFolder folder = (DataFolder)DataObject.find(f).getCookie(DataFolder.class); return new NodeFactoryPool(folder, def); } catch (DataObjectNotFoundException ex) { return null; } } synchronized static NodeFactoryPool createBrowserFactory() { if (browserFactories != null) return browserFactories; browserFactories = createFactoryPool("/NodeFactories/java/objectbrowser", createBasicBrowserFactory()); // NOI18N return browserFactories; } synchronized static NodeFactoryPool createExplorerFactory() { if (explorerFactories != null) return explorerFactories; explorerFactories = createFactoryPool("/NodeFactories/java/explorer", createBasicExplorerFactory()); // NOI18N return explorerFactories; } /** * @deprecated use installation layer for registering a factory for the the whole * time a module is installed. Note: This feature will be dropped in the next * release. */ public static void addExplorerFilterFactory( FilterFactory factory ) { NodeFactoryPool p = createExplorerFactory(); if (p != null) p.addFactory(factory); } /** * @deprecated use installation layer for registering a factory for the the whole * time a module is installed. Note: This feature will be dropped in the next * release. */ public static void removeExplorerFilterFactory( FilterFactory factory ) { NodeFactoryPool p = createExplorerFactory(); if (p != null) p.removeFactory(factory); } /** * @deprecated use installation layer for registering a factory for the the whole * time a module is installed. Note: This feature will be dropped in the next * release. */ public static void addBrowserFilterFactory(FilterFactory factory) { NodeFactoryPool p = createBrowserFactory(); if (p != null) p.addFactory(factory); } /** * @deprecated use installation layer for registering a factory for the the whole * time a module is installed. Note: This feature will be dropped in the next * release. */ public static void removeBrowserFilterFactory( FilterFactory factory ) { NodeFactoryPool p = createBrowserFactory(); if (p != null) p.removeFactory(factory); } /* ===================== File -> model dependency handling ===================== */ protected static boolean isValidPackageName(String str) { StringTokenizer tok = new StringTokenizer(str, "."); // NOI18N while (tok.hasMoreTokens()) { String part = tok.nextToken(); if (!org.openide.util.Utilities.isJavaIdentifier(part)) return false; } return true; } protected void primaryFileMoved(FileObject oldFile, FileObject newFile) { addSourceChangeListener(oldFile); } protected void primaryFileChanged() { // if (!getJavaEditor().isDocumentLoaded()) { // reparseResource(false); // } } void reparseResource(boolean force) { if (!isValid()) return; boolean failed = true; JavaMetamodel.getDefaultRepository().beginTrans(true); try { ResourceImpl res = (ResourceImpl)JavaMetamodel.getManager().getResource(getPrimaryFile()); if (res!=null) { res.updateFromDataObject(this,force); } failed = false; } finally { JavaMetamodel.getDefaultRepository().endTrans(failed); } } // =============== Primary file monitoring ============ private class PrimaryListener extends FileChangeAdapter implements PropertyChangeListener{ public void propertyChange(final PropertyChangeEvent evt) { if (!initialized) return; String propName = evt.getPropertyName(); if (PROP_PRIMARY_FILE.equals(propName)) { primaryFileMoved((FileObject)evt.getOldValue(), (FileObject)evt.getNewValue()); } else if (PROP_NAME.equals(propName)) { previousFileName = (String)evt.getOldValue(); primaryFileMoved(getPrimaryFile(), getPrimaryFile()); } } public void fileChanged(FileEvent e) { if (!initialized) return; primaryFileChanged(); } } /** * Extract the date of last modification of the source file. If the file is opened * in the editor AND marked as modified (in the editor), it returns true. * If the DataObject reports that it was modified, but the editor support knows * nothing about it, just ignore -- other parts of the DataObject are changed. */ Date getLastModified() { SaveCookie c = (SaveCookie)getCookie(SaveCookie.class); if (c != null) { EditorCookie ck = (EditorCookie)getCookie(EditorCookie.class); if (ck != null && ck.isModified()) return new Date(); } return getPrimaryFile().lastModified(); } public Node.Cookie getCookie(Class type) { if ((connectionManager==null && type == ConnectionCookie.class) || (parserGlue==null && (type == SynchronizeCodeCookie.class || SourceCookie.class.isAssignableFrom(type) || JavaParser.class.isAssignableFrom(type)))) { // needs transaction because of #44913 // but the cases when a transaction is needed need to be restricted as much as possible because of #46408 JavaMetamodel.getDefaultRepository().beginTrans(false); try { return super.getCookie(type); } finally { JavaMetamodel.getDefaultRepository().endTrans(false); } } return super.getCookie(type); } /** Creates a Node.Cookie of given class. The method * may be called more than once. */ public Node.Cookie createCookie(Class klass) { // all execution-related services -> getExecSupport if (klass == ConnectionCookie.class) { return getConnectionSupport(); } if (klass.isAssignableFrom(JavaEditor.class)) { return getJavaEditor(); } if (klass == SynchronizeCodeCookie.class) { initializeParsingSupport(); return connectionManager; } if (SourceCookie.class.isAssignableFrom(klass) || JavaParser.class.isAssignableFrom(klass)) { if (initializeParsingSupport() == null) return null; if (klass.isAssignableFrom(parserGlue.getClass())) return parserGlue; else return parserGlue.getParser(); } return null; } public Collection getCompiledClasses() { //TODO: Support should be introduced to find out the class files for source file. Thread.dumpStack(); return Collections.EMPTY_LIST; } public String toString() { return "[JDO for " + getPrimaryFile() + "]"; // NOI18N } private static class PersistentConnectionHandle implements Node.Handle { /** Handle to a DataObject's node. */ Node.Handle dataNodeHandle; private static final long serialVersionUID = -5037573245209142090L; PersistentConnectionHandle(JavaDataObject o) { this.dataNodeHandle = o.getNodeDelegate().getHandle(); } public Node getNode() throws IOException { // broken deserialization if (dataNodeHandle == null) { throw new IOException("Cannot deserialize do handle"); // NOI18N } JavaDataObject d = (JavaDataObject)dataNodeHandle.getNode().getCookie(JavaDataObject.class); if (d == null) { throw new IOException("JavaDataObject cannot be found"); // NOI18N } d.initializeParsingSupport(); Node n = d.connectionManager.getListenerNode(); return n; } } private class PersistentConnectionSupport extends SourceConnectionSupport { JavaDataObject target; PersistentConnectionSupport(SourceElement src, LangModel mod) { super(src, mod, JavaDataObject.this.getPrimaryFile().getPath()); target = JavaDataObject.this; } protected Node.Handle createListenerHandle(Node n) { return new PersistentConnectionHandle(target); } public int getSynchronizationMode(ClassElement t) { return (int)JavaDataObject.this.getSynchronizationType(); } public void setSynchronizationMode(ClassElement t, int type) { JavaDataObject.this.setSynchronizationType((byte)type); } protected void saveDependencies(String fqn, String[] deps) { } protected String[] readDependencies(String fqn) { return new String[0]; } protected String[] readDependencyList() { return new String[0]; } } }

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