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
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
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
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
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 }