/****************************************************************************** * Copyright (c) 2016 Oracle * 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: * Konstantin Komissarchik - initial implementation and ongoing maintenance ******************************************************************************/ package org.eclipse.sapphire.modeling; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; import org.eclipse.sapphire.Context; import org.eclipse.sapphire.LoggingService; import org.eclipse.sapphire.Sapphire; /** * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a> */ public abstract class ExtensionsLocator { protected static final String DEFAULT_PATH = "META-INF/sapphire-extension.xml"; private static ExtensionsLocator instance; public static synchronized final ExtensionsLocator instance() { if( instance == null ) { final ClassLoader cl = ExtensionsLocator.class.getClassLoader(); Class<?> implClass = null; try { implClass = cl.loadClass( "org.eclipse.sapphire.modeling.ExtensionsLocatorFactory" ); } catch( ClassNotFoundException e ) { // Intentionally ignoring. The discrete locator implementation is optional. } if( implClass != null ) { try { final Factory factory = (Factory) implClass.newInstance(); if( factory.applicable() ) { instance = factory.create(); } } catch( Exception e ) { // Problem here means a bug in the discrete locator implementation. Log the problem and fail over // to the default locator logic. Sapphire.service( LoggingService.class ).log( e ); } } if( instance == null ) { instance = new ExtensionsLocator() { @Override public List<Handle> find() { final List<Handle> handles = new ArrayList<Handle>(); try { final Enumeration<URL> urls = cl.getResources( DEFAULT_PATH ); while( urls.hasMoreElements() ) { final URL url = urls.nextElement(); if( url != null ) { handles.add( new Handle( url, Context.adapt( cl ) ) ); } } } catch( IOException e ) { Sapphire.service( LoggingService.class ).log( e ); } return Collections.unmodifiableList( handles ); } }; } } return instance; } public abstract List<Handle> find(); public static final class Handle { private final URL extension; private final Context context; public Handle( final URL extension, final Context context ) { this.extension = extension; this.context = context; } public URL extension() { return this.extension; } public Context context() { return this.context; } } public static abstract class Factory { public abstract boolean applicable(); public abstract ExtensionsLocator create(); } }