001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * Granite Data Services is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * Granite Data Services is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 020 * USA, or see <http://www.gnu.org/licenses/>. 021 */ 022package org.granite.gravity.adapters; 023 024/** 025 * Adapted from Greg Wilkins code (Jetty). 026 * 027 * @author William DRAI 028 */ 029public class TopicId { 030 031 public final static String WILD = "*"; 032 public final static String WILDWILD = "**"; 033 034 private final static String[] ROOT = {}; 035 036 private final String name; 037 private final String[] segments; 038 private final int wild; 039 040 public TopicId(String name) { 041 this.name = name; 042 if (name == null || name.length() == 0 || name.charAt(0) != '/') 043 throw new IllegalArgumentException("Illegal topic name: " + name); 044 045 if ("/".equals(name)) 046 segments = ROOT; 047 else { 048 if (name.charAt(name.length() - 1) == '/') 049 throw new IllegalArgumentException("Illegal topic name (should not end with '/'): " + name); 050 segments = name.substring(1).split("\\Q/\\E", -1); 051 } 052 053 if (segments.length > 0) { 054 if (WILD.equals(segments[segments.length-1])) 055 wild = 1; 056 else if (WILDWILD.equals(segments[segments.length-1])) 057 wild = 2; 058 else 059 wild = 0; 060 } 061 else 062 wild = 0; 063 } 064 065 public boolean isWild() { 066 return wild > 0; 067 } 068 069 @Override 070 public boolean equals(Object obj) { 071 if (this == obj) 072 return true; 073 074 if (obj instanceof TopicId) { 075 TopicId other = (TopicId)obj; 076 if (isWild()) { 077 if (other.isWild()) 078 return this.name.equals(other.name); 079 return matches(other); 080 } 081 if (other.isWild()) 082 return other.matches(this); 083 return name.equals(other.name); 084 } 085 else if (obj instanceof String) { 086 if (isWild()) 087 return matches((String)obj); 088 return name.equals(obj); 089 } 090 091 return false; 092 } 093 094 public boolean matches(TopicId name) { 095 if (name.isWild()) 096 return equals(name); 097 098 switch (wild) { 099 case 0: 100 return equals(name); 101 case 1: 102 if (name.segments.length != segments.length) 103 return false; 104 for (int i = segments.length-1; i-- > 0; ) 105 if (!segments[i].equals(name.segments[i])) 106 return false; 107 return true; 108 109 case 2: 110 if (name.segments.length < segments.length) 111 return false; 112 for (int i = segments.length-1; i-- > 0; ) 113 if (!segments[i].equals(name.segments[i])) 114 return false; 115 return true; 116 } 117 return false; 118 } 119 120 public boolean matches(String name) { 121 if (wild == 0) 122 return this.name.equals(name); 123 124 // TODO more efficient? 125 return matches(new TopicId(name)); 126 } 127 128 @Override 129 public int hashCode() { 130 return name.hashCode(); 131 } 132 133 @Override 134 public String toString() { 135 return name; 136 } 137 138 public int depth() { 139 return segments.length; 140 } 141 142 public boolean isParentOf(TopicId id) { 143 if (isWild() || depth() >= id.depth()) 144 return false; 145 146 for (int i = segments.length-1; i-- >0; ) 147 if (!segments[i].equals(id.segments[i])) 148 return false; 149 150 return true; 151 } 152 153 public String getSegment(int i) { 154 if (i > segments.length) 155 return null; 156 return segments[i]; 157 } 158 159 public static String normalize(String topicId) { 160 if (topicId == null) 161 return "/"; 162 if (topicId.indexOf('.') >= 0) 163 topicId = topicId.replace('.', '/'); 164 return (topicId.startsWith("/") ? topicId : ("/" + topicId)); 165 } 166}