/* * Copyright 2014 JBoss Inc * * 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 org.artificer.integration; import org.apache.commons.io.FileUtils; import org.artificer.integration.artifactbuilder.ArtifactBuilder; import org.artificer.integration.artifactbuilder.ArtifactBuilderProvider; import org.artificer.integration.artifactbuilder.BuiltInArtifactBuilderProvider; import org.artificer.integration.artifacttypedetector.ArtifactTypeDetector; import org.artificer.integration.artifacttypedetector.DefaultArtifactTypeDetector; import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.BaseArtifactType; import org.overlord.commons.services.ServiceRegistryUtil; import org.artificer.common.ArtifactContent; import org.artificer.common.ArtifactType; import org.artificer.common.ArtificerConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import java.util.ServiceLoader; import java.util.Set; /** * @author Brett Meyer. */ public class ExtensionFactory { private static final Logger LOGGER = LoggerFactory.getLogger(ExtensionFactory.class); private static List<ArtifactTypeDetector> typeDetectors = new ArrayList<ArtifactTypeDetector>(); private static List<ArtifactBuilderProvider> builderProviders = new ArrayList<ArtifactBuilderProvider>(); static { loadBuiltIn(); loadExtended(); // sort by priority Collections.sort(typeDetectors, new ArtifactTypeDetectorComparator()); } /** * Loads the built-in extensions. */ private static void loadBuiltIn() { typeDetectors.add(new DefaultArtifactTypeDetector()); builderProviders.add(new BuiltInArtifactBuilderProvider()); } /** * Loads any custom extensions. These can be contributed via the standard Java service loading mechanism * or through custom jars in the dir identified through sramp.extension.customDir */ private static void loadExtended() { // First load via the standard ServiceRegistry mechanism. Set<ArtifactTypeDetector> extendedTypeDetectors = ServiceRegistryUtil.getServices(ArtifactTypeDetector.class); typeDetectors.addAll(extendedTypeDetectors); Set<ArtifactBuilderProvider> extendedBuilderProviders = ServiceRegistryUtil.getServices( ArtifactBuilderProvider.class); builderProviders.addAll(extendedBuilderProviders); // Allow users to provide a directory path where we will check for JARs that // contain extension implementations. Collection<ClassLoader> loaders = new LinkedList<ClassLoader>(); String customDirPath = System.getProperty(ArtificerConstants.ARTIFICER_CUSTOM_EXTENSION_DIR); if (customDirPath != null && customDirPath.trim().length() > 0) { File directory = new File(customDirPath); if (directory.isDirectory()) { List<URL> jarURLs = new ArrayList<URL>(); Collection<File> jarFiles = FileUtils.listFiles(directory, new String[]{"jar"}, false); for (File jarFile : jarFiles) { try { URL jarUrl = jarFile.toURI().toURL(); jarURLs.add(jarUrl); } catch (MalformedURLException e) { } } URL[] urls = jarURLs.toArray(new URL[jarURLs.size()]); ClassLoader jarCL = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader()); loaders.add(jarCL); } } for (ClassLoader loader : loaders) { for (ArtifactTypeDetector typeDetector : ServiceLoader.load(ArtifactTypeDetector.class, loader)) { typeDetectors.add(typeDetector); } for (ArtifactBuilderProvider builderProvider : ServiceLoader.load(ArtifactBuilderProvider.class, loader)) { builderProviders.add(builderProvider); } } } public static ArtifactType detect(ArtifactContent content) { for (ArtifactTypeDetector typeDetector : typeDetectors) { ArtifactType artifactType = typeDetector.detect(content); if (artifactType != null) { return artifactType; } } return null; } public static ArtifactType detect(ArtifactContent content, ArchiveContext archiveContext) { for (ArtifactTypeDetector typeDetector : typeDetectors) { ArtifactType artifactType = typeDetector.detect(content, archiveContext); if (artifactType != null) { return artifactType; } } return null; } public static boolean isArchive(ArtifactContent content) { for (ArtifactTypeDetector typeDetector : typeDetectors) { if (typeDetector.isArchive(content)) { return true; } } return false; } public static boolean allowExpansionFromArchive(ArtifactContent content, ArchiveContext archiveContext) { for (ArtifactTypeDetector typeDetector : typeDetectors) { if (typeDetector.allowExpansionFromArchive(content, archiveContext)) { return true; } } return false; } public static List<ArtifactBuilder> createArtifactBuilders(BaseArtifactType primaryArtifact, ArtifactContent artifactContent) { List<ArtifactBuilder> builders = new ArrayList<ArtifactBuilder>(); for (ArtifactBuilderProvider builderProvider : builderProviders) { builders.addAll(builderProvider.createArtifactBuilders(primaryArtifact, artifactContent)); } return builders; } private static class ArtifactTypeDetectorComparator implements Comparator<ArtifactTypeDetector> { @Override public int compare(ArtifactTypeDetector o1, ArtifactTypeDetector o2) { Integer p1 = o1.getPriority(); Integer p2 = o2.getPriority(); // higest value first return p2.compareTo(p1); } } }