001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020 021package org.apache.james.rrt.lib; 022 023import java.io.Serializable; 024import java.util.ArrayList; 025import java.util.Collection; 026import java.util.Iterator; 027import java.util.StringTokenizer; 028 029import org.apache.james.rrt.lib.Mapping.Type; 030 031import com.google.common.base.Function; 032import com.google.common.base.Joiner; 033import com.google.common.base.MoreObjects; 034import com.google.common.base.Objects; 035import com.google.common.base.Optional; 036import com.google.common.base.Preconditions; 037import com.google.common.base.Predicate; 038import com.google.common.base.Predicates; 039import com.google.common.collect.FluentIterable; 040import com.google.common.collect.ImmutableList; 041import com.google.common.collect.Iterables; 042import com.google.common.collect.Lists; 043 044public class MappingsImpl implements Mappings, Serializable { 045 046 private static final long serialVersionUID = 1L; 047 048 public static MappingsImpl empty() { 049 return builder().build(); 050 } 051 052 public static MappingsImpl fromRawString(String raw) { 053 return fromCollection(mappingToCollection(raw)); 054 } 055 056 private static ArrayList<String> mappingToCollection(String rawMapping) { 057 ArrayList<String> map = new ArrayList<String>(); 058 StringTokenizer tokenizer = new StringTokenizer(rawMapping, RecipientRewriteTableUtil.getSeparator(rawMapping)); 059 while (tokenizer.hasMoreTokens()) { 060 final String raw = tokenizer.nextToken().trim(); 061 map.add(raw); 062 } 063 return map; 064 } 065 066 public static MappingsImpl fromCollection(Collection<String> mappings) { 067 Builder builder = builder(); 068 for (String mapping: mappings) { 069 builder.add(mapping); 070 } 071 return builder.build(); 072 } 073 074 public static MappingsImpl fromMappings(Iterable<Mapping> mappings) { 075 Builder builder = builder(); 076 for (Mapping mapping: mappings) { 077 builder.add(mapping); 078 } 079 return builder.build(); 080 } 081 082 public static Builder from(Mappings from) { 083 Builder builder = new Builder(); 084 builder.addAll(from); 085 return builder; 086 } 087 088 public static Builder builder() { 089 return new Builder(); 090 } 091 092 public static class Builder { 093 094 private final ImmutableList.Builder<Mapping> mappings; 095 096 private Builder() { 097 mappings = ImmutableList.builder(); 098 } 099 100 public Builder add(String mapping) { 101 return add(MappingImpl.of(mapping)); 102 } 103 104 public Builder add(Mapping mapping) { 105 mappings.add(mapping); 106 return this; 107 } 108 109 110 public Builder addAll(Mappings mappings) { 111 this.mappings.addAll(mappings); 112 return this; 113 } 114 115 public MappingsImpl build() { 116 return new MappingsImpl(mappings.build()); 117 } 118 119 } 120 121 private final ImmutableList<Mapping> mappings; 122 123 private MappingsImpl(Collection<Mapping> mappings) { 124 this.mappings = ImmutableList.copyOf(mappings); 125 } 126 127 @Override 128 public Iterable<String> asStrings() { 129 return FluentIterable.from(mappings).transform(new Function<Mapping, String>() { 130 @Override 131 public String apply(Mapping input) { 132 return input.asString(); 133 } 134 }); 135 } 136 137 @Override 138 public boolean contains(String mapping) { 139 return mappings.contains(mapping); 140 } 141 142 @Override 143 public int size() { 144 return mappings.size(); 145 } 146 147 @Override 148 public Mappings remove(String mappingAsString) { 149 MappingImpl mapping = MappingImpl.of(mappingAsString); 150 if (mappings.contains(mapping)) { 151 ArrayList<Mapping> updatedMappings = Lists.newArrayList(mappings); 152 updatedMappings.remove(mapping); 153 return new MappingsImpl(updatedMappings); 154 } 155 return this; 156 } 157 158 @Override 159 public boolean isEmpty() { 160 return mappings.isEmpty(); 161 } 162 163 @Override 164 public Iterator<Mapping> iterator() { 165 return mappings.iterator(); 166 } 167 168 @Override 169 public String serialize() { 170 return Joiner.on(';').join(asStrings()); 171 } 172 173 private Predicate<Mapping> hasType(final Mapping.Type type) { 174 return new Predicate<Mapping>() { 175 @Override 176 public boolean apply(Mapping input) { 177 return input.getType().equals(type); 178 } 179 }; 180 } 181 182 @Override 183 public boolean contains(Type type) { 184 Preconditions.checkNotNull(type); 185 return FluentIterable.from(mappings).anyMatch(hasType(type)); 186 } 187 188 @Override 189 public Mappings select(Type type) { 190 Preconditions.checkNotNull(type); 191 return fromMappings(FluentIterable.from(mappings).filter(hasType(type))); 192 } 193 194 195 @Override 196 public Mappings exclude(Type type) { 197 Preconditions.checkNotNull(type); 198 return fromMappings(FluentIterable.from(mappings).filter(Predicates.not(hasType(type)))); 199 } 200 201 @Override 202 public Mapping getError() { 203 Mappings errors = select(Type.Error); 204 Preconditions.checkState(!errors.isEmpty()); 205 return Iterables.getFirst(errors, null); 206 } 207 208 @Override 209 public Optional<Mappings> toOptional() { 210 if (isEmpty()) { 211 return Optional.absent(); 212 } 213 return Optional.<Mappings> of(this); 214 } 215 216 @Override 217 public Mappings union(Mappings mappings) { 218 Preconditions.checkState(mappings != null, "mappings is mandatory"); 219 return from(this).addAll(mappings).build(); 220 } 221 222 @Override 223 public int hashCode() { 224 return Objects.hashCode(mappings); 225 } 226 227 @Override 228 public boolean equals(Object obj) { 229 if (obj instanceof MappingsImpl) { 230 MappingsImpl other = (MappingsImpl) obj; 231 return Objects.equal(mappings, other.mappings); 232 } 233 return false; 234 } 235 236 @Override 237 public String toString() { 238 return MoreObjects.toStringHelper(getClass()).add("mappings", mappings).toString(); 239 } 240}