blob: 5cdbdceadbfddd42106e4ab2b0eeb65f88998a44 [file] [log] [blame]
/*
* 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.clerezza.platform.typerendering.seedsnipe;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.clerezza.platform.typerendering.CallbackRenderer;
import org.apache.clerezza.rdf.core.BNode;
import org.apache.clerezza.rdf.core.Language;
import org.apache.clerezza.rdf.core.Literal;
import org.apache.clerezza.rdf.core.LiteralFactory;
import org.apache.clerezza.rdf.core.NonLiteral;
import org.apache.clerezza.rdf.core.PlainLiteral;
import org.apache.clerezza.rdf.core.TripleCollection;
import org.apache.clerezza.rdf.core.TypedLiteral;
import org.apache.clerezza.rdf.core.UriRef;
import org.apache.clerezza.rdf.utils.GraphNode;
import org.apache.clerezza.templating.RenderingFunction;
import org.apache.clerezza.templating.RenderingFunctions;
/**
*
* @author rbn, mkr, dsr
*/
class WebRenderingFunctions implements RenderingFunctions {
private static final UriRef XML_DATE_LITERAL = new UriRef(
"http://www.w3.org/2001/XMLSchema#dateTime");
private final static UriRef RDF_XML_LITERAL = new UriRef(
"http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral");
private TripleCollection graph;
private GraphNode context;
private CallbackRenderer callbackRenderer;
private String mode;
WebRenderingFunctions(TripleCollection graph,
GraphNode context,
CallbackRenderer callbackRenderer, String mode) {
this.graph = graph;
this.context = context;
this.callbackRenderer = callbackRenderer;
this.mode = mode;
}
@Override
public RenderingFunction<Object, String> getDefaultFunction() {
return new RenderingFunction<Object, String>() {
@Override
public String process(Object... values) {
Object value = values[0];
if (value instanceof String) {
return (String) value;
}
String stringValue;
if (value instanceof Literal) {
if (value instanceof TypedLiteral) {
TypedLiteral typedLiteral = (TypedLiteral) value;
if (typedLiteral.getDataType().equals(RDF_XML_LITERAL)) {
return typedLiteral.getLexicalForm();
}
}
stringValue = ((Literal) value).getLexicalForm();
} else {
if (value instanceof UriRef) {
stringValue = ((UriRef) value).getUnicodeString();
} else {
stringValue = value.toString();
}
}
return escape(stringValue);
}
};
}
private String escape(String s) {
StringWriter resultWriter = new StringWriter();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
switch (ch) {
case '<':
resultWriter.write("&lt;");
break;
case '&':
resultWriter.write("&amp;");
break;
default:
resultWriter.write(ch);
}
}
return resultWriter.toString();
}
@Override
public Map<String, RenderingFunction> getNamedFunctions() {
Map<String, RenderingFunction> result = new HashMap<String, RenderingFunction>();
result.put("render", new RenderFunction());
result.put("mode", new ModeFunction());
result.put("language", languageFunction);
result.put("datatype", datatypeFunction);
result.put("type", typeFunction);
result.put("toString", toStringFunction);
result.put("date", dateFunction);
result.put("substring", substringFunction);
result.put("lexicalForm", lexicalFormFunction);
result.put("contains", containsFunction);
return result;
}
/**
* A functions that takes a node and optionally a templating mode as
* arguments
*/
private class RenderFunction implements RenderingFunction<Object, String> {
@Override
public String process(Object... values) throws IOException {
NonLiteral resource = (NonLiteral) values[0];
GraphNode graphNode = new GraphNode(resource, graph);
String mode = null;
if (values.length > 1) {
mode = (String) values[1];
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
callbackRenderer.render(graphNode, context, mode, out);
try {
return new String(out.toByteArray(), "utf-8");
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(ex);
}
}
}
/**
* A function that returns the current rendering mode
*/
private class ModeFunction implements RenderingFunction<Object, String> {
@Override
public String process(Object... values) {
return mode;
}
}
/**
* A function that returns the Language of a PlainLiteral or null if the
* Literal has no language or if the object is not a PlainLiteral
*/
private static RenderingFunction languageFunction = new RenderingFunction<Object, Language>() {
@Override
public Language process(Object... values) {
Object value = values[0];
if (value instanceof PlainLiteral) {
return ((PlainLiteral) value).getLanguage();
}
return null;
}
};
/**
* A function that returns the Datatype of a TypedLiteral or null if the
* Literal has no language or if the object is not a TypedLiteral
*/
private static RenderingFunction datatypeFunction = new RenderingFunction<Object, UriRef>() {
@Override
public UriRef process(Object... values) {
Object value = values[0];
if (value instanceof PlainLiteral) {
return ((TypedLiteral) value).getDataType();
}
return null;
}
};
/**
* A function that returns the value returned by the toString() method of an
* object
*/
private static RenderingFunction toStringFunction = new RenderingFunction<Object, String>() {
@Override
public String process(Object... values) {
Object value = values[0];
return value.toString();
}
};
/**
* A function that returns a String representing the type of the Object.
* Either oneof - plainLiteral - typedLiteral - uriRef - bNode
*
* or, for other types the SimpleName of the class.
*
*/
private static RenderingFunction typeFunction = new RenderingFunction<Object, String>() {
@Override
public String process(Object... values) {
Object value = values[0];
if (value instanceof PlainLiteral) {
return "plainLiteral";
}
if (value instanceof TypedLiteral) {
return "typedLiteral";
}
if (value instanceof UriRef) {
return "uriRef";
}
if (value instanceof BNode) {
return "bNode";
}
return value.getClass().getSimpleName();
}
};
/**
* A function that returns String representation of an XMLLiteral of type
* date or an empty String if value[0] is not an XML Literal of type date.
* Optionally it allows the date to be formated according to a format-String
* parameter which uses the Java SimpleFormat syntax.
*/
private static RenderingFunction dateFunction = new RenderingFunction<Object, String>() {
@Override
public String process(Object... values) {
TypedLiteral typedLiteral;
if (values[0] instanceof TypedLiteral && (typedLiteral = (TypedLiteral) values[0]).getDataType().equals(XML_DATE_LITERAL)) {
String dateString = typedLiteral.getLexicalForm();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
values.length >= 2 ? (String) values[1] : "yyyy-MM-ddHH:mm:ss.SSSZ");
Date date = LiteralFactory.getInstance().createObject(Date.class, typedLiteral);
return simpleDateFormat.format(date);
} else {
return "";
}
}
};
/**
* A function that takes an object, a beginindex and an endindex as
* arguments. It returns the substring from beginindex to endindex
* of the string representation of the first argument.
*/
private static RenderingFunction substringFunction = new RenderingFunction<Object, String>() {
@Override
public String process(Object... values) {
String str = values[0].toString();
int begin = 0;
int end = str.length();
if (values.length >= 2) {
begin = Integer.parseInt(values[1].toString());
if (!(begin >= 0)) {
begin = 0;
}
if (!(begin <= end)) {
begin = str.length();
}
}
if (values.length >= 3) {
end = Integer.parseInt(values[2].toString());
if (!(end >= begin)) {
end = begin;
}
if (!(end <= str.length())) {
end = str.length();
}
}
return str.substring(begin, end);
}
};
/**
* A function that takes an object and a string. It returns a boolean
* value that indicates if the string representation of the object
* (first argument) contains the string (second argument).
*/
private static RenderingFunction containsFunction = new RenderingFunction<Object, Boolean>() {
@Override
public Boolean process(Object... values) {
String str = values[0].toString();
String str2 = (String)values[1];
return str.contains(str2);
}
};
/**
* A function that takes a Literal as argument and returns the lexical form.
*/
private static RenderingFunction lexicalFormFunction = new RenderingFunction<Object, String>() {
@Override
public String process(Object... values) {
return ((Literal) values[0]).getLexicalForm();
}
};
}