FileDocCategorySizeDatePackage
MessageDestinationReferencerImpl.javaAPI DocGlassfish v2 API10545Fri May 04 22:31:22 BST 2007com.sun.enterprise.deployment

MessageDestinationReferencerImpl.java

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
package com.sun.enterprise.deployment;

import com.sun.enterprise.deployment.types.MessageDestinationReferencer;
import java.io.Serializable;
import java.util.Set;
import java.util.Iterator;

/**
 * Shared implementation for deployment descriptor entities that can refer
 * to a message destination.  Each MessageDestinationReferencer has an
 * owner.  The owner can either be a MessageDestinationReference
 * or a MessageDrivenBean. 
 *
 * @author Kenneth Saks
 *
*/

public class MessageDestinationReferencerImpl implements 
    MessageDestinationReferencer, Serializable {

    // holds the name of the message destination link.
    private String messageDestinationLinkName=null;

    // In case the reference has been resolved, this points to the
    // referenced message destination.
    private MessageDestinationDescriptor messageDestination=null;

    private MessageDestinationReferenceDescriptor ownerMsgDestRef = null;
    private EjbMessageBeanDescriptor ownerMsgBean = null;

    public MessageDestinationReferencerImpl(MessageDestinationReferencerImpl other) {
	//super(other);
	messageDestinationLinkName = other.messageDestinationLinkName; // immutable String
	messageDestination = other.messageDestination; // copy as-is
	ownerMsgDestRef = other.ownerMsgDestRef; // copy as-is
	ownerMsgBean = other.ownerMsgBean; // copy as-is
    }

    public MessageDestinationReferencerImpl(Descriptor desc) {
        if( desc instanceof MessageDestinationReferenceDescriptor ) {
            ownerMsgDestRef = (MessageDestinationReferenceDescriptor) desc;
        } else if( desc instanceof EjbMessageBeanDescriptor ) {
            ownerMsgBean = (EjbMessageBeanDescriptor) desc;
        } else {
            throw new IllegalArgumentException("Invalid desc = " + desc);
        }
    }

    /**
     * True if the owner is a message destination reference.
     */ 
    public boolean ownedByMessageDestinationRef() {
        return (ownerMsgDestRef != null);
    }

    /**
     * Get the descriptor for the message destination reference owner.
     */ 
    public MessageDestinationReferenceDescriptor getMessageDestinationRefOwner
        () {
        return ownerMsgDestRef;
    }

    /**
     * True if the owner is a message-driven bean.
     */ 
    public boolean ownedByMessageBean() {
        return (ownerMsgBean != null);
    }


    /**
     * Get the descriptor for the message-driven bean owner.
     */ 
    public EjbMessageBeanDescriptor getMessageBeanOwner() {
        return ownerMsgBean;
    }

    /**
     * True if this reference has been resolved to a valid MessageDestination
     * object.
     */
    public boolean isLinkedToMessageDestination() {
	return (messageDestination != null);
    }
    
    private BundleDescriptor getBundleDescriptor() {
        return ownedByMessageDestinationRef() ?
            ownerMsgDestRef.getReferringBundleDescriptor() :
            ownerMsgBean.getEjbBundleDescriptor();
    }

    /** 
     * @return the link name of the message destination to which I refer 
     * NOTE that this "link name" is potentially different from the actual 
     * name of the target message destination, since the message destination 
     * could be defined in a different module.
     */
    public String getMessageDestinationLinkName() {
        return messageDestinationLinkName;
    }

    /** 
     * Sets the name of the message destination to which I refer.
     * NOTE : Does *NOT* attempt to resolve link name.  Use 
     * alternate version of setMessageDestinationLinkName or resolveLink
     * if link resolution is required.
     */
    public void setMessageDestinationLinkName(String linkName) {
        setMessageDestinationLinkName(linkName, false);
    }    


    /** 
     * Sets the name of the message destination to which I refer.
     * @param resolve if true,  *try* to resolve link to the target message
     * destination.  
     *
     * @return MessageDestination to which link was resolved, or null if 
     * link name resolution failed.
     */
    public MessageDestinationDescriptor setMessageDestinationLinkName
        (String linkName, boolean resolve) {
                                                            
        messageDestinationLinkName = linkName;
        MessageDestinationDescriptor msgDest = null;        

        if( resolve ) {
            msgDest = resolveLinkName();
        }
        return msgDest;
    }    

    /** 
     * Try to resolve the current link name value to a MessageDestination
     * object.
     *
     * @return MessageDestination to which link was resolved, or null if 
     * link name resolution failed.
     */
    public MessageDestinationDescriptor resolveLinkName() {
        MessageDestinationDescriptor msgDest = null;

        String linkName = messageDestinationLinkName;

        if( (linkName != null) && (linkName.length() > 0) ) {
            int hashIndex = linkName.indexOf('#');

            BundleDescriptor bundleDescriptor = getBundleDescriptor();
            Application app = bundleDescriptor.getApplication();
            BundleDescriptor targetBundle = bundleDescriptor;
            String msgDestName = linkName;
            
            if( app != null ) {

                // explicit reference to another module
                if( hashIndex != -1 )  {
                    String relativeModuleUri = linkName.substring(0, hashIndex);
                    msgDestName = linkName.substring(hashIndex + 1);
                    targetBundle = app.getRelativeBundle(bundleDescriptor,
                                                         relativeModuleUri);
                } else {
                    // Default is to find message destination within this
                    // module.  If it's not there, try searching the other
                    // modules.  NOTE that it's up to the deployer to ensure
                    // that any message destinations that are referred to
                    // from outside the defining module without an explicit
                    // reference have names that are unique within all the
                    // message destinations in the .ear.  There is no 
                    // required search ordering.  
                    if( !bundleDescriptor.hasMessageDestinationByName
                          (msgDestName) ) {
                        Set modules = app.getBundleDescriptors();
                        for(Iterator iter = modules.iterator(); iter.hasNext();)
                        {
                            BundleDescriptor next=(BundleDescriptor)iter.next();
                            if( next.hasMessageDestinationByName(msgDestName) ) {
                                targetBundle = next;
                                break;
                            }
                        }
                    }
                }
            }
            try {
                if( targetBundle != null ) {
                    msgDest = targetBundle.getMessageDestinationByName
                        (msgDestName);
                }
            } catch(IllegalArgumentException iae) {}
        }
        if( msgDest != null ) {
            setMessageDestination(msgDest);
        }

        return msgDest;
    }
        
    /** 
     * @return the message destination to which I refer. Can be NULL.
    */
    public MessageDestinationDescriptor getMessageDestination() {
	return messageDestination;
    }  

    /**
     * @param messageDestiation the message destination to which I refer.
     */
    public void setMessageDestination(MessageDestinationDescriptor newMsgDest) {
        if( messageDestination != null ) {
            messageDestination.removeReferencer(this);
        }
        if( newMsgDest != null ) {
            newMsgDest.addReferencer(this);

            // Keep message destination link name in synch with message 
            // destination object.
            BundleDescriptor bundleDescriptor = getBundleDescriptor();
            BundleDescriptor targetBundleDescriptor = 
                newMsgDest.getBundleDescriptor();
            String linkName = newMsgDest.getName();
            if( bundleDescriptor != targetBundleDescriptor ) {
                Application app = bundleDescriptor.getApplication();
                String relativeUri = app.getRelativeUri(bundleDescriptor,
                                                        targetBundleDescriptor);
                linkName = relativeUri + "#" + linkName;
            }
            messageDestinationLinkName = linkName;
        }
        messageDestination = newMsgDest;
    }

}