
com.ebay.jetstream.messaging.topic.JetstreamTopic Maven / Gradle / Ivy
/*******************************************************************************
* Copyright © 2012-2015 eBay Software Foundation
* This program is dual licensed under the MIT and Apache 2.0 licenses.
* Please see LICENSE for more information.
*******************************************************************************/
package com.ebay.jetstream.messaging.topic;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
/**
*
*
* @author [email protected]
* @version
*/
public class JetstreamTopic implements Externalizable {
private static final long serialVersionUID = 1L;
private String m_name;
private ArrayList m_contextList = null;
/**
*
*/
public JetstreamTopic() {
}
/**
* @param name
*/
public JetstreamTopic(String name) {
m_name = name;
parse();
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj == null)
return false;
if (!(obj instanceof JetstreamTopic))
return false;
JetstreamTopic topic = (JetstreamTopic) obj;
if (!m_name.equals(topic.m_name))
return false;
return true;
}
/**
* The contexts are ordered in the returned array such that the first context is in location 0 in the array and the
* leaf is the last element of the array.
*/
public Object[] getContexts() {
if (m_contextList == null)
m_contextList = new ArrayList(10);
return m_contextList.toArray();
}
/**
*
* The following methods have specifically not been synchronized for performance We might want to consider
* synchronizing if we see a need. Since the parsing happens when the constructor fires or setName() gets called, I am
* willing to take the risk of not synchronizing the following 2 methods
*
*/
public String getRootContext() {
if (m_contextList == null)
return null;
return m_contextList.get(0);
}
/**
* @return
*/
public String getTopicName() {
return m_name;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return m_name.hashCode();
}
/**
* This method is intended to be called on the sender's topic instance and the topic instance passed in to this method
* must be the listener's topic instance
*
* @param listenerTopic
* @return
*/
public boolean matches(JetstreamTopic listenerTopic) {
if (listenerTopic.getRootContext().equals("/"))
return true;
Object[] passedContextList = listenerTopic.getContexts();
// our rule is sender should always have equal or more contexts than the listener
if (numContexts() < listenerTopic.numContexts())
return false;
Iterator itr = m_contextList.iterator();
int i = 0;
while (itr.hasNext()) {
if (!itr.next().equals(passedContextList[i++]))
return false;
if (i == passedContextList.length)
break;
}
return true;
}
/**
* @return
*/
public int numContexts() {
if (m_contextList != null)
return m_contextList.size();
return 0;
}
/**
*
*/
private void parse() {
if (m_name.equals("/")) {
if (m_contextList == null)
m_contextList = new ArrayList(10);
else
m_contextList.clear();
m_contextList.add(m_name);
return;
}
int previndex = 0;
int nextindex = m_name.indexOf('/');
if (nextindex < 0) {
m_contextList = new ArrayList(10);
m_contextList.add(m_name);
return; // no context specified
}
if (m_contextList == null)
m_contextList = new ArrayList(10);
else
m_contextList.clear();
// we should not have a context name greater than 100 characters
char[] contextname = new char[100];
Arrays.fill(contextname, (char) 0);
m_name.getChars(previndex, nextindex, contextname, 0);
m_contextList.add(new String(contextname, 0, nextindex - previndex));
while (true) {
previndex = nextindex + 1;
nextindex = m_name.indexOf('/', previndex);
if (nextindex == previndex)
return;
Arrays.fill(contextname, (char) 0);
if (nextindex < 0) {
nextindex = m_name.length();
Arrays.fill(contextname, (char) 0);
m_name.getChars(previndex, nextindex, contextname, 0);
m_contextList.add(new String(contextname, 0, nextindex - previndex));
return;
}
Arrays.fill(contextname, (char) 0);
m_name.getChars(previndex, nextindex, contextname, 0);
m_contextList.add(new String(contextname, 0, nextindex - previndex));
}
}
/*
* (non-Javadoc)
*
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
*/
public void readExternal(ObjectInput in) throws IOException {
try {
int nameLen = in.readInt();
byte[] b = new byte[nameLen];
in.readFully(b);
m_name = new String(b);
parse();
}
catch (IOException ioe) {
throw ioe;
}
}
/**
* @param name
*/
public void setTopicName(String name) {
m_name = name;
parse();
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return m_name;
}
/*
* (non-Javadoc)
*
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
*/
public void writeExternal(ObjectOutput out) throws IOException {
// out.writeObject(this.m_name);
out.writeInt(m_name.length());
out.write(m_name.getBytes());
}
public void writeKryo(Kryo kryo, Output output) {
output.writeString(m_name);
}
public void readKryo(Kryo kryo, Input input) {
m_name = input.readString();
parse();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy