All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.coos.messaging.Link Maven / Gradle / Ivy

There is a newer version: 1.3.1
Show newest version
/**
 * COOS - Connected Objects Operating System (www.connectedobjects.org).
 *
 * Copyright (C) 2009 Telenor ASA and Tellu AS. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 *
 * You may also contact one of the following for additional information:
 * Telenor ASA, Snaroyveien 30, N-1331 Fornebu, Norway (www.telenor.no)
 * Tellu AS, Hagalokkveien 13, N-1383 Asker, Norway (www.tellu.no)
 */
package org.coos.messaging;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import org.coos.messaging.impl.DefaultProcessor;
import org.coos.messaging.util.Log;
import org.coos.messaging.util.LogFactory;
import org.coos.messaging.util.UuidGenerator;

/**
 * @author Knut Eilif Husa, Tellu AS A link defines the processing used on a
 *         message
 */
public class Link extends DefaultProcessor implements ChannelProcessor {

	public static final String DEFAULT_QOS_CLASS = "defaultQos";
	public static final String ALIASES = "aliases";

	// The uuid of the destination node of this link
	private String destinationUuid;
	// Aliases of the the destination node of this Link
	private Vector aliases = new Vector();
	// The processors that runs on the messages
	private Vector filterProcessors = new Vector();
	// The processor that this link calls after all the filters have been
	// executed
	private Processor linkProcessor;
	// The costmap of this link
	private Hashtable costMap = new Hashtable();
	// The original costmap of this link
	private Hashtable origCostMap;
	// The owning channel of this link.
	private Channel channel;
	// The uuid of this link
	private String linkId;
	//indication whether this is an in or outlink
	private boolean inLink = true;
	
	protected Log log = LogFactory.getLog(this.getClass().getName());

	private static UuidGenerator linkUuid = new UuidGenerator("link");

	public Link() {
		linkId = String.valueOf(linkUuid.generateId());
		costMap.put(DEFAULT_QOS_CLASS, new Integer(0));
	}

	public Link(Channel channel) {
		this();
		costMap.put(DEFAULT_QOS_CLASS, new Integer(0));
		this.channel = channel;
	}

	public Link(int cost) {
		this();
		costMap.put(DEFAULT_QOS_CLASS, new Integer(cost));
	}

	public Link(String uuid, int cost) {
		this();
		this.destinationUuid = uuid;
		costMap.put(DEFAULT_QOS_CLASS, new Integer(cost));
	}
	
	public void setInLink(boolean inLink){
		this.inLink = inLink;
	}
	
	public boolean isInLink(){
		return inLink;
	}
	
	public void setOutLink(boolean outLink){
		this.inLink = !outLink;
	}
	
	public boolean isOutLink(){
		return !inLink;
	}
	

	/**
	 * Add linkProcessor that act as filter, i.e. a linkProcessor that can
	 * inspect the message and pass it on to the next linkProcessor Pattern is
	 * pipes and filters
	 * 
	 * @param processor
	 *            the filter linkProcessor to be added
	 */
	public void addFilterProcessor(Processor processor) {
		if (processor != null) {
			filterProcessors.addElement(processor);
		}
	}

	/**
	 * remove a filter linkProcessor
	 * 
	 * @param processor
	 *            the filter linkProcessor to be removed
	 */
	public void removeFilterProcessor(Processor processor) {
		filterProcessors.removeElement(processor);
	}

	/**
	 * remove a filter linkProcessor
	 * 
	 * @param processor
	 *            the filter linkProcessor to be removed
	 */
	public Vector getFilterProcessors() {
		return filterProcessors;
	}

	/**
	 * Get the linkProcessor that the link ends into,
	 * 
	 * @return the link end linkProcessor
	 */
	public Processor getLinkedProcessor() {
		return linkProcessor;
	}

	/**
	 * Set the linkProcessor that the link ends into,
	 * 
	 * @param processor
	 *            the link end linkProcessor
	 */
	public void setChainedProcessor(Processor processor) {
		this.linkProcessor = processor;
	}

	public void addAlias(String alias) {
		synchronized (aliases) {
			if (!aliases.contains(alias)) {
				aliases.addElement(alias);
			}
		}
	}

	/**
	 * Remove alias
	 * 
	 * @param alias
	 */
	public void removeAlias(String alias) {
		synchronized (aliases) {
			aliases.removeElement(alias);
		}
	}

	/**
	 * Remove all aliases
	 */
	public void removeAllAliases() {
		synchronized (aliases) {
			aliases.removeAllElements();
		}
	}

	/**
	 * Get the aliases
	 * 
	 * @return Vector containing all aliases
	 */
	public Vector getAlises() {
		return aliases;
	}

	/**
	 * Returns the unique link id
	 * 
	 * @return the link id
	 */
	public String getLinkId() {
		return linkId;
	}

	/**
	 * Returns the Channel this Link belongs to
	 * 
	 * @return the Channel
	 */
	public Channel getChannel() {
		return channel;
	}

	/**
	 * Sets the owning channel of this Link
	 */
	public void setChannel(Channel channel) {
		this.channel = channel;
	}

	/**
	 * Processing of the message
	 * 
	 * @param msg
	 */
	public void processMessage(Message msg) throws ProcessorException {
		
		if(channel != null){
			msg.getMessageContext().setCurrentChannel(channel);
		}
		msg.getMessageContext().setCurrentLink(this);
		
		
		if(inLink){
			if(channel != null){
				msg.getMessageContext().setInBoundChannel(channel);
			}
			msg.getMessageContext().setInBoundLink(this);
		} else {
			if(channel != null){
				msg.getMessageContext().setOutBoundChannel(channel);
			}
			msg.getMessageContext().setOutBoundLink(this);
			
		}
		
		for (int i = 0; i < filterProcessors.size(); i++) {
			Processor processor = (Processor) filterProcessors.elementAt(i);
			
			try {
				processor.processMessage(msg);
			} catch (ProcessorInterruptException e) {
				log.debug("Interrupted processing of message:"+ e.getMessage());
				return;
			}
		}
		
		linkProcessor.processMessage(msg);
	}

	/**
	 * Starting any linkProcessor that is a service
	 * 
	 * @throws Exception
	 */
	public void start() throws Exception {
		for (int i = 0; i < filterProcessors.size(); i++) {
			Processor processor = (Processor) filterProcessors.elementAt(i);
			if (processor instanceof Service) {
				((Service) processor).start();
			}
		}
		
		//The first time this Link starts we save the costMap in origCostMap. 
		//If the Link is started at any later time the original costMap is restored
		if(origCostMap == null){
			origCostMap = new Hashtable();
			Enumeration enumer = costMap.keys();
			while (enumer.hasMoreElements()) {
				String key = (String) enumer.nextElement();
				origCostMap.put(key, costMap.get(key));
			}
		} else {
			costMap = new Hashtable();
			Enumeration enumer = origCostMap.keys();
			while (enumer.hasMoreElements()) {
				String key = (String) enumer.nextElement();
				costMap.put(key, origCostMap.get(key));
			}
		}
	}

	/**
	 * stopping any linkProcessor that is a service
	 * 
	 * @throws Exception
	 */
	public void stop() throws Exception {
		for (int i = 0; i < filterProcessors.size(); i++) {
			Processor processor = (Processor) filterProcessors.elementAt(i);
			if (processor instanceof Service) {
				((Service) processor).stop();
			}
		}
	}

	/**
	 * Gets the default (if present) cost of a link
	 * 
	 * @return the cost
	 */
	public int getCost() {
		Integer integer = (Integer) costMap.get(DEFAULT_QOS_CLASS);
		if (integer != null) {
			return integer.intValue();
		} else {
			return 0;
		}
	}

	/**
	 * Gets the link cost of a link based on a qos class
	 * 
	 * @param qosClass
	 *            the qosClass
	 * @return the cost
	 */
	public int getCost(String qosClass) {
		Integer integer = (Integer) costMap.get(qosClass);
		if (integer != null) {
			return integer.intValue();
		} else {
			return 0;
		}
	}

	/**
	 * Sets the default cost
	 * 
	 * @param cost
	 *            the cost
	 */
	public void setCost(int cost) {
		costMap.put(DEFAULT_QOS_CLASS, new Integer(cost));
	}

	/**
	 * Gets the cost based on qosClass
	 * 
	 * @param qosClass
	 *            the qosClass
	 * @param cost
	 *            the cost
	 */
	public void setCost(String qosClass, int cost) {
		costMap.put(qosClass, new Integer(cost));
	}

	/**
	 * Returns the CostMap of this link
	 * 
	 * @return the costMap
	 */
	public Hashtable getCostMap() {
		return costMap;
	}

	/**
	 * Returns the destination UUID, i.e. the destination of this Link
	 * 
	 * @return the destination UUID
	 */
	public String getDestinationUuid() {
		return destinationUuid;
	}

	/**
	 * Sets the destination UUID, i.e. the destination of this Link
	 * 
	 * @param destinationUuid
	 */
	public void setDestinationUuid(String destinationUuid) {
		this.destinationUuid = destinationUuid;
	}

	public String toString() {
		if (linkProcessor != null) {
			return "Link to " + linkProcessor.toString() + ", aliases :" + aliases;
		}
		return "No link processor";
	}

	/**
	 * Returns a copy of the Link
	 * 
	 * @return the Link
	 */
	public Processor copy() {
		Link copy = new Link();
		for (int i = 0; i < filterProcessors.size(); i++) {
			Processor processor = (Processor) filterProcessors.elementAt(i);
			copy.addFilterProcessor(processor.copy());
		}
		Enumeration enumer = costMap.keys();
		while (enumer.hasMoreElements()) {
			String key = (String) enumer.nextElement();
			copy.setCost(new String(key), ((Integer) costMap.get(key)).intValue());
		}
		return copy;
	}

	
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((linkId == null) ? 0 : linkId.hashCode());
		return result;
	}

	
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Link other = (Link) obj;
		if (linkId == null) {
			if (other.linkId != null)
				return false;
		} else if (!linkId.equals(other.linkId))
			return false;
		return true;
	}
	
	

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy