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.param.defaults.methodnum;
021
022 import java.lang.reflect.Method;
023 import java.util.List;
024
025 import org.apache.isis.core.commons.lang.NameUtils;
026 import org.apache.isis.core.metamodel.adapter.map.AdapterMap;
027 import org.apache.isis.core.metamodel.adapter.map.AdapterMapAware;
028 import org.apache.isis.core.metamodel.exceptions.MetaModelException;
029 import org.apache.isis.core.metamodel.facetapi.Facet;
030 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
031 import org.apache.isis.core.metamodel.facetapi.FeatureType;
032 import org.apache.isis.core.metamodel.facets.FacetedMethod;
033 import org.apache.isis.core.metamodel.facets.FacetedMethodParameter;
034 import org.apache.isis.core.metamodel.facets.actions.defaults.ActionDefaultsFacet;
035 import org.apache.isis.core.metamodel.methodutils.MethodScope;
036 import org.apache.isis.core.progmodel.facets.MethodFinderUtils;
037 import org.apache.isis.core.progmodel.facets.MethodPrefixBasedFacetFactoryAbstract;
038 import org.apache.isis.core.progmodel.facets.MethodPrefixConstants;
039
040 /**
041 * Sets up all the {@link Facet}s for an action in a single shot.
042 */
043 public class ActionParameterDefaultsFacetFactory extends MethodPrefixBasedFacetFactoryAbstract implements
044 AdapterMapAware {
045
046 private static final String[] PREFIXES = {};
047
048 private AdapterMap adapterMap;
049
050 /**
051 * Note that the {@link Facet}s registered are the generic ones from noa-architecture (where they exist)
052 */
053 public ActionParameterDefaultsFacetFactory() {
054 super(FeatureType.ACTIONS_ONLY, PREFIXES);
055 }
056
057 // ///////////////////////////////////////////////////////
058 // Actions
059 // ///////////////////////////////////////////////////////
060
061 @Override
062 public void process(final ProcessMethodContext processMethodContext) {
063
064 final FacetedMethod facetedMethod = processMethodContext.getFacetHolder();
065 final List<FacetedMethodParameter> holderList = facetedMethod.getParameters();
066
067 attachDefaultFacetForParametersIfDefaultsNumMethodIsFound(processMethodContext, holderList);
068 }
069
070 private static void attachDefaultFacetForParametersIfDefaultsNumMethodIsFound(
071 final ProcessMethodContext processMethodContext, final List<FacetedMethodParameter> parameters) {
072
073 if (parameters.isEmpty()) {
074 return;
075 }
076
077 final Class<?> cls = processMethodContext.getCls();
078 final Method actionMethod = processMethodContext.getMethod();
079
080 final Class<?>[] paramTypes = actionMethod.getParameterTypes();
081 final String capitalizedName = NameUtils.capitalizeName(actionMethod.getName());
082
083 for (int i = 0; i < paramTypes.length; i++) {
084
085 final Method defaultMethod =
086 MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, MethodPrefixConstants.DEFAULT_PREFIX + i
087 + capitalizedName, paramTypes[i], new Class[0]);
088
089 if (defaultMethod == null) {
090 continue;
091 }
092 processMethodContext.removeMethod(defaultMethod);
093
094 final FacetedMethod facetedMethod = processMethodContext.getFacetHolder();
095 if (facetedMethod.containsDoOpFacet(ActionDefaultsFacet.class)) {
096 throw new MetaModelException(cls + " uses both old and new default syntax for "
097 + actionMethod.getName() + "(...) - must use one or other");
098 }
099
100 // add facets directly to parameters, not to actions
101 final FacetedMethodParameter paramAsHolder = parameters.get(i);
102 FacetUtil.addFacet(new ActionParameterDefaultsFacetViaMethod(defaultMethod, paramAsHolder));
103 }
104 }
105
106 // ///////////////////////////////////////////////////////////////
107 // Dependencies
108 // ///////////////////////////////////////////////////////////////
109
110 @Override
111 public void setAdapterMap(final AdapterMap adapterMap) {
112 this.adapterMap = adapterMap;
113 }
114
115 private AdapterMap getAdapterMap() {
116 return adapterMap;
117 }
118
119 }