/**************************************************************************** * Copyright (C) 2013 ecsec GmbH. * All rights reserved. * Contact: ecsec GmbH (info@ecsec.de) * * This file is part of the Open eCard App. * * GNU General Public License Usage * This file may be used under the terms of the GNU General Public * License version 3.0 as published by the Free Software Foundation * and appearing in the file LICENSE.GPL included in the packaging of * this file. Please review the following information to ensure the * GNU General Public License version 3.0 requirements will be met: * http://www.gnu.org/copyleft/gpl.html. * * Other Usage * Alternatively, this file may be used in accordance with the terms * and conditions contained in a signed written agreement between * you and ecsec GmbH. * ***************************************************************************/ package org.openecard.addon; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import javax.annotation.Nonnull; import org.openecard.addon.bind.AppExtensionAction; import org.openecard.addon.bind.AppExtensionActionProxy; import org.openecard.addon.bind.AppPluginAction; import org.openecard.addon.bind.AppPluginActionProxy; import org.openecard.addon.ifd.IFDProtocol; import org.openecard.addon.ifd.IFDProtocolProxy; import org.openecard.addon.manifest.AddonSpecification; import org.openecard.addon.manifest.AppExtensionSpecification; import org.openecard.addon.manifest.AppPluginSpecification; import org.openecard.addon.manifest.ProtocolPluginSpecification; import org.openecard.addon.sal.SALProtocol; import org.openecard.addon.sal.SALProtocolProxy; import org.openecard.common.interfaces.Dispatcher; import org.openecard.common.interfaces.EventManager; import org.openecard.common.sal.state.CardStateMap; import org.openecard.common.util.FacadeInvocationHandler; import org.openecard.gui.UserConsent; import org.openecard.recognition.CardRecognition; import org.openecard.ws.marshal.WSMarshallerException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Tobias Wich <tobias.wich@ecsec.de> * @author Dirk Petrautzki <petrautzki@hs-coburg.de> */ public class AddonManager { private static final Logger logger = LoggerFactory.getLogger(AddonManager.class); private final CombiningRegistry registry; private final AddonRegistry protectedRegistry; private final Dispatcher dispatcher; private final UserConsent userConsent; private final CardStateMap cardStates; private final CardRecognition recognition; private final EventManager eventManager; private final EventHandler eventHandler; public AddonManager(Dispatcher dispatcher, UserConsent userConsent, CardStateMap cardStates, CardRecognition recognition, EventManager eventManager) throws WSMarshallerException { this.registry = new CombiningRegistry(); this.protectedRegistry = getProtectedRegistry(registry); this.dispatcher = dispatcher; this.userConsent = userConsent; this.cardStates = cardStates; this.recognition = recognition; this.eventManager = eventManager; eventHandler = new EventHandler(eventManager); } /** * This method returns an instance of the given registry where only the interface methods are accessible. * * @param registry Unprotected registry instance. * @return Protected registry instance. */ private static AddonRegistry getProtectedRegistry(AddonRegistry registry) { ClassLoader cl = AddonManager.class.getClassLoader(); Class<?>[] interfaces = new Class<?>[] { AddonRegistry.class }; InvocationHandler handler = new FacadeInvocationHandler(registry); Object o = Proxy.newProxyInstance(cl, interfaces, handler); return (AddonRegistry) o; } public AddonRegistry getRegistry() { return protectedRegistry; } public AddonRegistry getBuiltinRegistry() { return getProtectedRegistry(registry.getClasspathRegistry()); } public AddonRegistry getExternalRegistry() { return getProtectedRegistry(registry.getFileRegistry()); } public void registerClasspathAddon(AddonSpecification desc) { // TODO: protect this method from the sandbox this.registry.getClasspathRegistry().register(desc); } public IFDProtocol getIFDProtocol(@Nonnull AddonSpecification addonSpec, @Nonnull String uri) { ProtocolPluginSpecification protoSpec = addonSpec.searchIFDActionByURI(uri); String className = protoSpec.getClassName(); ClassLoader cl = registry.downloadAddon(addonSpec); IFDProtocolProxy protoFactory = new IFDProtocolProxy(className, cl); try { Context aCtx = new Context(this, dispatcher, userConsent, cardStates, recognition, eventManager, eventHandler); protoFactory.init(aCtx); return protoFactory; } catch (ActionInitializationException e) { logger.error("Initialization of IFD Protocol failed", e); } return null; } public SALProtocol getSALProtocol(@Nonnull AddonSpecification addonSpec, @Nonnull String uri) { ProtocolPluginSpecification protoSpec = addonSpec.searchSALActionByURI(uri); String className = protoSpec.getClassName(); ClassLoader cl = registry.downloadAddon(addonSpec); SALProtocolProxy protoFactory = new SALProtocolProxy(className, cl); try { Context aCtx = new Context(this, dispatcher, userConsent, cardStates, recognition, eventManager, eventHandler); protoFactory.init(aCtx); return protoFactory; } catch (ActionInitializationException e) { logger.error("Initialization of SAL Protocol failed", e); } return null; } public AppExtensionAction getAppExtensionAction(@Nonnull AddonSpecification addonSpec, @Nonnull String actionId) { AppExtensionSpecification protoSpec = addonSpec.searchByActionId(actionId); String className = protoSpec.getClassName(); ClassLoader cl = registry.downloadAddon(addonSpec); AppExtensionActionProxy protoFactory = new AppExtensionActionProxy(className, cl); try { Context aCtx = new Context(this, dispatcher, userConsent, cardStates, recognition, eventManager, eventHandler); protoFactory.init(aCtx); return protoFactory; } catch (ActionInitializationException e) { logger.error("Initialization of AppExtensionAction failed", e); } return null; } public AppPluginAction getAppPluginAction(@Nonnull AddonSpecification addonSpec, @Nonnull String resourceName) { AppPluginSpecification protoSpec = addonSpec.searchByResourceName(resourceName); String className = protoSpec.getClassName(); ClassLoader cl = registry.downloadAddon(addonSpec); AppPluginActionProxy protoFactory = new AppPluginActionProxy(className, cl); try { Context aCtx = new Context(this, dispatcher, userConsent, cardStates, recognition, eventManager, eventHandler); protoFactory.init(aCtx); return protoFactory; } catch (ActionInitializationException e) { logger.error("Initialization of AppPluginAction failed", e); } return null; } }