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 020package org.apache.isis.core.progmodel.facets.object.value.annotation; 021 022import com.google.common.base.Strings; 023 024import org.apache.isis.applib.adapters.EncoderDecoder; 025import org.apache.isis.applib.adapters.Parser; 026import org.apache.isis.applib.annotation.Value; 027import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider; 028import org.apache.isis.core.commons.authentication.AuthenticationSessionProviderAware; 029import org.apache.isis.core.commons.config.IsisConfiguration; 030import org.apache.isis.core.commons.config.IsisConfigurationAware; 031import org.apache.isis.core.commons.lang.StringExtensions; 032import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager; 033import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware; 034import org.apache.isis.core.metamodel.deployment.DeploymentCategory; 035import org.apache.isis.core.metamodel.facetapi.FacetHolder; 036import org.apache.isis.core.metamodel.facetapi.FacetUtil; 037import org.apache.isis.core.metamodel.facetapi.FeatureType; 038import org.apache.isis.core.metamodel.facets.Annotations; 039import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract; 040import org.apache.isis.core.metamodel.facets.ebc.EqualByContentFacet; 041import org.apache.isis.core.metamodel.facets.object.aggregated.ParentedFacet; 042import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet; 043import org.apache.isis.core.metamodel.facets.object.icon.IconFacet; 044import org.apache.isis.core.metamodel.facets.object.immutable.ImmutableFacet; 045import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet; 046import org.apache.isis.core.metamodel.facets.object.title.TitleFacet; 047import org.apache.isis.core.metamodel.facets.object.value.ValueFacet; 048import org.apache.isis.core.metamodel.runtimecontext.RuntimeContext; 049import org.apache.isis.core.metamodel.runtimecontext.RuntimeContextAware; 050import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector; 051import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware; 052import org.apache.isis.core.progmodel.facets.object.value.ValueFacetFromConfiguration; 053import org.apache.isis.core.progmodel.facets.object.value.ValueSemanticsProviderContext; 054import org.apache.isis.core.progmodel.facets.object.value.ValueSemanticsProviderUtil; 055 056/** 057 * Processes the {@link Value} annotation. 058 * 059 * <p> 060 * As a result, will always install the following facets: 061 * <ul> 062 * <li> {@link TitleFacet} - based on the <tt>title()</tt> method if present, 063 * otherwise uses <tt>toString()</tt></li> 064 * <li> {@link IconFacet} - based on the <tt>iconName()</tt> method if present, 065 * otherwise derived from the class name</li> 066 * </ul> 067 * <p> 068 * In addition, the following facets may be installed: 069 * <ul> 070 * <li> {@link ParseableFacet} - if a {@link Parser} has been specified 071 * explicitly in the annotation (or is picked up through an external 072 * configuration file)</li> 073 * <li> {@link EncodableFacet} - if an {@link EncoderDecoder} has been specified 074 * explicitly in the annotation (or is picked up through an external 075 * configuration file)</li> 076 * <li> {@link ImmutableFacet} - if specified explicitly in the annotation 077 * <li> {@link EqualByContentFacet} - if specified explicitly in the annotation 078 * </ul> 079 * <p> 080 * Note that {@link ParentedFacet} is <i>not</i> installed. 081 */ 082public class ValueFacetFactory extends FacetFactoryAbstract implements IsisConfigurationAware, AuthenticationSessionProviderAware, AdapterManagerAware, ServicesInjectorAware, RuntimeContextAware { 083 084 private IsisConfiguration configuration; 085 private RuntimeContext runtimeContext; 086 private AuthenticationSessionProvider authenticationSessionProvider; 087 private AdapterManager adapterManager; 088 private ServicesInjector servicesInjector; 089 090 public ValueFacetFactory() { 091 super(FeatureType.OBJECTS_ONLY); 092 } 093 094 @Override 095 public void process(final ProcessClassContext processClassContaxt) { 096 FacetUtil.addFacet(create(processClassContaxt.getCls(), processClassContaxt.getFacetHolder())); 097 } 098 099 /** 100 * Returns a {@link ValueFacet} implementation. 101 */ 102 private ValueFacet create(final Class<?> cls, final FacetHolder holder) { 103 104 // create from annotation, if present 105 final Value annotation = Annotations.getAnnotation(cls, Value.class); 106 if (annotation != null) { 107 final ValueFacetAnnotation facet = new ValueFacetAnnotation(cls, holder, getIsisConfiguration(), createValueSemanticsProviderContext()); 108 if (facet.isValid()) { 109 return facet; 110 } 111 } 112 113 // otherwise, try to create from configuration, if present 114 final String semanticsProviderName = ValueSemanticsProviderUtil.semanticsProviderNameFromConfiguration(cls, configuration); 115 if (!Strings.isNullOrEmpty(semanticsProviderName)) { 116 final ValueFacetFromConfiguration facet = new ValueFacetFromConfiguration(semanticsProviderName, holder, getIsisConfiguration(), createValueSemanticsProviderContext()); 117 if (facet.isValid()) { 118 return facet; 119 } 120 } 121 122 // otherwise, no value semantic 123 return null; 124 } 125 126 protected ValueSemanticsProviderContext createValueSemanticsProviderContext() { 127 return new ValueSemanticsProviderContext(getDeploymentCategory(), getAuthenticationSessionProvider(), getSpecificationLoader(), getAdapterManager(), getServicesInjector()); 128 } 129 130 // //////////////////////////////////////////////////////////////////// 131 // Injected 132 // //////////////////////////////////////////////////////////////////// 133 134 /** 135 * Derived from {@link #setRuntimeContext(RuntimeContext)} (since {@link RuntimeContextAware}). 136 */ 137 private DeploymentCategory getDeploymentCategory() { 138 return runtimeContext.getDeploymentCategory(); 139 } 140 141 public IsisConfiguration getIsisConfiguration() { 142 return configuration; 143 } 144 145 @Override 146 public void setConfiguration(final IsisConfiguration configuration) { 147 this.configuration = configuration; 148 } 149 150 public AuthenticationSessionProvider getAuthenticationSessionProvider() { 151 return authenticationSessionProvider; 152 } 153 154 @Override 155 public void setAuthenticationSessionProvider(final AuthenticationSessionProvider authenticationSessionProvider) { 156 this.authenticationSessionProvider = authenticationSessionProvider; 157 } 158 159 public AdapterManager getAdapterManager() { 160 return adapterManager; 161 } 162 163 @Override 164 public void setAdapterManager(final AdapterManager adapterManager) { 165 this.adapterManager = adapterManager; 166 } 167 168 public ServicesInjector getServicesInjector() { 169 return servicesInjector; 170 } 171 172 @Override 173 public void setServicesInjector(final ServicesInjector dependencyInjector) { 174 this.servicesInjector = dependencyInjector; 175 } 176 177 @Override 178 public void setRuntimeContext(RuntimeContext runtimeContext) { 179 this.runtimeContext = runtimeContext; 180 } 181 182}