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