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.mdr.storagemodel;

import java.util.*;
import javax.jmi.reflect.*;
import javax.jmi.model.*;
import java.io.*;

import org.netbeans.mdr.handlers.*;
import org.netbeans.mdr.persistence.*;
import org.netbeans.mdr.util.*;
import org.netbeans.mdr.handlers.gen.TagSupport;

/** Storage object representing association proxy.
 *
 * @author Martin Matula, Pavel Buzek
 * @version 0.2
 */
public class StorableAssociation extends StorableBaseObject implements Streamable {

    /** Storage index for the first end (initialized lazily by getIndex method) */
    private transient Index aIndex;
    /** Storage index for the second end (initialized lazily by getIndex method) */
    private transient Index bIndex;
    /** name of the first end */
    private String endA;
    /** name of the second end */
    private String endB;

    private org.netbeans.mdr.persistence.MOFID endAId;
    private org.netbeans.mdr.persistence.MOFID endBId;

    private transient boolean multiValuedA;
    private transient boolean multiValuedB;

    private int minA, maxA;
    private int minB, maxB;
    private transient Class typeA;
    private transient Class typeB;
    private int typeANameIndex;
    private int typeBNameIndex;
    private boolean orderedA;
    private boolean orderedB;
    private boolean aggrA;
    private boolean aggrB;
    private boolean indexedA, indexedB;
    private Class associationSuperclass = null;
    private final Object superclassMutex = new Object();

    /** Creates new instance of association proxy.
     * This default constructor is to be called only when deserializing the association proxy.
     * Calling this constructor should be followed by read method invokation.
     */
    public StorableAssociation() {
        super();
    }

    /** Replaces MOFIDs using the passed map. (This method is used when rebuilding metaobjects.)
     * @param table Map of old MOFIDs to new MOFIDs.
     */
    protected void replaceValues(Map table) {
        objectWillChange();
        org.netbeans.mdr.persistence.MOFID backup1 = endAId;
        org.netbeans.mdr.persistence.MOFID backup2 = endBId;

        super.replaceValues(table);
        endAId = (org.netbeans.mdr.persistence.MOFID) table.get(endAId);
        endBId = (org.netbeans.mdr.persistence.MOFID) table.get(endBId);

        objectChanged();
    }

    /** Creates new instance of association proxy providing all needed arguments.
     * @param mdrStorage parent storage of created association proxy being created
     * @param immediatePackage MOFID of association proxy immediate package
     * @param MOFID of meta association proxy meta object
     * @param endAMofid MOFID of the first association end
     * @param endBMofid MOFID of the second association end
     * @param multiValuedA true if the first end is multivalued
     * @param multiValuedB true if the second end is multivalued
     * @param orderedA true if the first end is ordered
     * @param orderedB true if the second end is ordered
     * @param uniqueA true if the first end is unique
     * @param uniqueB true if the second end is unique
     * @param aggrA true if the first end is aggregate
     * @param aggrB true if the second end is aggregate
     * @throws StorageException problem in storage occurred during association proxy creation
     */
    public StorableAssociation(MdrStorage mdrStorage, org.netbeans.mdr.persistence.MOFID immediatePackage, org.netbeans.mdr.persistence.MOFID meta,
        String endA, org.netbeans.mdr.persistence.MOFID endAId, String endB, org.netbeans.mdr.persistence.MOFID endBId, Class typeA, Class typeB,
        int minA, int maxA, int minB, int maxB, boolean orderedA, boolean orderedB,
        boolean uniqueA, boolean uniqueB, boolean aggrA, boolean aggrB,
        boolean indexedA, boolean indexedB) throws StorageException {

            super(mdrStorage, immediatePackage, meta);

        //Logger.getDefault().log("association: endA: " + endA + ", endB: " + endB);
        this.endA = endA;
        this.endB = endB;
        this.endAId = endAId;
        this.endBId = endBId;
        this.orderedA = orderedA;
        this.orderedB = orderedB;
        this.multiValuedA = (maxA != 1);
        this.multiValuedB = (maxB != 1);
        this.aggrA = aggrA;
        this.aggrB = aggrB;
        this.minA = minA;
        this.minB = minB;
        this.maxA = maxA;
        this.maxB = maxB;
        this.typeA = typeA;
        this.typeB = typeB;
        this.indexedA = indexedA;
        this.indexedB = indexedB;
        this.typeANameIndex = mdrStorage.values(this.getMofId()).store(typeA.getName());
        this.typeBNameIndex = mdrStorage.values(this.getMofId()).store(typeB.getName());
        aIndex = createIndex(multiValuedA, orderedA, uniqueA, 1);
        bIndex = createIndex(multiValuedB, orderedB, uniqueB, 2);

        getMdrStorage().addObject(this);
        initFinished = true;
    }
    
    public Class getAssociationSuperclass() throws StorageException, ClassNotFoundException {
        if (associationSuperclass == null) {
            synchronized (superclassMutex) {
                if (associationSuperclass == null) {
                    objectWillChange();
                    associationSuperclass = resolveAssociationSuperclass();
                    objectChanged();
                }
            }
        }
        return associationSuperclass;
    }
    
    private Class resolveAssociationSuperclass() throws StorageException, ClassNotFoundException {
        try {
            return BaseObjectHandler.resolveImplementation(TagSupport.getImplFullName(getMetaObject(), TagSupport.ASSOCIATION));
        } catch (ClassNotFoundException e) {
//            if (((Boolean) getMetaObject().getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_IS_DERIVED)).booleanValue())
//                throw e;
            return AssociationHandler.class;
        }
    }

    public Class getAssociationCustomImpl() {
        try {
            Class sup = getAssociationSuperclass();
            return sup == AssociationHandler.class ? null : sup;
        } catch (Exception e) {}
        return null;
    }

    /** Returns multiplicity of the first association end.
     * @return true if the upper bound of association end is greater than 1
     */
    public boolean isMultivaluedA () {
        return multiValuedA;
    }

    /** Returns multiplicity of the second association end.
     * @return true if the upper bound of association end is greater than 1
     */
    public boolean isMultivaluedB () {
        return multiValuedB;
    }

    /** Returns true if the first association end is ordered.
     * @return true if the association end is ordered
     */
    public boolean isOrderedA () {
        return orderedA;
    }

    /** Returns true if the second association end is ordered.
     * @return true if the association end is ordered
     */
    public boolean isOrderedB () {
        return orderedB;
    }

    /**
     * @return
     */
    public boolean isAggregateA() {
        return aggrA;
    }

    /**
     * @return
     */
    public boolean isAggregateB() {
        return aggrB;
    }

    /** Returns true if the first association end is indexed.
     * @return true if the association end is indexed
     */
    public boolean isIndexedA() {
        return indexedA;
    }

    /** Returns true if the second association end is indexed.
     * @return true if the association end is indexed
     */
    public boolean isIndexedB() {
        return indexedB;
    }

    /**
     * @return
     */
    public String getEnd1Name() {
        return this.endA;
    }

    /**
     * @return
     */
    public String getEnd2Name() {
        return this.endB;
    }
    
    public org.netbeans.mdr.persistence.MOFID getEnd1Id () {
        return this.endAId;
    }
    
    public org.netbeans.mdr.persistence.MOFID getEnd2Id () {
        return this.endBId;
    }

    /**
     * @param a
     * @param b
     * @throws StorageException
     * @return
     */
    public boolean linkExists (org.netbeans.mdr.persistence.MOFID a, org.netbeans.mdr.persistence.MOFID b) throws StorageException {
        if (isMultivaluedB()) {
            return ((MultivaluedIndex) bIndex).getItems(a).contains(b);
        } else {
            return b.equals(((SinglevaluedIndex) bIndex).getIfExists(a));
        }
    }

    /**
     * Returns immutable, live collection of all links managed by this association
     * proxy.
     *
     * @throws StorageException
     * @return immutable, live collection of all links
     */
    public Collection getAllLinks() throws StorageException {
        return new LinkSetCollection();
    }

    /**
     * @param endMofid
     * @param obj
     * @throws StorageException
     * @return
     */
    public Object queryObjects(String endName, org.netbeans.mdr.persistence.MOFID obj) throws StorageException {
        //Logger.getDefault().log("query: end: " + endName + ", endA:" + endA + ", endB:" + endB);
        boolean isEndA = endName.equals(endB);
        boolean multi = isEndA ? multiValuedA : multiValuedB;
        boolean order = isEndA ? orderedA : orderedB;
        Index index = isEndA ? aIndex : bIndex;
        Index secondIndex = isEndA ? bIndex : aIndex;
        Class type = isEndA ? typeA : typeB;
        int min = isEndA ? minA : minB;
        int max = isEndA ? maxA : maxB;
        org.netbeans.mdr.persistence.MOFID endId, otherEndId;
        boolean isIndexed, isOtherIndexed;
        if (isEndA) {
            endId = endAId;
            otherEndId = endBId;
            isIndexed = indexedA;
            isOtherIndexed = indexedB;
        } else {
            endId = endBId;
            otherEndId = endAId;
            isIndexed = indexedB;
            isOtherIndexed = indexedA;
        }
        boolean aggr = isEndA ? aggrA : aggrB;
        boolean otherAggr = isEndA ? aggrB : aggrA;
        
        Object result;
        if (obj == null) throw new NullPointerException();

        if (multi) {
            if (order) {
                result = new AssocEndIndexUList(this, endId, otherEndId, (MultivaluedOrderedIndex) index, obj, secondIndex, type, max, true, aggr, otherAggr, isIndexed, isOtherIndexed);
            } else {
                result = new AssocEndIndexSet(this, endId, otherEndId, (MultivaluedIndex) index, obj, secondIndex, type, max, true, aggr, otherAggr, isIndexed, isOtherIndexed);
            }
        } else {
            result = getMdrStorage().getObjectFromIndexIfExists((SinglevaluedIndex) index, obj);
        }
        return result;
    }
    
    public void verify(Collection violations) throws StorageException {
        try {
            if (getAssociationSuperclass() == AssociationHandler.class) {
                for (Iterator it = aIndex.keySet().iterator(); it.hasNext();) {
                    verifyEnd(violations, endB, (org.netbeans.mdr.persistence.MOFID) it.next());
                }
                for (Iterator it = bIndex.keySet().iterator(); it.hasNext();) {
                    verifyEnd(violations, endA, (org.netbeans.mdr.persistence.MOFID) it.next());
                }
            }
        } catch (ClassNotFoundException e) {
            throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
        }
    }
    
    public void verifyEnd(Collection violations, String end, org.netbeans.mdr.persistence.MOFID object) throws StorageException {
        try {
            if (getAssociationSuperclass() == AssociationHandler.class) {
                int min = end.equals(endB) ? minA : minB;
                org.netbeans.mdr.persistence.MOFID endId = end.equals(endB) ? endAId : endBId;
                Object result = queryObjects(end, object);
                if ((result == null && min > 0) || 
                    (result instanceof Collection && ((Collection) result).size() < min)) {
                        violations.add(new WrongSizeException((RefObject) getMdrStorage().getRepository().getHandler(getMdrStorage().getObject(endId)),
                            "Not enough objects linked to " + object + " at end '" + end + "'."));
                }
            }
        } catch (ClassNotFoundException e) {
            throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
        }
    }
    
    public void checkType(Object endA, Object endB) {
        try {
            if (endA != null && !typeA.isInstance(endA)) {
                throw new TypeMismatchException(typeB, endB, 
                    (RefObject) getMdrStorage().getRepository().getHandler(getMdrStorage().getObject(endBId)));
            } else if (endB != null && !typeB.isInstance(endB)) {
                throw new TypeMismatchException(typeB, endB, 
                    (RefObject) getMdrStorage().getRepository().getHandler(getMdrStorage().getObject(endBId)));
            }
        } catch (StorageException e) {
            throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
        }
        throw new DebugException();
    }
    
    /**
     * @param a
     * @param b
     * @throws StorageException
     */
    public boolean addLink (org.netbeans.mdr.persistence.MOFID a, org.netbeans.mdr.persistence.MOFID b) throws StorageException {
        if (multiValuedA) {
            return ((Collection) queryObjects(endB, b)).add(a);
        } else if (multiValuedB) {
            return ((Collection) queryObjects(endA, a)).add(b);
        } else {
            try {
                StorableObject oA = null, oB = null;
                oA = (StorableObject) getMdrStorage().getObject(a);
                oB = (StorableObject) getMdrStorage().getObject(b);
                if (indexedA) {
                    oB.removeFromIndex (endAId);
                }
                if (indexedB) {
                    oA.removeFromIndex (endBId);
                }
                // set composites
                if (aggrA) {
                    oB.setComposite(oA, a, endAId);
                } else if (aggrB) {
                    oA.setComposite(oB, b, endBId);
                }
                aIndex.add(b, a);
                bIndex.add(a, b);
                if (indexedA) {
                    oB.addToIndex (endAId);
                }
                if (indexedB) {
                    oA.addToIndex (endBId);
                }

                return true;
            } catch (StorageBadRequestException e) {
                // ignore
                return false;
            }
        }
    }

    /**
     * @param a
     * @param b
     * @throws StorageException
     */
    public boolean removeLink (org.netbeans.mdr.persistence.MOFID a, org.netbeans.mdr.persistence.MOFID b) throws StorageException {
        try {
            StorableObject oA = null, oB = null;
            oA = (StorableObject) getMdrStorage().getObject(a);
            oB = (StorableObject) getMdrStorage().getObject(b);
            if (indexedA) {
                oB.removeFromIndex (endAId);
            }
            if (indexedB) {
                oA.removeFromIndex (endBId);
            }
            // remove composites
            if (aggrA) {
                oB.clearComposite();
            } else if (aggrB) {
                oA.clearComposite();
            }
            removeLinkEnd(b, a, aIndex, multiValuedA);
            removeLinkEnd(a, b, bIndex, multiValuedB);
            if (indexedA) {
                oB.addToIndex (endAId);
            }
            if (indexedB) {
                oA.addToIndex (endBId);
            }
            return true;
        } catch (StorageBadRequestException e) {
            return false;
        }
    }

    protected Index getIndex(String end) throws StorageException {
        if (end.equals(endA)) {
            return aIndex;
        } else if (end.equals(endB)) {
            return bIndex;
        } else {
            return null;
        }
    }

    /** Find the appropriate index in the storage.
    */
    protected Index findIndex(int end) throws StorageException {
        return getMdrStorage().getIndex(getOutermostPackageId(), getMofId(), end);
    }

    /**
     * @param a
     * @param b
     * @param end
     * @param multi
     * @param order
     * @throws StorageException
     */
    private void removeLinkEnd (org.netbeans.mdr.persistence.MOFID a, org.netbeans.mdr.persistence.MOFID b, Index index, boolean multi) throws StorageException {
        if (multi) {
            ((MultivaluedIndex) index).remove(a, b);
        } else {
            ((SinglevaluedIndex) index).remove(a);
        }
    }

    /**
     * @param multi
     * @param ordered
     * @param unique
     * @param end
     * @throws StorageException
     * @return
     */
    protected Index createIndex (boolean multi, boolean ordered, boolean unique, int end) throws StorageException {
        if (multi) {
            if (ordered) {
                return getMdrStorage().createMultivaluedOrderedIndex(getOutermostPackageId(), getMofId(), end, Storage.EntryType.MOFID, Storage.EntryType.MOFID, unique);
            } else {
                return getMdrStorage().createMultivaluedIndex(getOutermostPackageId(), getMofId(), end, Storage.EntryType.MOFID, Storage.EntryType.MOFID, unique);
            }
        } else {
            return getMdrStorage().createSinglevaluedIndex (getOutermostPackageId(), getMofId(), end, Storage.EntryType.MOFID, Storage.EntryType.MOFID);
        }
    }
    
    protected void deleteIndex (org.netbeans.mdr.persistence.MOFID opkgId, org.netbeans.mdr.persistence.MOFID mofId, int index) throws StorageException {
        getMdrStorage().dropIndex(opkgId, mofId, index);
    }

    protected void deleteRecursive() throws StorageException {
        deleteIndex (getOutermostPackageId(), getMofId(), 1);
        deleteIndex (getOutermostPackageId(), getMofId(), 2);
        super.deleteRecursive();
    }

    /**
     * @param outputStream
     * @throws StorageException
     */
    public void write(java.io.OutputStream outputStream) {
//        if (endA == null || endB == null || endAId == null || endBId == null) throw new NullPointerException();

        super.write (outputStream);

        try {
            IOUtils.write (outputStream, meta, this);
            IOUtils.write (outputStream, immediatePackage, this);
            IOUtils.writeString(outputStream, endA);
            IOUtils.writeString(outputStream, endB);
            IOUtils.write (outputStream, endAId, this);
            IOUtils.write (outputStream, endBId, this);
            IOUtils.writeInt(outputStream, minA);
            IOUtils.writeInt(outputStream, maxA);
            IOUtils.writeInt(outputStream, minB);
            IOUtils.writeInt(outputStream, maxB);
            IOUtils.writeBoolean(outputStream, aggrA);
            IOUtils.writeBoolean(outputStream, aggrB);
            IOUtils.writeBoolean(outputStream, orderedA);
            IOUtils.writeBoolean(outputStream, orderedB);
            IOUtils.writeInt(outputStream, typeANameIndex);
            IOUtils.writeInt(outputStream, typeBNameIndex);
            IOUtils.writeBoolean(outputStream, indexedA);
            IOUtils.writeBoolean(outputStream, indexedB);
        } catch (java.io.IOException e) {
            Logger.getDefault().notify(Logger.INFORMATIONAL, e);
        }
    }

    /**
     * @param inputStream
     * @throws StorageException
     */
    public void read(java.io.InputStream inputStream) {
        super.read (inputStream);
        try {
            meta = (org.netbeans.mdr.persistence.MOFID) IOUtils.read (inputStream,this);
            immediatePackage = (org.netbeans.mdr.persistence.MOFID) IOUtils.read (inputStream, this);

            endA = IOUtils.readString(inputStream);
            endB = IOUtils.readString(inputStream);
            endAId = (org.netbeans.mdr.persistence.MOFID) IOUtils.read (inputStream, this);
            endBId = (org.netbeans.mdr.persistence.MOFID) IOUtils.read (inputStream, this);
            minA = IOUtils.readInt(inputStream);
            maxA = IOUtils.readInt(inputStream);
            minB = IOUtils.readInt(inputStream);
            maxB = IOUtils.readInt(inputStream);
            multiValuedA = (maxA != 1);
            multiValuedB = (maxB != 1);
            aggrA = IOUtils.readBoolean(inputStream);
            aggrB = IOUtils.readBoolean(inputStream);
            orderedA = IOUtils.readBoolean(inputStream);
            orderedB = IOUtils.readBoolean(inputStream);
            typeANameIndex = IOUtils.readInt(inputStream);
            typeBNameIndex = IOUtils.readInt(inputStream);
            aIndex = findIndex(1);
            bIndex = findIndex(2);
            typeA = BaseObjectHandler.resolveInterface((String) getMdrStorage().values(this.getMofId()).resolve(typeANameIndex));
            typeB = BaseObjectHandler.resolveInterface((String) getMdrStorage().values(this.getMofId()).resolve(typeBNameIndex));
            indexedA = IOUtils.readBoolean(inputStream);
            indexedB = IOUtils.readBoolean(inputStream);
        } catch (java.io.IOException e) {
            throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
        } catch (StorageException ex) {
            throw (DebugException) Logger.getDefault().annotate(new DebugException(), ex);
        } catch (ClassNotFoundException e) {
            throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
        }
    }
    
    /* --------------------------------------------------------------------- */
    /* -- LinkSetCollection (inner class) ---------------------------------- */
    /* --------------------------------------------------------------------- */
    
    protected class LinkSetCollection extends AbstractCollection {
        
        public Iterator iterator() {
            return new LinkSetIterator();
        }
        
        public int size() {
            try {
                int size = 0;
                for (Iterator as = bIndex.keySet().iterator(); as.hasNext();) {
                    MOFID aID = (MOFID) as.next();
                    // fetch the first b for the given a, if exists
                    if ( isMultivaluedB() ) {
                        size += getMdrStorage().getObjectsFromIndex((MultivaluedIndex) bIndex, aID).size();
                    } else {
                        size++;
                    }
                }
                return size;
            } catch (StorageException se) {
                throw (DebugException) Logger.getDefault().annotate(new DebugException(), se);
            }
        }
    }
    
    /* --------------------------------------------------------------------- */
    /* -- LinkSetIterator (inner class) ------------------------------------ */
    /* --------------------------------------------------------------------- */
    
    protected class LinkSetIterator implements Iterator {

        boolean initialized = false;
        
        /**
         * Iterator through all instances at the a-side of this association or
         * null before the first access or if a storage problem
         * occured.
         */
        Iterator as = null;
        
        /**
         * MOF ID of the current instance at the a side. null
         * only before the first call to fetchNext().
         */
        org.netbeans.mdr.persistence.MOFID aID = null;
        
        /**
         * Object with ID aID or null if not yet
         * retrieved.
         */
        StorableObject a = null;
        
        /**
         * If the association if multi-valued at b's end, bs
         * contains the iterator for the b's associated with the current a.
         * Shall only be accessed inside fetchNext().
         */
        Iterator bs = null;
        
        /**
         * The current b object, null initially and after the
         * last link has been retrieved.
         */
        StorableObject b = null;
        
        private void initCheck() {
            if ( ! initialized ) {
                initialized = true;
                try {
                    as = bIndex.keySet().iterator();
                } catch ( StorageException se ) {
                    // [XXX]: probably throw a DebugException here
                    as = null;
                }
                fetchNext();
            }
        }
        
        private void fetchNext() {
            if ( as == null ) {
                return;
            }
            b = null;
            //  check if there is yet another b for the current a
            if ( bs != null ) {
                if ( bs.hasNext() ) {
                    b = (StorableObject) bs.next();
                    return;
                }
            }
            
            try {
                // fetch the next a
                while ( as.hasNext() ) {
                    aID = (org.netbeans.mdr.persistence.MOFID) as.next();
                    a = null;
                    // fetch the first b for the given a, if exists
                    if ( isMultivaluedB() ) {
                        bs = getMdrStorage().getObjectsFromIndex((MultivaluedIndex) bIndex, aID).iterator();
                        if ( bs.hasNext() ) {
                            b = (StorableObject) bs.next();
                        }
                    } else {
                        b = (StorableObject) getMdrStorage().getObjectFromIndexIfExists((SinglevaluedIndex) bIndex, aID);
                    }
                    // check, if a b was found, return, if yes
                    if ( b != null ) {
                        return;
                    }
                }
            } catch (StorageException se) {
                // [XXX]: probably throw a DebugException here
                as = null;
                b = null;
            }
            
            // there are not more links !
            return;
        }
        
        public boolean hasNext() {
            initCheck();
            return b != null;
        }
        
        public Object next() {
            initCheck();
            if ( b == null ) {
                throw new NoSuchElementException();
            }
            if ( a == null ) {
                try {
                    a = (StorableObject) getMdrStorage().getObject(aID);
                } catch (StorageException se) {
                    // {XXX]: better exception handling
                    throw (DebugException) Logger.getDefault().annotate(new DebugException(), se);
                }
            }
            AssociationLink link = new AssociationLink(a,b);
            fetchNext();
            return link;
        }
        
       /**
        * operation not supported
        */
        public void remove() {
            throw new UnsupportedOperationException();
        }
        
    }
}
... 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.