Package org.apache.isis.core.runtime.services.background

Source Code of org.apache.isis.core.runtime.services.background.BackgroundCommandExecution

/**
*  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.runtime.services.background;

import java.util.List;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import org.apache.isis.applib.clock.Clock;
import org.apache.isis.applib.services.background.ActionInvocationMemento;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.bookmark.BookmarkService;
import org.apache.isis.applib.services.command.Command;
import org.apache.isis.applib.services.command.Command.Executor;
import org.apache.isis.applib.services.command.CommandContext;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
import org.apache.isis.core.metamodel.adapter.oid.RootOidDefault;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.Contributed;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.facets.actions.interaction.CommandUtil;
import org.apache.isis.core.runtime.services.memento.MementoServiceDefault;
import org.apache.isis.core.runtime.sessiontemplate.AbstractIsisSessionTemplate;
import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
import org.apache.isis.core.runtime.system.transaction.TransactionalClosureAbstract;

/**
* Intended to be used as a base class for executing queued up {@link Command background action}s.
*
* <p>
* This implementation uses the {@link #findBackgroundCommandsToExecute() hook method} so that it is
* independent of the location where the actions have actually been persisted to.
*/
public abstract class BackgroundCommandExecution extends AbstractIsisSessionTemplate {

    private final MementoServiceDefault mementoService;

    public BackgroundCommandExecution() {
        // same as configured by BackgroundServiceDefault
        mementoService = new MementoServiceDefault().withNoEncoding();
    }
   
    // //////////////////////////////////////

   
    protected void doExecute(Object context) {

        final PersistenceSession persistenceSession = getPersistenceSession();
        final IsisTransactionManager transactionManager = getTransactionManager(persistenceSession);
        final List<Command> commands = Lists.newArrayList();
        transactionManager.executeWithinTransaction(new TransactionalClosureAbstract() {
            @Override
            public void execute() {
                commands.addAll(findBackgroundCommandsToExecute());
            }
        });

        for (final Command command : commands) {
            execute(transactionManager, command);
        }
    }

    /**
     * Mandatory hook method
     */
    protected abstract List<? extends Command> findBackgroundCommandsToExecute();

    // //////////////////////////////////////

   
    private void execute(final IsisTransactionManager transactionManager, final Command command) {
        transactionManager.executeWithinTransaction(new TransactionalClosureAbstract() {
            @Override
            public void execute() {
                commandContext.setCommand(command);
                try {

                    command.setStartedAt(Clock.getTimeAsJavaSqlTimestamp());
                    command.setExecutor(Executor.BACKGROUND);

                    final String memento = command.getMemento();
                    final ActionInvocationMemento aim = new ActionInvocationMemento(mementoService, memento);

                    final String actionId = aim.getActionId();

                    final Bookmark targetBookmark = aim.getTarget();
                    final Object targetObject = bookmarkService.lookup(targetBookmark);

                    final ObjectAdapter targetAdapter = adapterFor(targetObject);
                    final ObjectSpecification specification = targetAdapter.getSpecification();

                    final ObjectAction objectAction = findAction(specification, actionId);
                    if(objectAction == null) {
                        throw new Exception("Unknown action '" + actionId + "'");
                    }

                    final ObjectAdapter[] argAdapters = argAdaptersFor(aim);
                    final ObjectAdapter resultAdapter = objectAction.execute(targetAdapter, argAdapters);
                    if(resultAdapter != null) {
                        Bookmark resultBookmark = CommandUtil.bookmarkFor(resultAdapter);
                        command.setResult(resultBookmark);
                    }

                } catch (Exception e) {
                    command.setException(Throwables.getStackTraceAsString(e));
                } finally {
                    command.setCompletedAt(Clock.getTimeAsJavaSqlTimestamp());
                }
            }
        });
    }

    private ObjectAction findAction(final ObjectSpecification specification, final String actionId) {
        final List<ObjectAction> objectActions = specification.getObjectActions(Contributed.INCLUDED);
        for (final ObjectAction objectAction : objectActions) {
            if(objectAction.getIdentifier().toClassAndNameIdentityString().equals(actionId)) {
                return objectAction;
            }
        }
        return null;
    }

    private ObjectAdapter[] argAdaptersFor(final ActionInvocationMemento aim) throws ClassNotFoundException {
        final int numArgs = aim.getNumArgs();
        final List<ObjectAdapter> argumentAdapters = Lists.newArrayList();
        for(int i=0; i<numArgs; i++) {
            final ObjectAdapter argAdapter = argAdapterFor(aim, i);
            argumentAdapters.add(argAdapter);
        }
        return argumentAdapters.toArray(new ObjectAdapter[]{});
    }

    private ObjectAdapter argAdapterFor(final ActionInvocationMemento aim, int num) throws ClassNotFoundException {
        final Class<?> argType = aim.getArgType(num);
        final Object arg = aim.getArg(num, argType);
        if(arg == null) {
            return null;
        }
        if(Bookmark.class != argType) {
            return adapterFor(arg);
        } else {
            final Bookmark argBookmark = (Bookmark)arg;
            final RootOid rootOid = RootOidDefault.create(argBookmark);
            return adapterFor(rootOid);
        }
    }

   
    // //////////////////////////////////////

    @javax.inject.Inject
    private BookmarkService bookmarkService;

    @javax.inject.Inject
    private CommandContext commandContext;
}
TOP

Related Classes of org.apache.isis.core.runtime.services.background.BackgroundCommandExecution

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.