001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.isis.core.metamodel.specloader.specimpl; 018 019import java.util.List; 020 021import org.apache.isis.applib.Identifier; 022import org.apache.isis.applib.annotation.When; 023import org.apache.isis.applib.annotation.Where; 024import org.apache.isis.applib.filter.Filter; 025import org.apache.isis.core.commons.authentication.AuthenticationSession; 026import org.apache.isis.core.metamodel.adapter.ObjectAdapter; 027import org.apache.isis.core.metamodel.consent.Consent; 028import org.apache.isis.core.metamodel.consent.InteractionInvocationMethod; 029import org.apache.isis.core.metamodel.facetapi.Facet; 030import org.apache.isis.core.metamodel.facetapi.FacetHolder; 031import org.apache.isis.core.metamodel.facetapi.FacetHolderImpl; 032import org.apache.isis.core.metamodel.facetapi.FacetUtil; 033import org.apache.isis.core.metamodel.facetapi.MultiTypedFacet; 034import org.apache.isis.core.metamodel.facets.notpersisted.NotPersistedFacet; 035import org.apache.isis.core.metamodel.facets.notpersisted.NotPersistedFacetAbstract; 036import org.apache.isis.core.metamodel.interactions.InteractionUtils; 037import org.apache.isis.core.metamodel.interactions.UsabilityContext; 038import org.apache.isis.core.metamodel.interactions.VisibilityContext; 039import org.apache.isis.core.metamodel.spec.ObjectSpecification; 040import org.apache.isis.core.metamodel.spec.feature.ObjectAction; 041import org.apache.isis.core.metamodel.spec.feature.ObjectMemberContext; 042import org.apache.isis.core.progmodel.facets.members.disabled.DisabledFacet; 043import org.apache.isis.core.progmodel.facets.members.disabled.DisabledFacetImpl; 044 045public class OneToOneAssociationContributee extends OneToOneAssociationImpl implements ContributeeMember { 046 047 private final ObjectAdapter serviceAdapter; 048 private final ObjectAction serviceAction; 049 050 051 /** 052 * Hold facets rather than delegate to the contributed action (different types might 053 * use layout metadata to position the contributee in different ways) 054 */ 055 private final FacetHolder facetHolder = new FacetHolderImpl(); 056 057 private final Identifier identifier; 058 059 public OneToOneAssociationContributee( 060 final ObjectAdapter serviceAdapter, 061 final ObjectActionImpl serviceAction, 062 final ObjectSpecification contributeeType, 063 final ObjectMemberContext objectMemberContext) { 064 super(serviceAction.getFacetedMethod(), serviceAction.getReturnType(), objectMemberContext); 065 this.serviceAdapter = serviceAdapter; 066 this.serviceAction = serviceAction; 067 068 // copy over facets from contributed to own. 069 FacetUtil.copyFacets(serviceAction.getFacetedMethod(), facetHolder); 070 071 final NotPersistedFacet notPersistedFacet = new NotPersistedFacetAbstract(this) {}; 072 final DisabledFacet disabledFacet = disabledFacet(); 073 074 FacetUtil.addFacet(notPersistedFacet); 075 FacetUtil.addFacet(disabledFacet); 076 077 // calculate the identifier 078 final Identifier contributorIdentifier = serviceAction.getFacetedMethod().getIdentifier(); 079 final String memberName = contributorIdentifier.getMemberName(); 080 List<String> memberParameterNames = contributorIdentifier.getMemberParameterNames(); 081 082 identifier = Identifier.actionIdentifier(contributeeType.getCorrespondingClass().getName(), memberName, memberParameterNames); 083 } 084 085 private DisabledFacet disabledFacet() { 086 final DisabledFacet originalFacet = facetHolder.getFacet(DisabledFacet.class); 087 if( originalFacet != null && 088 originalFacet.when() == When.ALWAYS && 089 originalFacet.where() == Where.ANYWHERE) { 090 return originalFacet; 091 } 092 // ensure that the contributed association is always disabled 093 return new DisabledFacetImpl(When.ALWAYS, Where.ANYWHERE, "Contributed property", this); 094 } 095 096 @Override 097 public ObjectAdapter get(final ObjectAdapter ownerAdapter) { 098 return serviceAction.execute(serviceAdapter, new ObjectAdapter[]{ownerAdapter}); 099 } 100 101 @Override 102 public Identifier getIdentifier() { 103 return identifier; 104 } 105 106 107 @Override 108 public Consent isVisible(final AuthenticationSession session, final ObjectAdapter contributee, Where where) { 109 final VisibilityContext<?> ic = serviceAction.createVisibleInteractionContext(session, InteractionInvocationMethod.BY_USER, serviceAdapter, where); 110 ic.putContributee(0, contributee); // by definition, the contributee will be the first arg of the service action 111 return InteractionUtils.isVisibleResult(this, ic).createConsent(); 112 } 113 114 @Override 115 public Consent isUsable(final AuthenticationSession session, final ObjectAdapter contributee, Where where) { 116 final UsabilityContext<?> ic = serviceAction.createUsableInteractionContext(session, InteractionInvocationMethod.BY_USER, serviceAdapter, where); 117 ic.putContributee(0, contributee); // by definition, the contributee will be the first arg of the service action 118 return InteractionUtils.isUsableResult(this, ic).createConsent(); 119 } 120 121 122 // ////////////////////////////////////// 123 // FacetHolder 124 // ////////////////////////////////////// 125 126 @Override 127 public Class<? extends Facet>[] getFacetTypes() { 128 return facetHolder.getFacetTypes(); 129 } 130 131 @Override 132 public <T extends Facet> T getFacet(Class<T> cls) { 133 return facetHolder.getFacet(cls); 134 } 135 136 @Override 137 public boolean containsFacet(Class<? extends Facet> facetType) { 138 return facetHolder.containsFacet(facetType); 139 } 140 141 @Override 142 public boolean containsDoOpFacet(java.lang.Class<? extends Facet> facetType) { 143 return facetHolder.containsDoOpFacet(facetType); 144 } 145 146 @Override 147 public List<Facet> getFacets(Filter<Facet> filter) { 148 return facetHolder.getFacets(filter); 149 } 150 151 @Override 152 public void addFacet(Facet facet) { 153 facetHolder.addFacet(facet); 154 } 155 156 @Override 157 public void addFacet(MultiTypedFacet facet) { 158 facetHolder.addFacet(facet); 159 } 160 161 @Override 162 public void removeFacet(Facet facet) { 163 facetHolder.removeFacet(facet); 164 } 165 166 @Override 167 public void removeFacet(Class<? extends Facet> facetType) { 168 facetHolder.removeFacet(facetType); 169 } 170 171}