You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ss...@apache.org on 2013/02/19 18:04:23 UTC
[2/51] [abbrv] reorganized repository
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/LDPathClient.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/LDPathClient.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/LDPathClient.java
new file mode 100644
index 0000000..c581e9f
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/LDPathClient.java
@@ -0,0 +1,164 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.clients;
+
+import at.newmedialab.lmf.client.ClientConfiguration;
+import at.newmedialab.lmf.client.exception.ContentFormatException;
+import at.newmedialab.lmf.client.exception.LMFClientException;
+import at.newmedialab.lmf.client.exception.NotFoundException;
+import at.newmedialab.lmf.client.model.rdf.RDFNode;
+import at.newmedialab.lmf.client.util.HTTPUtil;
+import at.newmedialab.lmf.client.util.RDFJSONParser;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class LDPathClient {
+
+ private static Logger log = LoggerFactory.getLogger(LDPathClient.class);
+
+ private static final String URL_PATH_SERVICE = "/ldpath/path";
+ private static final String URL_PROGRAM_SERVICE = "/ldpath/program";
+
+
+ private ClientConfiguration config;
+
+ public LDPathClient(ClientConfiguration config) {
+ this.config = config;
+ }
+
+
+ /**
+ * Evaluate the path query passed as second argument, starting at the resource with the uri given as first argument.
+ * Returns a List of RDFNode objects.
+ *
+ *
+ * @param uri the uri of the resource where to start the path evaluation
+ * @param path the path to evaluate
+ * @return a list of RDFNodes representing the result of the path evaluation as returned by the server
+ * @throws LMFClientException
+ * @throws IOException
+ */
+ public List<RDFNode> evaluatePath(String uri, String path) throws LMFClientException, IOException {
+ HttpClient httpClient = HTTPUtil.createClient(config);
+
+ String serviceUrl = config.getLmfUri() + URL_PATH_SERVICE + "?path=" + URLEncoder.encode(path, "utf-8")
+ + "&uri=" + URLEncoder.encode(uri, "utf-8");
+
+ HttpGet get = new HttpGet(serviceUrl);
+ get.setHeader("Accept", "application/json");
+
+ try {
+
+ HttpResponse response = httpClient.execute(get);
+
+ switch(response.getStatusLine().getStatusCode()) {
+ case 200:
+ log.debug("LDPath Path Query {} evaluated successfully",path);
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
+ List<Map<String,String>> serverResult =
+ mapper.readValue(response.getEntity().getContent(),new TypeReference<List<Map<String,String>>>(){});
+
+
+ List<RDFNode> result = new ArrayList<RDFNode>();
+ for(Map<String,String> value : serverResult) {
+ result.add(RDFJSONParser.parseRDFJSONNode(value));
+ }
+ return result;
+ case 400:
+ log.error("the server did not accept the uri ({}) or path ({}) arguments",uri,path);
+ throw new ContentFormatException("the server did not accept the uri ("+uri+") or path ("+path+") arguments");
+ case 404:
+ log.error("the resource with URI {} does not exist on the server",uri);
+ throw new NotFoundException("the resource with URI "+uri+" does not exist on the server");
+ default:
+ log.error("error evaluating LDPath Path Query {}: {} {}",new Object[] {path,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
+ throw new LMFClientException("error evaluating LDPath Path Query "+path+": "+response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
+ }
+
+ } finally {
+ get.releaseConnection();
+ }
+
+ }
+
+
+ public Map<String,List<RDFNode>> evaluateProgram(String uri, String program) throws LMFClientException, IOException {
+ HttpClient httpClient = HTTPUtil.createClient(config);
+
+ String serviceUrl = config.getLmfUri() + URL_PROGRAM_SERVICE + "?program=" + URLEncoder.encode(program, "utf-8")
+ + "&uri=" + URLEncoder.encode(uri, "utf-8");
+
+ HttpGet get = new HttpGet(serviceUrl);
+ get.setHeader("Accept", "application/json");
+
+ try {
+
+ HttpResponse response = httpClient.execute(get);
+
+ switch(response.getStatusLine().getStatusCode()) {
+ case 200:
+ log.debug("LDPath Program Query evaluated successfully:\n{}",program);
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
+ Map<String,List<Map<String,String>>> serverResult =
+ mapper.readValue(response.getEntity().getContent(),new TypeReference<Map<String,List<Map<String,String>>>>(){});
+
+
+ Map<String,List<RDFNode>> result = new HashMap<String, List<RDFNode>>();
+ for(Map.Entry<String,List<Map<String,String>>> field : serverResult.entrySet()) {
+ List<RDFNode> row = new ArrayList<RDFNode>();
+ for(Map<String,String> node : field.getValue()) {
+ row.add(RDFJSONParser.parseRDFJSONNode(node));
+ }
+ result.put(field.getKey(),row);
+ }
+ return result;
+ case 400:
+ log.error("the server did not accept the uri ({}) or program ({}) arguments",uri,program);
+ throw new ContentFormatException("the server did not accept the uri ("+uri+") or program ("+program+") arguments");
+ case 404:
+ log.error("the resource with URI {} does not exist on the server",uri);
+ throw new NotFoundException("the resource with URI "+uri+" does not exist on the server");
+ default:
+ log.error("error evaluating LDPath Program Query: {} {}",new Object[] {response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
+ throw new LMFClientException("error evaluating LDPath Program Query: "+response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
+ }
+
+ } finally {
+ get.releaseConnection();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/ResourceClient.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/ResourceClient.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/ResourceClient.java
new file mode 100644
index 0000000..616be9d
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/ResourceClient.java
@@ -0,0 +1,372 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.clients;
+
+import at.newmedialab.lmf.client.ClientConfiguration;
+import at.newmedialab.lmf.client.exception.ContentFormatException;
+import at.newmedialab.lmf.client.exception.LMFClientException;
+import at.newmedialab.lmf.client.exception.NotFoundException;
+import at.newmedialab.lmf.client.model.content.Content;
+import at.newmedialab.lmf.client.model.content.StreamContent;
+import at.newmedialab.lmf.client.model.meta.Metadata;
+import at.newmedialab.lmf.client.util.HTTPUtil;
+import at.newmedialab.lmf.client.util.RDFJSONParser;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.ByteStreams;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpOptions;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.ContentProducer;
+import org.apache.http.entity.EntityTemplate;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Map;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class ResourceClient {
+
+ private static Logger log = LoggerFactory.getLogger(ResourceClient.class);
+
+ private static final String URL_RESOURCE_SERVICE = "/resource";
+
+ private ClientConfiguration config;
+
+ public ResourceClient(ClientConfiguration config) {
+ this.config = config;
+
+ }
+
+ /**
+ * Create a resource in the remote LMF installation
+ * @param uri
+ * @return
+ * @throws IOException
+ */
+ public boolean createResource(String uri) throws IOException {
+ HttpClient httpClient = HTTPUtil.createClient(config);
+
+ HttpPost post = new HttpPost(getServiceUrl(uri));
+
+ try {
+
+ HttpResponse response = httpClient.execute(post);
+
+ switch(response.getStatusLine().getStatusCode()) {
+ case 200:
+ log.debug("resource {} already existed, not creating new",uri);
+ return true;
+ case 201:
+ log.debug("resource {} created",uri);
+ return true;
+ default:
+ log.error("error creating resource {}: {} {}",new Object[] {uri,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
+ return true;
+ }
+
+ } catch (UnsupportedEncodingException e) {
+ log.error("could not encode URI parameter",e);
+ return false;
+ } finally {
+ post.releaseConnection();
+ }
+ }
+
+ /**
+ * Test whether the resource with the provided URI exists.
+ * <p/>
+ * Uses an OPTIONS call to the resource web service to determine whether the resource exists or not
+ *
+ * @param uri
+ * @return
+ * @throws IOException
+ */
+ public boolean existsResource(String uri) throws IOException {
+ HttpClient httpClient = HTTPUtil.createClient(config);
+
+ HttpOptions options = new HttpOptions(getServiceUrl(uri));
+
+ try {
+
+ HttpResponse response = httpClient.execute(options);
+
+ if(response.containsHeader("Access-Control-Allow-Methods") && response.getFirstHeader("Access-Control-Allow-Methods").getValue().equals("POST")) {
+ return false;
+ } else if(response.containsHeader("Access-Control-Allow-Methods") && response.getFirstHeader("Access-Control-Allow-Methods").getValue().contains("GET")) {
+ return true;
+ } else {
+ log.warn("OPTIONS response did not contain a access-control-allow-methods header");
+ return false;
+ }
+
+ } catch (UnsupportedEncodingException e) {
+ log.error("could not encode URI parameter",e);
+ return false;
+ } finally {
+ options.releaseConnection();
+ }
+ }
+
+ /**
+ * Return the resource metadata for the resource with the given URI, if it exists. Returns null if the
+ * resource exists but there is no metadata. Throws an exception if the resource does not exist or some
+ * other error code was returned.
+ *
+ * @param uri
+ * @return
+ * @throws IOException
+ * @throws LMFClientException
+ */
+ public Metadata getResourceMetadata(String uri) throws IOException, LMFClientException {
+ HttpClient httpClient = HTTPUtil.createClient(config);
+
+ HttpGet get = new HttpGet(getServiceUrl(uri));
+ get.setHeader("Accept", "application/rdf+json; rel=meta");
+
+ try {
+
+ HttpResponse response = httpClient.execute(get);
+
+ switch(response.getStatusLine().getStatusCode()) {
+ case 200:
+ log.debug("metadata for resource {} retrieved",uri);
+ Map<String,Metadata> result = RDFJSONParser.parseRDFJSON(response.getEntity().getContent());
+ if(result.containsKey(uri)) {
+ return result.get(uri);
+ } else {
+ return null;
+ }
+ case 406:
+ log.error("server does not support metadata type application/json for resource {}, cannot retrieve", uri);
+ throw new ContentFormatException("server does not support metadata type application/json for resource "+uri);
+ case 404:
+ log.error("resource {} does not exist, cannot retrieve", uri);
+ throw new NotFoundException("resource "+uri+" does not exist, cannot retrieve");
+ default:
+ log.error("error retrieving resource {}: {} {}",new Object[] {uri,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
+ throw new LMFClientException("error retrieving resource "+uri+": "+response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
+ }
+
+ } catch (UnsupportedEncodingException e) {
+ log.error("could not encode URI parameter",e);
+ throw new LMFClientException("could not encode URI parameter");
+ } finally {
+ get.releaseConnection();
+ }
+ }
+
+ /**
+ * Update (overwrite) the metadata of the resource identified by the given uri. The metadata will be serialised to
+ * application/json and sent to the Linked Media Framework server. The given metadata will override any metadata
+ * for the resource already existing on the server. The resource has to exist or be created before updating, otherwise
+ * the method will throw a NotFoundException.
+ *
+ * @param uri the URI of the resource to update
+ * @param metadata the metadata to upload to the resource
+ * @throws IOException
+ * @throws LMFClientException
+ */
+ public void updateResourceMetadata(final String uri, final Metadata metadata) throws IOException, LMFClientException {
+ HttpClient httpClient = HTTPUtil.createClient(config);
+
+ HttpPut put = new HttpPut(getServiceUrl(uri));
+ put.setHeader("Content-Type", "application/rdf+json; rel=meta");
+ ContentProducer cp = new ContentProducer() {
+ @Override
+ public void writeTo(OutputStream outstream) throws IOException {
+ RDFJSONParser.serializeRDFJSON(ImmutableMap.of(uri, metadata), outstream);
+ }
+ };
+ put.setEntity(new EntityTemplate(cp));
+
+ try {
+
+ HttpResponse response = httpClient.execute(put);
+
+ switch(response.getStatusLine().getStatusCode()) {
+ case 200:
+ log.debug("metadata for resource {} updated",uri);
+ break;
+ case 415:
+ log.error("server does not support metadata type application/json for resource {}, cannot update", uri);
+ throw new ContentFormatException("server does not support metadata type application/json for resource "+uri);
+ case 404:
+ log.error("resource {} does not exist, cannot update", uri);
+ throw new NotFoundException("resource "+uri+" does not exist, cannot update");
+ default:
+ log.error("error updating resource {}: {} {}",new Object[] {uri,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
+ throw new LMFClientException("error updating resource "+uri+": "+response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
+ }
+
+ } catch (UnsupportedEncodingException e) {
+ log.error("could not encode URI parameter",e);
+ throw new LMFClientException("could not encode URI parameter");
+ } finally {
+ put.releaseConnection();
+ }
+ }
+
+ /**
+ * Retrieve the (human-readable) content of the given mimeType of the given resource. Will return a content
+ * object that allows reading the input stream. In case no content of the given mime type exists for the resource,
+ * will throw a ContentFormatException.
+ *
+ * @param uri
+ * @param mimeType
+ * @return
+ * @throws IOException
+ * @throws LMFClientException
+ */
+ public Content getResourceContent(String uri, String mimeType) throws IOException, LMFClientException {
+ HttpClient httpClient = HTTPUtil.createClient(config);
+
+ HttpGet get = new HttpGet(getServiceUrl(uri));
+ get.setHeader("Accept", mimeType+"; rel=content");
+
+ try {
+
+ HttpResponse response = httpClient.execute(get);
+
+ switch(response.getStatusLine().getStatusCode()) {
+ case 200:
+ log.debug("metadata for resource {} retrieved",uri);
+ Content content = new StreamContent(response.getEntity().getContent(),response.getEntity().getContentType().getValue(),response.getEntity().getContentLength());
+ return content;
+ case 406:
+ log.error("server does not offer content type {} for resource {}, cannot retrieve", mimeType, uri);
+ throw new ContentFormatException("server does not offer content type "+mimeType+" for resource "+uri);
+ case 404:
+ log.error("resource {} does not exist, cannot retrieve content", uri);
+ throw new NotFoundException("resource "+uri+" does not exist, cannot retrieve");
+ default:
+ log.error("error retrieving resource {}: {} {}",new Object[] {uri,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
+ throw new LMFClientException("error retrieving resource "+uri+": "+response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
+ }
+
+ } catch (UnsupportedEncodingException e) {
+ log.error("could not encode URI parameter",e);
+ throw new LMFClientException("could not encode URI parameter");
+ } finally {
+ get.releaseConnection();
+ }
+ }
+
+ /**
+ * Update the content of the resource identified by the URI given as argument. The resource has to exist before
+ * content can be uploaded to it. Any existing content will be overridden. The stream of the content object
+ * will be consumed by this method. Throws ContentFormatException if the content type is not supported,
+ * NotFoundException if the resource does not exist.
+ * @param uri
+ * @param content
+ * @throws IOException
+ * @throws LMFClientException
+ */
+ public void updateResourceContent(final String uri, final Content content) throws IOException, LMFClientException {
+ HttpClient httpClient = HTTPUtil.createClient(config);
+
+ HttpPut put = new HttpPut(getServiceUrl(uri));
+ put.setHeader("Content-Type", content.getMimeType()+"; rel=content");
+ ContentProducer cp = new ContentProducer() {
+ @Override
+ public void writeTo(OutputStream outstream) throws IOException {
+ ByteStreams.copy(content.getStream(),outstream);
+ }
+ };
+ put.setEntity(new EntityTemplate(cp));
+
+ ResponseHandler<Boolean> handler = new ResponseHandler<Boolean>() {
+ @Override
+ public Boolean handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
+ EntityUtils.consume(response.getEntity());
+ switch(response.getStatusLine().getStatusCode()) {
+ case 200:
+ log.debug("content for resource {} updated",uri);
+ return true;
+ case 406:
+ log.error("server does not support content type {} for resource {}, cannot update", content.getMimeType(),uri);
+ return false;
+ case 404:
+ log.error("resource {} does not exist, cannot update", uri);
+ return false;
+ default:
+ log.error("error updating resource {}: {} {}",new Object[] {uri,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
+ return false;
+ }
+ }
+ };
+
+ try {
+ httpClient.execute(put, handler);
+ } catch(IOException ex) {
+ put.abort();
+ throw ex;
+ } finally {
+ put.releaseConnection();
+ }
+
+ }
+
+
+ public void deleteResource(String uri) throws IOException {
+ HttpClient httpClient = HTTPUtil.createClient(config);
+
+ HttpDelete delete = new HttpDelete(getServiceUrl(uri));
+
+ try {
+
+ HttpResponse response = httpClient.execute(delete);
+
+ switch(response.getStatusLine().getStatusCode()) {
+ case 200:
+ log.debug("resource {} deleted",uri);
+ break;
+ case 400:
+ log.error("resource {} invalid, cannot delete", uri);
+ break;
+ case 404:
+ log.error("resource {} does not exist, cannot delete", uri);
+ break;
+ default:
+ log.error("error deleting resource {}: {} {}",new Object[] {uri,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
+ }
+
+ } catch (UnsupportedEncodingException e) {
+ log.error("could not encode URI parameter",e);
+ } finally {
+ delete.releaseConnection();
+ }
+ }
+
+ private String getServiceUrl(String uri) throws UnsupportedEncodingException {
+ return config.getLmfUri() + URL_RESOURCE_SERVICE + "?uri=" + URLEncoder.encode(uri,"utf-8");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/SPARQLClient.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/SPARQLClient.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/SPARQLClient.java
new file mode 100644
index 0000000..4524928
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/SPARQLClient.java
@@ -0,0 +1,227 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.clients;
+
+import at.newmedialab.lmf.client.ClientConfiguration;
+import at.newmedialab.lmf.client.exception.LMFClientException;
+import at.newmedialab.lmf.client.model.rdf.BNode;
+import at.newmedialab.lmf.client.model.rdf.Literal;
+import at.newmedialab.lmf.client.model.rdf.RDFNode;
+import at.newmedialab.lmf.client.model.rdf.URI;
+import at.newmedialab.lmf.client.model.sparql.SPARQLResult;
+import at.newmedialab.lmf.client.util.HTTPUtil;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class SPARQLClient {
+
+ private static Logger log = LoggerFactory.getLogger(SPARQLClient.class);
+
+ private static final String URL_QUERY_SERVICE = "/sparql/select";
+ private static final String URL_UPDATE_SERVICE = "/sparql/update";
+
+ private ClientConfiguration config;
+
+ public SPARQLClient(ClientConfiguration config) {
+ this.config = config;
+ }
+
+ /**
+ * Run a SPARQL Select query against the LMF Server and return the results as SPARQL Result. Results will be
+ * transfered and parsed using the SPARQL JSON format.
+ * @param query a SPARQL Select query to run on the database
+ * @return
+ * @throws IOException
+ * @throws LMFClientException
+ */
+ @SuppressWarnings("unchecked")
+ public SPARQLResult select(String query) throws IOException, LMFClientException {
+ HttpClient httpClient = HTTPUtil.createClient(config);
+
+ String serviceUrl = config.getLmfUri() + URL_QUERY_SERVICE + "?query=" + URLEncoder.encode(query, "utf-8");
+
+ HttpGet get = new HttpGet(serviceUrl);
+ get.setHeader("Accept", "application/sparql-results+json");
+
+ try {
+
+ HttpResponse response = httpClient.execute(get);
+
+ switch(response.getStatusLine().getStatusCode()) {
+ case 200:
+ log.debug("SPARQL Query {} evaluated successfully",query);
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
+ Map<String,Map<String,List<?>>> resultMap =
+ mapper.readValue(response.getEntity().getContent(),new TypeReference<Map<String,Map<String,List<?>>>>(){});
+
+ if(resultMap.isEmpty()) {
+ return null;
+ } else {
+ List<?> head = resultMap.get("head").get("vars");
+ Set<String> fieldNames = new HashSet<String>();
+ for(Object o : head) {
+ if(o instanceof String) {
+ fieldNames.add((String)o);
+ }
+ }
+
+ SPARQLResult result = new SPARQLResult(fieldNames);
+
+ List<?> bindings = resultMap.get("results").get("bindings");
+ for(Object o : bindings) {
+ if(o instanceof Map) {
+ Map<String,RDFNode> row = new HashMap<String, RDFNode>();
+ for(Map.Entry<String,?> entry : ((Map<String,?>)o).entrySet()) {
+ Map<String,String> nodeDef = (Map<String,String>) entry.getValue();
+ RDFNode node = null;
+ if("uri".equalsIgnoreCase(nodeDef.get("type"))) {
+ node = new URI(nodeDef.get("value"));
+ } else if("literal".equalsIgnoreCase(nodeDef.get("type")) ||
+ "typed-literal".equalsIgnoreCase(nodeDef.get("type"))) {
+ String lang = nodeDef.get("xml:lang");
+ String datatype = nodeDef.get("datatype");
+
+ if(lang != null) {
+ node = new Literal(nodeDef.get("value"),lang);
+ } else if(datatype != null) {
+ node = new Literal(nodeDef.get("value"),new URI(datatype));
+ } else {
+ node = new Literal(nodeDef.get("value"));
+ }
+ } else if("bnode".equalsIgnoreCase(nodeDef.get("type"))) {
+ node = new BNode(nodeDef.get("value"));
+ } else {
+ log.error("unknown result node type: {}",nodeDef.get("type"));
+ }
+
+ if(node != null) {
+ row.put(entry.getKey(),node);
+ }
+ }
+ result.add(row);
+ }
+ }
+ return result;
+ }
+ default:
+ log.error("error evaluating SPARQL Select Query {}: {} {}",new Object[] {query,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
+ throw new LMFClientException("error evaluating SPARQL Select Query "+query+": "+response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
+ }
+
+ } finally {
+ get.releaseConnection();
+ }
+ }
+
+ /**
+ * Carry out a SPARQL ASK Query and return either true or false, depending on the query result.
+ *
+ * @param askQuery
+ * @return
+ * @throws IOException
+ * @throws LMFClientException
+ */
+ public boolean ask(String askQuery) throws IOException, LMFClientException {
+ HttpClient httpClient = HTTPUtil.createClient(config);
+
+ String serviceUrl = config.getLmfUri() + URL_QUERY_SERVICE + "?query=" + URLEncoder.encode(askQuery, "utf-8");
+
+ HttpGet get = new HttpGet(serviceUrl);
+ get.setHeader("Accept", "application/sparql-results+json");
+
+ try {
+
+ HttpResponse response = httpClient.execute(get);
+
+ switch(response.getStatusLine().getStatusCode()) {
+ case 200:
+ log.debug("SPARQL ASK Query {} evaluated successfully",askQuery);
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
+ Map<String,Object> resultMap =
+ mapper.readValue(response.getEntity().getContent(),new TypeReference<Map<String,Object>>(){});
+
+ if(resultMap.isEmpty()) {
+ return false;
+ } else {
+ Boolean result = resultMap.get("boolean") != null && ((String)resultMap.get("boolean")).equalsIgnoreCase("true");
+ return result;
+ }
+ default:
+ log.error("error evaluating SPARQL ASK Query {}: {} {}",new Object[] {askQuery,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
+ throw new LMFClientException("error evaluating SPARQL ASK Query "+askQuery+": "+response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
+ }
+
+ } finally {
+ get.releaseConnection();
+ }
+ }
+
+ /**
+ * Execute a SPARQL Update query according to the SPARQL 1.1 standard. The query will only be passed to the server,
+ * which will react either with ok (in this the method simply returns) or with error (in this case, the method
+ * throws an LMFClientException).
+ *
+ * @param updateQuery the SPARQL Update 1.1 query string
+ * @throws IOException in case a connection problem occurs
+ * @throws LMFClientException in case the server returned and error and did not execute the update
+ */
+ public void update(String updateQuery) throws IOException, LMFClientException {
+ HttpClient httpClient = HTTPUtil.createClient(config);
+
+ String serviceUrl = config.getLmfUri() + URL_UPDATE_SERVICE + "?update=" + URLEncoder.encode(updateQuery, "utf-8");
+
+ HttpGet get = new HttpGet(serviceUrl);
+
+ try {
+
+ HttpResponse response = httpClient.execute(get);
+
+ switch(response.getStatusLine().getStatusCode()) {
+ case 200:
+ log.debug("SPARQL UPDATE Query {} evaluated successfully",updateQuery);
+ break;
+ default:
+ log.error("error evaluating SPARQL UPDATE Query {}: {} {}",new Object[] {updateQuery,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
+ throw new LMFClientException("error evaluating SPARQL UPDATE Query "+updateQuery +": "+response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
+ }
+
+ } finally {
+ get.releaseConnection();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/SearchClient.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/SearchClient.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/SearchClient.java
new file mode 100644
index 0000000..ef6307e
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/clients/SearchClient.java
@@ -0,0 +1,161 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.clients;
+
+import at.newmedialab.lmf.client.ClientConfiguration;
+import at.newmedialab.lmf.client.exception.LMFClientException;
+import at.newmedialab.lmf.client.util.KiWiCollections;
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.impl.HttpSolrServer;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.params.MoreLikeThisParams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provide Semantic Search functionality to the LMF search cores based on SOLRJ queries and results. Any SOLRJ query
+ * can be used and a SOLRJ result is returned, so the client provides maximum flexibility.
+ * <p/>
+ * SOLR updating is not supported through this client, since this is not an intended use of the LMF search cores.
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class SearchClient {
+
+ private static Logger log = LoggerFactory.getLogger(CoresClient.class);
+
+ private static final String URL_SOLR_SERVICE = "/solr";
+
+ private ClientConfiguration config;
+
+ Set<String> cores;
+
+ public SearchClient(ClientConfiguration config) {
+ this.config = config;
+
+ CoresClient coresClient = new CoresClient(config);
+ cores = new HashSet<String>();
+ try {
+ cores.addAll(coresClient.listCores());
+ } catch (IOException e) {
+ log.error("could not initialise list of cores; search functionality will not work",e);
+ } catch (LMFClientException e) {
+ log.error("could not initialise list of cores; search functionality will not work", e);
+ }
+ }
+
+ /**
+ * Run a SOLR search against the selected core and return the result as SolrDocumentList.
+ *
+ * @param coreName name of the core to query
+ * @param query the SolrQuery to run on the core
+ * @return
+ * @throws IOException
+ * @throws LMFClientException
+ */
+ public SolrDocumentList search(String coreName, SolrQuery query) throws IOException, LMFClientException {
+ Preconditions.checkArgument(cores.contains(coreName),"core {} does not exist",coreName);
+
+ SolrServer server = new HttpSolrServer(config.getLmfUri()+URL_SOLR_SERVICE+"/"+ URLEncoder.encode(coreName,"utf-8"));
+
+ try {
+ QueryResponse response = server.query(query);
+ return response.getResults();
+ } catch (SolrServerException e) {
+ log.error("error while evaluating SOLR query",e);
+ throw new LMFClientException("error while evaluating SOLR query",e);
+ }
+
+ }
+
+
+ /**
+ * Perform a simple string search on the given core using default parameters for the SolrQuery.
+ */
+ public SolrDocumentList simpleSearch(String coreName, String queryString, Map<String,String> options) throws IOException, LMFClientException {
+ SolrQuery query = new SolrQuery();
+ query.setQuery(queryString);
+ if(options != null && options.containsKey("fields")) {
+ query.setFields(options.get("fields"));
+ } else {
+ query.setFields("*,score");
+ }
+
+ if(options != null && options.containsKey("sort")) {
+ query.addSortField(options.get("sort"), SolrQuery.ORDER.desc);
+ } else {
+ query.addSortField("score", SolrQuery.ORDER.desc);
+ }
+
+ if(options != null && options.containsKey("facets")) {
+ for(String facet : options.get("facets").split(",")) {
+ query.addFacetField(facet);
+ }
+ }
+ if(options != null && options.containsKey("offset")) {
+ query.setStart(Integer.parseInt(options.get("offset")));
+ }
+ if(options != null && options.containsKey("limit")) {
+ query.setRows(Integer.parseInt(options.get("limit")));
+ }
+ return search(coreName,query);
+
+ }
+
+
+ /**
+ * Retrieve recommendations for the given URI using the SOLR moreLikeThis handler for the core passed as first argument.
+ * The fieldWeights map field names to weights, where 1 is the standard weight. Can be used to improve the significance of
+ * a field in the calculation of recommendations.
+ *
+ * @param coreName
+ * @param uri
+ * @param fieldWeights
+ * @return
+ * @throws IOException
+ * @throws LMFClientException
+ */
+ public SolrDocumentList recommendations(String coreName, String uri, Map<String,Double> fieldWeights) throws IOException, LMFClientException {
+ SolrQuery query = new SolrQuery();
+ query.setQuery("uri:\""+URLEncoder.encode(uri,"utf-8")+"\"");
+ query.setFields("*,score");
+ query.addSortField("score", SolrQuery.ORDER.desc);
+ query.setQueryType("/" + MoreLikeThisParams.MLT);
+ query.set(MoreLikeThisParams.MATCH_INCLUDE, false);
+ query.set(MoreLikeThisParams.MIN_DOC_FREQ, 1);
+ query.set(MoreLikeThisParams.MIN_TERM_FREQ, 1);
+ query.set(MoreLikeThisParams.SIMILARITY_FIELDS, KiWiCollections.fold(fieldWeights.keySet(),","));
+ query.set(MoreLikeThisParams.QF, KiWiCollections.fold(Collections2.transform(fieldWeights.entrySet(), new Function<Map.Entry<String, Double>, Object>() {
+ @Override
+ public Object apply(Map.Entry<String, Double> input) {
+ return input.getKey()+"^"+input.getValue();
+ }
+ })," "));
+ return search(coreName,query);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/ContentFormatException.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/ContentFormatException.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/ContentFormatException.java
new file mode 100644
index 0000000..8a1d140
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/ContentFormatException.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.exception;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class ContentFormatException extends LMFClientException {
+
+ /**
+ * Constructs a new exception with <code>null</code> as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ */
+ public ContentFormatException() {
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message. The
+ * cause is not initialized, and may subsequently be initialized by
+ * a call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public ContentFormatException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * <code>cause</code> is <i>not</i> automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public ContentFormatException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+ * typically contains the class and detail message of <tt>cause</tt>).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public ContentFormatException(Throwable cause) {
+ super(cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/LMFClientException.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/LMFClientException.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/LMFClientException.java
new file mode 100644
index 0000000..f9a97ff
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/LMFClientException.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.exception;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class LMFClientException extends Exception{
+
+ /**
+ * Constructs a new exception with <code>null</code> as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ */
+ public LMFClientException() {
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message. The
+ * cause is not initialized, and may subsequently be initialized by
+ * a call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public LMFClientException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * <code>cause</code> is <i>not</i> automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public LMFClientException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+ * typically contains the class and detail message of <tt>cause</tt>).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public LMFClientException(Throwable cause) {
+ super(cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/NotFoundException.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/NotFoundException.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/NotFoundException.java
new file mode 100644
index 0000000..c4cbca6
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/NotFoundException.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.exception;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class NotFoundException extends LMFClientException {
+ /**
+ * Constructs a new exception with <code>null</code> as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ */
+ public NotFoundException() {
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message. The
+ * cause is not initialized, and may subsequently be initialized by
+ * a call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public NotFoundException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * <code>cause</code> is <i>not</i> automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public NotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+ * typically contains the class and detail message of <tt>cause</tt>).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public NotFoundException(Throwable cause) {
+ super(cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/ParseException.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/ParseException.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/ParseException.java
new file mode 100644
index 0000000..5039afb
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/exception/ParseException.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.exception;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class ParseException extends LMFClientException {
+
+ /**
+ * Constructs a new exception with <code>null</code> as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ */
+ public ParseException() {
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message. The
+ * cause is not initialized, and may subsequently be initialized by
+ * a call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public ParseException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * <code>cause</code> is <i>not</i> automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public ParseException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+ * typically contains the class and detail message of <tt>cause</tt>).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public ParseException(Throwable cause) {
+ super(cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/classification/Classification.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/classification/Classification.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/classification/Classification.java
new file mode 100644
index 0000000..3bee617
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/classification/Classification.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.model.classification;
+
+import at.newmedialab.lmf.client.model.rdf.URI;
+
+
+/**
+ * A classification result of the classifier; for each category, provides a probability value indicating how much
+ * the text fits to a category.
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class Classification implements Comparable<Classification> {
+
+
+ private URI category;
+ private double probability;
+
+ public Classification(URI category, double probability) {
+ this.category = category;
+ this.probability = probability;
+ }
+
+ /**
+ * The category for which the classifier computed a probability
+ *
+ * @return
+ */
+ public URI getCategory() {
+ return category;
+ }
+
+ /**
+ * The probability the text fits to this category.
+ *
+ * @return
+ */
+ public double getProbability() {
+ return probability;
+ }
+
+ /**
+ * Compares this object with the specified object for order. Returns a
+ * negative integer, zero, or a positive integer as this object is less
+ * than, equal to, or greater than the specified object.
+ * <p/>
+ * Classifiers with higher probability take precedence (are smaller) than classifiers with lower probability.
+ *
+ * @param o the object to be compared.
+ * @return a negative integer, zero, or a positive integer as this object
+ * is less than, equal to, or greater than the specified object.
+ * @throws ClassCastException if the specified object's type prevents it
+ * from being compared to this object.
+ */
+ @Override
+ public int compareTo(Classification o) {
+ if(getProbability() > o.getProbability()) {
+ return -1;
+ } else if(getProbability() < o.getProbability()) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/config/Configuration.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/config/Configuration.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/config/Configuration.java
new file mode 100644
index 0000000..11593be
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/config/Configuration.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.model.config;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class Configuration {
+
+ private String key;
+
+ private Object value;
+
+
+ public Configuration(String key, Object value) {
+ this.key = key;
+ this.value = value;
+ }
+
+
+ public String getKey() {
+ return key;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public String getString() {
+ if(value instanceof Collection) {
+ if(((Collection) value).isEmpty()) {
+ return null;
+ } else {
+ return ((Collection) value).iterator().next().toString();
+ }
+ } else {
+ return value.toString();
+ }
+ }
+
+ public List<String> getList() {
+ List<String> result = new ArrayList<String>();
+ if(value instanceof Collection) {
+ for(Object o : (Collection) value) {
+ result.add(o.toString());
+ }
+ } else {
+ result.add(value.toString());
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/ByteContent.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/ByteContent.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/ByteContent.java
new file mode 100644
index 0000000..6814b58
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/ByteContent.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.model.content;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class ByteContent extends Content {
+
+ private byte[] bytes;
+
+ public ByteContent(byte[] bytes, String mimeType, long size) {
+ super(mimeType, size);
+ this.bytes = bytes;
+ }
+
+ /**
+ * Return the content of this object as stream. Note that the stream is only guaranteed to be consumable once.
+ *
+ * @return
+ */
+ @Override
+ public InputStream getStream() {
+ return new ByteArrayInputStream(bytes);
+ }
+
+ /**
+ * Return the content of this object as byte array. Note that when calling this method it is not safe to
+ * call the getStream method afterwards.
+ *
+ * @return
+ */
+ @Override
+ public byte[] getBytes() {
+ return bytes;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/Content.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/Content.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/Content.java
new file mode 100644
index 0000000..3c6029d
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/Content.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.model.content;
+
+import java.io.InputStream;
+
+/**
+ * Representation of media content returned by the Linked Media Framework. Provides an InputStream for
+ * reading the media data. Optionally, supports reading all content into a byte array.
+ *
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public abstract class Content {
+
+ private String mimeType;
+
+ private long size;
+
+
+ public Content(String mimeType, long size) {
+ this.mimeType = mimeType;
+ this.size = size;
+ }
+
+ /**
+ * Return the content of this object as stream. Note that the stream is only guaranteed to be consumable once.
+ * @return
+ */
+ public abstract InputStream getStream();
+
+
+ /**
+ * Return the content of this object as byte array. Note that when calling this method it is not safe to
+ * call the getStream method afterwards.
+ * @return
+ */
+ public abstract byte[] getBytes();
+
+
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ public long getSize() {
+ return size;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/StreamContent.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/StreamContent.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/StreamContent.java
new file mode 100644
index 0000000..a0a8747
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/StreamContent.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.model.content;
+
+import com.google.common.io.ByteStreams;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class StreamContent extends Content {
+
+ private InputStream data;
+
+ public StreamContent(InputStream data, String mimeType, long size) {
+ super(mimeType, size);
+ this.data = data;
+ }
+
+ /**
+ * Return the content of this object as stream. Note that the stream is only guaranteed to be consumable once.
+ *
+ * @return
+ */
+ @Override
+ public InputStream getStream() {
+ return data;
+ }
+
+ /**
+ * Return the content of this object as byte array. Note that when calling this method it is not safe to
+ * call the getStream method afterwards.
+ *
+ * @return
+ */
+ @Override
+ public byte[] getBytes() {
+ try {
+ return ByteStreams.toByteArray(data);
+ } catch (IOException e) {
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/StringContent.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/StringContent.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/StringContent.java
new file mode 100644
index 0000000..9b5bfe2
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/content/StringContent.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.model.content;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class StringContent extends Content {
+
+ private String data;
+
+ public StringContent(String data, String mimeType) {
+ super(mimeType, data.getBytes().length);
+ this.data = data;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ /**
+ * Return the content of this object as stream. Note that the stream is only guaranteed to be consumable once.
+ *
+ * @return
+ */
+ @Override
+ public InputStream getStream() {
+ return new ByteArrayInputStream(getBytes());
+ }
+
+ /**
+ * Return the content of this object as byte array. Note that when calling this method it is not safe to
+ * call the getStream method afterwards.
+ *
+ * @return
+ */
+ @Override
+ public byte[] getBytes() {
+ try {
+ return data.getBytes("utf-8");
+ } catch (UnsupportedEncodingException e) {
+ return data.getBytes();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/meta/Metadata.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/meta/Metadata.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/meta/Metadata.java
new file mode 100644
index 0000000..1f711a9
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/meta/Metadata.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.model.meta;
+
+import at.newmedialab.lmf.client.model.rdf.Literal;
+import at.newmedialab.lmf.client.model.rdf.RDFNode;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class Metadata extends HashMap<String,Set<RDFNode>> {
+
+ private String subject;
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the default initial capacity
+ * (16) and the default load factor (0.75).
+ */
+ public Metadata(String subject) {
+ this.subject = subject;
+ }
+
+ public String getSubject() {
+ return subject;
+ }
+
+ public RDFNode getFirst(String propertyUri) {
+ Preconditions.checkNotNull(get(propertyUri));
+ Preconditions.checkState(get(propertyUri).iterator().hasNext());
+
+ return get(propertyUri).iterator().next();
+ }
+
+
+ /**
+ * Convert a more simple property map into a metadata representation. Note that all keys of the property map still
+ * are required to be valid RDF URI resources. All properties will have string literal values in the resulting metadata.
+ *
+ * @param resource
+ * @param map
+ * @return
+ */
+ public static Metadata fromPropertiesMap(String resource, Map<String,String> map) {
+ Metadata m = new Metadata(resource);
+ for(Map.Entry<String,String> entry : map.entrySet()) {
+ m.put(entry.getKey(), ImmutableSet.<RDFNode>of(new Literal(entry.getValue())));
+ }
+ return m;
+ }
+
+ /**
+ * Convert a metadata representation into a simpler property map, potentially loosing information. Only the
+ * first literal value of a property is copied to the resulting map.
+ *
+ * @param metadata
+ * @return
+ */
+ public static Map<String,String> toPropertiesMap(Metadata metadata) {
+ Map<String,String> result = new HashMap<String, String>();
+ for(Map.Entry<String,Set<RDFNode>> entry : metadata.entrySet()) {
+ for(RDFNode n : entry.getValue()) {
+ if(n instanceof Literal) {
+ result.put(entry.getKey(),((Literal) n).getContent());
+ break;
+ }
+ }
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/BNode.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/BNode.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/BNode.java
new file mode 100644
index 0000000..58f8e66
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/BNode.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.model.rdf;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class BNode extends RDFNode {
+
+ private String anonId;
+
+ public BNode(String anonId) {
+ this.anonId = anonId;
+ }
+
+ public String getAnonId() {
+ return anonId;
+ }
+
+ public void setAnonId(String anonId) {
+ this.anonId = anonId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ BNode bNode = (BNode) o;
+
+ if (anonId != null ? !anonId.equals(bNode.anonId) : bNode.anonId != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return anonId != null ? anonId.hashCode() : 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/Literal.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/Literal.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/Literal.java
new file mode 100644
index 0000000..4374233
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/Literal.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.model.rdf;
+
+/**
+ * A lightweight RDF Literal implementation providing the base functionalities.
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class Literal extends RDFNode {
+
+ private String content;
+
+ private String language;
+
+ private URI type;
+
+
+ public Literal(String content) {
+ this.content = content;
+ }
+
+ public Literal(String content, String language) {
+ this.content = content;
+ this.language = language;
+ }
+
+ public Literal(String content, URI type) {
+ this.content = content;
+ this.type = type;
+ }
+
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public URI getType() {
+ return type;
+ }
+
+ public void setType(URI type) {
+ this.type = type;
+ }
+
+
+ public int getInt() {
+ return Integer.parseInt(content);
+ }
+
+ public long getLong() {
+ return Long.parseLong(content);
+ }
+
+ public double getDouble() {
+ return Double.parseDouble(content);
+ }
+
+ public float getFloat() {
+ return Float.parseFloat(content);
+ }
+
+ public boolean getBoolean() {
+ return Boolean.getBoolean(content);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Literal literal = (Literal) o;
+
+ if (!content.equals(literal.content)) return false;
+ if (language != null ? !language.equals(literal.language) : literal.language != null) return false;
+ if (type != null ? !type.equals(literal.type) : literal.type != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = content.hashCode();
+ result = 31 * result + (language != null ? language.hashCode() : 0);
+ result = 31 * result + (type != null ? type.hashCode() : 0);
+ return result;
+ }
+
+
+ @Override
+ public String toString() {
+ return content;
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/RDFNode.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/RDFNode.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/RDFNode.java
new file mode 100644
index 0000000..ec4da16
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/RDFNode.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.model.rdf;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class RDFNode {
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/75439f3a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/URI.java
----------------------------------------------------------------------
diff --git a/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/URI.java b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/URI.java
new file mode 100644
index 0000000..07c4f94
--- /dev/null
+++ b/client/marmotta-client-java/src/main/java/at/newmedialab/lmf/client/model/rdf/URI.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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 at.newmedialab.lmf.client.model.rdf;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class URI extends RDFNode {
+
+ private String uri;
+
+ public URI(String uri) {
+ this.uri = uri;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ URI uri1 = (URI) o;
+
+ if (!uri.equals(uri1.uri)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return uri.hashCode();
+ }
+
+ /**
+ * Returns a string representation of the object. In general, the
+ * <code>toString</code> method returns a string that
+ * "textually represents" this object. The result should
+ * be a concise but informative representation that is easy for a
+ * person to read.
+ * It is recommended that all subclasses override this method.
+ * <p/>
+ * The <code>toString</code> method for class <code>Object</code>
+ * returns a string consisting of the name of the class of which the
+ * object is an instance, the at-sign character `<code>@</code>', and
+ * the unsigned hexadecimal representation of the hash code of the
+ * object. In other words, this method returns a string equal to the
+ * value of:
+ * <blockquote>
+ * <pre>
+ * getClass().getName() + '@' + Integer.toHexString(hashCode())
+ * </pre></blockquote>
+ *
+ * @return a string representation of the object.
+ */
+ @Override
+ public String toString() {
+ return uri;
+ }
+}