aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/itmill/toolkit/data/util/QueryContainer.java
blob: 46566ef29ef50b466d9b7f899c184965f9551113 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
/* *************************************************************************
 
                               IT Mill Toolkit 

               Development of Browser User Interfaces Made Easy

                    Copyright (C) 2000-2006 IT Mill Ltd
                     
   *************************************************************************

   This product is distributed under commercial license that can be found
   from the product package on license.pdf. Use of this product might 
   require purchasing a commercial license from IT Mill Ltd. For guidelines 
   on usage, see licensing-guidelines.html

   *************************************************************************
   
   For more information, contact:
   
   IT Mill Ltd                           phone: +358 2 4802 7180
   Ruukinkatu 2-4                        fax:   +358 2 4802 7181
   20540, Turku                          email:  info@itmill.com
   Finland                               company www: www.itmill.com
   
   Primary source for information and releases: www.itmill.com

   ********************************************************************** */

package com.itmill.toolkit.data.util;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;

import com.itmill.toolkit.data.Container;
import com.itmill.toolkit.data.Item;
import com.itmill.toolkit.data.Property;
import com.itmill.toolkit.data.util.ObjectProperty;

/** SQL query container.
 * Implementation of container interface for SQL tables accessed through
 * JDBC connection.
 * 
 * @author IT Mill Ltd.
 * @version
 * @VERSION@
 * @since 4.0
 */
public class QueryContainer implements Container, Container.Ordered, Container.Indexed {

    String queryStatement;

    Connection connection;

    ResultSet result;

    Collection propertyIds;

    HashMap propertyTypes = new HashMap();

    int size = -1;

    Statement statement;

    /**
     * Constructor for Query.
     */
    public QueryContainer(String queryStatement, Connection connection)
            throws SQLException {
        this.connection = connection;
        this.queryStatement = queryStatement;
        refresh();
        ResultSetMetaData metadata;
        metadata = result.getMetaData();
        int count = metadata.getColumnCount();
        ArrayList list = new ArrayList(count);
        for (int i = 1; i <= count; i++) {
            String columnName = metadata.getColumnName(i);
            list.add(columnName);
            Property p = getContainerProperty(new Integer(1), columnName);
            propertyTypes.put(columnName, p == null ? Object.class : p
                    .getType());
        }
        propertyIds = Collections.unmodifiableCollection(list);
    }

    public void refresh() throws SQLException {
        close();
        statement = connection.createStatement();
        result = statement.executeQuery(queryStatement);
        result.last();
        size = result.getRow();
    }

    public void close() throws SQLException {
        if (statement != null)
            statement.close();
        statement = null;
    }

    public Item getItem(Object id) {
        return new Row(id);
    }

    public Collection getContainerPropertyIds() {
        return propertyIds;
    }

    public Collection getItemIds() {
        Collection c = new ArrayList(size);
        for (int i = 1; i <= size; i++)
            c.add(new Integer(i));
        return c;
    }

    public synchronized Property getContainerProperty(Object itemId,
            Object propertyId) {
        if (!(itemId instanceof Integer && propertyId instanceof String))
            return null;
        Object value;
        try {
            result.absolute(((Integer) itemId).intValue());
            value = result.getObject((String) propertyId);
        } catch (Exception e) {
            return null;
        }

        // Also deal with null values from the DB
        return new ObjectProperty(value != null ? value : new String(""));
    }

    public Class getType(Object id) {
        return (Class) propertyTypes.get(id);
    }

    public int size() {
        return size;
    }

    public boolean containsId(Object id) {
        if (!(id instanceof Integer))
            return false;
        int i = ((Integer) id).intValue();
        if (i < 1)
            return false;
        if (i > size)
            return false;
        return true;
    }

    public Item addItem(Object arg0) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    public Object addItem() throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    public boolean removeItem(Object arg0) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    public boolean addContainerProperty(Object arg0, Class arg1, Object arg2)
            throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    public boolean removeContainerProperty(Object arg0)
            throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    public boolean removeAllItems() throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    public Item addItemAfter(Object arg0, Object arg1)
            throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    public Object addItemAfter(Object arg0)
            throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    public Object firstItemId() {
        if (size < 1)
            return null;
        return new Integer(1);
    }

    public boolean isFirstId(Object id) {
        return size > 0 && (id instanceof Integer)
                && ((Integer) id).intValue() == 1;
    }

    public boolean isLastId(Object id) {
        return size > 0 && (id instanceof Integer)
                && ((Integer) id).intValue() == size;
    }

    public Object lastItemId() {
        if (size < 1)
            return null;
        return new Integer(size);
    }

    public Object nextItemId(Object id) {
        if (size < 1 || !(id instanceof Integer))
            return null;
        int i = ((Integer) id).intValue();
        if (i >= size)
            return null;
        return new Integer(i + 1);
    }

    public Object prevItemId(Object id) {
        if (size < 1 || !(id instanceof Integer))
            return null;
        int i = ((Integer) id).intValue();
        if (i <= 1)
            return null;
        return new Integer(i - 1);
    }

    /** Query result row */
    class Row implements Item {

        Object id;

        private Row(Object rowId) {
            id = rowId;
        }

        public boolean addItemProperty(Object arg0, Property arg1)
                throws UnsupportedOperationException {
            throw new UnsupportedOperationException();
        }

        public Property getItemProperty(Object propertyId) {
            return getContainerProperty(id, propertyId);
        }

        public Collection getItemPropertyIds() {
            return propertyIds;
        }

        public boolean removeItemProperty(Object arg0)
                throws UnsupportedOperationException {
            throw new UnsupportedOperationException();
        }

    }

    public void finalize() {
        try {
            close();
        } catch (SQLException ignored) {

        }
    }

    public Item addItemAt(int arg0, Object arg1)
            throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    public Object addItemAt(int arg0) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    public Object getIdByIndex(int index) {
        if (size < 1 || index < 0 || index >= size)
            return null;
        return new Integer(index + 1);
    }

    public int indexOfId(Object id) {
        if (size < 1 || !(id instanceof Integer))
            return -1;
        int i = ((Integer) id).intValue();
        if (i >= size || i < 1)
            return -1;
        return i - 1;
    }

}