You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by wi...@apache.org on 2013/02/19 13:52:01 UTC
[10/52] [partial] code contribution,
initial import of relevant modules of LMF-3.0.0-SNAPSHOT based on
revision 4bf944319368 of the default branch at https://code.google.com/p/lmf/
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/modules/ModuleServiceImpl.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/modules/ModuleServiceImpl.java b/lmf-core/src/main/java/kiwi/core/services/modules/ModuleServiceImpl.java
new file mode 100644
index 0000000..dbca89c
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/modules/ModuleServiceImpl.java
@@ -0,0 +1,291 @@
+/**
+ * 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 kiwi.core.services.modules;
+
+import com.google.common.collect.ImmutableList;
+import kiwi.core.api.modules.ModuleService;
+import kiwi.core.model.module.ModuleConfiguration;
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.MapConfiguration;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Collection;
+import java.util.Enumeration;
+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/>
+ * User: sschaffe
+ */
+@ApplicationScoped
+public class ModuleServiceImpl implements ModuleService {
+
+ private Logger log = LoggerFactory.getLogger(ModuleServiceImpl.class);
+
+ private Set<String> modules;
+
+ private Map<String,Configuration> configurationMap;
+ private Map<String, Configuration> jarURLs;
+
+ @PostConstruct
+ public void initialize() {
+ modules = new HashSet<String>();
+ configurationMap = new HashMap<String, Configuration>();
+ jarURLs = new HashMap<String, Configuration>();
+
+ try {
+ Enumeration<URL> modulePropertiesEnum = this.getClass().getClassLoader().getResources("kiwi-module.properties");
+
+ while(modulePropertiesEnum.hasMoreElements()) {
+ URL moduleUrl = modulePropertiesEnum.nextElement();
+
+ Configuration moduleProperties = null;
+ try {
+ Set<Configuration> configurations = new HashSet<Configuration>();
+
+ // get basic module configuration
+ moduleProperties = new PropertiesConfiguration(moduleUrl);
+ configurations.add(moduleProperties);
+
+ String moduleName = moduleProperties.getString("name");
+ modules.add(moduleName);
+
+
+ URLConnection urlConnection = moduleUrl.openConnection();
+ URL jarUrl;
+ if(urlConnection instanceof JarURLConnection) {
+ JarURLConnection conn = (JarURLConnection)urlConnection;
+ jarUrl = conn.getJarFileURL();
+ } else {
+ String fileUrl = moduleUrl.toString();
+ jarUrl = new URL(fileUrl.substring(0,fileUrl.lastIndexOf("/")));
+ }
+
+
+
+ // get the build information
+ try {
+ PropertiesConfiguration buildInfo = new PropertiesConfiguration(new URL("jar:"+jarUrl.toString()+"!/buildinfo.properties"));
+ buildInfo.setDelimiterParsingDisabled(true);
+ configurations.add(buildInfo);
+ } catch(ConfigurationException ex) {
+ }
+
+ // alternative: maven buildinfo plugin
+ try {
+ PropertiesConfiguration buildInfo = new PropertiesConfiguration(new URL("jar:"+jarUrl.toString()+"!/build.info"));
+ buildInfo.setDelimiterParsingDisabled(true);
+ configurations.add(buildInfo);
+ } catch(ConfigurationException ex) {
+ }
+
+
+
+ // create runtime configuration
+ MapConfiguration runtimeConfiguration = new MapConfiguration(new HashMap<String, Object>());
+ runtimeConfiguration.setProperty("runtime.jarfile", jarUrl.toString());
+ configurations.add(runtimeConfiguration);
+
+
+ CompositeConfiguration moduleConfiguration = new CompositeConfiguration(configurations);
+ configurationMap.put(moduleName, moduleConfiguration);
+ jarURLs.put(jarUrl.toString(), moduleConfiguration);
+
+ } catch (ConfigurationException e) {
+ log.error("error parsing kiwi-module.properties file at {}",moduleUrl,e);
+ }
+
+
+ }
+ } catch (IOException ex) {
+ log.error("I/O error while trying to retrieve kiwi-module.properties file",ex);
+ }
+ }
+
+ /**
+ * Provide the current module configuration to the service injecting it
+ *
+ */
+ @Override
+ @Produces
+ public ModuleConfiguration getModuleConfiguration(InjectionPoint injectionPoint) {
+ URL jarUrl = injectionPoint.getMember().getDeclaringClass().getProtectionDomain().getCodeSource().getLocation();
+ Configuration cfg = jarURLs.get(jarUrl.toString());
+ if(cfg != null) {
+ return new ModuleConfiguration(cfg);
+ } else {
+ return new ModuleConfiguration(new MapConfiguration(new HashMap<String, Object>()));
+ }
+ }
+
+ /**
+ * Provide the current module configuration for the given class, i.e. the configuration of the
+ * module containing the class.
+ */
+ @Override
+ public ModuleConfiguration getModuleConfiguration(Class<?> cls) {
+ URL jarUrl = cls.getProtectionDomain().getCodeSource().getLocation();
+ Configuration cfg = jarURLs.get(jarUrl.toString());
+ if(cfg != null) {
+ return new ModuleConfiguration(cfg);
+ } else {
+ return new ModuleConfiguration(new MapConfiguration(new HashMap<String, Object>()));
+ }
+ }
+
+ /**
+ * Return a list of entities used by this module. Each entry is a fully-qualified classname of
+ * an entity class that this module registers.
+ *
+ * @param moduleName
+ * @return
+ */
+ @Override
+ public Collection<String> getEntities(String moduleName) {
+ Configuration config = getModuleConfiguration(moduleName).getConfiguration();
+ if(config != null) return ImmutableList.copyOf(config.getStringArray("entities"));
+ else
+ return null;
+ }
+
+ /**
+ * List the names of all currently active modules
+ *
+ * @return
+ */
+ @Override
+ public Collection<String> listModules() {
+ return modules;
+ }
+
+ /**
+ * Return the configuration for the module identified by the name given as argument. Returns an
+ * immutable Apache Commons Configuration object, or null if the module is not found.
+ *
+ * @param moduleName
+ * @return
+ */
+ @Override
+ public ModuleConfiguration getModuleConfiguration(String moduleName) {
+
+ Configuration cfg = configurationMap.get(moduleName);
+ if(cfg != null) {
+ return new ModuleConfiguration(cfg);
+ } else {
+ return new ModuleConfiguration(new MapConfiguration(new HashMap<String, Object>()));
+ }
+ }
+
+ /**
+ * Get the URL of the JAR file of the module whose name is given as argument.
+ *
+ * @param moduleName
+ * @return
+ */
+ @Override
+ public URL getModuleJar(String moduleName) {
+ try {
+ return new URL(configurationMap.get(moduleName).getString("runtime.jarfile"));
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Get the path relative to the LMF base URL where the web contents of this URL can be found
+ *
+ * @param moduleName
+ * @return
+ */
+ @Override
+ public String getModuleWeb(String moduleName) {
+ Configuration config = getModuleConfiguration(moduleName).getConfiguration();
+ if(config != null) return config.getString("baseurl", "/" + moduleName);
+ else
+ return null;
+ }
+
+ /**
+ * Return a list of webservices used by this module. Each entry is a fully-qualified classname
+ * of a webservice class that this module registers.
+ *
+ * @param moduleName
+ * @return
+ */
+ @Override
+ public Collection<String> getWebservices(String moduleName) {
+ Configuration config = getModuleConfiguration(moduleName).getConfiguration();
+ if(config != null) return ImmutableList.copyOf(config.getStringArray("webservices"));
+ else
+ return null;
+ }
+
+ /**
+ * Return a list of filters used by this module. Each entry is a fully-qualified classname
+ * of a filter class implementing LMFHttpFilter that this module registers.
+ *
+ * @param moduleName
+ * @return
+ */
+ @Override
+ public Collection<String> getFilters(String moduleName) {
+ Configuration config = getModuleConfiguration(moduleName).getConfiguration();
+ if(config != null) return ImmutableList.copyOf(config.getStringArray("filters"));
+ else
+ return null;
+ }
+
+ /**
+ * Return a list of admin pages (paths)
+ * @param moduleName
+ * @return
+ */
+ @Override
+ public List<String> getAdminPages(String moduleName) {
+ Configuration config = getModuleConfiguration(moduleName).getConfiguration();
+ if(config != null) return ImmutableList.copyOf(config.getStringArray("adminpages"));
+ else
+ return null;
+ }
+
+ @Override
+ public int getWeight(String moduleName) {
+ Configuration config = getModuleConfiguration(moduleName).getConfiguration();
+ if (config != null)
+ return config.getInt("weight", 50);
+ else
+ return 50;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/prefix/PrefixCC.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/prefix/PrefixCC.java b/lmf-core/src/main/java/kiwi/core/services/prefix/PrefixCC.java
new file mode 100644
index 0000000..5265e31
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/prefix/PrefixCC.java
@@ -0,0 +1,107 @@
+/**
+ * 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 kiwi.core.services.prefix;
+
+import kiwi.core.api.http.HttpClientService;
+import kiwi.core.api.prefix.PrefixProvider;
+import kiwi.core.util.http.HttpRequestUtil;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import java.io.IOException;
+
+/**
+ * Prefix.cc Provider
+ *
+ * @author Sergio Fernández
+ *
+ */
+@ApplicationScoped
+public class PrefixCC implements PrefixProvider {
+
+ private static final String URI = "http://prefix.cc/";
+ private static final String USER_AGENT = "LMF Prefix";
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private HttpClientService httpClientService;
+
+ @Override
+ public String getNamespace(final String prefix) {
+ HttpGet get = new HttpGet(URI + prefix + ".file.json");
+ HttpRequestUtil.setUserAgentString(get, USER_AGENT);
+ get.setHeader("Accept", "application/json");
+ try {
+ return httpClientService.execute(get, new ResponseHandler<String>() {
+
+ @Override
+ public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
+ try {
+ if (200 == response.getStatusLine().getStatusCode()) {
+ HttpEntity entity = response.getEntity();
+ JSONObject json = new JSONObject(EntityUtils.toString(entity));
+ return json.getString(prefix);
+ } else {
+ log.error("Error: prefix '" + prefix + "' not found at prefix.cc");
+ return null;
+ }
+ } catch (JSONException e) {
+ throw new IOException(e);
+ }
+ }
+ });
+ } catch (Exception e) {
+ log.error("Error retrieving prefix '" + prefix + "' from prefix.cc: " + e.getMessage());
+ return null;
+ }
+ }
+
+ @Override
+ public String getPrefix(String namespace) {
+ HttpHead head = new HttpHead(URI + "reverse?uri=" + namespace);
+ HttpRequestUtil.setFollowRedirect(head, false);
+ HttpRequestUtil.setUserAgentString(head, USER_AGENT);
+ try {
+ return httpClientService.execute(head, new ResponseHandler<String>() {
+ @Override
+ public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
+ if (response.containsHeader("location")) {
+ Header location = response.getFirstHeader("location");
+ return location.getValue().substring(URI.length());
+ } else
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ log.error("Error trying to retrieve prefic.cc reverse lookup for namespace '" + namespace + "': " + e.getMessage());
+ return null;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/prefix/PrefixServiceCC.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/prefix/PrefixServiceCC.java b/lmf-core/src/main/java/kiwi/core/services/prefix/PrefixServiceCC.java
new file mode 100644
index 0000000..175f692
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/prefix/PrefixServiceCC.java
@@ -0,0 +1,110 @@
+/**
+ * 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 kiwi.core.services.prefix;
+
+import java.net.URISyntaxException;
+
+import kiwi.core.api.prefix.PrefixProvider;
+import org.apache.commons.lang.StringUtils;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Alternative;
+import javax.inject.Inject;
+
+/**
+ * Prefix manager supporting prefix.cc as eager external provider
+ *
+ * @author Sergio Fernández
+ *
+ */
+@Alternative
+@ApplicationScoped
+public class PrefixServiceCC extends PrefixServiceImpl {
+
+ @Inject
+ private PrefixProvider prefixcc;
+
+ public PrefixServiceCC() {
+ super();
+ }
+
+ @Override
+ public String getNamespace(String prefix) {
+ String namespace = super.getNamespace(prefix);
+ if (StringUtils.isNotBlank(namespace))
+ return namespace;
+ else
+ try {
+ return namespaceLookup(prefix);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ @Override
+ public String getPrefix(String namespace) {
+ String prefix = super.getPrefix(namespace);
+ if (StringUtils.isNotBlank(prefix))
+ return prefix;
+ else
+ try {
+ return prefixLookup(namespace);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ @Override
+ public boolean containsPrefix(String prefix) {
+ if (!super.containsPrefix(prefix)) {
+ try {
+ namespaceLookup(prefix);
+ } catch (Exception e) {
+ return false;
+ }
+ }
+ return super.containsPrefix(prefix);
+ }
+
+ @Override
+ public boolean containsNamespace(String namespace) {
+ if (!super.containsNamespace(namespace)) {
+ try {
+ prefixLookup(namespace);
+ } catch (Exception e) {
+ return false;
+ }
+ }
+ return super.containsNamespace(namespace);
+ }
+
+ private String prefixLookup(String namespace) throws IllegalArgumentException, URISyntaxException {
+ String prefix = prefixcc.getPrefix(namespace);
+ if (StringUtils.isNotBlank(prefix)) {
+ add(prefix, namespace);
+ }
+ return prefix;
+ }
+
+ private String namespaceLookup(String prefix) throws IllegalArgumentException, URISyntaxException {
+ String namespace = prefixcc.getNamespace(prefix);
+ if (StringUtils.isNotBlank(namespace)) {
+ add(prefix, namespace);
+ }
+ return namespace;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/prefix/PrefixServiceImpl.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/prefix/PrefixServiceImpl.java b/lmf-core/src/main/java/kiwi/core/services/prefix/PrefixServiceImpl.java
new file mode 100644
index 0000000..3c492e3
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/prefix/PrefixServiceImpl.java
@@ -0,0 +1,186 @@
+/**
+ * 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 kiwi.core.services.prefix;
+
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.Map;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.inject.Inject;
+
+import kiwi.core.api.config.ConfigurationService;
+import kiwi.core.api.prefix.PrefixService;
+import kiwi.core.events.ConfigurationChangedEvent;
+import kiwi.core.events.ConfigurationServiceInitEvent;
+
+import kiwi.core.events.SesameStartupEvent;
+import org.apache.commons.lang.StringUtils;
+import org.apache.marmotta.commons.http.UriUtil;
+import org.slf4j.Logger;
+
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+
+/**
+ * Prefix Manager default implementation
+ *
+ * @author Sergio Fernández
+ *
+ */
+@ApplicationScoped
+public class PrefixServiceImpl implements PrefixService {
+
+ private static final String CONFIGURATION_PREFIX = "prefix";
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private ConfigurationService configurationService;
+
+ private BiMap<String, String> cache;
+
+ public PrefixServiceImpl() {
+ super();
+ cache = HashBiMap.create();
+ }
+
+ protected void initialize(@Observes SesameStartupEvent event) {
+ for (String key : configurationService.listConfigurationKeys(CONFIGURATION_PREFIX)) {
+ String prefix = key.substring(CONFIGURATION_PREFIX.length() + 1);
+ String namespace = configurationService.getStringConfiguration(key);
+ cache.put(prefix, namespace);
+ }
+ addLocalMappings();
+ }
+
+ protected void onConfigurationChange(@Observes ConfigurationChangedEvent event) {
+ for (String changedKey : event.getKeys()) {
+ if (changedKey.startsWith(CONFIGURATION_PREFIX + ".")) {
+ String prefix = changedKey.substring(CONFIGURATION_PREFIX.length() + 1);
+ String namespace = configurationService.getStringConfiguration(changedKey);
+ cache.put(prefix, namespace);
+ }
+ }
+ }
+
+ protected void addLocalMappings() {
+ String base = configurationService.getBaseUri();
+ cache.put("local", base + ConfigurationService.RESOURCE_PATH + "/");
+ cache.put("context", base + ConfigurationService.CONTEXT_PATH + "/");
+ }
+
+ @Override
+ public String getNamespace(String prefix) {
+ return cache.get(prefix);
+ }
+
+ @Override
+ public String getPrefix(String namespace) {
+ return cache.inverse().get(namespace);
+ }
+
+ @Override
+ public synchronized void add(String prefix, String namespace) throws IllegalArgumentException, URISyntaxException {
+ if (cache.containsKey(prefix)) {
+ log.error("prefix " + prefix + " already managed");
+ throw new IllegalArgumentException("prefix " + prefix + " already managed, use forceAdd() if you'd like to force its rewrite");
+ } else {
+ String validatedNamespace = validateNamespace(namespace);
+ if (validatedNamespace != null) {
+ try {
+ cache.put(prefix, validatedNamespace);
+ configurationService.setConfiguration(CONFIGURATION_PREFIX + "." + prefix, validatedNamespace);
+ } catch (IllegalArgumentException e) {
+ log.error("namespace " + validatedNamespace + " is already bound to '" + getPrefix(validatedNamespace) + "' prefix, use forceAdd() if you'd like to force its rewrite");
+ throw new IllegalArgumentException("namespace " + validatedNamespace + " is already bound to '" + getPrefix(validatedNamespace) + "' prefix");
+ }
+ } else {
+ log.error("Namespace <" + namespace + "> is not valid");
+ throw new URISyntaxException(namespace, "Namespace <" + namespace + "> is not valid");
+ }
+ }
+ }
+
+ @Override
+ public void forceAdd(String prefix, String namespace) {
+ cache.forcePut(prefix, namespace);
+ configurationService.setConfiguration(CONFIGURATION_PREFIX + prefix, namespace);
+ }
+
+ @Override
+ public Map<String, String> getMappings() {
+ return Collections.unmodifiableMap(cache);
+ }
+
+ @Override
+ public boolean containsPrefix(String prefix) {
+ return cache.containsKey(prefix);
+ }
+
+ @Override
+ public boolean containsNamespace(String namespace) {
+ return cache.containsValue(namespace);
+ }
+
+ private String validateNamespace(String namespace) {
+ String last = namespace.substring(namespace.length() - 1);
+ if (last.compareTo("/") != 0) {
+ if (last.compareTo("#") != 0) {
+ namespace += "#";
+ }
+ }
+ if (UriUtil.validate(namespace)) {
+ return namespace;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public String getCurie(String uri) {
+ if (UriUtil.validate(uri)) {
+ String ns = UriUtil.getNamespace(uri);
+ String ref = UriUtil.getReference(uri);
+ if (StringUtils.isNotBlank(ns) && StringUtils.isNotBlank(ref) && containsNamespace(ns))
+ return getPrefix(ns) + ":" + ref;
+ else
+ return null;
+ } else
+ return null;
+ }
+
+ @Override
+ public String serializePrefixMapping() {
+ StringBuffer sb = new StringBuffer();
+ for (Map.Entry<String, String> mapping : cache.entrySet()) {
+ sb.append("\n").append(mapping.getKey()).append(": ").append(mapping.getValue()).append(" ");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public String serializePrefixesSparqlDeclaration() {
+ StringBuffer sb = new StringBuffer();
+ for (Map.Entry<String, String> mapping : cache.entrySet()) {
+ sb.append("PREFIX ").append(mapping.getKey()).append(": <").append(mapping.getValue()).append("> \n");
+ }
+ return sb.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/sesame/KiWiSesameUtil.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/sesame/KiWiSesameUtil.java b/lmf-core/src/main/java/kiwi/core/services/sesame/KiWiSesameUtil.java
new file mode 100644
index 0000000..1390be6
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/sesame/KiWiSesameUtil.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 kiwi.core.services.sesame;
+
+import org.apache.marmotta.kiwi.model.rdf.KiWiTriple;
+import org.openrdf.model.Resource;
+import org.openrdf.model.Statement;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.RepositoryResult;
+
+import java.util.Date;
+
+/**
+ * Some utils to work with KiWi model and Sesame
+ *
+ * @author Sebastian Schaffert
+ */
+public class KiWiSesameUtil {
+
+
+ /**
+ * Get the last modification of the set of triples passed as argument.
+ *
+ * @deprecated this class will be removed before the 2.6 release, the helper function should be moved elsewhere
+ * @return date
+ * @throws RepositoryException
+ */
+ public static Date lastModified(Resource resource, RepositoryConnection conn) throws RepositoryException {
+ Date last_modified = new Date(0);
+ RepositoryResult<Statement> triples = conn.getStatements(resource, null, null, false);
+ try {
+ while (triples.hasNext()) {
+ Statement triple = triples.next();
+ if (triple instanceof KiWiTriple) {
+ KiWiTriple t = (KiWiTriple) triple;
+ if (t.getCreated().getTime() > last_modified.getTime()) {
+ last_modified = t.getCreated();
+ }
+ }
+ }
+ } finally {
+ triples.close();
+ }
+ return last_modified;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/sesame/ResourceSubjectMetadata.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/sesame/ResourceSubjectMetadata.java b/lmf-core/src/main/java/kiwi/core/services/sesame/ResourceSubjectMetadata.java
new file mode 100644
index 0000000..1661bad
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/sesame/ResourceSubjectMetadata.java
@@ -0,0 +1,78 @@
+/**
+ * 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 kiwi.core.services.sesame;
+
+import org.apache.marmotta.kiwi.model.rdf.KiWiAnonResource;
+import org.apache.marmotta.kiwi.model.rdf.KiWiUriResource;
+import org.openrdf.model.BNode;
+import org.openrdf.model.Resource;
+import org.openrdf.model.Value;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.event.base.RepositoryConnectionInterceptorAdapter;
+
+/**
+ * A filter/view on repositories that displays only the metadata for a resource
+ *
+ * @author Sebastian Schaffert
+ *
+ */
+public class ResourceSubjectMetadata extends RepositoryConnectionInterceptorAdapter {
+
+ private Resource subject;
+
+ public ResourceSubjectMetadata(Resource subject) {
+ this.subject = subject;
+ }
+
+ @Override
+ public boolean add(RepositoryConnection conn, Resource s, org.openrdf.model.URI p, Value o, Resource... contexts) {
+ boolean denyAdd = true;
+ if (s instanceof org.openrdf.model.URI && subject instanceof org.openrdf.model.URI ) {
+ // if s is a URI and subject a KiWiUriResource, return
+ // true if they are different
+ denyAdd = !s.stringValue().equals(((KiWiUriResource) subject).toString());
+ } else if (s instanceof BNode && subject instanceof BNode) {
+ // if s is a BNode and subject a KiWiAnonResource,
+ // return true if they are different
+ denyAdd = !s.stringValue().equals(((KiWiAnonResource) subject).getID());
+ } else {
+ // in all other cases, return true to filter out the
+ // triple
+ denyAdd = true;
+ }
+ return denyAdd;
+ };
+
+ @Override
+ public boolean remove(RepositoryConnection conn, Resource s, org.openrdf.model.URI p, Value o, Resource... contexts) {
+ boolean denyRemove = true;
+ if (s instanceof org.openrdf.model.URI && subject instanceof org.openrdf.model.URI ) {
+ // if s is a URI and subject a KiWiUriResource, return
+ // true if they are different
+ denyRemove = !s.stringValue().equals(subject.stringValue());
+ } else if (s instanceof BNode && subject instanceof BNode) {
+ // if s is a BNode and subject a KiWiAnonResource,
+ // return true if they are different
+ denyRemove = !s.stringValue().equals(subject.stringValue());
+ } else {
+ // in all other cases, return true to filter out the
+ // triple
+ denyRemove = true;
+ }
+ return denyRemove;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/statistics/StatisticsServiceImpl.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/statistics/StatisticsServiceImpl.java b/lmf-core/src/main/java/kiwi/core/services/statistics/StatisticsServiceImpl.java
new file mode 100644
index 0000000..2140847
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/statistics/StatisticsServiceImpl.java
@@ -0,0 +1,186 @@
+/**
+ * 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 kiwi.core.services.statistics;
+
+import kiwi.core.api.config.ConfigurationService;
+import kiwi.core.api.statistics.StatisticsModule;
+import kiwi.core.api.statistics.StatisticsService;
+import kiwi.core.events.ConfigurationChangedEvent;
+import org.slf4j.Logger;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * StatisticsServiceImpl
+ *
+ * @author Sebastian Schaffert
+ *
+ */
+@ApplicationScoped
+@Named("kiwi.core.statisticsService")
+public class StatisticsServiceImpl implements StatisticsService {
+
+ private LinkedHashMap<String,StatisticsModule> modules;
+
+ private boolean enabled = false;
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private ConfigurationService configurationService;
+
+ /**
+ * Initialise all statistics modules that are found in the system
+ * @param modules
+ */
+ @Inject
+ protected void initModules(@Any Instance<StatisticsModule> modules) {
+ log.info("LMF StatisticsService starting up ...");
+
+ this.modules = new LinkedHashMap<String,StatisticsModule>();
+
+ for(StatisticsModule module : modules) {
+ registerModule(module.getName(),module);
+ }
+
+ if(configurationService.getBooleanConfiguration("statistics.enabled",false)) {
+ enableAll();
+ } else {
+ disableAll();
+ }
+ }
+
+ public void configurationChangedEvent(@Observes ConfigurationChangedEvent event) {
+ if (event.containsChangedKey("statistics.enabled")) {
+ if(configurationService.getBooleanConfiguration("statistics.enabled",false)) {
+ enableAll();
+ } else {
+ disableAll();
+ }
+ }
+ }
+
+
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsService#enableAll()
+ */
+ @Override
+ public void enableAll() {
+ for(StatisticsModule mod : modules.values()) {
+ mod.enable();
+ }
+
+ enabled = true;
+ }
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsService#disableAll()
+ */
+ @Override
+ public void disableAll() {
+ for(StatisticsModule mod : modules.values()) {
+ mod.disable();
+ }
+
+ enabled = false;
+ }
+
+
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsService#isEnabled()
+ */
+ @Override
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsService#enableModule(java.lang.String)
+ */
+ @Override
+ public void enableModule(String modName) {
+ if(modules.get(modName) != null) {
+ modules.get(modName).enable();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsService#disableModule(java.lang.String)
+ */
+ @Override
+ public void disableModule(String modName) {
+ if(modules.get(modName) != null) {
+ modules.get(modName).disable();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsService#registerModule(java.lang.String, kiwi.api.statistics.StatisticsModule)
+ */
+ @Override
+ public void registerModule(String modName, StatisticsModule mod) {
+ log.info("registering statistics module \"{}\"", modName);
+ modules.put(modName,mod);
+ }
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsService#unregisterModule(kiwi.api.statistics.StatisticsModule)
+ */
+ @Override
+ public void unregisterModule(StatisticsModule mod) {
+ unregisterModule(mod.getName());
+ }
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsService#unregisterModule(java.lang.String)
+ */
+ @Override
+ public void unregisterModule(String modName) {
+ log.info("unregistering statistics module \"{}\"", modName);
+ modules.remove(modName);
+ }
+
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsService#getModule(java.lang.String)
+ */
+ @Override
+ public StatisticsModule getModule(String modName) {
+ return modules.get(modName);
+ }
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsService#listModules()
+ */
+ @Override
+ public List<String> listModules() {
+ return new LinkedList<String>(modules.keySet());
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/statistics/ehcache/EHCacheStatisticsModule.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/statistics/ehcache/EHCacheStatisticsModule.java b/lmf-core/src/main/java/kiwi/core/services/statistics/ehcache/EHCacheStatisticsModule.java
new file mode 100644
index 0000000..372f1c3
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/statistics/ehcache/EHCacheStatisticsModule.java
@@ -0,0 +1,138 @@
+/**
+ * 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 kiwi.core.services.statistics.ehcache;
+
+import kiwi.core.api.cache.CachingService;
+import kiwi.core.api.statistics.StatisticsModule;
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Statistics;
+import org.slf4j.Logger;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Offer statistical information about the EHCache caches used in the KiWi System
+ * <p/>
+ * User: sschaffe
+ */
+public class EHCacheStatisticsModule implements StatisticsModule {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private CachingService cachingService;
+
+ @PostConstruct
+ public void initialize() {
+
+
+ }
+
+ /**
+ * Enable this module. Depending on the type of information, this may involve additional runtime overhead.
+ */
+ @Override
+ public void enable() {
+ for(String cacheName : cachingService.getCacheNames()) {
+ Ehcache cache = cachingService.getCacheByName(cacheName);
+ if(cache != null) {
+ cache.setStatisticsEnabled(true);
+ cache.setStatisticsAccuracy(Statistics.STATISTICS_ACCURACY_GUARANTEED);
+ }
+ }
+ }
+
+ /**
+ * Disable this module.
+ */
+ @Override
+ public void disable() {
+ for(String cacheName : cachingService.getCacheNames()) {
+ Ehcache cache = cachingService.getCacheByName(cacheName);
+ if(cache != null) {
+ cache.setStatisticsEnabled(false);
+ cache.setStatisticsAccuracy(Statistics.STATISTICS_ACCURACY_NONE);
+ }
+ }
+ }
+
+ /**
+ * Return true if the module is enabled.
+ *
+ * @return
+ */
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ /**
+ * Return all names of properties supported by this module.
+ *
+ * @return
+ */
+ @Override
+ public List<String> getPropertyNames() {
+
+ List<String> propertyNames = new LinkedList<String>();
+ for(String cacheName : cachingService.getCacheNames()) {
+ propertyNames.add(cacheName + " hits");
+ propertyNames.add(cacheName + " misses");
+ propertyNames.add(cacheName + " size");
+ }
+ return propertyNames;
+ }
+
+ /**
+ * Return the statistics as a map from key to value
+ *
+ * @return
+ */
+ @Override
+ public Map<String, String> getStatistics() {
+
+ LinkedHashMap<String,String> result = new LinkedHashMap<String, String>();
+ for(String cacheName : cachingService.getCacheNames()) {
+ Ehcache cache = cachingService.getCacheByName(cacheName);
+ if(cache != null) {
+ Statistics stat = cache.getStatistics();
+
+ result.put(cacheName + " hits",""+stat.getCacheHits());
+ result.put(cacheName + " misses",""+stat.getCacheMisses());
+ result.put(cacheName + " size",""+stat.getObjectCount());
+ } else {
+ log.warn("cache with name {} does not exist",cacheName);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Return the display name of the statistics module.
+ *
+ * @return
+ */
+ @Override
+ public String getName() {
+ return "Cache Statistics";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/statistics/system/SystemStatisticsModule.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/statistics/system/SystemStatisticsModule.java b/lmf-core/src/main/java/kiwi/core/services/statistics/system/SystemStatisticsModule.java
new file mode 100644
index 0000000..88ebfaf
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/statistics/system/SystemStatisticsModule.java
@@ -0,0 +1,112 @@
+/**
+ * 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 kiwi.core.services.statistics.system;
+
+import kiwi.core.api.statistics.StatisticsModule;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * SystemStatisticsModule
+ *
+ * @author Sebastian Schaffert
+ *
+ */
+public class SystemStatisticsModule implements StatisticsModule {
+
+
+ /**
+ * Return the display name of the statistics module.
+ *
+ * @return
+ */
+ @Override
+ public String getName() {
+ return "System Statistics";
+ }
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsModule#enable()
+ */
+ @Override
+ public void enable() {
+ // do nothing, system statistics always enabled
+ }
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsModule#disable()
+ */
+ @Override
+ public void disable() {
+ // do nothing, system statistics always enabled
+ }
+
+
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsModule#isEnabled()
+ */
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsModule#getPropertyNames()
+ */
+ @Override
+ public List<String> getPropertyNames() {
+ List<String> result = new LinkedList<String>();
+
+ result.add("java version");
+ result.add("java vendor");
+ result.add("operating system");
+
+ result.add("free memory");
+ result.add("total memory");
+ result.add("max memory");
+
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see kiwi.api.statistics.StatisticsModule#getStatistics()
+ */
+ @Override
+ public Map<String, String> getStatistics() {
+
+
+
+ LinkedHashMap<String,String> result = new LinkedHashMap<String, String>();
+
+ result.put("java version", System.getProperty("java.version"));
+ result.put("java vendor", System.getProperty("java.vendor"));
+ result.put("operating system", System.getProperty("os.name")+" ("+System.getProperty("os.version")+")");
+
+ Runtime rt = Runtime.getRuntime();
+ result.put("free memory",""+rt.freeMemory()/(1024*1024)+"MB");
+ result.put("total memory",""+rt.totalMemory()/(1024*1024)+"MB");
+ result.put("max memory",""+rt.maxMemory()/(1024*1024)+"MB");
+
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/task/TaskImpl.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/task/TaskImpl.java b/lmf-core/src/main/java/kiwi/core/services/task/TaskImpl.java
new file mode 100644
index 0000000..bfc9746
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/task/TaskImpl.java
@@ -0,0 +1,50 @@
+/**
+ * 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 kiwi.core.services.task;
+
+import kiwi.core.api.task.Task;
+import kiwi.core.api.task.TaskManagerService;
+
+
+class TaskImpl extends Task {
+
+ private static final String WAITING_DETAIL = "Waiting in status";
+
+ private final TaskManagerService manager;
+
+ TaskImpl(TaskManagerService manager, String uuid, String name, String group) {
+ super(uuid);
+ this.manager = manager;
+ this.name = name;
+ this.group = group;
+ }
+
+ @Override
+ public long endTask() {
+ long dur = System.currentTimeMillis() - started;
+ manager.endTask(this);
+ return dur;
+ }
+
+ public void subTastStarting(Task subTask) {
+ detailMessages.put(WAITING_DETAIL, getMessage());
+ updateMessage("waiting for Task " + subTask.getName() + " to complete");
+ }
+
+ public void subTaskEnded() {
+ updateMessage(detailMessages.remove(WAITING_DETAIL));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/task/TaskManagerServiceImpl.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/task/TaskManagerServiceImpl.java b/lmf-core/src/main/java/kiwi/core/services/task/TaskManagerServiceImpl.java
new file mode 100644
index 0000000..1d9a969
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/task/TaskManagerServiceImpl.java
@@ -0,0 +1,267 @@
+/**
+ * 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 kiwi.core.services.task;
+
+import at.newmedialab.sesame.commons.util.HashUtils;
+import kiwi.core.api.task.Task;
+import kiwi.core.api.task.TaskInfo;
+import kiwi.core.api.task.TaskManagerService;
+import org.slf4j.Logger;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import java.lang.ref.WeakReference;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+import java.util.WeakHashMap;
+
+@ApplicationScoped
+public class TaskManagerServiceImpl implements TaskManagerService {
+
+ private static final String DEFAULT_GROUP = "default";
+
+ private final WeakHashMap<Thread, Stack<TaskImpl>> tasks;
+
+ private final ThreadWatchdog watchdog;
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ public TaskManagerServiceImpl() {
+ tasks = new WeakHashMap<Thread, Stack<TaskImpl>>();
+ watchdog = new ThreadWatchdog(15000);
+ }
+
+ @PostConstruct
+ public void startup() {
+ watchdog.start();
+ }
+
+ /* (non-Javadoc)
+ * @see xx.test.taks.TaskManagerService#endTask(xx.test.taks.TaskInfo)
+ */
+ @Override
+ public void endTask(TaskInfo task) {
+ final Stack<TaskImpl> stack = getStack();
+ if (stack.contains(task)) {
+ while (!stack.isEmpty()) {
+ Task t = stack.pop();
+ if (t.equals(task)) {
+ log.debug("Ending task {}.{}", t.getGroup(), t.getName());
+ break;
+ } else {
+ log.debug("Ending task {}.{} because it's a sub-task", t.getGroup(), t.getName());
+ t.endTask();
+ }
+ }
+ if (!stack.isEmpty()) {
+ stack.peek().subTaskEnded();
+ }
+ } else {
+ log.debug("Not ending task {} because thread {} is not the owner", task.getName(), Thread.currentThread().getName());
+ }
+ if (stack.isEmpty()) {
+ tasks.remove(Thread.currentThread());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see xx.test.taks.TaskManagerService#getTasks()
+ */
+ @Override
+ public List<TaskInfo> getTasks() {
+ LinkedList<TaskInfo> ts = new LinkedList<TaskInfo>();
+ for (Stack<TaskImpl> stack : tasks.values()) {
+ ts.addAll(stack);
+ }
+ return Collections.unmodifiableList(ts);
+ }
+
+ /* (non-Javadoc)
+ * @see xx.test.taks.TaskManagerService#getTask()
+ */
+ @Override
+ public Task getTask() {
+ return createTask(Thread.currentThread().getName());
+ }
+
+ /* (non-Javadoc)
+ * @see xx.test.taks.TaskManagerService#createTask(java.lang.String)
+ */
+ @Override
+ public Task createTask(String name, String group) {
+ final Stack<TaskImpl> stack = getStack();
+ final Task task;
+ if (stack.isEmpty())
+ return createSubTask(name, group);
+ else {
+ task = stack.peek();
+ task.updateName(name);
+ if (group != null) {
+ task.updateGroup(group);
+ }
+ }
+ return task;
+ }
+
+ @Override
+ public Task createTask(String string) {
+ return createTask(string, null);
+ }
+
+ /* (non-Javadoc)
+ * @see xx.test.taks.TaskManagerService#createSubTask(java.lang.String)
+ */
+ @Override
+ public Task createSubTask(String name) {
+ return createSubTask(name, null);
+ }
+
+ @Override
+ public Task createSubTask(String name, String group) {
+ final Stack<TaskImpl> stack = getStack();
+ final TaskImpl task;
+ synchronized (stack) {
+ task = new TaskImpl(this, createUUID(), name, group != null ? group : DEFAULT_GROUP);
+ if (!stack.isEmpty()) {
+ stack.peek().subTastStarting(task);
+ }
+ stack.push(task);
+ }
+ return task;
+ }
+
+ private String createUUID() {
+ final Thread t = Thread.currentThread();
+ String string = String.format("%d: %s %tR", t.getId(), t.getName(), new Date());
+ return HashUtils.md5sum(string);
+ }
+
+ private Stack<TaskImpl> getStack() {
+ final Thread key = Thread.currentThread();
+ Stack<TaskImpl> stack = tasks.get(key);
+ if (stack == null) {
+ stack = new Stack<TaskImpl>();
+ tasks.put(key, stack);
+ }
+ return stack;
+ }
+
+ /* (non-Javadoc)
+ * @see xx.test.taks.TaskManagerService#getTasksByGroup()
+ */
+ @Override
+ public Map<String, List<TaskInfo>> getTasksByGroup() {
+ Map<String, List<TaskInfo>> result = new LinkedHashMap<String, List<TaskInfo>>();
+
+ for (TaskInfo task : getTasks()) {
+ final String group = task.getGroup();
+ List<TaskInfo> list = result.get(group);
+ if (list == null) {
+ list = new LinkedList<TaskInfo>();
+ result.put(group, list);
+ }
+ list.add(task);
+ }
+
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see xx.test.taks.TaskManagerService#getTasksByThread()
+ */
+ @Override
+ public Map<WeakReference<Thread>, Stack<TaskInfo>> getTasksByThread() {
+ Map<WeakReference<Thread>, Stack<TaskInfo>> result = new LinkedHashMap<WeakReference<Thread>, Stack<TaskInfo>>();
+
+ for (Map.Entry<Thread, Stack<TaskImpl>> e : tasks.entrySet()) {
+ Stack<TaskInfo> list = new Stack<TaskInfo>();
+ list.addAll(e.getValue());
+ result.put(new WeakReference<Thread>(e.getKey()), list);
+ }
+
+ return result;
+ }
+
+ private class ThreadWatchdog extends Thread {
+
+ private final long millis;
+ private boolean running;
+
+ public ThreadWatchdog(long millis) {
+ super("TaskThreadWatchdog");
+ this.millis = millis;
+ }
+
+ @Override
+ public void run() {
+ running = true;
+ log.trace("Watchdog: starting up");
+ final Task task = getTask();
+ int count = 0;
+ while (running) {
+ task.updateMessage("cleaning up");
+ task.updateProgress(++count);
+ try {
+ HashSet<Thread> dead = new HashSet<Thread>();
+ for (Thread t : tasks.keySet()) {
+ if (!t.isAlive()) {
+ dead.add(t);
+ }
+ }
+ for (Thread t : dead) {
+ log.debug("Watchdog: cleaning up dead thread " + t.getName());
+ tasks.remove(t);
+ t = null;
+ }
+ dead.clear();
+ dead = null;
+ task.updateMessage("sleeping");
+ synchronized (ThreadWatchdog.this) {
+ this.wait(millis);
+ }
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ task.endTask();
+ log.trace("Watchdog: shutdown");
+ }
+
+ public void shutdown() {
+ running = false;
+ synchronized (this) {
+ this.notify();
+ }
+ }
+
+ }
+
+ @PreDestroy
+ public void shutdown() {
+ watchdog.shutdown();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/templating/TemplatingHelper.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/templating/TemplatingHelper.java b/lmf-core/src/main/java/kiwi/core/services/templating/TemplatingHelper.java
new file mode 100644
index 0000000..84610db
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/templating/TemplatingHelper.java
@@ -0,0 +1,77 @@
+/**
+ * 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 kiwi.core.services.templating;
+
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import kiwi.core.api.templating.TemplatingService;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Some methods useful for template working
+ *
+ * @author Sergio Fernández
+ *
+ */
+public class TemplatingHelper {
+
+ public static Configuration getConfiguration() {
+ Configuration cfg = new Configuration();
+ cfg.setClassForTemplateLoading(TemplatingHelper.class, TemplatingService.PATH);
+ return cfg;
+ }
+
+ public static Template getTemplate(String name) throws IOException {
+ return getConfiguration().getTemplate(name);
+ }
+
+ public static Template getTemplate(Configuration conf, String name) throws IOException {
+ return conf.getTemplate(name);
+ }
+
+ public static String processTemplate(String name) throws IOException, TemplateException {
+ return processTemplate(name, new HashMap<String, Object>());
+ }
+
+ public static String processTemplate(String name, Map<String, Object> data) throws IOException, TemplateException {
+ Template tpl = getTemplate(name);
+ OutputStream os = new ByteArrayOutputStream();
+ Writer writer = new BufferedWriter(new OutputStreamWriter(os));
+ tpl.process(data, writer);
+ writer.flush();
+ return os.toString();
+ }
+
+ public static void processTemplate(String name, Writer writer) throws IOException, TemplateException {
+ processTemplate(name, new HashMap<String, Object>(), writer);
+ }
+
+ public static void processTemplate(String name, Map<String, Object> data, Writer writer) throws IOException, TemplateException {
+ Template tpl = getTemplate(name);
+ tpl.process(data, writer);
+ writer.flush();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/templating/TemplatingServiceImpl.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/templating/TemplatingServiceImpl.java b/lmf-core/src/main/java/kiwi/core/services/templating/TemplatingServiceImpl.java
new file mode 100644
index 0000000..a3dc54d
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/templating/TemplatingServiceImpl.java
@@ -0,0 +1,307 @@
+/**
+ * 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 kiwi.core.services.templating;
+
+import freemarker.template.Template;
+import kiwi.core.api.config.ConfigurationService;
+import kiwi.core.api.modules.ModuleService;
+import kiwi.core.api.templating.TemplatingService;
+import kiwi.core.events.ConfigurationChangedEvent;
+import kiwi.core.exception.TemplatingException;
+import kiwi.core.model.template.MenuItem;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.inject.Inject;
+import javax.servlet.ServletContext;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * User: Thomas Kurz
+ * Date: 22.07.11
+ * Time: 13:06
+ */
+@ApplicationScoped
+public class TemplatingServiceImpl implements TemplatingService {
+
+ private ServletContext context;
+
+ private static enum Properties { HEAD, CONTENT }
+
+ @Inject
+ private ModuleService moduleService;
+
+ @Inject
+ private ConfigurationService configurationService;
+
+ //some statics
+ private static final String TEMPLATE_STRING = "admin.ftl";
+ private static final String DEFAULT_REST_PATH = "/doc/rest/";
+ private static final String DEFAULT_REST_FILE = "overview-summary.html";
+ private static final String DEFAULT_STYLE = "screen";
+ private static final String DEFAULT_TITLE_FOR_WEBSERVICES = "webservices";
+ private static final String DEFAULT_PROJECT = "lmf";
+
+ //pattern to filter comments content
+ private static final Pattern PATTERN = Pattern.compile("\\<!--###BEGIN_([^#]+)###--\\>(.+)\\<!--###END_\\1###--\\>",Pattern.DOTALL);
+ private Template tpl;
+ private Menu menu;
+
+ /**
+ * inits a freemarker template service with a servlet context
+ * @param context a servlet context
+ */
+ @Override
+ public void init(ServletContext context) throws TemplatingException {
+ this.context = context;
+ initDataModel();
+ try {
+ tpl = TemplatingHelper.getTemplate(TEMPLATE_STRING);
+ } catch (IOException e) {
+ //e.printStackTrace();
+ throw new TemplatingException(e.getMessage());
+ }
+ }
+
+ /**
+ * Check whether the templating service considers the resource passed in the path as a menu entry it is
+ * responsible for.
+ *
+ * @param path a url path
+ * @return if the give path points to an admin page
+ */
+ @Override
+ public boolean isMenuEntry(String path) {
+ if(menu.path_titles.keySet().contains(configurationService.getPath()+path)) return true;
+ if(path.contains(DEFAULT_REST_PATH)) return true;
+ else return false;
+ }
+
+ /**
+ * this method wraps a file with a specified admin template. If the file is not a admin page,
+ * the bytes are returned unprocessed
+ * @param bytes content represented in a byte array
+ * @return the processed (templated) byte array
+ */
+ @Override
+ public byte[] process(byte[] bytes, String path) throws TemplatingException {
+
+ if(!configurationService.getBooleanConfiguration("templating.cache.enabled",true) && context!=null) {
+ init(context);
+ }
+ //apply template
+ if(!isMenuEntry(path)) return bytes;
+ //activate
+ String module = menu.getCurrentModule(configurationService.getPath() + path);
+ //fill data model
+ @SuppressWarnings("unchecked")
+ Map<String, Object> datamodel = (Map<String, Object>)basic_map.clone();
+ //begin hack!!!
+ datamodel.put("USER_MODULE_IS_ACTIVE", moduleService.listModules().contains("Users"));
+ //end hack!!!
+ datamodel.put("MODULE_MENU",menu.menuItems);
+ datamodel.put("DEFAULT_STYLE", configurationService.getStringConfiguration("kiwi.pages.style", DEFAULT_STYLE));
+ datamodel.put("CURRENT_TITLE", getNameFromPath(path));
+ datamodel.put("CURRENT_MODULE",module);
+ try {
+ String s = new String(bytes);
+ Matcher m = PATTERN.matcher(s);
+ while (m.find()) {
+ datamodel.put(m.group(1),m.group(2));
+ }
+ } catch (Exception e) {
+ throw new TemplatingException(e.getMessage());
+ }
+
+ //make magic happen
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ tpl.process(datamodel, new OutputStreamWriter(bos));
+ bytes = bos.toByteArray();
+ bos.flush();
+ bos.close();
+ } catch (Exception e) {
+ throw new TemplatingException(e.getMessage());
+ }
+ return bytes;
+ }
+
+ //datamodel may not be empty
+ private HashMap<String,String> basic_map;
+ /**
+ * creates a data model, which contains all properties (with empty values)
+ */
+ private void initDataModel() {
+ basic_map = new HashMap<String,String>();
+ for(Properties p : Properties.values()) {
+ basic_map.put(p.name(),"<!-- "+p.name()+" not defined -->");
+ }
+ basic_map.put("SERVER_URL", configurationService.getServerUri());
+ basic_map.put("BASIC_URL", configurationService.getBaseUri());
+ String project = configurationService.getStringConfiguration("kiwi.pages.project", DEFAULT_PROJECT);
+ basic_map.put("PROJECT", project);
+ basic_map.put("LOGO", configurationService.getStringConfiguration("kiwi.pages.project."+project+".logo", project+".png"));
+ basic_map.put("FOOTER", configurationService.getStringConfiguration("kiwi.pages.project."+project+".footer", "(footer not properly configured for project "+project+")"));
+
+ menu = new Menu();
+ }
+
+ /**
+ * Update the data model in case an important value has changed
+ * @param event
+ */
+ public void configurationChangedEvent(@Observes ConfigurationChangedEvent event) {
+ if (event.getKeys().contains("kiwi.context")
+ || event.getKeys().contains("kiwi.host")
+ || event.getKeys().contains("templating.sort_by_weight")
+ || event.getKeys().contains("kiwi.pages.project")) {
+ initDataModel();
+ }
+ }
+
+ /**
+ * This object represents a menu for the admin interface. It is build using the ModuleService.
+ */
+ class Menu {
+
+ public List<MenuItem> menuItems;
+ public Map<String,String> path_titles;
+
+ public Menu() {
+ //instantiate
+ menuItems = new ArrayList<MenuItem>();
+ path_titles = new HashMap<String, String>();
+ //sort menu
+ ArrayList<String> menuSorted = new ArrayList<String>(moduleService.listModules());
+ if(configurationService.getBooleanConfiguration("templating.sort_by_weight",true)) {
+ Collections.sort(menuSorted, new Comparator<String>() {
+ @Override
+ public int compare(String o1, String o2) {
+ final int w1 = moduleService.getWeight(o1), w2 = moduleService.getWeight(o2);
+ if (w1 == w2) return o1.compareTo(o2);
+ return w1 - w2;
+ }
+ });
+ } else {
+ Collections.sort(menuSorted);
+ }
+
+ //build structure
+ for(String module : menuSorted) {
+ String path = configurationService.getPath() + moduleService.getModuleWeb(module);
+ if(moduleHasAdminPages(module)) {
+ MenuItem menu_item = new MenuItem();
+ menu_item.getProperties().put("title",module);
+ menu_item.getProperties().put("baseurl",moduleService.getModuleConfiguration(module).getConfiguration().getString("baseurl","/"+module));
+ for(String page : moduleService.getAdminPages(module)) {
+ if(page.equals("")) {
+ continue;
+ }
+ MenuItem submenu = new MenuItem();
+ submenu.getProperties().put("title",getNameFromPath(page));
+ submenu.getProperties().put("path",path+page);
+ //test if it is active
+ menu_item.getSubmenu().add(submenu);
+ path_titles.put(path+page,page);
+ }
+ if(moduleService.getWebservices(module)!=null &&
+ !moduleService.getWebservices(module).isEmpty() &&
+ !moduleService.getWebservices(module).iterator().next().equals("")) {
+ MenuItem submenu = new MenuItem();
+ submenu.getProperties().put("title",DEFAULT_TITLE_FOR_WEBSERVICES);
+ submenu.getProperties().put("path",path+DEFAULT_REST_PATH+DEFAULT_REST_FILE);
+ //test if it is active
+ menu_item.getSubmenu().add(submenu);
+ path_titles.put(path+DEFAULT_REST_PATH+DEFAULT_REST_FILE,DEFAULT_TITLE_FOR_WEBSERVICES);
+ }
+ menuItems.add(menu_item);
+ }
+ }
+ }
+
+ /**
+ * get current module and set submenu to active
+ * @param path the current system path
+ * @return current module name
+ */
+ public String getCurrentModule(String path) {
+ String module = "";
+ boolean active = false;
+ //test with module and submenu must be active
+ for(MenuItem menuItem : menuItems) {
+ if(path.startsWith((String)menuItem.getProperties().get("baseurl"))) {
+ module = (String)menuItem.getProperties().get("title");
+ }
+ for(MenuItem submenu : menuItem.getSubmenu()) {
+ if(submenu.getProperties().get("path").equals(path)) {
+ submenu.getProperties().put("active",true);
+ module = (String)menuItem.getProperties().get("title");
+ active = true;
+ } else {
+ submenu.getProperties().put("active",false);
+ }
+ }
+ }
+ //workaround for webservices (autogenerated pages that are nit fix stored in the menu structure)
+ if(!active) {
+ for(MenuItem menuItem : menuItems) {
+ if(module.equals(menuItem.getProperties().get("title"))) {
+ for(MenuItem submenu : menuItem.getSubmenu()) {
+ if(submenu.getProperties().get("title").equals(DEFAULT_TITLE_FOR_WEBSERVICES)) {
+ submenu.getProperties().put("active",true);
+ }
+ }
+ }
+ }
+ }
+ return module;
+ }
+
+ /**
+ * Tests if a module should appear in the menu
+ * @param module a module name
+ * @return true is module should appear, false if not
+ */
+ private boolean moduleHasAdminPages(String module) {
+ if(moduleService.getAdminPages(module)!=null &&
+ !moduleService.getAdminPages(module).isEmpty() &&
+ !moduleService.getAdminPages(module).get(0).equals(""))
+ return true;
+ else if(moduleService.getWebservices(module)!=null &&
+ !moduleService.getWebservices(module).isEmpty() &&
+ !moduleService.getWebservices(module).iterator().next().equals("")) return true;
+ return false;
+ }
+
+ }
+
+ /**
+ * returns a proper name for a path by using the filename.
+ * @param path
+ * @return
+ */
+ private String getNameFromPath(String path) {
+ if(path.contains(DEFAULT_REST_PATH)) return DEFAULT_TITLE_FOR_WEBSERVICES;
+ return path.substring(path.lastIndexOf("/")).replaceAll("/"," ").replaceAll("_"," ").replaceAll(".html","").replaceAll(".jsp","");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/java/kiwi/core/services/triplestore/ContextServiceImpl.java
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/java/kiwi/core/services/triplestore/ContextServiceImpl.java b/lmf-core/src/main/java/kiwi/core/services/triplestore/ContextServiceImpl.java
new file mode 100644
index 0000000..1b00b2b
--- /dev/null
+++ b/lmf-core/src/main/java/kiwi/core/services/triplestore/ContextServiceImpl.java
@@ -0,0 +1,389 @@
+/**
+ * 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 kiwi.core.services.triplestore;
+
+import static at.newmedialab.sesame.commons.repository.ExceptionUtils.handleRepositoryException;
+
+import at.newmedialab.sesame.commons.repository.ResourceUtils;
+import kiwi.core.api.config.ConfigurationService;
+import kiwi.core.api.importer.ImportService;
+import kiwi.core.api.triplestore.ContextService;
+import kiwi.core.api.triplestore.SesameService;
+import kiwi.core.api.user.UserService;
+import kiwi.core.exception.io.LMFImportException;
+import kiwi.core.qualifiers.kspace.*;
+import org.apache.commons.lang.StringUtils;
+import org.openrdf.model.Resource;
+import org.openrdf.model.URI;
+import org.openrdf.model.vocabulary.RDFS;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.RepositoryResult;
+import org.slf4j.Logger;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * The context (named graphs in LMF, formerly "knowledge space" in KiWi) service offers convenience
+ * functions for working with LMF Contexts. Low level manipulation of contexts is offered by
+ * TripleStore.
+ * <p/>
+ * A context or (other name) named graph represent a own graph for a separation of the whole
+ * data in the context. In other words: the relationship between triples and a context is
+ * a 1 to N relationship. Every triple is though the context connect to exactly one context.
+ * <p/>
+ * Every context has own access rights, triples, reasoning rules and other metadata.
+ * <p/>
+ * You can create contexts for user, for imported ontologies, own created content, inferred
+ * triples and system data
+ * <p/>
+ * every new triple without information of a context is connect with the context to the
+ * default context
+ * <p/>
+ *
+ * @author Stefan
+ * @author Sergio Fernández
+ */
+@Named("knowledgeSpaceService")
+@ApplicationScoped
+public class ContextServiceImpl implements ContextService {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private ConfigurationService configurationService;
+
+ @Inject
+ private SesameService sesameService;
+
+ @Inject
+ private ImportService importService;
+
+ @Inject
+ private UserService userService;
+ @PostConstruct
+ public void initialize() {
+ log.debug("Creating default contexts...");
+ createContext(configurationService.getDefaultContext(), "default");
+ createContext(configurationService.getCacheContext(), "cache");
+ createContext(configurationService.getInferredContext(), "inferred");
+ }
+
+ @Override
+ public List<URI> listContexts() {
+ return listContexts(false);
+ }
+
+ @Override
+ public List<URI> listContexts(boolean filter) {
+ List<URI> contexts = new ArrayList<URI>();
+ try {
+ RepositoryConnection conn = sesameService.getConnection();
+ try {
+ conn.begin();
+ RepositoryResult<Resource> result = conn.getContextIDs();
+ while(result.hasNext()) {
+ Resource next = result.next();
+ if(next instanceof URI) {
+ URI uri = (URI)next;
+ if (filter) {
+ if (uri.stringValue().startsWith(configurationService.getBaseContext())) {
+ contexts.add(uri);
+ }
+ } else {
+ contexts.add(uri);
+ }
+ }
+ }
+ result.close();
+ } finally {
+ conn.commit();
+ conn.close();
+ }
+ } catch (RepositoryException e) {
+
+ }
+ return contexts;
+ }
+
+ /**
+ * Check the connection's namespace, using the base context when needed
+ *
+ * @param conn
+ * @throws RepositoryException
+ */
+ private void checkConnectionNamespace(RepositoryConnection conn)
+ throws RepositoryException {
+ if(conn.getNamespace(DEFAULT_PREFIX) == null) {
+ conn.setNamespace(DEFAULT_PREFIX, getBaseContext());
+ }
+ }
+
+ @Override
+ public Set<String> getAcceptFormats() {
+ return importService.getAcceptTypes();
+ }
+
+ //****************************************
+ // get/create default, inferred
+ //****************************************
+
+ /**
+ * Create a new context with the given URI or return the already existing context. Essentially
+ * just calls resourceService.createUriResource, but sets some resource parameters correctly.
+ *
+ *
+ * @param uri the uri of the context to create
+ * @return a URI representing the created context, or null if the URI could not be created
+ */
+ @Override
+ public URI createContext(String uri) {
+ return createContext(uri, null);
+ }
+
+ @Override
+ public URI createContext(String uri, String label) {
+ try {
+ RepositoryConnection conn = sesameService.getConnection();
+ try {
+ conn.begin();
+ checkConnectionNamespace(conn);
+ URI ctx = conn.getValueFactory().createURI(uri);
+ if (StringUtils.isNotBlank(label)) {
+ conn.add(ctx, RDFS.LABEL, conn.getValueFactory().createLiteral(label), ctx);
+ }
+ return ctx;
+ } finally {
+ conn.commit();
+ conn.close();
+ }
+ } catch(RepositoryException ex) {
+ handleRepositoryException(ex,ContextServiceImpl.class);
+ }
+ return null;
+ }
+
+ @Override
+ public URI getContext(String context_uri) {
+ try {
+ RepositoryConnection conn = sesameService.getConnection();
+ try {
+ conn.begin();
+ checkConnectionNamespace(conn);
+ if (ResourceUtils.isContext(conn, context_uri)) return conn.getValueFactory().createURI(context_uri);
+ } finally {
+ conn.commit();
+ conn.close();
+ }
+ } catch(RepositoryException ex) {
+ handleRepositoryException(ex, ContextServiceImpl.class);
+ }
+ return null;
+ }
+
+ /**
+ * Return the context that is currently selected for write access. The currently active knowledge space
+ * is either the default context or explicitly passed as argument ctx to web service calls.
+ *
+ * @return a KiWiUriResource representing the current knowledge space
+ */
+ @Override
+ @Produces @RequestScoped @CurrentKnowledgeSpace
+ public URI getCurrentContext() {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ /**
+ * Return the context used for storing system information.
+ *
+ * @return a KiWiUriResource representing the system knowledge space
+ */
+ @Override
+ @Produces @RequestScoped @SystemKnowledgeSpace
+ public URI getSystemContext() {
+ return createContext(configurationService.getSystemContext());
+ }
+
+ /**
+ * Return the set of contexts that is currently active for reading. The set of active contexts
+ * is either selected explicitly in web service calls or it consists of all contexts.
+ *
+ * @return a set of KiWiUriResources indicating the active contexts
+ */
+ @Override
+ @Produces @RequestScoped @ActiveKnowledgeSpaces
+ public Set<URI> getActiveContext() {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ /**
+ * Get the base context URI
+ *
+ * @return base context
+ */
+ @Override
+ public String getBaseContext() {
+ return configurationService.getBaseContext();
+ }
+
+ /**
+ * Get the uri of the inferred context
+ *
+ * @return uri of this inferred context
+ */
+ @Override
+ @Produces @RequestScoped @InferredKnowledgeSpace
+ public URI getInferredContext() {
+ return createContext(configurationService.getInferredContext());
+ }
+
+ /**
+ * Get the uri of the default context
+ *
+ * @return
+ */
+ @Override
+ @Produces @RequestScoped @DefaultKnowledgeSpace
+ public URI getDefaultContext() {
+ return createContext(configurationService.getDefaultContext());
+ }
+
+ /**
+ * Get the uri of the context used for caching linked data
+ *
+ * @return
+ */
+ @Override
+ public URI getCacheContext() {
+ return createContext(configurationService.getCacheContext());
+ }
+
+ /**
+ * Return a human-readable label for the context, either the rdfs:label or the last part of the URI.
+ *
+ *
+ * @param context
+ * @return
+ */
+ @Override
+ public String getContextLabel(URI context) {
+ try {
+ RepositoryConnection conn = sesameService.getConnection();
+ try {
+ conn.begin();
+ return ResourceUtils.getLabel(conn, context);
+ } finally {
+ conn.commit();
+ conn.close();
+ }
+ } catch(RepositoryException ex) {
+ handleRepositoryException(ex, ContextServiceImpl.class);
+ }
+ return null;
+ }
+
+ /**
+ * Import content into the context
+ *
+ * @param context
+ * @param is
+ * @param format
+ * @return
+ */
+ @Override
+ public boolean importContent(String context, InputStream is, String format) {
+ try {
+ RepositoryConnection conn = sesameService.getConnection();
+ try {
+ conn.begin();
+ checkConnectionNamespace(conn);
+ URI ctx = conn.getValueFactory().createURI(context);
+ int imported = importService.importData(is, format, userService.getCurrentUser(), ctx);
+ return imported > 0;
+ } catch (LMFImportException e) {
+ log.error(e.getMessage(), e);
+ } finally {
+ conn.commit();
+ conn.close();
+ }
+ } catch(RepositoryException ex) {
+ handleRepositoryException(ex,ContextServiceImpl.class);
+ }
+ return false;
+ }
+
+ /**
+ * Remove (clean whole content) the context represented by this URI
+ *
+ * @param context_uri uri of the context to remove
+ * @return operation result, false if context does not exist
+ */
+ @Override
+ public boolean removeContext(String context_uri) {
+ try {
+ RepositoryConnection conn = sesameService.getConnection();
+ try {
+ conn.begin();
+ URI context = conn.getValueFactory().createURI(context_uri);
+ conn.remove((Resource)null, null, null, context);
+ return true;
+ } finally {
+ conn.commit();
+ conn.close();
+ }
+ } catch(RepositoryException ex) {
+ handleRepositoryException(ex, ContextServiceImpl.class);
+ }
+ return false;
+ }
+
+ /**
+ * Remove (clean whole content) the context represented by this resource
+ *
+ *
+ * @param context resource
+ * @return operation result, false if context does not exist
+ */
+ @Override
+ public boolean removeContext(URI context) {
+ try {
+ RepositoryConnection conn = sesameService.getConnection();
+ try {
+ conn.begin();
+ conn.remove((Resource)null, null, null, context);
+ return true;
+ } finally {
+ conn.commit();
+ conn.close();
+ }
+ } catch(RepositoryException ex) {
+ handleRepositoryException(ex, ContextServiceImpl.class);
+ }
+ return false;
+ }
+
+}