001/* 002 * Copyright 2002-2012 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jca.cci.object; 018 019import java.sql.SQLException; 020import javax.resource.ResourceException; 021import javax.resource.cci.ConnectionFactory; 022import javax.resource.cci.InteractionSpec; 023import javax.resource.cci.Record; 024import javax.resource.cci.RecordFactory; 025 026import org.springframework.dao.DataAccessException; 027import org.springframework.jca.cci.core.RecordCreator; 028import org.springframework.jca.cci.core.RecordExtractor; 029 030/** 031 * EIS operation object that expects mapped input and output objects, 032 * converting to and from CCI Records. 033 * 034 * <p>Concrete subclasses must implement the abstract 035 * {@code createInputRecord(RecordFactory, Object)} and 036 * {@code extractOutputData(Record)} methods, to create an input 037 * Record from an object and to convert an output Record into an object, 038 * respectively. 039 * 040 * @author Thierry Templier 041 * @author Juergen Hoeller 042 * @since 1.2 043 * @see #createInputRecord(javax.resource.cci.RecordFactory, Object) 044 * @see #extractOutputData(javax.resource.cci.Record) 045 */ 046public abstract class MappingRecordOperation extends EisOperation { 047 048 /** 049 * Constructor that allows use as a JavaBean. 050 */ 051 public MappingRecordOperation() { 052 } 053 054 /** 055 * Convenient constructor with ConnectionFactory and specifications 056 * (connection and interaction). 057 * @param connectionFactory ConnectionFactory to use to obtain connections 058 */ 059 public MappingRecordOperation(ConnectionFactory connectionFactory, InteractionSpec interactionSpec) { 060 getCciTemplate().setConnectionFactory(connectionFactory); 061 setInteractionSpec(interactionSpec); 062 } 063 064 /** 065 * Set a RecordCreator that should be used for creating default output Records. 066 * <p>Default is none: CCI's {@code Interaction.execute} variant 067 * that returns an output Record will be called. 068 * <p>Specify a RecordCreator here if you always need to call CCI's 069 * {@code Interaction.execute} variant with a passed-in output Record. 070 * This RecordCreator will then be invoked to create a default output Record instance. 071 * @see javax.resource.cci.Interaction#execute(javax.resource.cci.InteractionSpec, Record) 072 * @see javax.resource.cci.Interaction#execute(javax.resource.cci.InteractionSpec, Record, Record) 073 * @see org.springframework.jca.cci.core.CciTemplate#setOutputRecordCreator 074 */ 075 public void setOutputRecordCreator(RecordCreator creator) { 076 getCciTemplate().setOutputRecordCreator(creator); 077 } 078 079 /** 080 * Execute the interaction encapsulated by this operation object. 081 * @param inputObject the input data, to be converted to a Record 082 * by the {@code createInputRecord} method 083 * @return the output data extracted with the {@code extractOutputData} method 084 * @throws DataAccessException if there is any problem 085 * @see #createInputRecord 086 * @see #extractOutputData 087 */ 088 public Object execute(Object inputObject) throws DataAccessException { 089 return getCciTemplate().execute( 090 getInteractionSpec(), new RecordCreatorImpl(inputObject), new RecordExtractorImpl()); 091 } 092 093 094 /** 095 * Subclasses must implement this method to generate an input Record 096 * from an input object passed into the {@code execute} method. 097 * @param inputObject the passed-in input object 098 * @return the CCI input Record 099 * @throws ResourceException if thrown by a CCI method, to be auto-converted 100 * to a DataAccessException 101 * @see #execute(Object) 102 */ 103 protected abstract Record createInputRecord(RecordFactory recordFactory, Object inputObject) 104 throws ResourceException, DataAccessException; 105 106 /** 107 * Subclasses must implement this method to convert the Record returned 108 * by CCI execution into a result object for the {@code execute} method. 109 * @param outputRecord the Record returned by CCI execution 110 * @return the result object 111 * @throws ResourceException if thrown by a CCI method, to be auto-converted 112 * to a DataAccessException 113 * @see #execute(Object) 114 */ 115 protected abstract Object extractOutputData(Record outputRecord) 116 throws ResourceException, SQLException, DataAccessException; 117 118 119 /** 120 * Implementation of RecordCreator that calls the enclosing 121 * class's {@code createInputRecord} method. 122 */ 123 protected class RecordCreatorImpl implements RecordCreator { 124 125 private final Object inputObject; 126 127 public RecordCreatorImpl(Object inObject) { 128 this.inputObject = inObject; 129 } 130 131 @Override 132 public Record createRecord(RecordFactory recordFactory) throws ResourceException, DataAccessException { 133 return createInputRecord(recordFactory, this.inputObject); 134 } 135 } 136 137 138 /** 139 * Implementation of RecordExtractor that calls the enclosing 140 * class's {@code extractOutputData} method. 141 */ 142 protected class RecordExtractorImpl implements RecordExtractor<Object> { 143 144 @Override 145 public Object extractData(Record record) throws ResourceException, SQLException, DataAccessException { 146 return extractOutputData(record); 147 } 148 } 149 150}