001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.betwixt.strategy; 018 019 import org.apache.commons.betwixt.XMLUtils; 020 021 /** 022 * <code>NameMapper</code> implementation that processes a name by replacing or stripping 023 * illegal characters before passing result down the chain. 024 * 025 * @author Robert Burrell Donkin 026 * @since 0.5 027 */ 028 public class BadCharacterReplacingNMapper implements NameMapper { 029 /** Next mapper in chain, possibly null */ 030 private NameMapper chainedMapper; 031 /** Replacement character, possibly null */ 032 private Character replacement = null; 033 034 /** 035 * Constructs a replacing mapper which delegates to given mapper. 036 * @param chainedMapper next link in processing chain, possibly null 037 */ 038 public BadCharacterReplacingNMapper(NameMapper chainedMapper) { 039 this.chainedMapper = chainedMapper; 040 } 041 042 /** 043 * Gets the character that should be used to replace bad characters 044 * if null then bad characters will be deleted. 045 * @return the replacement Character possibly null 046 */ 047 public Character getReplacement() { 048 return replacement; 049 } 050 051 /** 052 * Sets the character that should be used to replace bad characters. 053 * @param replacement the Charcter to be used for replacement if not null. 054 * Otherwise, indicates that illegal characters should be deleted. 055 */ 056 public void setReplacement( Character replacement ) { 057 this.replacement = replacement; 058 } 059 060 /** 061 * This implementation processes characters which are not allowed in xml 062 * element names and then returns the result from the next link in the chain. 063 * This processing consists of deleting them if no replacement character 064 * has been set. 065 * Otherwise, the character will be replaced. 066 * 067 * @param typeName the string to convert 068 * @return the processed input 069 */ 070 public String mapTypeToElementName(String typeName) { 071 072 StringBuffer buffer = new StringBuffer( typeName ); 073 for (int i=0, size = buffer.length(); i< size; i++) { 074 char nextChar = buffer.charAt( i ); 075 boolean bad = false; 076 if ( i==0 ) { 077 bad = !XMLUtils.isNameStartChar( nextChar ); 078 } else { 079 bad = !XMLUtils.isNameChar( nextChar ); 080 } 081 082 if (bad) { 083 if ( replacement != null ) { 084 buffer.setCharAt( i, replacement.charValue() ); 085 } else { 086 // delete 087 buffer.deleteCharAt( i ); 088 i--; 089 size--; 090 } 091 } 092 } 093 094 if ( buffer.length() == 0 ) { 095 throw new IllegalArgumentException( 096 "Element name contains no legal characters and no replacements have been set."); 097 } 098 099 typeName = buffer.toString(); 100 101 if ( chainedMapper == null ) { 102 return typeName; 103 } 104 return chainedMapper.mapTypeToElementName( typeName ); 105 } 106 }