/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.testing_framework;
import java.util.StringTokenizer ;
import org.apache.jena.datatypes.xsd.XSDDatatype ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.NodeFactory ;
import org.apache.jena.graph.Triple ;
import org.apache.jena.graph.impl.LiteralLabel ;
import org.apache.jena.graph.impl.LiteralLabelFactory ;
import org.apache.jena.shared.JenaException ;
import org.apache.jena.shared.PrefixMapping ;
/**
* Creating nodes from string specifications.
*/
public class NodeCreateUtils {
/**
* Returns a Node described by the string, primarily for testing purposes.
* The string represents a URI, a numeric literal, a string literal, a bnode
* label, or a variable.
* <ul>
* <li>'some text' :: a string literal with that text
* <li>'some text'someLanguage:: a string literal with that text and
* language
* <li>'some text'someURI:: a typed literal with that text and datatype
* <li>digits :: a literal [OF WHAT TYPE] with that [numeric] value
* <li>_XXX :: a bnode with an AnonId built from _XXX
* <li>?VVV :: a variable with name VVV
* <li>&PPP :: to be done
* <li>name:stuff :: the URI; name may be expanded using the Extended map
* </ul>
*
* @param x
* the string describing the node
* @return a node of the appropriate type with the appropriate label
*/
public static Node create(String x) {
return create(PrefixMapping.Extended, x);
}
/**
* Returns a Node described by the string, primarily for testing purposes.
* The string represents a URI, a numeric literal, a string literal, a bnode
* label, or a variable.
* <ul>
* <li>'some text' :: a string literal with that text
* <li>'some text'someLanguage:: a string literal with that text and
* language
* <li>'some text'someURI:: a typed literal with that text and datatype
* <li>digits :: a literal [OF WHAT TYPE] with that [numeric] value
* <li>_XXX :: a bnode with an AnonId built from _XXX
* <li>?VVV :: a variable with name VVV
* <li>&PPP :: to be done
* <li>name:stuff :: the URI; name may be expanded using the Extended map
* </ul>
*
* @param pm
* the PrefixMapping for translating pre:X strings
* @param x
* the string encoding the node to create
* @return a node with the appropriate type and label
*/
public static Node create(PrefixMapping pm, String x) {
if (x.equals(""))
throw new JenaException(
"Node.create does not accept an empty string as argument");
char first = x.charAt(0);
if (first == '\'' || first == '\"')
return NodeFactory.createLiteral(newString(pm, first, x));
if (Character.isDigit(first))
return NodeFactory.createLiteral(x, "", XSDDatatype.XSDinteger);
if (first == '_')
return NodeFactory.createBlankNode(x);
if (x.equals("??"))
return Node.ANY;
if (first == '?')
return NodeFactory.createVariable(x.substring(1));
if (first == '&')
return NodeFactory.createURI("q:" + x.substring(1));
int colon = x.indexOf(':');
String d = pm.getNsPrefixURI("");
return colon < 0 ? NodeFactory.createURI((d == null ? "eh:/" : d) + x)
: NodeFactory.createURI(pm.expandPrefix(x));
}
public static String unEscape(String spelling) {
if (spelling.indexOf('\\') < 0)
return spelling;
StringBuffer result = new StringBuffer(spelling.length());
int start = 0;
while (true) {
int b = spelling.indexOf('\\', start);
if (b < 0)
break;
result.append(spelling.substring(start, b));
result.append(unEscape(spelling.charAt(b + 1)));
start = b + 2;
}
result.append(spelling.substring(start));
return result.toString();
}
public static char unEscape(char ch) {
switch (ch) {
case '\\':
case '\"':
case '\'':
return ch;
case 'n':
return '\n';
case 's':
return ' ';
case 't':
return '\t';
default:
return 'Z';
}
}
public static LiteralLabel literal(PrefixMapping pm, String spelling,
String langOrType) {
String content = unEscape(spelling);
int colon = langOrType.indexOf(':');
return colon < 0 ? LiteralLabelFactory.create(content, langOrType,
false) : LiteralLabelFactory.createLiteralLabel(content, "",
NodeFactory.getType(pm.expandPrefix(langOrType)));
}
public static LiteralLabel newString(PrefixMapping pm, char quote,
String nodeString) {
int close = nodeString.lastIndexOf(quote);
return literal(pm, nodeString.substring(1, close),
nodeString.substring(close + 1));
}
/**
* Utility factory as for create(String), but allowing the PrefixMapping to
* be specified explicitly.
*/
public static Triple createTriple(PrefixMapping pm, String fact) {
StringTokenizer st = new StringTokenizer(fact);
Node sub = create(pm, st.nextToken());
Node pred = create(pm, st.nextToken());
Node obj = create(pm, st.nextToken());
return Triple.create(sub, pred, obj);
}
/**
* Utility factory method for creating a triple based on the content of an
* "S P O" string. The S, P, O are processed by Node.create, see which for
* details of the supported syntax. This method exists to support test code.
* Nodes are interpreted using the Standard prefix mapping.
*/
public static Triple createTriple(String fact) {
return createTriple(PrefixMapping.Standard, fact);
}
}