View Javadoc
1   /*
2   Copyright (c) 2007 Health Market Science, Inc.
3   
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7   
8       http://www.apache.org/licenses/LICENSE-2.0
9   
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15  */
16  
17  package com.healthmarketscience.jackcess.util;
18  
19  import java.io.IOException;
20  import java.lang.reflect.Field;
21  import java.lang.reflect.Modifier;
22  import java.nio.ByteOrder;
23  import java.util.List;
24  
25  import static com.healthmarketscience.jackcess.Database.*;
26  import com.healthmarketscience.jackcess.Column;
27  import com.healthmarketscience.jackcess.ColumnBuilder;
28  import com.healthmarketscience.jackcess.Cursor;
29  import com.healthmarketscience.jackcess.CursorBuilder;
30  import com.healthmarketscience.jackcess.DataType;
31  import com.healthmarketscience.jackcess.Database;
32  import com.healthmarketscience.jackcess.Table;
33  import com.healthmarketscience.jackcess.TableBuilder;
34  import com.healthmarketscience.jackcess.impl.ColumnImpl;
35  import com.healthmarketscience.jackcess.impl.JetFormatTest;
36  import com.healthmarketscience.jackcess.impl.TableImpl;
37  import junit.framework.TestCase;
38  import static com.healthmarketscience.jackcess.TestUtil.*;
39  
40  /**
41   * @author James Ahlborn
42   */
43  public class ErrorHandlerTest extends TestCase 
44  {
45  
46    public ErrorHandlerTest(String name) {
47      super(name);
48    }
49  
50    public void testErrorHandler() throws Exception
51    {
52      for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
53        Database db = create(fileFormat);
54  
55        Table table =
56          new TableBuilder("test")
57          .addColumn(new ColumnBuilder("col", DataType.TEXT))
58          .addColumn(new ColumnBuilder("val", DataType.LONG))
59          .toTable(db);
60  
61        table.addRow("row1", 1);
62        table.addRow("row2", 2);
63        table.addRow("row3", 3);
64  
65        assertTable(createExpectedTable(
66                        createExpectedRow("col", "row1",
67                                          "val", 1),
68                        createExpectedRow("col", "row2",
69                                          "val", 2),
70                        createExpectedRow("col", "row3",
71                                          "val", 3)),
72                    table);
73  
74  
75        replaceColumn(table, "val");
76  
77        table.reset();
78        try {
79          table.getNextRow();
80          fail("IOException should have been thrown");
81        } catch(IOException e) {
82          // success
83        }
84  
85        table.reset();
86        table.setErrorHandler(new ReplacementErrorHandler());
87  
88        assertTable(createExpectedTable(
89                        createExpectedRow("col", "row1",
90                                          "val", null),
91                        createExpectedRow("col", "row2",
92                                          "val", null),
93                        createExpectedRow("col", "row3",
94                                          "val", null)),
95                    table);
96  
97        Cursor c1 = CursorBuilder.createCursor(table);
98        Cursor c2 = CursorBuilder.createCursor(table);
99        Cursor c3 = CursorBuilder.createCursor(table);
100 
101       c2.setErrorHandler(new DebugErrorHandler("#error"));
102       c3.setErrorHandler(ErrorHandler.DEFAULT);
103 
104       assertCursor(createExpectedTable(
105                       createExpectedRow("col", "row1",
106                                         "val", null),
107                       createExpectedRow("col", "row2",
108                                         "val", null),
109                       createExpectedRow("col", "row3",
110                                         "val", null)),
111                   c1);
112 
113       assertCursor(createExpectedTable(
114                       createExpectedRow("col", "row1",
115                                         "val", "#error"),
116                       createExpectedRow("col", "row2",
117                                         "val", "#error"),
118                       createExpectedRow("col", "row3",
119                                         "val", "#error")),
120                   c2);
121 
122       try {
123         c3.getNextRow();
124         fail("IOException should have been thrown");
125       } catch(IOException e) {
126         // success
127       }
128 
129       table.setErrorHandler(null);
130       c1.setErrorHandler(null);
131       c1.reset();
132       try {
133         c1.getNextRow();
134         fail("IOException should have been thrown");
135       } catch(IOException e) {
136         // success
137       }
138 
139 
140       db.close();
141     }
142   }
143 
144   @SuppressWarnings("unchecked")
145   private static void replaceColumn(Table t, String colName) throws Exception
146   {
147     Field colsField = TableImpl.class.getDeclaredField("_columns");
148     colsField.setAccessible(true);
149     List<Column> cols = (List<Column>)colsField.get(t);
150 
151     Column srcCol = null;
152     ColumnImpl destCol = new BogusColumn(t, colName);
153     for(int i = 0; i < cols.size(); ++i) {
154       srcCol = cols.get(i);
155       if(srcCol.getName().equals(colName)) {
156         cols.set(i, destCol);
157         break;
158       }
159     }
160 
161     // copy fields from source to dest
162     for(Field f : Column.class.getDeclaredFields()) {
163       if(!Modifier.isFinal(f.getModifiers())) {
164         f.setAccessible(true);
165         f.set(destCol, f.get(srcCol));
166       }
167     }
168     
169   }
170 
171   private static class BogusColumn extends ColumnImpl
172   {
173     private BogusColumn(Table table, String name) {
174       super((TableImpl)table, name, DataType.LONG, 1, 0, 0);
175     }
176     
177     @Override
178     public Object read(byte[] data, ByteOrder order) throws IOException {
179       throw new IOException("bogus column");
180     }
181   }
182 
183 }