View Javadoc

1   package com.ontotext.ordi.mapper.processor;
2   
3   import java.lang.reflect.Constructor;
4   import java.util.ArrayList;
5   import java.util.HashMap;
6   import java.util.Iterator;
7   import java.util.List;
8   import java.util.Map;
9   import java.util.Properties;
10  
11  import org.apache.log4j.Logger;
12  import org.openrdf.model.Literal;
13  import org.openrdf.model.Resource;
14  import org.openrdf.model.Statement;
15  import org.openrdf.model.URI;
16  import org.openrdf.model.Value;
17  import org.openrdf.model.impl.URIImpl;
18  
19  import com.ontotext.ordi.mapper.model.DataHandler;
20  import com.ontotext.ordi.mapper.model.DataSource;
21  import com.ontotext.ordi.mapper.model.MapperDescriptor;
22  import com.ontotext.ordi.mapper.model.PasswordManager;
23  import com.ontotext.ordi.mapper.model.PredicatePattern;
24  import com.ontotext.ordi.mapper.rdbms.JdbcPredicatePatternImpl;
25  import com.ontotext.ordi.mapper.rdbms.RDBMSDataSource;
26  
27  public class OntologyMapperReader {
28  
29      // Name-spaces
30      public static final String RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
31      public static final String ORDI_NS = "http://www.ontotext.com/ordi/rdfmapper/";
32  
33      // Types
34      public static final URI RDF_TYPE = new URIImpl(RDF_NS + "type");
35      public static final URI SQLPRED_TYPE = new URIImpl(ORDI_NS
36              + "SQLPredicatePattern");
37      public static final URI DATASOURCE_TYPE = new URIImpl(ORDI_NS + "Database");
38      public static final URI DATA_HANDLER_TYPE = new URIImpl(ORDI_NS
39              + "DataHandler");
40  
41      // Predicates
42      public static final URI hasDriverName = new URIImpl(ORDI_NS
43              + "hasDriverName");
44      public static final URI hasConectionString = new URIImpl(ORDI_NS
45              + "hasConnectionString");
46      public static final URI hasUserName = new URIImpl(ORDI_NS + "hasUserName");
47      public static final URI hasPassword = new URIImpl(ORDI_NS + "hasPassword");
48      public static final URI hasPredicate = new URIImpl(ORDI_NS + "hasPredicate");
49      public static final URI hasNamedGraph = new URIImpl(ORDI_NS
50              + "hasNamedGraph");
51      public static final URI hasObjectHandler = new URIImpl(ORDI_NS
52              + "hasObjectHandler");
53      public static final URI hasSubjectHandler = new URIImpl(ORDI_NS
54              + "hasSubjectHandler");
55      public static final URI hasQuery = new URIImpl(ORDI_NS + "hasQuery");
56      public static final URI hasDataSource = new URIImpl(ORDI_NS
57              + "hasDataSource");
58      public static final URI hasClassName = new URIImpl(ORDI_NS + "hasClassName");
59  
60      // Private attributes
61      private List<Statement> statements;
62      private Map<Resource, Map<URI, Value>> dataSources = new HashMap<Resource, Map<URI, Value>>();
63      private Map<Resource, Map<URI, Value>> dataHandlers = new HashMap<Resource, Map<URI, Value>>();
64      private Map<Resource, Map<URI, Value>> predPatterns = new HashMap<Resource, Map<URI, Value>>();
65      private Map<Resource, DataHandler> createdHandlers = new HashMap<Resource, DataHandler>();
66      private Logger logger = Logger.getLogger(this.getClass());
67  
68      public OntologyMapperReader(List<Statement> statements) {
69          if (statements == null) {
70              throw new IllegalArgumentException();
71          }
72          this.statements = statements;
73          initialize();
74      }
75  
76      public List<DataSource> getDataSources() {
77          List<DataSource> result = new ArrayList<DataSource>();
78          for (Iterator<Statement> i = filter(RDF_TYPE, DATASOURCE_TYPE)
79                  .iterator(); i.hasNext();) {
80              Statement st = i.next();
81              String driverName = getObjAsString(st.getSubject(), hasDriverName);
82              String userName = getObjAsString(st.getSubject(), hasUserName);
83              String password = getObjAsString(st.getSubject(), hasPassword);
84              String connectionString = getObjAsString(st.getSubject(),
85                      hasConectionString);
86  
87              if (st.getSubject() instanceof URI == false) {
88                  logger.info(String.format("The DataSource %s is ignored "
89                          + "because identified by BNode!", st.getSubject()));
90              } else if (driverName == null || connectionString == null) {
91                  logger.info(String.format("The DataSource %s is ignored "
92                          + "because incomplete data!", st.getSubject()));
93              } else {
94                  Properties properties = new Properties();
95                  if (userName != null)
96                      properties.setProperty("user", userName);
97                  if (password != null)
98                      properties.setProperty("password", password);
99                  PasswordManager
100                         .registerProperties(connectionString, properties);
101 
102                 result.add(new RDBMSDataSource((URI) st.getSubject(),
103                         driverName, connectionString));
104             }
105         }
106         return result;
107     }
108 
109     public List<PredicatePattern> getPredicatePatterns(MapperDescriptor mapper) {
110         List<PredicatePattern> result = new ArrayList<PredicatePattern>();
111         for (Iterator<Statement> i = filter(RDF_TYPE, SQLPRED_TYPE).iterator(); i
112                 .hasNext();) {
113             Statement st = i.next();
114             String query = getObjAsString(st.getSubject(), hasQuery);
115             Resource dataSource = getResource(st.getSubject(), hasDataSource);
116             Resource predicate = getResource(st.getSubject(), hasPredicate);
117             DataHandler subjHandler = getDataHandler(getResource(st
118                     .getSubject(), hasSubjectHandler));
119             DataHandler objectHandler = getDataHandler(getResource(st
120                     .getSubject(), hasObjectHandler));
121 
122             if (subjHandler instanceof DataHandler == false
123                     || predicate instanceof URI == false) {
124                 logger.info(String.format(
125                         "The PredicatePattern %s is ignored, "
126                                 + "because invalid value of %s!", st
127                                 .getSubject(), st.getPredicate()));
128             } else if (query == null || dataSource == null || predicate == null
129                     || objectHandler == null || subjHandler == null) {
130                 logger.info(String.format(
131                         "The PredicatePattern %s is ignored, "
132                                 + "because incomplete data!", st.getSubject()));
133             } else {
134                 result.add(new JdbcPredicatePatternImpl(mapper, subjHandler,
135                         objectHandler, (URI) predicate, null, query,
136                         (URI) dataSource));
137             }
138         }
139         return result;
140     }
141 
142     private DataHandler getDataHandler(Resource subj) {
143         if (subj == null)
144             return null;
145         if (createdHandlers.containsKey(subj) == false) {
146             String className = getObjAsString(subj, hasClassName);
147             if (className == null) {
148                 logger.info(String.format(
149                         "DataHandler %s is ignored because could "
150                                 + "not find its class name!", subj.toString()));
151             }
152             try {
153                 Class<?> cls = Class.forName(className);
154                 if (DataHandler.class.isAssignableFrom(cls) == false) {
155                     logger.info(String.format(
156                             "DataHandler %s is ignored because the class %s "
157                                     + "does not implement DataHandler!", subj
158                                     .toString(), className));
159                 }
160                 Constructor<?> constructor = cls
161                         .getConstructor(new Class<?>[0]);
162                 DataHandler dataHandler = (DataHandler) constructor
163                         .newInstance(new Object[0]);
164 
165                 Map<String, String> params = new HashMap<String, String>();
166                 for (Iterator<Statement> i = statements.iterator(); i.hasNext();) {
167                     Statement st = i.next();
168                     if (st.getSubject().equals(subj))
169                         params.put(st.getPredicate().getLocalName(), st
170                                 .getObject() instanceof Literal ? ((Literal) st
171                                 .getObject()).getLabel() : st.getObject()
172                                 .toString());
173                 }
174                 dataHandler.initialize(params);
175 
176                 createdHandlers.put(subj, dataHandler);
177             } catch (Exception e) {
178                 logger.info(String.format(
179                         "Could not find or instantiate DataHandler "
180                                 + "(%s), because exception %s!", subj, e));
181             }
182         }
183         return createdHandlers.get(subj);
184     }
185 
186     private List<Statement> filter(URI pred, Value obj) {
187         List<Statement> result = new ArrayList<Statement>();
188         for (Iterator<Statement> i = statements.iterator(); i.hasNext();) {
189             Statement st = i.next();
190             if (st.getPredicate().equals(pred) && st.getObject().equals(obj))
191                 result.add(st);
192         }
193         return result;
194     }
195 
196     private String getObjAsString(Resource subj, URI pred) {
197         Value result = null;
198         for (Iterator<Statement> i = statements.iterator(); i.hasNext();) {
199             Statement st = i.next();
200             if (st.getSubject().equals(subj) && st.getPredicate().equals(pred)) {
201 
202                 if (result != null)
203                     logger.info(String.format("Duplicated value in statement "
204                             + "(%s) is ignored!", st));
205                 else
206                     result = st.getObject();
207 
208             }
209         }
210         if (result instanceof Literal)
211             return ((Literal) result).getLabel();
212         if (result == null)
213             return null;
214         return result.toString();
215     }
216 
217     private Resource getResource(Resource subj, URI pred) {
218         Resource result = null;
219         for (Iterator<Statement> i = statements.iterator(); i.hasNext();) {
220             Statement st = i.next();
221             if (st.getSubject().equals(subj) && st.getPredicate().equals(pred)) {
222 
223                 if (st.getObject() instanceof Resource == false)
224                     logger.info(String.format("The statement (%s) is ignored!"
225                             + " (expected Resource, but found %s!)", st, st
226                             .getObject()));
227 
228                 if (result != null)
229                     logger.info(String.format(
230                             "The statement (%s) is ignored (duplicated)!", st));
231                 else
232                     result = (Resource) st.getObject();
233 
234             }
235         }
236         return result;
237     }
238 
239     private void initialize() {
240         for (Iterator<Statement> i = statements.iterator(); i.hasNext();) {
241             Statement st = i.next();
242             if (st.getPredicate().equals(RDF_TYPE)) {
243 
244                 if (st.getObject().equals(SQLPRED_TYPE))
245                     predPatterns
246                             .put(st.getSubject(), new HashMap<URI, Value>());
247                 else if (st.getObject().equals(DATASOURCE_TYPE))
248                     dataSources.put(st.getSubject(), new HashMap<URI, Value>());
249                 else if (st.getObject().equals(DATA_HANDLER_TYPE))
250                     dataHandlers
251                             .put(st.getSubject(), new HashMap<URI, Value>());
252                 else if (logger.isDebugEnabled())
253                     logger.info(String.format(
254                             "Statement (%s) is ignored because "
255                                     + "the unknown type!", st));
256             } else {
257 
258                 if (dataHandlers.containsKey(st.getSubject()))
259                     dataHandlers.get(st.getSubject()).put(st.getPredicate(),
260                             st.getObject());
261                 else if (dataSources.containsKey(st.getSubject()))
262                     dataSources.get(st.getSubject()).put(st.getPredicate(),
263                             st.getObject());
264                 else if (predPatterns.containsKey(st.getSubject()))
265                     predPatterns.get(st.getSubject()).put(st.getPredicate(),
266                             st.getObject());
267                 else if (logger.isDebugEnabled())
268                     logger
269                             .info(String.format("Statement (%s) is ignored!",
270                                     st));
271             }
272         }
273     }
274 }