/** * Copyright (c) 2012 - 2018 Data In Motion and others. * All rights reserved. * * This program and the accompanying materials are made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Data In Motion - initial API and implementation */ package org.gecko.runtime.resources.internal; import java.io.File; import java.net.URI; import java.net.URL; import java.util.Collection; import java.util.Dictionary; import java.util.logging.Level; import java.util.logging.Logger; import org.gecko.runtime.resources.GeckoResourcesConstants; import org.gecko.runtime.resources.GeckoResourcesProvider; import org.osgi.annotation.bundle.Capability; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.ConfigurationPolicy; import org.osgi.service.component.annotations.Modified; /** * Component that registers resources depending on their configuration. * It is possible to start a base with: * gecko.data.dir/test, which then will be replaces with the value from the corresponding service. * It there is no service available the default data path hat user.home/.gecko/data will be taken. * @author Mark Hoffmann * @since 9 Mar 2018 */ @Capability( namespace="gecko.addons", name="resources", version="1.0.0" ) @Component(configurationPolicy=ConfigurationPolicy.REQUIRE, configurationPid=GeckoResourcesConstants.RESOURCES_FACTORY_ID, service=GeckoResourcesProvider.class) public class ResourcesConfigurationComponent implements GeckoResourcesProvider, GeckoResourcesConstants { private static final Logger logger = Logger.getLogger(ResourcesConfigurationComponent.class.getName()); private String name; private URI pathURI; private ComponentContext ctx; /** * Called on component activation * @param ctx the component context * @throws ConfigurationException */ @Activate public void activate(ComponentContext ctx) throws ConfigurationException { this.ctx = ctx; updateURL(ctx.getProperties()); } /** * Called on configuration modification * @param ctx the component context * @throws ConfigurationException */ @Modified public void modified(ComponentContext ctx) throws ConfigurationException { updateURL(ctx.getProperties()); } /** * Updates the given configuration properties and creates a URL from it * @param properties the component properties * @throws ConfigurationException */ private void updateURL(Dictionary properties) throws ConfigurationException { name = (String) properties.get(RESOURCE_NAME); if (name == null) { throw new ConfigurationException(RESOURCE_NAME, "The name for the resource has to be defined"); } String path = (String) properties.get(RESOURCE_PATH); if (path == null) { throw new ConfigurationException(RESOURCE_PATH, "The path for the resource has to be defined"); } String envPath = System.getenv(RESOURCE_PATH); if (envPath != null) { path = envPath; } String propPath = System.getProperty(RESOURCE_PATH); if (propPath != null) { path = propPath; } String defaultBasePath = System.getProperty("user.home") + "/" + DEFAULT_GECKO_DATA_DIR + "/" + name; path = substitutePath(path, defaultBasePath); try { pathURI = URI.create(path); if (!pathURI.isAbsolute()) { pathURI = URI.create("file://" + path); } } catch (Exception e) { logger.log(Level.SEVERE, "[{0}] Cannot parse URI '" + path + "'", new Object[] {getName(), e}); } } /** * Substitutes the determined path. This can be e.g. the * @param path the path that was detected * @param defaultBasePath the default path to substitute with * @return the substituted path */ private String substitutePath(String path, String defaultBasePath) { if (path.startsWith(PROP_GECKO_DATA_DIR)) { String substituteDir = defaultBasePath; try { Collection> references = ctx.getBundleContext().getServiceReferences(URL.class, "(" + PROP_GECKO_DATA_DIR + "=true)"); if (!references.isEmpty()) { substituteDir = (String) references.iterator().next().getProperty(PROP_SERVICE_URL); } return path.replace(PROP_GECKO_DATA_DIR, substituteDir); } catch (InvalidSyntaxException e) { logger.severe("Error finding an URL with the given filter. The filter is invalid"); } } return path; } /* * (non-Javadoc) * @see org.gecko.runtime.resources.GeckoResourcesProvider#getName() */ @Override public String getName() { return name; } /* * (non-Javadoc) * @see org.gecko.runtime.resources.GeckoResourcesProvider#getURI() */ @Override public URI getURI() { return pathURI; } /* * (non-Javadoc) * @see org.gecko.runtime.resources.GeckoResourcesProvider#getFile() */ @Override public File getFile() { if (getURI() == null) { return null; } return new File(getURI()); } /* * (non-Javadoc) * @see org.gecko.runtime.resources.GeckoResourcesProvider#getURLString() */ @Override public String getURIString() { if (getURI() == null) { return null; } return getURI().toString(); } }