Package org.apache.muse.ws.notification.topics.impl

Source Code of org.apache.muse.ws.notification.topics.impl.SimpleTopic

/*=============================================================================*
*  Copyright 2006 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*=============================================================================*/

package org.apache.muse.ws.notification.topics.impl;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import javax.xml.namespace.QName;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.muse.util.messages.Messages;
import org.apache.muse.util.messages.MessagesFactory;
import org.apache.muse.util.xml.XPathUtils;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.util.xml.XsdUtils;
import org.apache.muse.ws.resource.basefaults.BaseFault;
import org.apache.muse.ws.notification.NotificationMessage;
import org.apache.muse.ws.notification.faults.InvalidTopicExpressionFault;
import org.apache.muse.ws.notification.topics.Topic;
import org.apache.muse.ws.notification.topics.TopicPathExpression;
import org.apache.muse.ws.notification.topics.TopicNamespace;
import org.apache.muse.ws.notification.topics.WstConstants;

/**
*
* SimpleTopic is Muse's default implementation of the wsnt:Topic data structure
* defined in WS-Notification v1.3 and WS-Topics v1.3.
*
* @author Dan Jemiolo (danj)
*
*/

public class SimpleTopic implements Topic
{
    private static Messages _MESSAGES = MessagesFactory.get(SimpleTopic.class);
   
    //
    // keep children in the order they were added for serialization purposes
    //
    private Map _childTopics = new LinkedHashMap();
   
    //
    // the last message published for this topic
    //
    private NotificationMessage _currentMessage = null;
   
    private boolean _isFinal = false;
   
    private String _messagePattern = null;

    private Set _messageTypes = new HashSet();

    private String _name = null;
   
    private Topic _parentTopic = null;
   
    private TopicNamespace _topicSpace = null;
   
    public SimpleTopic(Element root, TopicNamespace topicSpace)
        throws InvalidTopicExpressionFault, BaseFault
    {
        if (root == null)
            throw new NullPointerException(_MESSAGES.get("NullTopicElement"));
       
        if (topicSpace == null)
            throw new NullPointerException(_MESSAGES.get("NullTopicSpace"));

        _topicSpace = topicSpace;
       
        _name = root.getAttribute(XsdUtils.NAME);
       
        if (_name == null || _name.length() == 0)
            throw new InvalidTopicExpressionFault(_MESSAGES.get("NoTopicName"));
       
        String finalValue = root.getAttribute(WstConstants.FINAL);
       
        if (finalValue != null && finalValue.length() > 0)
            _isFinal = Boolean.valueOf(finalValue).booleanValue();
       
        String messageTypesValue = root.getAttribute(WstConstants.MESSAGE_TYPES);
       
        if (messageTypesValue != null && messageTypesValue.length() > 0)
        {
            String[] values = messageTypesValue.split(" ");
           
            for (int n = 0; n < values.length; ++n)
            {
                QName qname = XmlUtils.parseQName(values[n], root);
                _messageTypes.add(qname);
            }
        }
       
        _messagePattern = XmlUtils.getElementText(root, WstConstants.PATTERN_QNAME);
       
        Element[] children = XmlUtils.getElements(root, WstConstants.TOPIC_QNAME);
       
        for (int n = 0; n < children.length; ++n)
        {
            SimpleTopic topic = new SimpleTopic(children[n], topicSpace);
            addTopicEvenIfFinal(topic);
        }
    }
   
    public SimpleTopic(String name, TopicNamespace topicSpace)
        throws BaseFault
    {
        if (name == null)
            throw new NullPointerException(_MESSAGES.get("NullTopicName"));
       
        if (topicSpace == null)
            throw new NullPointerException(_MESSAGES.get("NullTopicSpace"));
       
        _topicSpace = topicSpace;
       
        int slash = name.indexOf('/');
        int end = slash >= 0 ? slash : name.length();
        _name = name.substring(0, end);
               
        if (end < name.length())
        {
            String childName = name.substring(end + 1);
            addTopic(new SimpleTopic(childName, topicSpace));
        }
    }
   
    public synchronized final void addMessageType(QName messageType)
    {
        if (messageType == null)
            throw new NullPointerException(_MESSAGES.get("NullMessageType"));
       
        _messageTypes.add(messageType);
    }
   
    public synchronized final void addTopic(Topic childTopic)
        throws InvalidTopicExpressionFault, BaseFault
    {
        if (childTopic == null)
            throw new NullPointerException(_MESSAGES.get("NullTopic"));
       
        if (isFinal())
        {
            Object[] filler = { getConcretePath() };
            throw new InvalidTopicExpressionFault(_MESSAGES.get("NoNewTopics", filler));
        }
       
        addTopicEvenIfFinal(childTopic);
    }
   
    private void addTopicEvenIfFinal(Topic childTopic)
        throws InvalidTopicExpressionFault, BaseFault
    {
        String name = childTopic.getName();
       
        if (_childTopics.containsKey(name))
        {
            Object[] filler = { name, getConcretePath() };
            throw new InvalidTopicExpressionFault(_MESSAGES.get("SubTopicExists", filler));
        }
       
        String topicNS = childTopic.getTopicNamespace().getTargetNamespace();
        String targetNS = getTopicNamespace().getTargetNamespace();
       
        if (!targetNS.equals(topicNS))
        {
            Object[] filler = { topicNS, targetNS };
            throw new InvalidTopicExpressionFault(_MESSAGES.get("InvalidTopicNS", filler));
        }
       
        childTopic.setParentTopic(this);
       
        _childTopics.put(name, childTopic);
    }
   
    /**
     *
     * @return True if the two topics have the same local name, topic namespace,
     *         concrete path, message pattern, and 'final' status.
     *        
     */
    public synchronized boolean equals(Object obj)
    {
        if (obj == null)
            return false;
       
        Topic that = (Topic)obj;
       
        if (!getName().equals(that.getName()))
            return false;
       
        String thisNS = getTopicNamespace().getTargetNamespace();
        String thatNS = that.getTopicNamespace().getTargetNamespace();
       
        if (!thisNS.equals(thatNS))
            return false;
       
        if (!getConcretePath().equals(that.getConcretePath()))
            return false;

        if (isFinal() != that.isFinal())
            return false;
       
        String thisPattern = getMessagePattern();
        String thatPattern = that.getMessagePattern();
       
        if (thisPattern != null)
            return thisPattern.equals(thatPattern);
       
        return thatPattern == null;
    }
   
    public synchronized QName getConcretePath()
    {
        TopicPathExpression path = new ConcretePathExpression(this);
        return path.getTopicPath();
    }
   
    public synchronized NotificationMessage getCurrentMessage()
    {
        return _currentMessage;
    }
   
    /**
     *
     * @return An XPath that further expresses the types of messages
     *         this topic publishes.
     *
     */
    public synchronized String getMessagePattern()
    {
        return _messagePattern;
    }
   
    /**
     *
     * @return The XPath 1.0 namespace.
     *
     */
    public String getMessagePatternDialect()
    {
        return XPathUtils.NAMESPACE_URI;
    }
   
    public Set getMessageTypes()
    {
        return Collections.unmodifiableSet(_messageTypes);
    }
   
    public final String getName()
    {
        return _name;
    }
   
    public synchronized Topic getParentTopic()
    {
        return _parentTopic;
    }
   
    public synchronized Topic getTopic(String topicName)
    {
        return (Topic)_childTopics.get(topicName);
    }
   
    public synchronized TopicNamespace getTopicNamespace()
    {
        return _topicSpace;
    }
   
    public synchronized Collection getTopics()
    {
        return Collections.unmodifiableCollection(_childTopics.values());
    }
   
    /**
     *
     * @return A hash code based on the same values used for testing equality.
     *
     * @see #equals(Object)
     *
     */
    public synchronized int hashCode()
    {
        String pattern = getMessagePattern();
        String ns = getTopicNamespace().getTargetNamespace();
       
        return getName().hashCode() +
               ns.hashCode() +
               getConcretePath().hashCode() +
               ( isFinal() ? 1 : 0 ) +
               ( pattern == null ? 0 : pattern.hashCode());
    }
   
    public synchronized boolean hasTopic(String topicName)
    {
        return getTopic(topicName) != null;
    }
   
    public synchronized boolean isFinal()
    {
        return _isFinal;
    }
   
    public synchronized boolean isRootTopic()
    {
        return getParentTopic() == null;
    }
   
    public synchronized final void removeAllTopics()
    {
        _childTopics.clear();
    }
   
    public synchronized final void removeMessageType(QName messageType)
    {
        if (messageType == null)
            throw new NullPointerException(_MESSAGES.get("NullMessageType"));
       
        _messageTypes.remove(messageType);
    }
   
    public synchronized final void removeTopic(String topicName)
    {
        if (topicName == null)
            throw new NullPointerException(_MESSAGES.get("NullTopicName"));
       
        _childTopics.remove(topicName);
    }
   
    public void setCurrentMessage(NotificationMessage message)
    {
        _currentMessage = message;
    }
   
    public synchronized void setFinal(boolean isFinal)
    {
        _isFinal = isFinal;
    }
   
    public synchronized void setMessagePattern(String messagePattern)
    {
        _messagePattern = messagePattern;
    }
   
    public synchronized void setParentTopic(Topic parentTopic)
    {
        _parentTopic = parentTopic;
    }
   
    public synchronized String toString()
    {
        return XmlUtils.toString(toXML(), false);
    }
   
    public synchronized Element toXML()
    {
        return toXML(XmlUtils.EMPTY_DOC);
    }
   
    public synchronized Element toXML(Document doc)
    {
        if (doc == null)
            throw new NullPointerException(_MESSAGES.get("NullDocument"));
       
        Element root = XmlUtils.createElement(doc, WstConstants.TOPIC_QNAME);
       
        root.setAttribute(XsdUtils.NAME, getName());
        root.setAttribute(XmlUtils.TARGET_NS, getTopicNamespace().getTargetNamespace());
        root.setAttribute(WstConstants.FINAL, Boolean.toString(isFinal()));
       
        String pattern = getMessagePattern();
       
        if (pattern != null)
        {
            Element patternXML =
                XmlUtils.createElement(doc, WstConstants.PATTERN_QNAME, pattern);
            root.appendChild(patternXML);
           
            patternXML.setAttribute(WstConstants.DIALECT, XPathUtils.NAMESPACE_URI);
        }
       
        Set messageTypes = getMessageTypes();
       
        if (!messageTypes.isEmpty())
        {
            Iterator i = messageTypes.iterator();
           
            int size = messageTypes.size();
            StringBuffer buffer = new StringBuffer(size * 128);
           
            for (int n = 1; i.hasNext(); ++n)
            {
                QName messageName = (QName)i.next();
                buffer.append(XmlUtils.toString(messageName));
               
                if (n != size)
                    buffer.append(' ');
            }
           
            root.setAttribute(WstConstants.MESSAGE_TYPES, buffer.toString());
        }
       
        Iterator i = getTopics().iterator();
       
        while (i.hasNext())
        {
            Topic topic = (Topic)i.next();
            Element topicXML = topic.toXML(doc);
            root.appendChild(topicXML);
        }
       
        return root;
    }
}
TOP

Related Classes of org.apache.muse.ws.notification.topics.impl.SimpleTopic

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.