/****************************************************************************** * 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.osgi; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Locale; import java.util.Map; import org.eclipse.sapphire.Context; import org.eclipse.sapphire.LocalizableText; import org.eclipse.sapphire.Text; import org.eclipse.sapphire.modeling.ResourceStoreException; import org.eclipse.sapphire.modeling.UrlResourceStore; import org.eclipse.sapphire.modeling.localization.LocalizationService; import org.eclipse.sapphire.modeling.localization.StandardLocalizationService; import org.osgi.framework.Bundle; /** * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a> */ public class BundleResourceStore extends UrlResourceStore { @Text( "Could not find resource \"{1}\" in bundle \"{0}\"." ) private static LocalizableText couldNotFindBundleResource; static { LocalizableText.init( BundleResourceStore.class ); } private final String bundleId; private final String path; private Bundle bundle; private Context context; public BundleResourceStore( final String bundleId, final String path ) throws ResourceStoreException { super( toUrl( bundleId, path, true ) ); this.bundleId = bundleId; this.path = path; } public final Bundle bundle() { if( this.bundle == null ) { this.bundle = BundleLocator.find( this.bundleId ); } return this.bundle; } @Override public boolean isOutOfDate() { return false; } @Override protected LocalizationService initLocalizationService( final Locale locale ) { return new StandardLocalizationService( locale ) { @Override protected boolean load( final Locale locale, final Map<String,String> keyToText ) { final String bundleId = BundleResourceStore.this.bundleId; final String path = BundleResourceStore.this.path; final int lastDot = path.lastIndexOf( '.' ); if( lastDot != -1 ) { String resFilePath = path.substring( 0, lastDot ); final String localeString = locale.toString(); if( localeString.length() > 0 ) { resFilePath = resFilePath + "_" + localeString; } resFilePath = resFilePath + ".properties"; final URL resFileUrl = toUrl( bundleId, resFilePath, false ); if( resFileUrl != null ) { try( InputStream stream = resFileUrl.openStream() ) { return parse( stream, keyToText ); } catch( final IOException e ) { return false; } } } return false; } }; } private static final URL toUrl( final String bundleId, final String path, final boolean throwExceptionOnNotFound ) { final Bundle bundle = BundleLocator.find( bundleId ); final URL url = bundle.getResource( path ); if( url == null && throwExceptionOnNotFound ) { final String msg = couldNotFindBundleResource.format( bundleId, path ); throw new IllegalArgumentException( msg ); } return url; } @Override public <A> A adapt( final Class<A> adapterType ) { if( adapterType == Context.class ) { if( this.context == null ) { this.context = BundleBasedContext.adapt( bundle() ); } return adapterType.cast( this.context ); } else if( adapterType == Bundle.class ) { return adapterType.cast( bundle() ); } return super.adapt( adapterType ); } }