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 package org.openrdf.elmo.codegen;
30
31 import groovy.lang.Binding;
32 import groovy.lang.MissingPropertyException;
33 import groovy.util.GroovyScriptEngine;
34 import groovy.util.ResourceConnector;
35 import groovy.util.ResourceException;
36
37 import java.io.CharArrayWriter;
38 import java.io.IOException;
39 import java.io.PrintWriter;
40 import java.net.URL;
41 import java.net.URLConnection;
42 import java.util.HashMap;
43 import java.util.Map;
44
45 import javax.xml.namespace.QName;
46
47 import org.openrdf.concepts.owl.Ontology;
48 import org.openrdf.concepts.rdfs.Datatype;
49 import org.openrdf.elmo.ElmoModule;
50 import org.openrdf.elmo.ElmoQuery;
51 import org.openrdf.elmo.sesame.SesameManager;
52 import org.openrdf.elmo.sesame.SesameManagerFactory;
53 import org.openrdf.elmo.sesame.roles.SesameEntity;
54 import org.openrdf.model.URI;
55 import org.openrdf.model.vocabulary.OWL;
56 import org.openrdf.model.vocabulary.RDF;
57 import org.openrdf.model.vocabulary.RDFS;
58 import org.openrdf.repository.Repository;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62
63
64
65
66
67
68
69 public class CodeGenerator implements ResourceConnector {
70
71 private static String CONCEPT_TEMPLATE = "org/openrdf/elmo/codegen/templates/concept.groovy";
72
73 private static String DATATYPE_TEMPLATE = "org/openrdf/elmo/codegen/templates/datatype.groovy";
74
75 private static String PACKAGE_TEMPLATE = "org/openrdf/elmo/codegen/templates/package.groovy";
76
77 private static final String CLASS_DEFINED_BY = "PREFIX rdf: <"
78 + RDF.NAMESPACE
79 + "> PREFIX rdfs: <"
80 + RDFS.NAMESPACE
81 + "> PREFIX owl: <"
82 + OWL.NAMESPACE
83 + "> SELECT ?bean WHERE { ?bean rdfs:isDefinedBy ?ont . { ?bean rdf:type owl:Class } UNION {?bean rdf:type rdfs:Datatype } }";
84
85 private final Logger logger = LoggerFactory.getLogger(CodeGenerator.class);
86
87 private SesameManagerFactory factory;
88
89 private GroovyScriptEngine engine;
90
91 private OwlNormalizer normalizer;
92
93 private Map<URI, String> ontologies = new HashMap<URI, String>();
94
95 private String propertyNamesPrefix;
96
97 private Class<?>[] baseClasses = new Class<?>[0];
98
99 public Class<?>[] getBaseClasses() {
100 return baseClasses;
101 }
102
103 public void setBaseClasses(Class<?>[] baseClasses) {
104 this.baseClasses = baseClasses;
105 }
106
107 public String getPropertyNamesPrefix() {
108 return propertyNamesPrefix;
109 }
110
111 public void setPropertyNamesPrefix(String prefixPropertyNames) {
112 this.propertyNamesPrefix = prefixPropertyNames;
113 }
114
115 public void addOntologyPackage(URI ontology, String pkgName) {
116 ontologies.put(ontology, pkgName);
117 }
118
119 public URLConnection getResourceConnection(String name)
120 throws ResourceException {
121 try {
122 URL url = getClass().getResource("/" + name);
123 if (url != null)
124 return url.openConnection();
125 throw new ResourceException("Resource not found: " + name);
126 } catch (IOException e) {
127 throw new ResourceException(e);
128 }
129 }
130
131 public void setRepository(Repository repository) {
132 this.factory = new SesameManagerFactory(new ElmoModule(), repository);
133 }
134
135 public void setGroovyScriptEngine(GroovyScriptEngine engine) {
136 this.engine = engine;
137 }
138
139 public void init() throws Exception {
140 normalizer = new OwlNormalizer();
141 normalizer.setRepository(factory.getRepository());
142 normalizer.normalize();
143 }
144
145 public void exportSourceCode(SourceCodeHandler handler) throws Exception {
146 SesameManager manager = factory.createElmoManager();
147 try {
148 ElmoQuery query;
149 query = manager.createQuery(CLASS_DEFINED_BY);
150 for (Map.Entry<URI, String> e : ontologies.entrySet()) {
151 query.setParameter("ont", new QName(e.getKey().toString()));
152 try {
153 for (Object o : query.getResultList()) {
154 SesameEntity bean = (SesameEntity) o;
155 try {
156 if (bean.getQName() == null)
157 continue;
158 if (bean instanceof Datatype) {
159 buildDatatype(bean, e.getValue(), manager,
160 handler);
161 } else {
162 buildClass(bean, e.getValue(), manager, handler);
163 }
164 } catch (MissingPropertyException exc) {
165 logger.error("Error processing {}", bean);
166 StringBuilder sb = new StringBuilder();
167 for (Class<?> inter : exc.getType().getInterfaces()) {
168 sb.append(inter.getSimpleName()).append(" ");
169 }
170 String sn = exc.getType().getSimpleName();
171 logger.warn("Class {} implements {}", sn, sb
172 .toString());
173 throw exc;
174 } catch (Exception exc) {
175 logger.error("Error processing {}", bean);
176 throw exc;
177 }
178 }
179 } finally {
180 query.close();
181 }
182 }
183 for (URI ontology : ontologies.keySet()) {
184 buildOntology(ontology, manager, handler);
185 }
186 } finally {
187 manager.close();
188 }
189 }
190
191 private void buildClass(SesameEntity bean, String packageName,
192 SesameManager manager, SourceCodeHandler handler) throws Exception {
193 Binding bindings = createBindings();
194 CharArrayWriter output = new CharArrayWriter();
195 setVariables(bindings, manager, packageName, bean);
196 bindings.setVariable("content", new PrintWriter(output));
197 bindings.setVariable("propertyPrefix", propertyNamesPrefix);
198 bindings.setVariable("baseClasses", baseClasses);
199 engine.run(CONCEPT_TEMPLATE, bindings);
200 String content = output.toString();
201 if (content.length() > 0) {
202 handler.handleSource(content);
203 }
204 }
205
206 private void buildDatatype(SesameEntity bean, String packageName,
207 SesameManager manager, SourceCodeHandler handler) throws Exception {
208 Binding bindings = createBindings();
209 CharArrayWriter output = new CharArrayWriter();
210 setVariables(bindings, manager, packageName, bean);
211 bindings.setVariable("content", new PrintWriter(output));
212 engine.run(DATATYPE_TEMPLATE, bindings);
213 String content = output.toString();
214 if (content.length() > 0) {
215 handler.handleSource(content);
216 }
217 }
218
219 private void buildOntology(URI ontology, SesameManager manager,
220 SourceCodeHandler handler) throws Exception {
221 Binding bindings = createBindings();
222 CharArrayWriter output = new CharArrayWriter();
223 Ontology ont = manager.designate(ontology, Ontology.class);
224 bindings.setVariable("bean", ont);
225 bindings.setVariable("packageName", ontologies.get(ontology));
226 bindings.setVariable("uri", ontology);
227 bindings.setVariable("manager", manager);
228 bindings.setVariable("content", new PrintWriter(output));
229 engine.run(PACKAGE_TEMPLATE, bindings);
230 String content = output.toString();
231 if (content.length() > 0) {
232 handler.handleSource(content);
233 }
234 }
235
236 private Binding createBindings() {
237 Binding bindings = new Binding();
238 bindings.setVariable("packageNames", ontologies);
239 bindings.setVariable("literals", factory.getLiteralManager());
240 bindings.setVariable("roles", factory.getRoleMapper());
241 return bindings;
242 }
243
244 private void setVariables(Binding bindings, SesameManager manager,
245 String packageName, SesameEntity bean) {
246 URI uri = (URI) bean.getSesameResource();
247 uri = normalizer.getOriginal(uri);
248 bindings.setVariable("bean", bean);
249 bindings.setVariable("packageName", packageName);
250 bindings.setVariable("uri", uri);
251 bindings.setVariable("manager", manager);
252 }
253 }