Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 5c68ab0a4b42185f13cdb59b4b5143b1af84a2f3 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                                                
                                                        



                                                                         
   

                                                        


                                                                                                          
                                                                                 
                                                        
 



                                      
                                                                          
                                                               
                                 
                                        
 



                                                                              

                                                  

                                                                          
                                                                                
                                                                              
                                                                                

                                                                            

                                                             
 

                                                               
 


                                            
 



                                                                                                               
                                                                      

                                                                                                                    
                                                                             
                                       
                                     

         
                                                             



                                                                                                                                                 
                     

                                                              

                                                             
                                    


                     




                                                                      
                                                                                                  
                                     
                                                                   








                                                                                                       
                                                                              
                                                                                 
 


                                                                            
                         

                                                   
                 


                             
                                                            



                                                   

                            
 




















                                                                                                               

                                                                                                                         
 
                                                                                                                                                                                                      








                                                                                                            

                                                                                

                                                                                                     
                                      







                                                                                                         



                                                                                                                        




                                           
                                      
                 
                              

         
                                                                                         
                                                



                                                                                      

         







                                                                                      

                                                                                   
                                                                              
                 

         
                                                   
                                                                                                                
                                                                
                                       
                                                   

         

                                                             
                                                                 

                                                             

         



                                                  
         
 
/*******************************************************************************
 *  Copyright (c) 2007, 2015 IBM Corporation and others.
 *  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:
 *      IBM Corporation - initial API and implementation
 *      Ericsson AB (Pascal Rapicault) - Bug 397216 -[Shared] Better shared configuration change discovery
 *      Red Hat, Inc (Krzysztof Daniel) - Bug 421935: Extend simpleconfigurator to
 * read .info files from many locations 
 *******************************************************************************/
package org.eclipse.equinox.internal.simpleconfigurator;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import org.eclipse.equinox.internal.provisional.configurator.Configurator;
import org.eclipse.equinox.internal.simpleconfigurator.utils.*;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

/*
 * SimpleConfigurator provides ways to install bundles listed in a file
 * accessible by the specified URL and expect states for it in advance without
 * actual application.
 * 
 * In every methods of SimpleConfiguration object,
 * 
 * 1. A value will be gotten by @{link BundleContext#getProperty(key) with
 * {@link SimpleConfiguratorConstants#PROP_KEY_EXCLUSIVE_INSTALLATION} as a key.
 * 2. If it equals "true", it will do exclusive installation, which means that
 * the bundles will not be listed in the specified url but installed at the time
 * of the method call except SystemBundle will be uninstalled. Otherwise, no
 * uninstallation will not be done.
 */
public class SimpleConfiguratorImpl implements Configurator {

	private static URL configurationURL = null;
	private static Object configurationLock = new Object();

	private BundleContext context;
	private ConfigApplier configApplier;
	private Bundle bundle;

	//for change detection in the base when running in shared install mode
	private static final long NO_TIMESTAMP = -1;
	public static final String BASE_TIMESTAMP_FILE_BUNDLESINFO = ".baseBundlesInfoTimestamp"; //$NON-NLS-1$
	public static final String KEY_BUNDLESINFO_TIMESTAMP = "bundlesInfoTimestamp";
	public static final String KEY_EXT_TIMESTAMP = "extTimestamp";
	public static final String PROP_IGNORE_USER_CONFIGURATION = "eclipse.ignoreUserConfiguration"; //$NON-NLS-1$

	public SimpleConfiguratorImpl(BundleContext context, Bundle bundle) {
		this.context = context;
		this.bundle = bundle;
	}

	public URL getConfigurationURL() throws IOException {
		String specifiedURL = context.getProperty(SimpleConfiguratorConstants.PROP_KEY_CONFIGURL);
		if (specifiedURL == null)
			specifiedURL = "file:" + SimpleConfiguratorConstants.CONFIGURATOR_FOLDER + "/" + SimpleConfiguratorConstants.CONFIG_LIST;

		try {
			//If it is not a file URL use it as is
			if (!specifiedURL.startsWith("file:"))
				return new URL(specifiedURL);
		} catch (MalformedURLException e) {
			return null;
		}

		try {
			// if it is an absolute file URL, use it as is
			boolean done = false;
			URL url = null;
			String file = specifiedURL;
			while (!done) {
				// TODO what is this while loop for?  nested file:file:file: urls?
				try {
					url = Utils.buildURL(file);
					file = url.getFile();
				} catch (java.net.MalformedURLException e) {
					done = true;
				}
			}
			if (url != null && new File(url.getFile()).isAbsolute())
				return url;

			//if it is an relative file URL, then resolve it against the configuration area
			// TODO Support relative file URLs when not on Equinox
			URL[] configURL = EquinoxUtils.getConfigAreaURL(context);

			URL result = chooseConfigurationURL(url, configURL);
			if (result != null) {
				return result;
			}
		} catch (MalformedURLException e) {
			return null;
		}

		//Last resort
		try {
			return Utils.buildURL(specifiedURL);
		} catch (MalformedURLException e) {
			//Ignore
		}

		return null;
	}

	/**
	 * This method is public for testing purposes only.
	 * @param relativeURL - a relative URL of the configuration
	 * @param configURL - an array of parent config URLs to which relativeURL can be appended. 
	 */
	public URL chooseConfigurationURL(URL relativeURL, URL[] configURL) throws MalformedURLException {
		if (configURL != null) {
			File userConfig = new File(configURL[0].getFile(), relativeURL.getFile());
			if (configURL.length == 1)
				return userConfig.exists() ? userConfig.toURL() : null;

			File sharedConfig = new File(configURL[1].getFile(), relativeURL.getFile());
			if (!userConfig.exists())
				return sharedConfig.exists() ? sharedConfig.toURL() : null;

			if (!sharedConfig.exists())
				return userConfig.toURL();

			if (Boolean.TRUE.toString().equals(System.getProperty(PROP_IGNORE_USER_CONFIGURATION)))
				return sharedConfig.toURL();

			long[] sharedBundlesInfoTimestamp = getCurrentBundlesInfoBaseTimestamp(sharedConfig);
			long[] lastKnownBaseTimestamp = getLastKnownBundlesInfoBaseTimestamp(userConfig.getParentFile());

			if ((lastKnownBaseTimestamp[0] == sharedBundlesInfoTimestamp[0] && lastKnownBaseTimestamp[1] == sharedBundlesInfoTimestamp[1]) || lastKnownBaseTimestamp[0] == NO_TIMESTAMP) {
				return userConfig.toURL();
			} else {
				System.setProperty(PROP_IGNORE_USER_CONFIGURATION, Boolean.TRUE.toString());
				return sharedConfig.toURL();
			}
		}
		return null;
	}

	private long[] getLastKnownBundlesInfoBaseTimestamp(File configFolder) {
		long[] result = new long[] {NO_TIMESTAMP, NO_TIMESTAMP};
		File storedSharedTimestamp = new File(configFolder, BASE_TIMESTAMP_FILE_BUNDLESINFO);
		if (!storedSharedTimestamp.exists())
			return result;

		Properties p = new Properties();
		InputStream is = null;
		try {
			try {
				is = new BufferedInputStream(new FileInputStream(storedSharedTimestamp));
				p.load(is);
				if (p.get(KEY_BUNDLESINFO_TIMESTAMP) != null) {
					result[0] = Long.valueOf((String) p.get(KEY_BUNDLESINFO_TIMESTAMP)).longValue();
				}
				if (p.get(KEY_EXT_TIMESTAMP) != null) {
					result[1] = Long.valueOf((String) p.get(KEY_EXT_TIMESTAMP)).longValue();
				}
			} finally {
				is.close();
			}
		} catch (IOException e) {
			return result;
		}
		return result;
	}

	public static long[] getCurrentBundlesInfoBaseTimestamp(File sharedBundlesInfo) {
		if (!sharedBundlesInfo.exists())
			return new long[] {NO_TIMESTAMP, NO_TIMESTAMP};
		long lastModified = sharedBundlesInfo.lastModified();
		long extLastModified = SimpleConfiguratorUtils.getExtendedTimeStamp();
		return new long[] {lastModified, extLastModified};
	}

	public void applyConfiguration(URL url) throws IOException {
		synchronized (configurationLock) {
			if (Activator.DEBUG)
				System.out.println("applyConfiguration() URL=" + url);
			if (url == null)
				return;
			configurationURL = url;

			if (this.configApplier == null)
				configApplier = new ConfigApplier(context, bundle);
			configApplier.install(url, isExclusiveInstallation());
		}
	}

	private boolean isExclusiveInstallation() {
		String value = context.getProperty(SimpleConfiguratorConstants.PROP_KEY_EXCLUSIVE_INSTALLATION);
		if (value == null || value.trim().length() == 0)
			value = "true";
		return Boolean.parseBoolean(value);
	}

	public void applyConfiguration() throws IOException {
		synchronized (configurationLock) {
			configurationURL = getConfigurationURL();
			applyConfiguration(configurationURL);
		}
	}

	public URL getUrlInUse() {
		synchronized (configurationLock) {
			return configurationURL;
		}
	}
}

Back to the top