EMMA Coverage Report (generated Sat Nov 03 21:53:04 GMT 2007)
[all classes][sf.qof.adapter]

COVERAGE SUMMARY FOR SOURCE FILE [BlobAdapter.java]

nameclass, %method, %block, %line, %
BlobAdapter.java100% (1/1)91%  (10/11)94%  (233/249)93%  (71/76)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class BlobAdapter100% (1/1)91%  (10/11)94%  (233/249)93%  (71/76)
getNumberOfColumns (): int 0%   (0/1)0%   (0/2)0%   (0/1)
generateToPreparedStatement (ParameterMapping, CodeEmitter, Local, int [], Lo... 100% (1/1)85%  (77/91)86%  (25/29)
<static initializer> 100% (1/1)100% (55/55)100% (12/12)
BlobAdapter (): void 100% (1/1)100% (3/3)100% (1/1)
emitProcessResult (ResultMapping, CodeEmitter): void 100% (1/1)100% (38/38)100% (13/13)
generateFromResult (ResultMapping, CodeEmitter, Local, int []): void 100% (1/1)100% (18/18)100% (5/5)
generateFromResultSet (ResultMapping, CodeEmitter, Local, String []): void 100% (1/1)100% (17/17)100% (5/5)
generateRegisterOutputParameters (ResultMapping, CodeEmitter, Local, int []):... 100% (1/1)100% (16/16)100% (5/5)
getTypes (): Set 100% (1/1)100% (2/2)100% (1/1)
register (): void 100% (1/1)100% (3/3)100% (2/2)
register (String): void 100% (1/1)100% (4/4)100% (2/2)

1/*
2 * Copyright 2007 brunella ltd
3 *
4 * Licensed under the LGPL Version 3 (the "License");
5 * you may not use this file except in compliance with the License.
6 *
7 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
8 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
10 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
11 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
12 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
13 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
14 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
15 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
16 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
17 * THE POSSIBILITY OF SUCH DAMAGE.
18 */
19package sf.qof.adapter;
20 
21import static sf.qof.codegen.Constants.SIG_registerOutParameter;
22import static sf.qof.codegen.Constants.SIG_setNull;
23import static sf.qof.codegen.Constants.TYPE_CallableStatement;
24import static sf.qof.codegen.Constants.TYPE_PreparedStatement;
25import static sf.qof.codegen.Constants.TYPE_ResultSet;
26import static sf.qof.codegen.Constants.TYPE_int;
27 
28import java.io.ByteArrayInputStream;
29import java.util.HashSet;
30import java.util.Set;
31 
32import net.sf.cglib.core.CodeEmitter;
33import net.sf.cglib.core.Local;
34import net.sf.cglib.core.Signature;
35 
36import org.objectweb.asm.Label;
37import org.objectweb.asm.Type;
38 
39import sf.qof.QueryObjectFactory;
40import sf.qof.mapping.ParameterMapping;
41import sf.qof.mapping.ResultMapping;
42 
43/**
44 * BlobAdapter is a generator mapping adapter for SQL Blob data types.
45 * 
46 * <p>It maps <code>Blob</code> columns to <code>byte[]</code> and vice versa.</p>
47 * 
48 * @see java.sql.Blob
49 */
50public class BlobAdapter implements GeneratorMappingAdapter {
51 
52  private static final Type TYPE_ByteArrayInputStream = Type.getType(ByteArrayInputStream.class);
53  private static final Type TYPE_Blob = Type.getType(java.sql.Blob.class);
54  private static final Type TYPE_BlobReader = Type.getType(BlobReader.class);
55  private static final Type TYPE_ByteArray = Type.getType("[B");
56  private static final Signature SIG_setBinaryStream = new Signature("setBinaryStream", "(ILjava/io/InputStream;I)V");
57  private static final Signature SIG_ConstructorByteArrayInputStream = new Signature("<init>", "([B)V");
58  private static final Signature SIG_getBlob = new Signature("getBlob", "(I)Ljava/sql/Blob;");
59  private static final Signature SIG_getBlobNamed = new Signature("getBlob", "(Ljava/lang/String;)Ljava/sql/Blob;");
60  private static final Signature SIG_readBlob = new Signature("readBlob", "(Ljava/sql/Blob;)[B");
61 
62  public void generateFromResult(ResultMapping resultMapping, CodeEmitter co, Local result, int[] indexes) {
63    co.load_local(result);
64    co.push(indexes[0]);
65    co.invoke_interface(result.getType(), SIG_getBlob);
66    emitProcessResult(resultMapping, co);
67  }
68 
69  public void generateFromResultSet(ResultMapping resultMapping, CodeEmitter co, Local resultSet, String[] columns) {
70    co.load_local(resultSet);
71    co.push(columns[0]);
72    co.invoke_interface(TYPE_ResultSet, SIG_getBlobNamed);
73    emitProcessResult(resultMapping, co);
74  }
75 
76  private void emitProcessResult(ResultMapping resultMapping, CodeEmitter co) {
77    Local localBlob = co.make_local(TYPE_Blob);
78    co.store_local(localBlob);
79    Label labelNull = co.make_label();
80    co.load_local(localBlob);
81    co.ifnull(labelNull);
82    // not null
83    co.load_local(localBlob);
84    co.invoke_static(TYPE_BlobReader, SIG_readBlob);
85    
86    Label labelEnd = co.make_label();
87    co.goTo(labelEnd);
88    
89    // null
90    co.mark(labelNull);
91    co.aconst_null();
92    co.mark(labelEnd);
93  }
94 
95  public void generateToPreparedStatement(ParameterMapping parameterMapping, CodeEmitter co, Local preparedStatement, int[] indexes, Local indexOffset) {
96    Local localByteArray = co.make_local(TYPE_ByteArray);
97    Label labelNull = co.make_label();
98    Label labelEnd = co.make_label();
99    co.store_local(localByteArray);
100    co.load_local(localByteArray);
101    co.ifnull(labelNull);
102    // not null
103    co.load_local(preparedStatement);
104    co.push(indexes[0]);
105    if (indexOffset != null) {
106      co.load_local(indexOffset);
107      co.math(CodeEmitter.ADD, TYPE_int);
108    }
109    co.new_instance(TYPE_ByteArrayInputStream);
110    co.dup();
111    co.load_local(localByteArray);
112    co.invoke_constructor(TYPE_ByteArrayInputStream, SIG_ConstructorByteArrayInputStream);
113    co.load_local(localByteArray);
114    co.arraylength();
115    co.invoke_interface(TYPE_PreparedStatement, SIG_setBinaryStream);
116    co.goTo(labelEnd);
117    
118    co.mark(labelNull);
119    // null
120    co.load_local(preparedStatement);
121    co.push(indexes[0]);
122    if (indexOffset != null) {
123      co.load_local(indexOffset);
124      co.math(CodeEmitter.ADD, TYPE_int);
125    }
126    co.push(java.sql.Types.BLOB);
127    co.invoke_interface(TYPE_PreparedStatement, SIG_setNull);
128    
129    co.mark(labelEnd);
130  }
131 
132  public int getNumberOfColumns() {
133    return 1;
134  }
135 
136  public Set<Class<?>> getTypes() {
137    return typeSet;
138  }
139 
140  private static Set<Class<?>> typeSet;
141  
142  static {
143    typeSet = new HashSet<Class<?>>();
144    typeSet.add(byte[].class);
145  }
146  
147  private final static BlobAdapter generator = new BlobAdapter();
148  
149  /**
150   * Register the mapping adapter with the default name "blob".
151   */
152  public static void register() {
153    register("blob");
154  }
155  
156  /**
157   * Register the mapping adapter with the specified name.
158   * 
159   * @param typeName type name
160   */
161  public static void register(String typeName) {
162    QueryObjectFactory.registerMapper(typeName, generator);
163  }
164 
165  public void generateRegisterOutputParameters(ResultMapping resultMapping, CodeEmitter co, Local callableStatement,
166      int[] indexes) {
167    co.load_local(callableStatement);
168    co.push(indexes[0]);
169    co.push(java.sql.Types.BLOB);
170    co.invoke_interface(TYPE_CallableStatement, SIG_registerOutParameter);
171  }
172  
173}

[all classes][sf.qof.adapter]
EMMA 2.0.5312 (C) Vladimir Roubtsov