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 package org.apache.isis.core.progmodel.facets.properties.accessor;
021
022 import java.lang.reflect.Method;
023 import java.util.List;
024
025 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
026 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
027 import org.apache.isis.core.metamodel.facetapi.FeatureType;
028 import org.apache.isis.core.metamodel.facetapi.MethodRemover;
029 import org.apache.isis.core.metamodel.methodutils.MethodScope;
030 import org.apache.isis.core.progmodel.facets.MethodPrefixConstants;
031 import org.apache.isis.core.progmodel.facets.PropertyOrCollectionIdentifyingFacetFactoryAbstract;
032
033 public class PropertyAccessorFacetFactory extends PropertyOrCollectionIdentifyingFacetFactoryAbstract {
034
035 private static final String[] PREFIXES = { MethodPrefixConstants.GET_PREFIX, MethodPrefixConstants.IS_PREFIX };
036
037 public PropertyAccessorFacetFactory() {
038 super(FeatureType.PROPERTIES_ONLY, PREFIXES);
039 }
040
041 @Override
042 public void process(final ProcessMethodContext processMethodContext) {
043 attachPropertyAccessFacetForAccessorMethod(processMethodContext);
044 }
045
046 private static void attachPropertyAccessFacetForAccessorMethod(final ProcessMethodContext processMethodContext) {
047
048 final Method accessorMethod = processMethodContext.getMethod();
049
050 processMethodContext.removeMethod(accessorMethod);
051
052 final FacetHolder property = processMethodContext.getFacetHolder();
053 FacetUtil.addFacet(new PropertyAccessorFacetViaAccessor(accessorMethod, property));
054 }
055
056 // ///////////////////////////////////////////////////////
057 // PropertyOrCollectionIdentifying
058 // ///////////////////////////////////////////////////////
059
060 @Override
061 public boolean isPropertyOrCollectionAccessorCandidate(final Method method) {
062 final String methodName = method.getName();
063 if (methodName.startsWith(MethodPrefixConstants.GET_PREFIX)) {
064 return true;
065 }
066 if (methodName.startsWith(MethodPrefixConstants.IS_PREFIX) && method.getReturnType() == boolean.class) {
067 return true;
068 }
069 return false;
070 }
071
072 /**
073 * The method way well represent a collection, but this facet factory does not have any opinion on the matter.
074 */
075 @Override
076 public boolean isCollectionAccessor(final Method method) {
077 return false;
078 }
079
080 @Override
081 public boolean isPropertyAccessor(final Method method) {
082 if (!isPropertyOrCollectionAccessorCandidate(method)) {
083 return false;
084 }
085 final Class<?> methodReturnType = method.getReturnType();
086 return isCollectionOrArray(methodReturnType);
087 }
088
089 @Override
090 public void findAndRemovePropertyAccessors(final MethodRemover methodRemover,
091 final List<Method> methodListToAppendTo) {
092 appendMatchingMethods(methodRemover, MethodPrefixConstants.IS_PREFIX, boolean.class, methodListToAppendTo);
093 appendMatchingMethods(methodRemover, MethodPrefixConstants.GET_PREFIX, Object.class, methodListToAppendTo);
094 }
095
096 private static void appendMatchingMethods(final MethodRemover methodRemover, final String prefix,
097 final Class<?> returnType, final List<Method> methodListToAppendTo) {
098 methodListToAppendTo.addAll(methodRemover.removeMethods(MethodScope.OBJECT, prefix, returnType, false, 0));
099 }
100
101 @Override
102 public void findAndRemoveCollectionAccessors(final MethodRemover methodRemover,
103 final List<Method> methodListToAppendTo) {
104 // does nothing
105 }
106
107 }