01: /*
02: * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2007.
03: *
04: * Licensed under the Aduna BSD-style license.
05: */
06: package org.openrdf.query.parser.sparql;
07:
08: import info.aduna.net.ParsedURI;
09:
10: import org.openrdf.query.MalformedQueryException;
11: import org.openrdf.query.parser.sparql.ast.ASTBaseDecl;
12: import org.openrdf.query.parser.sparql.ast.ASTIRI;
13: import org.openrdf.query.parser.sparql.ast.ASTQueryContainer;
14: import org.openrdf.query.parser.sparql.ast.VisitorException;
15:
16: /**
17: * Resolves relative URIs in a query model using either an external base URI or
18: * using the base URI specified in the query model itself. The former takes
19: * precedence over the latter.
20: *
21: * @author Arjohn Kampman
22: */
23: class BaseDeclProcessor {
24:
25: /**
26: * Resolves relative URIs in the supplied query model using either the
27: * specified <tt>externalBaseURI</tt> or, if this parameter is
28: * <tt>null</tt>, the base URI specified in the query model itself.
29: *
30: * @param qc
31: * The query model to resolve relative URIs in.
32: * @param externalBaseURI
33: * The external base URI to use for resolving relative URIs, or
34: * <tt>null</tt> if the base URI that is specified in the query
35: * model should be used.
36: * @throws IllegalArgumentException
37: * If an external base URI is specified that is not an absolute URI.
38: * @throws MalformedQueryException
39: * If the base URI specified in the query model is not an absolute
40: * URI.
41: */
42: public static void process(ASTQueryContainer qc,
43: String externalBaseURI) throws MalformedQueryException {
44: ParsedURI parsedBaseURI = null;
45:
46: // Use the query model's own base URI, if available
47: ASTBaseDecl baseDecl = qc.getBaseDecl();
48: if (baseDecl != null) {
49: parsedBaseURI = new ParsedURI(baseDecl.getIRI());
50:
51: if (!parsedBaseURI.isAbsolute()) {
52: throw new MalformedQueryException(
53: "BASE IRI is not an absolute IRI: "
54: + externalBaseURI);
55: }
56: } else if (externalBaseURI != null) {
57: // Use external base URI if the query doesn't contain one itself
58: parsedBaseURI = new ParsedURI(externalBaseURI);
59:
60: if (!parsedBaseURI.isAbsolute()) {
61: throw new IllegalArgumentException(
62: "Supplied base URI is not an absolute IRI: "
63: + externalBaseURI);
64: }
65: } else {
66: // FIXME: use the "Default Base URI"?
67: }
68:
69: if (parsedBaseURI != null) {
70: RelativeIRIResolver visitor = new RelativeIRIResolver(
71: parsedBaseURI);
72: try {
73: qc.jjtAccept(visitor, null);
74: } catch (VisitorException e) {
75: throw new MalformedQueryException(e);
76: }
77: }
78: }
79:
80: private static class RelativeIRIResolver extends ASTVisitorBase {
81:
82: private ParsedURI parsedBaseURI;
83:
84: public RelativeIRIResolver(ParsedURI parsedBaseURI) {
85: this .parsedBaseURI = parsedBaseURI;
86: }
87:
88: @Override
89: public Object visit(ASTIRI node, Object data)
90: throws VisitorException {
91: ParsedURI resolvedURI = parsedBaseURI.resolve(node
92: .getValue());
93: node.setValue(resolvedURI.toString());
94:
95: return super.visit(node, data);
96: }
97: }
98: }
|