1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.betwixt.strategy; 18 19 import java.util.Iterator; 20 import java.util.Map; 21 22 import org.apache.commons.betwixt.ElementDescriptor; 23 import org.apache.commons.logging.Log; 24 import org.apache.commons.logging.LogFactory; 25 26 /** 27 * A default implementation of the plural name stemmer which 28 * tests for some common english plural/singular patterns and 29 * then uses a simple starts-with algorithm 30 * 31 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a> 32 * @author <a href="mailto:martin@mvdb.net">Martin van den Bemt</a> 33 * @version $Revision: 438373 $ 34 */ 35 public class DefaultPluralStemmer implements PluralStemmer { 36 37 /** Log used for logging (Doh!) */ 38 protected static Log log = LogFactory.getLog( DefaultPluralStemmer.class ); 39 40 /** 41 * <p>Algorithm supports common english plural patterns.</p> 42 * 43 * <p>First, common english plural constructions will be tried. 44 * If the property doesn't end with <code>'y'</code> then this method will look for 45 * a property with which has <code>'es'</code> appended. 46 * If the property ends with <code>'y'</code> then a property with the <code>'y'</code> 47 * replaced by <code>'ies'</code> will be searched for.</p> 48 * 49 * <p>If no matches are found then - if one exists - a property starting with the 50 * singular name will be returned.</p> 51 * 52 * @param propertyName the property name string to match 53 * @param map the <code>Map</code> containing the <code>ElementDescriptor</code>'s 54 * to be searched 55 * @return The plural descriptor for the given singular property name. 56 * If more than one descriptor matches, then the best match is returned. 57 */ 58 public ElementDescriptor findPluralDescriptor( String propertyName, Map map ) { 59 int foundKeyCount = 0; 60 String keyFound = null; 61 ElementDescriptor answer = (ElementDescriptor) map.get( propertyName + "s" ); 62 63 if ( answer == null && !propertyName.endsWith( "y" )) { 64 answer = (ElementDescriptor) map.get( propertyName + "es" ); 65 } 66 67 if ( answer == null ) { 68 int length = propertyName.length(); 69 if ( propertyName.endsWith( "y" ) && length > 1 ) { 70 String key = propertyName.substring(0, length - 1) + "ies"; 71 answer = (ElementDescriptor) map.get( key ); 72 } 73 74 if ( answer == null ) { 75 // lets find the first one that starts with the propertyName 76 for ( Iterator iter = map.keySet().iterator(); iter.hasNext(); ) { 77 String key = (String) iter.next(); 78 if ( key.startsWith( propertyName ) ) { 79 if (answer == null) { 80 answer = (ElementDescriptor) map.get(key); 81 if (key.equals(propertyName)) { 82 // we found the best match.. 83 break; 84 } 85 foundKeyCount++; 86 keyFound = key; 87 88 } else { 89 // check if we have a better match,, 90 if (keyFound.length() > key.length()) { 91 answer = (ElementDescriptor) map.get(key); 92 keyFound = key; 93 } 94 foundKeyCount++; 95 96 } 97 } 98 } 99 } 100 } 101 if (foundKeyCount > 1) { 102 log.warn("More than one type matches, using closest match "+answer.getQualifiedName()); 103 } 104 return answer; 105 106 } 107 }