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