View Javadoc

1   /*
2    ORDI - Ontology Repository and Data Integration
3   
4    Copyright (c) 2004-2007, OntoText Lab. / SIRMA
5   
6    This library is free software; you can redistribute it and/or modify it under
7    the terms of the GNU Lesser General Public License as published by the Free
8    Software Foundation; either version 2.1 of the License, or (at your option)
9    any later version.
10   This library is distributed in the hope that it will be useful, but WITHOUT
11   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13   details.
14   You should have received a copy of the GNU Lesser General Public License along
15   with this library; if not, write to the Free Software Foundation, Inc.,
16   59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17   */
18  package com.ontotext.ordi.mapper.rdbms;
19  
20  import java.sql.Connection;
21  import java.sql.DriverManager;
22  import java.sql.PreparedStatement;
23  import java.sql.SQLException;
24  import java.util.HashMap;
25  import java.util.Map;
26  import java.util.Properties;
27  
28  import org.apache.log4j.Logger;
29  import org.openrdf.model.Resource;
30  import org.openrdf.model.URI;
31  import org.openrdf.model.Value;
32  
33  import com.ontotext.ordi.mapper.model.DataHandler;
34  import com.ontotext.ordi.mapper.model.MapperDescriptor;
35  import com.ontotext.ordi.mapper.model.PasswordManager;
36  import com.ontotext.ordi.mapper.model.RDFResultSet;
37  import com.ontotext.ordi.mapper.processor.RDFResultManager;
38  
39  public class JdbcPredicatePatternImpl extends PredicatePatternBase {
40  
41      private SqlGenerator sqlQuery;
42      private Map<String, PreparedStatement> statements;
43      private RDBMSDataSource dataSource;
44      private static Logger logger = Logger
45              .getLogger(JdbcPredicatePatternImpl.class);
46      private volatile static int executionLogId = 0;
47  
48      public JdbcPredicatePatternImpl(MapperDescriptor descriptor,
49              DataHandler subjectHandler, DataHandler objectHandler,
50              URI predicate, URI namedGraph, String query, URI ds) {
51          super(descriptor, subjectHandler, objectHandler, predicate, namedGraph,
52                  query, ds);
53          if (descriptor.getDataSource(ds) instanceof RDBMSDataSource == false) {
54              throw new IllegalArgumentException(String.format(
55                      "%s class supports only %s (%s was provided!",
56                      JdbcPredicatePatternImpl.class.getName(),
57                      RDBMSDataSource.class.getName(), descriptor
58                              .getDataSource(ds)));
59          }
60          dataSource = (RDBMSDataSource) descriptor.getDataSource(ds);
61          sqlQuery = new SqlGenerator(query);
62          statements = new HashMap<String, PreparedStatement>();
63  
64      }
65  
66      public boolean isValid() {
67          Properties props = PasswordManager.getProperties(dataSource
68                  .getConnectionString());
69          if (props.getProperty("user") == null
70                  || props.getProperty("password") == null) {
71              logger.error(String.format("The data source %s with connection "
72                      + " string %s has not specified user and password!",
73                      dataSource.getName(), dataSource.getConnectionString()));
74          }
75          try {
76              // FIXME: Find a smarter way to do validation of the query without to
77              // start it!
78              return true;
79          } catch (Exception e) {
80              logger.error(String.format("PredicatePattern %s with query (%s) is"
81                      + " ignored because error: %s!", predicate, query, e));
82              return false;
83          }
84      }
85  
86      public void execute(Resource subject, URI pred, Value object,
87              URI namedGraph, RDFResultManager resultManager) {
88          if (pred != null && pred.equals(predicate) == false)
89              return;
90          PreparedStatement statement = generateStatement(subject, object);
91          RDFResultSet resultSet = new JdbcResultSet(statement, this,
92                  resultManager);
93          int executionLogId = JdbcPredicatePatternImpl.executionLogId++;
94          if (logger.isTraceEnabled()) {
95              logger
96                      .trace(String
97                              .format(
98                                      "Executing pattern id %d: {subj=%s, pred=%s, obj=%s}\n%s",
99                                      executionLogId, subject, pred, object,
100                                     statement.toString()));
101         }
102         Thread thread = new Thread(resultSet);
103         //thread.start();
104         thread.run();
105 
106         if (logger.isTraceEnabled()) {
107             logger.trace(String.format(
108                     "Executed pattern id %d . Start fetching the results!",
109                     executionLogId));
110         }
111     }
112 
113     private PreparedStatement generateStatement(Resource subject, Value object) {
114         try {
115             String sql = sqlQuery.generateSQL(subject != null, object != null);
116             if (statements.containsKey(sql) == false) {
117                 Properties props = PasswordManager.getProperties(dataSource
118                         .getConnectionString());
119                 Connection conn = DriverManager.getConnection(dataSource
120                         .getConnectionString(), props);
121                 conn.setAutoCommit(false);
122                 statements.put(sql, conn.prepareStatement(sql));
123             }
124             PreparedStatement statement = statements.get(sql);
125             int param = 1;
126             if (subject != null)
127                 statement.setString(param++, subjectHandler.valueToSql(subject)
128                         .toString());
129             if (object != null) {
130                 statement.setString(param++, (objectHandler).valueToSql(object)
131                         .toString());
132             }
133             return statement;
134         } catch (SQLException se) {
135             se.printStackTrace();
136             throw new RuntimeException("Could not prepare SQL exception!", se);
137         }
138     }
139 }