001    /*
002     * Copyright 2002-2004 The Apache Software Foundation
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.apache.commons.clazz.reflect.common;
017    
018    import java.util.ArrayList;
019    import java.util.HashMap;
020    import java.util.HashSet;
021    import java.util.Iterator;
022    import java.util.List;
023    import java.util.Map;
024    
025    import org.apache.commons.clazz.ClazzProperty;
026    import org.apache.commons.clazz.reflect.ReflectedClazz;
027    import org.apache.commons.clazz.reflect.ReflectedPropertyIntrospector;
028    
029    /**
030     * 
031     * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
032     * @version $Id: ReflectedPropertyIntrospectorSupport.java 155436 2005-02-26 13:17:48Z dirkv $
033     */
034    public abstract class ReflectedPropertyIntrospectorSupport
035        implements ReflectedPropertyIntrospector 
036    {
037        /**
038         */
039        public List introspectProperties(ReflectedClazz clazz, Class javaClass) {
040            HashMap parseResultMap = new HashMap();
041            introspectProperties(clazz, javaClass, parseResultMap);
042    
043            boolean loggingEnabled = clazz.isLoggingEnabled();
044    
045            ArrayList list = new ArrayList();
046            Iterator iter = parseResultMap.values().iterator();
047            while (iter.hasNext()) {
048                ReflectedPropertyParseResults parseResults =
049                    (ReflectedPropertyParseResults) iter.next();
050                if (clazz.getProperty(parseResults.getPropertyName()) != null) {
051                    continue;
052                }
053    
054                boolean aliasExists = false;
055                String aliases[] = parseResults.getAliases();
056                for (int i = 0; i < aliases.length; i++) {
057                    if (clazz.getProperty(aliases[i]) != null) {
058                        aliasExists = true;
059                        break;
060                    }
061                }
062                if (aliasExists) {
063                    continue;
064                }
065    
066                boolean consistent = parseResults.checkConsistency();
067                if (consistent) {
068                    list.add(createProperty(clazz, parseResults));
069                }
070                if (loggingEnabled) {
071                    clazz.logPropertyParseResults(parseResults);
072                }
073            }
074            return list;
075        }
076        
077        public abstract void introspectProperties(
078            ReflectedClazz clazz,
079            Class javaClass,
080            Map parseResultMap);
081    
082        public List introspectDeclaredProperties(
083                ReflectedClazz clazz,
084                Class javaClass)
085        {
086            Class instanceClass = clazz.getInstanceClass();
087            List declaredPropertyList = null;
088            if (instanceClass.getSuperclass() == null) {
089                declaredPropertyList = clazz.getProperties();
090            }
091            else {
092                List superProperties = clazz.getSuperclazz().getProperties();
093                if (superProperties.size() == 0) {
094                    declaredPropertyList = clazz.getProperties();
095                }
096                else {
097                    HashSet superNames = new HashSet();
098                    for (int i = 0; i < superProperties.size(); i++) {
099                        ClazzProperty property =
100                                (ClazzProperty) superProperties.get(i);
101                        superNames.add(property.getName());
102                    }
103    
104                    List properties = clazz.getProperties();
105                    declaredPropertyList = new ArrayList();
106                    for (int i = 0; i < properties.size(); i++) {
107                        ClazzProperty property =
108                            (ClazzProperty) properties.get(i);
109                        String name = property.getName();
110                        if (!superNames.contains(name)) {
111                            declaredPropertyList.add(property);
112                        }
113                    }
114                }
115            }
116            return declaredPropertyList;
117        }
118                    
119        /**
120         * Creates a new ReflectedAccessorPairProperty based on parse results. 
121         */
122        protected abstract ReflectedAccessorPairProperty createProperty(
123            ReflectedClazz clazz,
124            ReflectedPropertyParseResults parseResults);
125        
126        
127        /**
128         * Returns true if the <code>plural</code> parameter is
129         * a correct plural form for the property names <code>singular</code>.
130         * If the plural.startsWith(singular), calls isCorrectPluralSuffix
131         * with the singular form and the remaining part of the plural form.
132         * Separately handles the "~y" - "~ies" substitution for English.
133         */
134        protected boolean isCorrectPluralForm(String singular, String plural) {
135            if (plural.startsWith(singular)) {
136                return isCorrectPluralSuffix(
137                    singular,
138                    plural.substring(singular.length()));
139            }
140            else if (
141                singular.endsWith("y")
142                    && plural.endsWith("ies")
143                    && plural.substring(0, plural.length() - 3).equals(
144                        singular.substring(singular.length() - 1))) {
145                return true;
146            }
147            return false;
148        }
149        
150        protected boolean isCorrectPluralSuffix(String singular, String suffix) {
151            return suffix.equals("s");
152        }
153    }