wildfire chat server source initial submit

This commit is contained in:
heavyrain2012
2019-03-16 17:04:23 +08:00
parent e59217bd10
commit cab3ca0916
1466 changed files with 528862 additions and 15919 deletions
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2012-2017 The original author or authors
* ------------------------------------------------------
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*/
package io.moquette.spi.impl.subscriptions;
/**
* Internal use only class.
*/
public class Token {
static final Token EMPTY = new Token("");
static final Token MULTI = new Token("#");
static final Token SINGLE = new Token("+");
final String name;
protected Token(String s) {
name = s;
}
protected String name() {
return name;
}
protected boolean match(Token t) {
if (t == MULTI || t == SINGLE) {
return false;
}
if (this == MULTI || this == SINGLE) {
return true;
}
return equals(t);
}
@Override
public int hashCode() {
int hash = 7;
hash = 29 * hash + (this.name != null ? this.name.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Token other = (Token) obj;
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
return true;
}
@Override
public String toString() {
return name;
}
}
@@ -0,0 +1,183 @@
/*
* Copyright (c) 2012-2017 The original author or authors
* ------------------------------------------------------
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*/
package io.moquette.spi.impl.subscriptions;
import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Topic implements Serializable {
private static final Logger LOG = LoggerFactory.getLogger(Topic.class);
private static final long serialVersionUID = 2438799283749822L;
private final String topic;
private transient List<Token> tokens;
private transient boolean valid;
public Topic(String topic) {
this.topic = topic;
}
public String getTopic() {
return topic;
}
public List<Token> getTokens() {
if (tokens == null) {
try {
tokens = parseTopic(topic);
valid = true;
} catch (ParseException e) {
valid = false;
LOG.error("Error parsing the topic: {}, message: {}", topic, e.getMessage());
}
}
return tokens;
}
private List<Token> parseTopic(String topic) throws ParseException {
List<Token> res = new ArrayList<>();
String[] splitted = topic.split("/");
if (splitted.length == 0) {
res.add(Token.EMPTY);
}
if (topic.endsWith("/")) {
// Add a fictious space
String[] newSplitted = new String[splitted.length + 1];
System.arraycopy(splitted, 0, newSplitted, 0, splitted.length);
newSplitted[splitted.length] = "";
splitted = newSplitted;
}
for (int i = 0; i < splitted.length; i++) {
String s = splitted[i];
if (s.isEmpty()) {
// if (i != 0) {
// throw new ParseException("Bad format of topic, expetec topic name between
// separators", i);
// }
res.add(Token.EMPTY);
} else if (s.equals("#")) {
// check that multi is the last symbol
if (i != splitted.length - 1) {
throw new ParseException(
"Bad format of topic, the multi symbol (#) has to be the last one after a separator",
i);
}
res.add(Token.MULTI);
} else if (s.contains("#")) {
throw new ParseException("Bad format of topic, invalid subtopic name: " + s, i);
} else if (s.equals("+")) {
res.add(Token.SINGLE);
} else if (s.contains("+")) {
throw new ParseException("Bad format of topic, invalid subtopic name: " + s, i);
} else {
res.add(new Token(s));
}
}
return res;
}
public boolean isValid() {
if (tokens == null)
getTokens();
return valid;
}
/**
* Verify if the 2 topics matching respecting the rules of MQTT Appendix A
*
* @param subscriptionTopic
* the topic filter of the subscription
* @return true if the two topics match.
*/
// TODO reimplement with iterators or with queues
public boolean match(Topic subscriptionTopic) {
List<Token> msgTokens = getTokens();
List<Token> subscriptionTokens = subscriptionTopic.getTokens();
int i = 0;
for (; i < subscriptionTokens.size(); i++) {
Token subToken = subscriptionTokens.get(i);
if (subToken != Token.MULTI && subToken != Token.SINGLE) {
if (i >= msgTokens.size()) {
return false;
}
Token msgToken = msgTokens.get(i);
if (!msgToken.equals(subToken)) {
return false;
}
} else {
if (subToken == Token.MULTI) {
return true;
}
if (subToken == Token.SINGLE) {
// skip a step forward
}
}
}
// if last token was a SINGLE then treat it as an empty
// if (subToken == Token.SINGLE && (i - msgTokens.size() == 1)) {
// i--;
// }
return i == msgTokens.size();
}
@Override
public String toString() {
return topic;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Topic other = (Topic) obj;
return Objects.equals(this.topic, other.topic);
}
@Override
public int hashCode() {
return topic.hashCode();
}
/**
* Factory method
* */
public static Topic asTopic(String s) {
return new Topic(s);
}
}