/****************************************************************************** * 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; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Enumeration; import java.util.List; import java.util.jar.Attributes; import java.util.jar.Manifest; import org.eclipse.sapphire.services.Service; import org.eclipse.sapphire.services.ServiceContext; /** * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a> */ public final class Sapphire { private static final String VERSION_QUALIFIER_SUFFIX = ".qualifier"; private static boolean devmode = Boolean.parseBoolean( System.getProperty( "sapphire.dev.mode" ) ); private static Version version; private static ServiceContext services; private static ObservableMap<String,Object> global; /** * This class is not meant to be instantiated. */ private Sapphire() { } public static boolean isDevMode() { return devmode; } /** * Determines the version of Sapphire. * * @return the version of Sapphire */ public static synchronized Version version() { if( version == null ) { Enumeration<URL> itr = null; try { itr = Sapphire.class.getClassLoader().getResources( "META-INF/MANIFEST.MF" ); } catch( Exception e ) { Sapphire.service( LoggingService.class ).log( e ); version = new Version( 0 ); } if( itr != null ) { while( itr.hasMoreElements() && version == null ) { Manifest manifest = null; try( InputStream stream = itr.nextElement().openStream() ) { manifest = new Manifest( stream ); } catch( final IOException e ) { // Do not actually want to log this as we could be reading some other JAR's corrupted manifest. } if( manifest != null ) { final Attributes attributes = manifest.getMainAttributes(); final String bundleSymbolicName = attributes.getValue( "Bundle-SymbolicName" ); if( bundleSymbolicName != null && bundleSymbolicName.equals( "org.eclipse.sapphire.modeling" ) ) { String bundleVersion = attributes.getValue( "Bundle-Version" ); if( bundleVersion != null ) { bundleVersion = bundleVersion.trim(); if( bundleVersion.endsWith( VERSION_QUALIFIER_SUFFIX ) ) { bundleVersion = bundleVersion.substring( 0, bundleVersion.length() - VERSION_QUALIFIER_SUFFIX.length() ); } try { version = new Version( bundleVersion ); } catch( IllegalArgumentException e ) { Sapphire.service( LoggingService.class ).log( e ); } } if( version == null ) { version = new Version( 0 ); } } } } } } return version; } /** * Returns the service of the specified type from the root service context. * * @param <S> the type of the service * @param type the type of the service * @return the service or <code>null</code> if not available */ public static <S extends Service> S service( final Class<S> type ) { return services().service( type ); } /** * Returns services of the specified type from the root service context. * * @param <S> the type of the service * @param type the type of the service * @return the list of services or an empty list if none are available */ public static <S extends Service> List<S> services( final Class<S> type ) { return services().services( type ); } /** * Returns the root service context. * * @return the root service context */ public static synchronized ServiceContext services() { if( services == null ) { services = new ServiceContext( ServiceContext.ID_ROOT ); } return services; } /** * Returns a map where objects can be stored that need to be globally accessible and visible * through Sapphire EL. * * @return an editable map of global objects */ public static synchronized ObservableMap<String,Object> global() { if( global == null ) { global = new ObservableMap<String,Object>(); } return global; } }