/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2012 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.extension; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Extension provider that is able to find extensions from multiple sources. * For example you might want to combine a local folder extension provider with a Marketplace extension provider. Or you might want to combine two local folders extension providers. * @author acostescu */ public class ComposedExtensionProvider implements IExtensionProvider { protected final IExtensionProvider provider1; protected final IExtensionProvider provider2; /** * Creates a new composed extension provider. This will get extension related data from both specified sources.<br> * It will try to find what it needs in provider1 and then in provider2. In case of duplicate entries only one will be returned - the * one from provider1. * @param provider1 the higher priority extension provider. * @param provider2 the lower priority extension provider. */ public ComposedExtensionProvider(IExtensionProvider provider1, IExtensionProvider provider2) { this.provider1 = provider1; this.provider2 = provider2; } public DependencyMetadata[] getDependencyMetadata(ExtensionDependencyDeclaration extensionDependency) { DependencyMetadata[] dmd1 = provider1.getDependencyMetadata(extensionDependency); DependencyMetadata[] dmd2 = provider2.getDependencyMetadata(extensionDependency); // if there are duplicates (same extension id/version), only return the ones from provider1 List<DependencyMetadata> result = new ArrayList<DependencyMetadata>((dmd1 != null ? dmd1.length : 0) + (dmd2 != null ? dmd2.length : 0)); if (dmd1 != null) result.addAll(Arrays.asList(dmd1)); if (dmd2 != null) { for (DependencyMetadata dmd : dmd2) { // check to see that it's not already present from provider1 boolean found = false; for (int i = result.size() - 1; !found && i >= 0; i--) { if (dmd.id.equals(result.get(i).id) && VersionStringUtils.sameVersion(dmd.version, result.get(i).version)) { found = true; } } if (!found) { result.add(dmd); } } } return result.size() > 0 ? result.toArray(new DependencyMetadata[result.size()]) : null; } public File getEXPFile(String extensionId, String version, IProgress progress) { // TODO create separate sub-progress monitors File f = provider1.getEXPFile(extensionId, version, progress); if (f == null) f = provider2.getEXPFile(extensionId, version, progress); return f; } public Message[] getMessages() { Message[] w1 = provider1.getMessages(); Message[] w2 = provider2.getMessages(); ArrayList<Message> messages = new ArrayList<Message>(w1.length + w2.length); messages.addAll(Arrays.asList(w1)); messages.addAll(Arrays.asList(w2)); return messages.toArray(new Message[messages.size()]); } public void clearMessages() { provider1.clearMessages(); provider2.clearMessages(); } public void dispose() { provider1.dispose(); provider2.dispose(); } }