GeoPubby  Version 0.1.0.0
PubbyIRIEscaper Class Reference

IRI rewriter that implements special behaviour for Pubby: Any IRI within a certain namespace (the namespace that Pubby is serving) will have characters that interfer with IRI derferencing %-escaped. More...

Inheritance diagram for PubbyIRIEscaper:
Collaboration diagram for PubbyIRIEscaper:

Public Member Functions

 PubbyIRIEscaper (String namespace, boolean encodeURIsToIRIs)
 
String rewrite (String absoluteIRI)
 Rewrites an IRI. More...
 
String unrewrite (String absoluteIRI)
 Rewrites an IRI. More...
 
Property rewrite (Property original)
 
Resource rewrite (Resource original)
 
Model rewrite (Model original)
 Rewrites the RDF graph in a Jena model by returning a new in-memory model that contains all statements from the original with any IRIs rewritten. More...
 
Map< Property, Integer > rewrite (Map< Property, Integer > original)
 
Property unrewrite (Property rewritten)
 
Resource unrewrite (Resource rewritten)
 

Static Public Member Functions

static String escapeSpecialCharacters (String absoluteIRI)
 Escapes any characters that have special meaning in IRIs so that they are safe for use in a Pubby path. More...
 
static String unescapeSpecialCharacters (String absoluteIRI)
 Reverses the escaping done by unescapeSpecialCharacters(String). More...
 
static IRIRewriter createNamespaceBased (final String originalNamespace, final String rewrittenNamespace)
 Creates a new rewriter that rewrites all IRIs starting with a given namespace by replacing that namespace with another namespace. More...
 
static IRIRewriter chain (final IRIRewriter rewriter1, final IRIRewriter rewriter2)
 Creates an IRIRewriter that applies two existing IRIRewriters. More...
 

Static Public Attributes

static final IRIRewriter identity
 The trivial IRI rewriter that returns IRIs unmodified. More...
 

Private Attributes

final boolean encodeURIsToIRIs
 

Detailed Description

IRI rewriter that implements special behaviour for Pubby: Any IRI within a certain namespace (the namespace that Pubby is serving) will have characters that interfer with IRI derferencing %-escaped.

Any IRI outside that namespace is left alone. The escaped characters are '#' and '?'.

This rewriter can also encode URIs to IRIs as part of the rewriting process. Pubby always wants to work on IRIs. Most data sources use IRIs. Some don't, and all characters outside US-ASCII appear %-encoded in their IRIs. If configured to encode URIs to IRIs, then in the rewritten identifiers we will see proper Unicode characters instead of %-encoded sequences. Note that we do this only within the namespace.

TODO: The URI-to-IRI rewriting should probably be a separate class.

Constructor & Destructor Documentation

◆ PubbyIRIEscaper()

PubbyIRIEscaper ( String  namespace,
boolean  encodeURIsToIRIs 
)
23  {
24  this.namespace = namespace;
26  }
final boolean encodeURIsToIRIs
Definition: PubbyIRIEscaper.java:20

References PubbyIRIEscaper.encodeURIsToIRIs.

Member Function Documentation

◆ chain()

static IRIRewriter chain ( final IRIRewriter  rewriter1,
final IRIRewriter  rewriter2 
)
staticinherited

Creates an IRIRewriter that applies two existing IRIRewriters.

214  {
215  if (rewriter1 == identity) return rewriter2;
216  if (rewriter2 == identity) return rewriter1;
217  return new IRIRewriter() {
218  @Override
219  public String rewrite(String absoluteIRI) {
220  return rewriter2.rewrite(rewriter1.rewrite(absoluteIRI));
221  }
222  @Override
223  public String unrewrite(String absoluteIRI) {
224  return rewriter1.unrewrite(rewriter2.unrewrite(absoluteIRI));
225  }
226  };
227  }
abstract String rewrite(String absoluteIRI)
Rewrites an IRI.
static final IRIRewriter identity
The trivial IRI rewriter that returns IRIs unmodified.
Definition: IRIRewriter.java:31
abstract String unrewrite(String absoluteIRI)
Rewrites an IRI.

References IRIRewriter.identity, IRIRewriter.rewrite(), and IRIRewriter.unrewrite().

Referenced by Dataset.buildDataSource().

◆ createNamespaceBased()

static IRIRewriter createNamespaceBased ( final String  originalNamespace,
final String  rewrittenNamespace 
)
staticinherited

Creates a new rewriter that rewrites all IRIs starting with a given namespace by replacing that namespace with another namespace.

Any IRIs that don't start with theat namespace are returned unchanged. For example, if original namespace is https://example.com/ and replacement namespace is http://localhost:8080/, then the IRI https://example.com/foo/bar will be rewritten to http://localhost:8080/foo/bar, and the IRI https://foo.example.org/bar will be rewritten to itself as it doesn't start with the original namespace.

Parameters
originalNamespaceThe namespace to be replaced
rewrittenNamespaceThe replacement namespace
Returns
171  {
172  if (originalNamespace.equals(rewrittenNamespace)) {
173  return identity;
174  }
175  if (originalNamespace.startsWith(rewrittenNamespace) ||
176  rewrittenNamespace.startsWith(originalNamespace)) {
177  throw new IllegalArgumentException(
178  "Cannot rewrite overlapping namespaces, " +
179  "this would be ambiguous: " + originalNamespace +
180  " => " + rewrittenNamespace);
181  }
182  return new IRIRewriter() {
183  @Override
184  public String rewrite(String absoluteIRI) {
185  if (absoluteIRI.startsWith(originalNamespace)) {
186  return rewrittenNamespace + absoluteIRI.substring(
187  originalNamespace.length());
188  }
189  if (absoluteIRI.startsWith(rewrittenNamespace)) {
190  throw new IllegalArgumentException(
191  "Can't rewrite already rewritten IRI: " + absoluteIRI);
192  }
193  return absoluteIRI;
194  }
195  @Override
196  public String unrewrite(String absoluteIRI) {
197  if (absoluteIRI.startsWith(rewrittenNamespace)) {
198  return originalNamespace + absoluteIRI.substring(
199  rewrittenNamespace.length());
200  }
201  if (absoluteIRI.startsWith(originalNamespace)) {
202  throw new IllegalArgumentException(
203  "Can't unrewrite IRI that already is in the original namespace: " + absoluteIRI);
204  }
205  return absoluteIRI;
206  }
207  };
208  }

References IRIRewriter.identity, IRIRewriter.rewrite(), and IRIRewriter.unrewrite().

Referenced by Dataset.buildDataSource().

◆ escapeSpecialCharacters()

static String escapeSpecialCharacters ( String  absoluteIRI)
static

Escapes any characters that have special meaning in IRIs so that they are safe for use in a Pubby path.

56  {
57  return absoluteIRI.replace("#", "%23").replace("?", "%3F");
58  }

Referenced by HypermediaControls.getPathURL(), HypermediaControls.getPubbyPath(), and PubbyIRIEscaper.rewrite().

◆ rewrite() [1/5]

Map<Property, Integer> rewrite ( Map< Property, Integer >  original)
inherited
146  {
147  if (original == null) return null;
148  Map<Property, Integer> result = new HashMap<Property, Integer>();
149  for (Property p: original.keySet()) {
150  result.put(rewrite(p), original.get(p));
151  }
152  return result;
153  }

References IRIRewriter.rewrite().

◆ rewrite() [2/5]

Model rewrite ( Model  original)
inherited

Rewrites the RDF graph in a Jena model by returning a new in-memory model that contains all statements from the original with any IRIs rewritten.

It rewrites IRIs in subject, predicate, and object position. Also rewrites the namespace prefix mappings, if any are present.

Parameters
originalAn RDF graph in Jena model form
Returns
Rewritten version of the graph
122  {
123  Model result = ModelFactory.createDefaultModel();
124  for (String prefix: original.getNsPrefixMap().keySet()) {
125  String uri = original.getNsPrefixURI(prefix);
126  result.setNsPrefix(prefix, rewrite(uri));
127  }
128  StmtIterator it = original.listStatements();
129  while (it.hasNext()) {
130  Statement stmt = it.nextStatement();
131  Resource s = stmt.getSubject();
132  if (s.isURIResource()) {
133  s = result.createResource(rewrite(s.getURI()));
134  }
135  Property p = result.createProperty(
136  rewrite(stmt.getPredicate().getURI()));
137  RDFNode o = stmt.getObject();
138  if (o.isURIResource()) {
139  o = result.createResource(rewrite(o.asResource().getURI()));
140  }
141  result.add(s, p, o);
142  }
143  return result;
144  }

References IRIRewriter.rewrite().

◆ rewrite() [3/5]

Property rewrite ( Property  original)
inherited
81  {
82  String rewritten = rewrite(original.getURI());
83  if (rewritten.equals(original.getURI())) {
84  return original;
85  }
86  return ResourceFactory.createProperty(rewritten);
87  }

References IRIRewriter.rewrite().

◆ rewrite() [4/5]

Resource rewrite ( Resource  original)
inherited
97  {
98  String rewritten = rewrite(original.getURI());
99  if (rewritten.equals(original.getURI())) {
100  return original;
101  }
102  return ResourceFactory.createResource(rewritten);
103  }

References IRIRewriter.rewrite().

◆ rewrite() [5/5]

String rewrite ( String  absoluteIRI)

Rewrites an IRI.

Parameters
Anyabsolute IRI
Returns
The rewritten form of the IRI

Reimplemented from IRIRewriter.

29  {
30  if (absoluteIRI.startsWith(namespace)) {
31  if (encodeURIsToIRIs) {
32  // absoluteIRI is really a URI
33  absoluteIRI = IRIEncoder.toIRI(absoluteIRI);
34  }
35  return escapeSpecialCharacters(absoluteIRI);
36  }
37  return absoluteIRI;
38  }
static String escapeSpecialCharacters(String absoluteIRI)
Escapes any characters that have special meaning in IRIs so that they are safe for use in a Pubby pat...
Definition: PubbyIRIEscaper.java:56

References PubbyIRIEscaper.encodeURIsToIRIs, PubbyIRIEscaper.escapeSpecialCharacters(), and IRIEncoder.toIRI().

◆ unescapeSpecialCharacters()

static String unescapeSpecialCharacters ( String  absoluteIRI)
static

Reverses the escaping done by unescapeSpecialCharacters(String).

63  {
64  return absoluteIRI.replace("%23", "#").replace("%3F", "?");
65  }

Referenced by HypermediaControls.createFromPubbyPath(), ValuesBaseServlet.doGet(), and PubbyIRIEscaper.unrewrite().

◆ unrewrite() [1/3]

Property unrewrite ( Property  rewritten)
inherited
89  {
90  String original = unrewrite(rewritten.getURI());
91  if (original.equals(rewritten.getURI())) {
92  return rewritten;
93  }
94  return ResourceFactory.createProperty(original);
95  }

References IRIRewriter.unrewrite().

◆ unrewrite() [2/3]

Resource unrewrite ( Resource  rewritten)
inherited
105  {
106  String original = unrewrite(rewritten.getURI());
107  if (original.equals(rewritten.getURI())) {
108  return rewritten;
109  }
110  return ResourceFactory.createResource(original);
111  }

References IRIRewriter.unrewrite().

◆ unrewrite() [3/3]

String unrewrite ( String  absoluteIRI)

Rewrites an IRI.

For any valid IRI,

Parameters
Anyabsolute IRI
Returns
The rewritten form of the IRI

Reimplemented from IRIRewriter.

41  {
42  if (absoluteIRI.startsWith(namespace)) {
43  if (encodeURIsToIRIs) {
44  absoluteIRI = IRIEncoder.toURI(absoluteIRI);
45  // It's now really a URI, not an IRI
46  }
47  return unescapeSpecialCharacters(absoluteIRI);
48  }
49  return absoluteIRI;
50  }
static String unescapeSpecialCharacters(String absoluteIRI)
Reverses the escaping done by unescapeSpecialCharacters(String).
Definition: PubbyIRIEscaper.java:63

References PubbyIRIEscaper.encodeURIsToIRIs, IRIEncoder.toURI(), and PubbyIRIEscaper.unescapeSpecialCharacters().

Member Data Documentation

◆ encodeURIsToIRIs

final boolean encodeURIsToIRIs
private

◆ identity

final IRIRewriter identity
staticinherited

The trivial IRI rewriter that returns IRIs unmodified.

We override all methods for efficiency.

Referenced by Dataset.buildDataSource(), IRIRewriter.chain(), and IRIRewriter.createNamespaceBased().