/* * Copyright (c) 2012 Mike Heath. All rights reserved. * * 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 cloudeventbus; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.ThreadLocalRandom; import java.util.regex.Pattern; /** * Class for holding a subject. Facilitates validating a subject is a "sub" subject. * * @author Mike Heath <elcapo@gmail.com> */ public class Subject { public static final String WILD_CARD_TOKEN = "*"; public static final Subject ALL = new Subject("*"); private static final char[] VALID_SUBJECT_CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); private static final Pattern SUBJECT_PATTERN = Pattern.compile("[0-9a-zA-Z_-]+(\\.[0-9a-zA-Z_-]+)*(\\.\\*){0,1}"); public static List<Subject> list(String... subjects) { final Subject[] list = new Subject[subjects.length]; for (int i = 0; i < subjects.length; i++) { list[i] = new Subject(subjects[i]); } return Collections.unmodifiableList(Arrays.asList(list)); } public static List<Subject> list(List<String> subjects) { final List<Subject> list = new ArrayList<>(subjects.size()); for (String subject : subjects) { list.add(new Subject(subject)); } return Collections.unmodifiableList(list); } public static Subject createRequestReplySubject() { final ThreadLocalRandom random = ThreadLocalRandom.current(); final char[] randomChars = new char[Constants.REQUEST_REPLY_SUBJECT_SIZE]; for (int i=0; i < Constants.REQUEST_REPLY_SUBJECT_SIZE; i++) { randomChars[i] = VALID_SUBJECT_CHARS[random.nextInt(VALID_SUBJECT_CHARS.length)]; } return new Subject(Constants.REQUEST_REPLY_SUBJECT_PREFIX + new String(randomChars)); } public static boolean isRequestReplySubject(String subject) { return subject != null && subject.startsWith(Constants.REQUEST_REPLY_SUBJECT_PREFIX); } private final String subject; public Subject(String subject) { if (subject == null) { throw new NullPointerException("subject can not be null"); } if (!WILD_CARD_TOKEN.equals(subject) && !SUBJECT_PATTERN.matcher(subject).matches()) { throw new IllegalArgumentException("Not valid subject syntax."); } this.subject = subject; } public boolean isWildCard() { return subject.endsWith(WILD_CARD_TOKEN); } public boolean isSub(Subject subSubject) { if (subject.equals(WILD_CARD_TOKEN)) { return true; } if (isWildCard()) { final String subjectSansWildcard = subject.substring(0, subject.length() - 1); return subSubject.subject.startsWith(subjectSansWildcard); } return equals(subSubject); } public boolean isRequestReply() { return isRequestReplySubject(subject); } @Override public int hashCode() { return subject.hashCode(); } @Override public boolean equals(Object obj) { if (obj == null) { return false; } return obj.getClass() == Subject.class && subject.equals(((Subject) obj).subject); } /** * Returns the subject as a string. * @return the subject as a string. */ @Override public String toString() { return subject; } }