001 /* 002 * Copyright (C) 2005 Joe Walnes. 003 * Copyright (C) 2006, 2007, 2008, 2009, 2013, 2014 XStream Committers. 004 * All rights reserved. 005 * 006 * The software in this package is published under the terms of the BSD 007 * style license a copy of which has been included with this distribution in 008 * the LICENSE.txt file. 009 * 010 * Created on 09. April 2005 by Joe Walnes 011 */ 012 package com.thoughtworks.xstream.mapper; 013 014 import com.thoughtworks.xstream.core.util.FastField; 015 016 import java.util.HashMap; 017 import java.util.HashSet; 018 import java.util.Iterator; 019 import java.util.LinkedHashSet; 020 import java.util.Map; 021 import java.util.Set; 022 import java.util.regex.Pattern; 023 024 /** 025 * Mapper that allows a field of a specific class to be replaced with a shorter alias, or omitted 026 * entirely. 027 * 028 * @author Joe Walnes 029 */ 030 public class FieldAliasingMapper extends MapperWrapper { 031 032 protected final Map fieldToAliasMap = new HashMap(); 033 protected final Map aliasToFieldMap = new HashMap(); 034 protected final Set fieldsToOmit = new HashSet(); 035 protected final Set unknownFieldsToIgnore = new LinkedHashSet(); 036 037 public FieldAliasingMapper(Mapper wrapped) { 038 super(wrapped); 039 } 040 041 public void addFieldAlias(String alias, Class type, String fieldName) { 042 fieldToAliasMap.put(key(type, fieldName), alias); 043 aliasToFieldMap.put(key(type, alias), fieldName); 044 } 045 046 public void addFieldsToIgnore(final Pattern pattern) { 047 unknownFieldsToIgnore.add(pattern); 048 } 049 050 private Object key(Class type, String name) { 051 return new FastField(type, name); 052 } 053 054 public String serializedMember(Class type, String memberName) { 055 String alias = getMember(type, memberName, fieldToAliasMap); 056 if (alias == null) { 057 return super.serializedMember(type, memberName); 058 } else { 059 return alias; 060 } 061 } 062 063 public String realMember(Class type, String serialized) { 064 String real = getMember(type, serialized, aliasToFieldMap); 065 if (real == null) { 066 return super.realMember(type, serialized); 067 } else { 068 return real; 069 } 070 } 071 072 private String getMember(Class type, String name, Map map) { 073 String member = null; 074 for (Class declaringType = type; 075 member == null && declaringType != Object.class && declaringType != null; 076 declaringType = declaringType.getSuperclass()) { 077 member = (String) map.get(key(declaringType, name)); 078 } 079 return member; 080 } 081 082 public boolean shouldSerializeMember(Class definedIn, String fieldName) { 083 if (fieldsToOmit.contains(key(definedIn, fieldName))) { 084 return false; 085 } else if (definedIn == Object.class && !unknownFieldsToIgnore.isEmpty()) { 086 for(Iterator iter = unknownFieldsToIgnore.iterator(); iter.hasNext();) { 087 Pattern pattern = (Pattern)iter.next(); 088 if (pattern.matcher(fieldName).matches()) { 089 return false; 090 } 091 } 092 } 093 return true; 094 } 095 096 public void omitField(Class definedIn, String fieldName) { 097 fieldsToOmit.add(key(definedIn, fieldName)); 098 } 099 }