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.javacore.jmiimpl.javamodel;

import java.util.*;
import javax.jmi.reflect.InvalidObjectException;
import javax.jmi.reflect.RefClass;
import javax.jmi.reflect.RefFeatured;
import javax.jmi.reflect.RefObject;
import org.netbeans.jmi.javamodel.*;
import org.netbeans.lib.java.parser.ASTree;
import org.netbeans.lib.java.parser.ParserTokens;
import org.netbeans.lib.java.parser.Token;
import org.netbeans.mdr.handlers.AttrListWrapper;
import org.netbeans.mdr.handlers.BaseObjectHandler;
import org.netbeans.mdr.persistence.StorageException;
import org.netbeans.mdr.storagemodel.StorableFeatured;
import org.netbeans.mdr.storagemodel.StorableObject;
import org.netbeans.modules.javacore.ClassIndex;
import org.netbeans.modules.javacore.ExclusiveMutex;
import org.netbeans.modules.javacore.JMManager;

import org.netbeans.modules.javacore.parser.*;
import org.openide.ErrorManager;
import org.openide.util.Utilities;

/**
 * Superclass for the partialy persistent elements.
 *
 * @author  Martin Matula
 * @author  Pavel Flaska
 */
public abstract class SemiPersistentElement extends MetadataElement implements NamedElement {
    private boolean isUpToDate = false;
    private boolean recentlyPersisted = false;
    private ElementInfo info;
    RefFeatured parent; // used for hard-referencing parent

    /** Creates a new instance of SemiPersistentElement */
    public SemiPersistentElement(StorableObject o) {
        super(o);
    }

    /** Should be called by a class proxy whenever a new metadata object is created via
     * standard API (it has no ASTInfo so a default ASTInfo is set into it)
     */
    protected final void setNew() {
        setChanged();
        if (this.info != null) {
            for (Iterator it = getInitedChildren().iterator(); it.hasNext();) {
                ((MetadataElement) it.next()).setNew();
            }
        }
        this.info = getDefaultInfo();
        setPersisted(true);
        childrenInited = true;
        // [TODO] uncomment this
//        ((ExclusiveMutex) _getMdrStorage().getRepositoryMutex()).addNew(this);
    }

    public void setPersisted(boolean persisted) {
    }

    protected final boolean isNew() {
        return this.info == getDefaultInfo();
    }
    
    protected final boolean infoIdenticalTo(ElementInfo info) {
        return this.info == info;
    }

    /** This method is called from parent to set ASTInfo of this element. It can be called
     * basically in two cases:
     * 
    *
  • object was not initialized - it needs AST info to be able to read value of some of its attributes *
  • object was changed externally (in editor) - it gets an updated AST and needs to fire * match it with the original AST and fire appropriate change events *
* This method should not be called for new objects. setNew should be called instead. */ protected final void setElementInfo(ElementInfo info) { if (infoIdenticalTo(info)) return; boolean changes = disableChanges; disableChanges = true; try { if (isInitialized()) { // whole ASTInfo should be matched matchElementInfo(info); } this.info = info; hardRefParent(true); // go down via containment hierarchy and force ASTInfo renewal if (childrenInited) { initChildren(); } } finally { disableChanges = changes; } resetChange(); } protected void hardRefParent(boolean enabled) { parent = enabled ? refImmediateComposite() : null; } protected void parentChanged() { parent = refImmediateComposite(); if (parent == null || ((BaseObjectHandler) parent)._getDelegate() instanceof DeferredObject) { if (!(_getDelegate() instanceof DeferredObject)) mutate(true); // make object transient parent = null; } else { if (_getDelegate() instanceof DeferredObject) mutate(false); // make object persistent } } protected void mutate(boolean makeTransient) { StorableObject newDelegate; StorableObject oldDelegate = (StorableObject) _getDelegate(); try { if (makeTransient) { newDelegate = new DeferredObject(oldDelegate); } else { newDelegate = new StorableObject(oldDelegate); } _setDelegate(newDelegate); oldDelegate.clearComposite(); oldDelegate.deleteInstance(); } catch (StorageException e) { throw (RuntimeException) ErrorManager.getDefault().annotate(new RuntimeException(), e); } } public final ElementInfo getElementInfo() { initCheck(); if (info == null && (_getDelegate() instanceof StorableObject)) { String name; if (this instanceof JavaClass) { name = getName(); } else { name = ""; } JMManager.getLog().notify(ErrorManager.INFORMATIONAL, new Exception("***** Info is null for element: " + getName() + " (instanceof: " + getClass().getName() + " MOFID: " + refMofId() + ")")); if (this instanceof JavaClass) { JavaClass replacement = null; SemiPersistentElement composite = (SemiPersistentElement) refImmediateComposite(); if (composite == null) { JMManager.getLog().log(" composite is null - need to find the class with the same name in index..."); JMManager.getLog().log(" classindex classes for the same FQN in this extent:"); for (Iterator it = ClassIndex.getIndex((JavaModelPackage) refImmediatePackage()).getClassesByFqn(getName()).iterator(); it.hasNext();) { JavaClass feat = (JavaClass) it.next(); JMManager.getLog().log(" " + feat.getName() + " (instanceof: " + feat.getClass().getName() + " MOFID: " + feat.refMofId() + ")" + (refMofId().equals(feat.refMofId()) && feat != this ? " !! same MOFID as me, but different object" : "") + (feat.refImmediateComposite() == null ? " !! composite is null" : "")); if (!equals(feat)) { replacement = feat; } } } else { JMManager.getLog().log(" composite contains the following features: "); List features; if (composite instanceof JavaClass) { features = ((JavaClass) composite).getFeatures(); } else { features = ((Resource) composite).getClassifiers(); } for (Iterator it = features.iterator(); it.hasNext();) { Feature feat = (Feature) it.next(); JMManager.getLog().log(" " + feat.getName() + " (instanceof: " + feat.getClass().getName() + " MOFID: " + feat.refMofId() + ")" + (refMofId().equals(feat.refMofId()) && feat != this ? " !! same MOFID as me, but different object" : "")); if ((feat instanceof JavaClass) && Utilities.compareObjects(feat.getName(), getName())) { replacement = (JavaClass) feat; } } } if (replacement == null) { JMManager.getLog().log("No suitable replacement found in index - we need to create a fake info for class."); setNew(); } else { JMManager.getLog().log("Acquired info from a replacement class: " + replacement.refMofId()); this.info = ((SemiPersistentElement) replacement).info; } } else { setNew(); } ((JMManager) JMManager.getManager()).getTransactionMutex().invalidateAtCommit(this); } return info; } public final boolean isInitialized() { return info != null; } protected void uninitialize() { info = null; hardRefParent(false); } protected void checkUpToDate() { if (!isUpToDate) { if (this instanceof ResourceImpl) { ((ResourceImpl) this).checkUpToDate(true, null, false); } else { SemiPersistentElement parent = (SemiPersistentElement) refImmediateComposite(); // the element must have a parent // with an exception of Resource if (parent != null) { parent.checkUpToDate(); if (!isPersisted()) { initCheck(); } } } } } protected void persist() { if (!recentlyPersisted) { recentlyPersisted = true; Object parent = refImmediateComposite(); if (parent instanceof SemiPersistentElement) { if (!((SemiPersistentElement) parent).recentlyPersisted) { ((ExclusiveMutex) _getMdrStorage().getRepositoryMutex()).registerPersisted(this); } } } } public void clearPersist(boolean fail) { if (fail) { isUpToDate = false; if (!isPersisted()) { updatePersistent(info); } } else { recentlyPersisted = false; } } public boolean isPersisted() { return false; } /** * Find referenced resources of this element */ Resource[] findReferencedResources() { return new Resource[] {getResource()}; } public Collection getReferences() { Resource[] res = findReferencedResources(); UsageFinder finder = new UsageFinder(this); return finder.getUsers(res); } /** Should be overriden by elements that have persistent attributes. * They should implement this method to compare values in newly passed AST info with * values of the persistent attributes and if the values do not match, they should be * updated and proper events should be fired. */ protected void matchPersistent(ElementInfo info) { isUpToDate = true; matchName(info); } protected final void updatePersistent(ElementInfo info) { boolean changes = disableChanges; disableChanges = true; try { matchPersistent(info); } finally { disableChanges = changes; } } protected void matchName(ElementInfo info) { if ((this instanceof NamedElement) && !Utilities.compareObjects(info.name, this.getName())) { setName(info.name); } } protected abstract ElementInfo getDefaultInfo(); /** The method has to make sure that the AST infos of children are also updated. */ protected void matchElementInfo(ElementInfo newInfo) { if (info.infoType!=newInfo.infoType) { if (!(info instanceof ClassInfo) || !(newInfo instanceof ClassInfo)) throw new IllegalArgumentException("Illegal element type "+info.infoType+"!="+newInfo.infoType); // NOI18N } } public void setName(String name) { objectChanged(CHANGED_NAME); super_setName(name); } protected abstract void super_setName(String name); protected static String getInnerIndentation(int level) { StringBuffer indentation = new StringBuffer(); for (int i = 0; i < level; i++) { indentation.append(INDENTATION); } return indentation.toString(); } /** * Return indentation of the element. If the element is new, it asks * for parent's indentation and appends its own. * * @return indentation */ protected String getIndentation() { super.getIndentation(); if (isNew()) { // For the new element it asks parent (immediateComposite) // for its indentation and appends its own indentation. return ((MetadataElement) refImmediateComposite()).getIndentation().concat(INDENTATION); } else { // For the existing element, it tries to analyze element to // get the indentation. It asks parent for its indentation, // takes its paddings. In the paddings, it looks for the nearest // end-line char to the first token. Difference between end-line // character and first char of the first token is parent's // indentation. Token firstToken = getParser().getToken(getASTree().getFirstToken()); Token[] pad = firstToken.getPadding(); Token endLine = null; for (int i = pad.length-1; i >= 0; i--) { if (pad[i].getType() == ParserTokens.EOL) { endLine = pad[i]; break; } } if (endLine != null) { String src = getParser().getSourceText(); return src.substring(endLine.getEndOffset(), firstToken.getStartOffset()); } else { // todo (#pf): what to do when there is no endline character // before the first token? -- now, it indents from the line // beginning. return ""; } } } /** * Returns indentation of the body of element * * @return indentation of the body of element */ protected String getBodyIndentation() { return getIndentation().concat(INDENTATION); } private void deleteCollection(Collection col) { RefObject delArr[]=(RefObject[])col.toArray(new RefObject[col.size()]); int i; col.clear(); for (i=0;i
... 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.