001/* 002 * Copyright 2006 - 2013 003 * Stefan Balev <stefan.balev@graphstream-project.org> 004 * Julien Baudry <julien.baudry@graphstream-project.org> 005 * Antoine Dutot <antoine.dutot@graphstream-project.org> 006 * Yoann Pigné <yoann.pigne@graphstream-project.org> 007 * Guilhelm Savin <guilhelm.savin@graphstream-project.org> 008 * 009 * This file is part of GraphStream <http://graphstream-project.org>. 010 * 011 * GraphStream is a library whose purpose is to handle static or dynamic 012 * graph, create them from scratch, file or any source and display them. 013 * 014 * This program is free software distributed under the terms of two licenses, the 015 * CeCILL-C license that fits European law, and the GNU Lesser General Public 016 * License. You can use, modify and/ or redistribute the software under the terms 017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following 018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by 019 * the Free Software Foundation, either version 3 of the License, or (at your 020 * option) any later version. 021 * 022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY 023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 024 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 025 * 026 * You should have received a copy of the GNU Lesser General Public License 027 * along with this program. If not, see <http://www.gnu.org/licenses/>. 028 * 029 * The fact that you are presently reading this means that you have had 030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms. 031 */ 032package org.graphstream.util; 033 034import java.util.Collection; 035 036import org.graphstream.graph.Edge; 037import org.graphstream.graph.Element; 038import org.graphstream.graph.Node; 039 040public class Filters { 041 public static <T extends Element> Filter<T> falseFilter() { 042 return new Filter<T>() { 043 public boolean isAvailable(T e) { 044 return false; 045 } 046 }; 047 } 048 049 public static <T extends Element> Filter<T> trueFilter() { 050 return new Filter<T>() { 051 public boolean isAvailable(T e) { 052 return true; 053 } 054 }; 055 } 056 057 public static <T extends Element> Filter<T> byAttributeFilter(String key, 058 Object expectedValue) { 059 return new ByAttributeFilter<T>(key, expectedValue); 060 } 061 062 public static <T extends Element, U extends Element> Filter<Element> separateNodeAndEdgeFilter( 063 Filter<T> nodeFilter, Filter<U> edgeFilter) { 064 return new SeparateNodeEdgeFilter<T, U>(nodeFilter, edgeFilter); 065 } 066 067 public static <T extends Element, U extends Element> Filter<T> byExtremitiesFilter( 068 Filter<U> f) { 069 return new ExtremitiesFilter<T, U>(f); 070 } 071 072 public static <T extends Element> Filter<T> byIdFilter(String idPattern) { 073 return new ByIdFilter<T>(idPattern); 074 } 075 076 public static <T extends Element> Filter<T> isContained( 077 final Collection<? extends T> set) { 078 return new Filter<T>() { 079 public boolean isAvailable(T e) { 080 return set.contains(e); 081 } 082 }; 083 } 084 085 public static <T extends Element> Filter<T> isIdContained( 086 final Collection<String> set) { 087 return new Filter<T>() { 088 public boolean isAvailable(T e) { 089 return set.contains(e.getId()); 090 } 091 }; 092 } 093 094 public static <T extends Element> Filter<T> and(Filter<T> f1, Filter<T> f2) { 095 return new AndFilter<T>(f1, f2); 096 } 097 098 public static <T extends Element> Filter<T> or(Filter<T> f1, Filter<T> f2) { 099 return new OrFilter<T>(f1, f2); 100 } 101 102 public static <T extends Element> Filter<T> xor(Filter<T> f1, Filter<T> f2) { 103 return new XorFilter<T>(f1, f2); 104 } 105 106 public static <T extends Element> Filter<T> not(Filter<T> f) { 107 return new NotFilter<T>(f); 108 } 109 110 static class ByAttributeFilter<T extends Element> implements Filter<T> { 111 112 protected String key; 113 protected Object value; 114 115 ByAttributeFilter(String key, Object value) { 116 this.key = key; 117 this.value = value; 118 } 119 120 public boolean isAvailable(T e) { 121 return e.hasAttribute(key) 122 && (value == null ? e.getAttribute(key) == null : value 123 .equals(e.getAttribute(key))); 124 } 125 } 126 127 static class ByIdFilter<T extends Element> implements Filter<T> { 128 String nodePattern; 129 String edgePattern; 130 131 ByIdFilter(String pattern) { 132 this(pattern, pattern); 133 } 134 135 ByIdFilter(String nodePattern, String edgePattern) { 136 this.nodePattern = nodePattern; 137 this.edgePattern = edgePattern; 138 } 139 140 public boolean isAvailable(Element e) { 141 if (e instanceof Edge) 142 return e.getId().matches(edgePattern); 143 144 return e.getId().matches(nodePattern); 145 } 146 } 147 148 static class SeparateNodeEdgeFilter<T extends Element, U extends Element> 149 implements Filter<Element> { 150 151 Filter<T> nodeFilter; 152 Filter<U> edgeFilter; 153 154 SeparateNodeEdgeFilter(Filter<T> nodeFilter, Filter<U> edgeFilter) { 155 this.nodeFilter = nodeFilter; 156 this.edgeFilter = edgeFilter; 157 } 158 159 @SuppressWarnings("unchecked") 160 public boolean isAvailable(Element e) { 161 if (e instanceof Edge) 162 return edgeFilter.isAvailable((U) e); 163 164 return nodeFilter.isAvailable((T) e); 165 } 166 } 167 168 static class ExtremitiesFilter<T extends Element, U extends Element> 169 implements Filter<T> { 170 Filter<U> f; 171 172 ExtremitiesFilter(Filter<U> f) { 173 this.f = f; 174 } 175 176 @SuppressWarnings("unchecked") 177 public boolean isAvailable(T e) { 178 if (e instanceof Node) 179 return true; 180 181 return f.isAvailable((U) ((Edge) e).getNode0()) 182 && f.isAvailable((U) ((Edge) e).getNode1()); 183 } 184 } 185 186 static class AndFilter<T extends Element> implements Filter<T> { 187 Filter<T> f1, f2; 188 189 AndFilter(Filter<T> f1, Filter<T> f2) { 190 this.f1 = f1; 191 this.f2 = f2; 192 } 193 194 public boolean isAvailable(T e) { 195 return f1.isAvailable(e) && f2.isAvailable(e); 196 } 197 } 198 199 static class OrFilter<T extends Element> implements Filter<T> { 200 Filter<T> f1, f2; 201 202 OrFilter(Filter<T> f1, Filter<T> f2) { 203 this.f1 = f1; 204 this.f2 = f2; 205 } 206 207 public boolean isAvailable(T e) { 208 return f1.isAvailable(e) || f2.isAvailable(e); 209 } 210 } 211 212 static class XorFilter<T extends Element> implements Filter<T> { 213 Filter<T> f1, f2; 214 215 XorFilter(Filter<T> f1, Filter<T> f2) { 216 this.f1 = f1; 217 this.f2 = f2; 218 } 219 220 public boolean isAvailable(T e) { 221 return f1.isAvailable(e) ^ f2.isAvailable(e); 222 } 223 } 224 225 static class NotFilter<T extends Element> implements Filter<T> { 226 Filter<T> f; 227 228 NotFilter(Filter<T> f) { 229 this.f = f; 230 } 231 232 public boolean isAvailable(T e) { 233 return !f.isAvailable(e); 234 } 235 } 236}