<commit_before>/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.apache.isis.core.runtimeservices.publish;

import java.util.Optional;

import javax.annotation.Nullable;

import org.apache.isis.applib.services.command.Command;
import org.apache.isis.applib.services.iactn.Execution;
import org.apache.isis.applib.services.publishing.spi.CommandSubscriber;
import org.apache.isis.applib.services.publishing.spi.EntityChanges;
import org.apache.isis.applib.services.publishing.spi.EntityChangesSubscriber;
import org.apache.isis.applib.services.publishing.spi.EntityPropertyChange;
import org.apache.isis.applib.services.publishing.spi.EntityPropertyChangeSubscriber;
import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.debug.xray.XrayUi;
import org.apache.isis.core.interaction.session.InteractionTracker;
import org.apache.isis.core.runtime.util.XrayUtil;
import org.apache.isis.core.runtime.util.XrayUtil.SequenceHandle;

import lombok.NonNull;
import lombok.val;

final class _Xray {
    
    // -- COMMAND
    
    static SequenceHandle enterCommandPublishing(
            final @NonNull InteractionTracker iaTracker,
            final @Nullable Command command,
            final boolean canPublish,
            final @NonNull Can<CommandSubscriber> enabledSubscribers) {
        
        if(!XrayUi.isXrayEnabled()) {
            return null;
        }
        
        val enteringLabel = canPublish 
                ? String.format("publishing command to %d subscriber(s)", enabledSubscribers.size())
                : "not publishing command";
        
        val handleIfAny = XrayUtil.createSequenceHandle(iaTracker, "cmd-publisher");
        handleIfAny.ifPresent(handle->{
           
            handle.submit(sequenceData->{
                
                sequenceData.alias("cmd-publisher", "Command-\nPublisher-\n(Default)");
                
                val callee = handle.getCallees().getFirstOrFail();
                sequenceData.enter(handle.getCaller(), callee, enteringLabel);
                sequenceData.activate(callee);
            });
            
        });
        
        return handleIfAny.orElse(null);
        
    }
    
    // -- EXECUTION
    
    public static SequenceHandle enterExecutionPublishing(
            final @NonNull InteractionTracker iaTracker,
            final @Nullable Execution<?, ?> command,
            final boolean canPublish,
            final @NonNull Can<ExecutionSubscriber> enabledSubscribers) {
        
        if(!XrayUi.isXrayEnabled()) {
            return null;
        }
        
        val enteringLabel = canPublish 
                ? String.format("publishing execution to %d subscriber(s)", enabledSubscribers.size())
                : "not publishing execution";
        
        val handleIfAny = XrayUtil.createSequenceHandle(iaTracker, "exec-publisher");
        handleIfAny.ifPresent(handle->{
            
            handle.submit(sequenceData->{
                
                sequenceData.alias("exec-publisher", "Execution-\nPublisher-\n(Default)");
                
                val callee = handle.getCallees().getFirstOrFail();
                sequenceData.enter(handle.getCaller(), callee, enteringLabel);
                sequenceData.activate(callee);
            });
            
        });
        
        return handleIfAny.orElse(null);
        
    }
    
    // -- ENTITY CHANGES
    
    public static SequenceHandle enterEntityChangesPublishing(
            final @NonNull InteractionTracker iaTracker,
            final @NonNull Optional<EntityChanges> payload,
            final @NonNull Can<EntityChangesSubscriber> enabledSubscribers) {
        return null;
    }
    
    // -- ENTITY PROPERTY CHANGES
    
    public static SequenceHandle enterEntityPropertyChangePublishing(
            final @NonNull InteractionTracker iaTracker,
            final @NonNull Can<EntityPropertyChange> payload,
            final @NonNull Can<EntityPropertyChangeSubscriber> enabledSubscribers) {
        return null;
    }
    
    // -- EXIT
    
    public static void exitPublishing(final @Nullable SequenceHandle handle) {
        
        if(handle==null) {
            return; // x-ray is not enabled
        }
        
        handle.submit(sequenceData->{
            val callee = handle.getCallees().getFirstOrFail();
            sequenceData.exit(callee, handle.getCaller());
            sequenceData.deactivate(callee);
        });
        
    }
    
}
<commit_msg>ISIS-2573: xray: integrate w/ entity change tracking<commit_after>/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.apache.isis.core.runtimeservices.publish;

import java.util.Optional;

import javax.annotation.Nullable;

import org.apache.isis.applib.services.command.Command;
import org.apache.isis.applib.services.iactn.Execution;
import org.apache.isis.applib.services.publishing.spi.CommandSubscriber;
import org.apache.isis.applib.services.publishing.spi.EntityChanges;
import org.apache.isis.applib.services.publishing.spi.EntityChangesSubscriber;
import org.apache.isis.applib.services.publishing.spi.EntityPropertyChange;
import org.apache.isis.applib.services.publishing.spi.EntityPropertyChangeSubscriber;
import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.debug.xray.XrayUi;
import org.apache.isis.core.interaction.session.InteractionTracker;
import org.apache.isis.core.runtime.util.XrayUtil;
import org.apache.isis.core.runtime.util.XrayUtil.SequenceHandle;

import lombok.NonNull;
import lombok.val;

final class _Xray {
    
    // -- COMMAND
    
    static SequenceHandle enterCommandPublishing(
            final @NonNull InteractionTracker iaTracker,
            final @Nullable Command command,
            final boolean canPublish,
            final @NonNull Can<CommandSubscriber> enabledSubscribers) {
        
        if(!XrayUi.isXrayEnabled()) {
            return null;
        }
        
        val enteringLabel = canPublish 
                ? String.format("publishing command to %d subscriber(s)", enabledSubscribers.size())
                : "not publishing command";
        
        val handleIfAny = XrayUtil.createSequenceHandle(iaTracker, "cmd-publisher");
        handleIfAny.ifPresent(handle->{
           
            handle.submit(sequenceData->{
                
                sequenceData.alias("cmd-publisher", "Command-\nPublisher-\n(Default)");
                
                val callee = handle.getCallees().getFirstOrFail();
                sequenceData.enter(handle.getCaller(), callee, enteringLabel);
                sequenceData.activate(callee);
            });
            
        });
        
        return handleIfAny.orElse(null);
        
    }
    
    // -- EXECUTION
    
    public static SequenceHandle enterExecutionPublishing(
            final @NonNull InteractionTracker iaTracker,
            final @Nullable Execution<?, ?> command,
            final boolean canPublish,
            final @NonNull Can<ExecutionSubscriber> enabledSubscribers) {
        
        if(!XrayUi.isXrayEnabled()) {
            return null;
        }
        
        val enteringLabel = canPublish 
                ? String.format("publishing execution to %d subscriber(s)", enabledSubscribers.size())
                : "not publishing execution";
        
        val handleIfAny = XrayUtil.createSequenceHandle(iaTracker, "exec-publisher");
        handleIfAny.ifPresent(handle->{
            
            handle.submit(sequenceData->{
                
                sequenceData.alias("exec-publisher", "Execution-\nPublisher-\n(Default)");
                
                val callee = handle.getCallees().getFirstOrFail();
                sequenceData.enter(handle.getCaller(), callee, enteringLabel);
                sequenceData.activate(callee);
            });
            
        });
        
        return handleIfAny.orElse(null);
        
    }
    
    // -- ENTITY CHANGES
    
    public static SequenceHandle enterEntityChangesPublishing(
            final @NonNull InteractionTracker iaTracker,
            final @NonNull Optional<EntityChanges> payload,
            final @NonNull Can<EntityChangesSubscriber> enabledSubscribers) {
        
        if(!XrayUi.isXrayEnabled()) {
            return null;
        }
        
        val enteringLabel = payload.isPresent() 
                ? String.format("publishing entity-changes to %d subscriber(s)", enabledSubscribers.size())
                : "not publishing entity-changes";
        
        val handleIfAny = XrayUtil.createSequenceHandle(iaTracker, "ec-publisher");
        handleIfAny.ifPresent(handle->{
            
            handle.submit(sequenceData->{
                
                sequenceData.alias("ec-publisher", "EntityChanges-\nPublisher-\n(Default)");
                
                val callee = handle.getCallees().getFirstOrFail();
                sequenceData.enter(handle.getCaller(), callee, enteringLabel);
                sequenceData.activate(callee);
            });
            
        });
        
        return handleIfAny.orElse(null);
        
    }
    
    // -- ENTITY PROPERTY CHANGES
    
    public static SequenceHandle enterEntityPropertyChangePublishing(
            final @NonNull InteractionTracker iaTracker,
            final @NonNull Can<EntityPropertyChange> payload,
            final @NonNull Can<EntityPropertyChangeSubscriber> enabledSubscribers) {
        
        if(!XrayUi.isXrayEnabled()) {
            return null;
        }
        
        val enteringLabel = !payload.isEmpty() 
                ? String.format("publishing entity-property-changes to %d subscriber(s)", enabledSubscribers.size())
                : "not publishing entity-property-changes";
        
        val handleIfAny = XrayUtil.createSequenceHandle(iaTracker, "epc-publisher");
        handleIfAny.ifPresent(handle->{
            
            handle.submit(sequenceData->{
                
                sequenceData.alias("epc-publisher", "EntityProperty-\nChanges-Publisher-\n(Default)");
                
                val callee = handle.getCallees().getFirstOrFail();
                sequenceData.enter(handle.getCaller(), callee, enteringLabel);
                sequenceData.activate(callee);
            });
            
        });
        
        return handleIfAny.orElse(null);
        
    }
    
    // -- EXIT
    
    public static void exitPublishing(final @Nullable SequenceHandle handle) {
        
        if(handle==null) {
            return; // x-ray is not enabled
        }
        
        handle.submit(sequenceData->{
            val callee = handle.getCallees().getFirstOrFail();
            sequenceData.exit(callee, handle.getCaller());
            sequenceData.deactivate(callee);
        });
        
    }
    
}

{'fraction_non_alphanumeric': 0.09106052193225986, 'fraction_numerical': 0.0009518521456333783, 'mean_word_length': 2.219611848825332, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5567798', 'n_tokens_mistral': 3347, 'n_tokens_neox': 3270, 'n_words': 700}