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.metamodel.interactions; 021 022import java.util.Map; 023 024import com.google.common.collect.ImmutableMap; 025 026import org.apache.isis.applib.Identifier; 027import org.apache.isis.applib.events.InteractionEvent; 028import org.apache.isis.core.commons.authentication.AuthenticationSession; 029import org.apache.isis.core.metamodel.adapter.ObjectAdapter; 030import org.apache.isis.core.metamodel.consent.InteractionContextType; 031import org.apache.isis.core.metamodel.consent.InteractionInvocationMethod; 032import org.apache.isis.core.metamodel.deployment.DeploymentCategory; 033import org.apache.isis.core.metamodel.facetapi.Facet; 034 035/** 036 * Represents an interaction between the framework and (a {@link Facet} of) the 037 * domain object. 038 * 039 * <p> 040 * There are two main responsibilities: 041 * <ul> 042 * <li>Wraps up a target object, parameters and a {@link AuthenticationSession}. 043 * Defining this as a separate interface makes for a more stable API</li> 044 * <li>Acts as a factory for the corresponding {@link InteractionEvent} (more on 045 * this below).</li> 046 * </ul> 047 * 048 * <p> 049 * The {@link InteractionContext} hierarchy is parallel to the 050 * {@link InteractionEvent} hierarchy. Having parallel hierarchies is a bit of a 051 * code-smell. However, it is required because the {@link InteractionContext 052 * context} hierarchy is internal to the framework (with references to 053 * {@link ObjectAdapter}s, {@link AuthenticationSession}s and so forth), whereas 054 * the {@link InteractionEvent event} hierarchy is part of the corelib, that is 055 * public API. 056 * 057 * <p> 058 * The class is genericized so that the {@link #createInteractionEvent() factory 059 * method} can return the correct subclass without having to downcast. 060 */ 061public abstract class InteractionContext<T extends InteractionEvent> { 062 063 private final InteractionContextType interactionType; 064 private final Identifier identifier; 065 private final InteractionInvocationMethod invocation; 066 private final AuthenticationSession session; 067 private final ObjectAdapter target; 068 private final DeploymentCategory deploymentCategory; 069 070 private int contributeeParam = -1; // no contributee 071 private ObjectAdapter contributee = null; 072 073 public InteractionContext(final InteractionContextType interactionType, DeploymentCategory deploymentCategory, final AuthenticationSession session, final InteractionInvocationMethod invocationMethod, final Identifier identifier, final ObjectAdapter target) { 074 this.interactionType = interactionType; 075 this.invocation = invocationMethod; 076 this.identifier = identifier; 077 this.session = session; 078 this.target = target; 079 this.deploymentCategory = deploymentCategory; 080 } 081 082 public DeploymentCategory getDeploymentCategory() { 083 return deploymentCategory; 084 } 085 086 /** 087 * The type of interaction. 088 * 089 * <p> 090 * Available for use by {@link Facet}s that apply only in certain 091 * conditions. For example, some facets for collections will care only when 092 * an object is being added to the collection, but won't care when an object 093 * is being removed from the collection. 094 * 095 * <p> 096 * Alternatively, {@link Facet}s can use <tt>instanceof</tt>. 097 */ 098 public InteractionContextType getInteractionType() { 099 return interactionType; 100 } 101 102 /** 103 * The identifier of the object or member that is being identified with. 104 * 105 * <p> 106 * If the {@link #getInteractionType() type} is 107 * {@link InteractionContextType#OBJECT_VALIDATE}, will be the identifier of 108 * the {@link #getTarget() target} object's specification. Otherwise will be 109 * the identifier of the member. 110 */ 111 public Identifier getIdentifier() { 112 return identifier; 113 } 114 115 /** 116 * The {@link AuthenticationSession user or role} that is performing this 117 * interaction. 118 */ 119 public AuthenticationSession getSession() { 120 return session; 121 } 122 123 /** 124 * How the interaction was initiated. 125 */ 126 public InteractionInvocationMethod getInvocationMethod() { 127 return invocation; 128 } 129 130 /** 131 * Convenience method that indicates whether the 132 * {@link #getInvocationMethod() interaction was invoked} programmatically. 133 */ 134 public boolean isProgrammatic() { 135 return invocation == InteractionInvocationMethod.PROGRAMMATIC; 136 } 137 138 /** 139 * The target object that this interaction is with. 140 */ 141 public ObjectAdapter getTarget() { 142 return target; 143 } 144 145 // ////////////////////////////////////// 146 147 public void putContributee(int contributeeParam, ObjectAdapter contributee) { 148 this.contributeeParam = contributeeParam; 149 this.contributee = contributee; 150 } 151 152 public Map<Integer, ObjectAdapter> getContributeeAsMap() { 153 return contributee != null 154 ? ImmutableMap.<Integer, ObjectAdapter>of(contributeeParam, contributee) 155 : ImmutableMap.<Integer, ObjectAdapter>of(); 156 } 157 158 // ////////////////////////////////////// 159 160 161 162 /** 163 * Factory method to create corresponding {@link InteractionEvent}. 164 * 165 * @return 166 */ 167 public abstract T createInteractionEvent(); 168 169}