/** * Licensed to The Apereo Foundation under one or more contributor license * agreements. See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * * The Apereo Foundation licenses this file to you under the Educational * Community 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://opensource.org/licenses/ecl2.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * */ package org.opencastproject.index.service.resources.list.impl; import org.opencastproject.index.service.exception.ListProviderException; import org.opencastproject.index.service.resources.list.api.ListProvidersService; import org.opencastproject.index.service.resources.list.api.ResourceListProvider; import org.opencastproject.index.service.resources.list.api.ResourceListQuery; import org.opencastproject.security.api.Organization; import org.apache.commons.io.IOUtils; import org.apache.felix.fileinstall.ArtifactInstaller; import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Properties; public class ListProvidersScanner implements ArtifactInstaller { /** The directory name that has the properties file defining the list providers **/ public static final String LIST_PROVIDERS_DIRECTORY = "listproviders"; /** The key to look for in the properties file to name the list provider. **/ public static final String LIST_NAME_KEY = "list.name"; /** The key to attach this list to a particular org, if not present then all orgs can get list **/ public static final String LIST_ORG_KEY = "list.org"; /** The logging instance */ private static final Logger logger = LoggerFactory.getLogger(ListProvidersScanner.class); /** The Map to go from file locations of properties files to list names. **/ private Map<String, String> fileToListNames = new HashMap<String, String>(); /** The list providers service to add the list provider to. **/ private ListProvidersService listProvidersService; void activate(BundleContext ctx) { logger.info("Activated"); } void deactivate(BundleContext ctx) { logger.info("Deactivated"); } public void setListProvidersService(ListProvidersService listProvidersService) { this.listProvidersService = listProvidersService; } /** * {@inheritDoc} * * @see org.apache.felix.fileinstall.ArtifactListener#canHandle(java.io.File) */ @Override public boolean canHandle(File artifact) { return LIST_PROVIDERS_DIRECTORY.equals(artifact.getParentFile().getName()) && artifact.getName().endsWith(".properties"); } /** * Inner class used to represent a new list. */ private class SingleResourceListProviderImpl implements ResourceListProvider { private String listName; private String orgId = ""; private Map<String, String> list; /** * Default constructor. * * @param listName * The name of the new list to add. * @param list * The list of properties to expose. */ SingleResourceListProviderImpl(String listName, Map<String, String> list) { this.listName = listName; this.list = list; } public String getListName() { return listName; } @Override public String[] getListNames() { String[] listNames = { listName }; return listNames; } public void setOrg(String orgName) { this.orgId = orgName; } @Override public Map<String, String> getList(String listName, ResourceListQuery query, Organization organization) throws ListProviderException { logger.debug("Getting list " + listName + " query " + query + " org " + organization); if (this.listName.equals(listName) && "".equals(this.orgId)) { return Collections.unmodifiableMap(list); } else if (this.listName.equals(listName) && organization != null && organization.getId().equals(this.orgId)) { return Collections.unmodifiableMap(list); } else { return null; } } } /** * Add a list provider based upon a configuration file. * * @param artifact * The File representing the configuration file for the list. */ public void addResourceListProvider(File artifact) throws IOException { logger.debug("Adding {}", artifact.getAbsolutePath()); // Format name FileInputStream in = null; Properties properties = new Properties(); try { in = new FileInputStream(artifact); properties.load(in); } finally { IOUtils.closeQuietly(in); } String listName = ""; if (properties.getProperty(LIST_NAME_KEY) != null) { listName = properties.getProperty(LIST_NAME_KEY).toString(); } String orgId = ""; logger.debug("Found list with name '{}'", listName); if (!"".equals(listName)) { HashMap<String, String> list = new HashMap<String, String>(); Enumeration<Object> keys = properties.keys(); while (keys.hasMoreElements()) { Object key = keys.nextElement(); String keyString = key.toString(); if (!keyString.equalsIgnoreCase(LIST_NAME_KEY) && !keyString.equalsIgnoreCase(LIST_ORG_KEY)) { String value = properties.get(key).toString(); list.put(keyString, value); logger.debug("Found key:{} value:{}", keyString, value); } else if (keyString.equalsIgnoreCase(LIST_ORG_KEY)) { orgId = properties.get(key).toString(); logger.debug("Found org:{}", orgId); } else { logger.debug("Skipping key:{}", keyString); } } SingleResourceListProviderImpl singleResourceListProviderImpl = new SingleResourceListProviderImpl(listName, list); if (orgId != null && !"".equals(orgId)) { singleResourceListProviderImpl.setOrg(orgId); } listProvidersService.addProvider(singleResourceListProviderImpl.getListName(), singleResourceListProviderImpl); fileToListNames.put(artifact.getAbsolutePath(), singleResourceListProviderImpl.getListName()); } else { logger.error( "Unable to add {} as a list provider because the {} entry was empty. Please add it to get this list provider to work.", new Object[] { artifact.getAbsolutePath(), LIST_NAME_KEY, listName }); } } /** * Remove a list provider based upon the location of its configuration file. * * @param artifact * The File representing the configuration file for the list. */ public void removeResourceListProvider(File artifact) { String listName = fileToListNames.remove(artifact.getAbsoluteFile()); if (listName != null) { listProvidersService.removeProvider(listName); } } @Override public void install(File artifact) throws Exception { logger.info("Installing list provider {}", artifact.getAbsolutePath()); addResourceListProvider(artifact); } @Override public void update(File artifact) throws Exception { logger.info("Updating list provider {}", artifact.getAbsolutePath()); removeResourceListProvider(artifact); addResourceListProvider(artifact); } @Override public void uninstall(File artifact) throws Exception { logger.info("Removing list provider {}", artifact.getAbsolutePath()); removeResourceListProvider(artifact); } }