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.objectstore.jdo.applib.service.command; 018 019import java.util.UUID; 020 021import org.slf4j.Logger; 022import org.slf4j.LoggerFactory; 023 024import org.apache.isis.applib.AbstractService; 025import org.apache.isis.applib.annotation.Command.ExecuteIn; 026import org.apache.isis.applib.annotation.Command.Persistence; 027import org.apache.isis.applib.annotation.DomainService; 028import org.apache.isis.applib.annotation.Programmatic; 029import org.apache.isis.applib.clock.Clock; 030import org.apache.isis.applib.services.command.Command; 031import org.apache.isis.applib.services.command.Command.Executor; 032import org.apache.isis.applib.services.command.spi.CommandService; 033 034/** 035 * 036 */ 037@DomainService 038public class CommandServiceJdo extends AbstractService implements CommandService { 039 040 @SuppressWarnings("unused") 041 private static final Logger LOG = LoggerFactory.getLogger(CommandServiceJdo.class); 042 043 /** 044 * Creates an {@link CommandJdo}, initializing its 045 * {@link Command#setExecuteIn(Command.ExecuteIn) nature} to be 046 * {@link Command.ExecuteIn#OTHER rendering}. 047 */ 048 @Programmatic 049 @Override 050 public Command create() { 051 CommandJdo command = newTransientInstance(CommandJdo.class); 052 command.setExecutor(Executor.OTHER); 053 command.setPersistence(Persistence.IF_HINTED); 054 return command; 055 } 056 057 @Programmatic 058 @Override 059 public void startTransaction(final Command command, final UUID transactionId) { 060 if(command instanceof CommandJdo) { 061 // should be the case, since this service created the object in the #create() method 062 final CommandJdo commandJdo = (CommandJdo) command; 063 final UUID currentTransactionId = commandJdo.getTransactionId(); 064 if(currentTransactionId != null && !currentTransactionId.equals(transactionId)) { 065 // the logic in IsisTransaction means that any subsequent transactions within a given command 066 // should reuse the xactnId of the first transaction created within that interaction. 067 throw new IllegalStateException("Attempting to set a different transactionId on command"); 068 } 069 commandJdo.setTransactionId(transactionId); 070 } 071 } 072 073 @Programmatic 074 @Override 075 public void complete(final Command command) { 076 final CommandJdo commandJdo = asUserInitiatedCommandJdo(command); 077 if(commandJdo == null) { 078 return; 079 } 080 if(commandJdo.getCompletedAt() != null) { 081 // already attempted to complete. 082 // chances are, we're here as the result of a redirect following a previous exception 083 // so just ignore. 084 return; 085 } 086 087 commandJdo.setCompletedAt(Clock.getTimeAsJavaSqlTimestamp()); 088 persistIfNotAlready(commandJdo); 089 } 090 091 @Override 092 public boolean persistIfPossible(Command command) { 093 if(!(command instanceof CommandJdo)) { 094 // ought not to be the case, since this service created the object in the #create() method 095 return false; 096 } 097 final CommandJdo commandJdo = (CommandJdo)command; 098 persistIfNotAlready(commandJdo); 099 return true; 100 } 101 102 103 /** 104 * Not API, also used by {@link CommandServiceJdoRepository}. 105 */ 106 CommandJdo asUserInitiatedCommandJdo(final Command command) { 107 if(!(command instanceof CommandJdo)) { 108 // ought not to be the case, since this service created the object in the #create() method 109 return null; 110 } 111 if(command.getExecuteIn() != ExecuteIn.FOREGROUND) { 112 return null; 113 } 114 final CommandJdo commandJdo = (CommandJdo) command; 115 return commandJdo.shouldPersist()? commandJdo: null; 116 } 117 118 119}