/*
* Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License, Version 1.0,
* which accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*
*/
package net.rim.ejde.internal.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
/**
* A utility class provides static methods to read windows Registry.
*
*/
public class WindowsRegistryReader {
private static Logger log = Logger.getLogger( WindowsRegistryReader.class );
private static final String REGQUERY_UTIL = "reg query ";
private static final String REGSTR_TOKEN = "REG_SZ";
private static final String JDE_INSTALL_CMD = REGQUERY_UTIL
+ "\"HKLM\\SOFTWARE\\Research In Motion\\BlackBerry Handheld JDE\"";
private static final String JDE_COMPONENT_INSTALL_CMD = REGQUERY_UTIL
+ "\"HKLM\\SOFTWARE\\Research In Motion\\BlackBerry JDE Components\"";
private static final String JDK_INSTALL_CMD = REGQUERY_UTIL + "\"HKLM\\SOFTWARE\\JavaSoft\\Java Development Kit\"";
private static final String VC2008_RUNTIME_CMD = REGQUERY_UTIL
+ "\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4}\"";
private static final String JDE_INSTALL_DIR_CMD = " /v InstallDir";
private static final String JDK_JAVA_HOME_DIR_CMD = " /v JavaHome";
private static final String VC2008_DISPLAYNAME_CMD = " /v DisplayName";
private Map< String, CompatibilityVersion > installedJDEMap;
private Map< String, CompatibilityVersion > installedJDKMap;
public WindowsRegistryReader() {
installedJDKMap = getInstalledJDKMap();
}
/**
* Returns the installed JDE paths from the Windows Registry.
*
* @return - Windows Registry JDE paths.
*/
public static List< String > getInstalledJDEPaths() {
List< String > paths = new ArrayList< String >();
List< String > registryPaths = getRegistryPaths( JDE_INSTALL_CMD );
for( String regPath : registryPaths ) {
String pathToAdd = getInstalledDir( regPath );
if( !paths.contains( pathToAdd ) )
paths.add( pathToAdd );
}
return paths;
}
/**
* Returns the installed JDE Components paths from the Windows Registry.
*
* @return - Windows Registry JDE Components paths.
*/
public static List< String > getInstalledJDEComponentsPaths() {
List< String > paths = new ArrayList< String >();
List< String > registryPaths = getRegistryPaths( JDE_COMPONENT_INSTALL_CMD );
for( String regPath : registryPaths ) {
String pathToAdd = getInstalledDir( regPath );
if( !paths.contains( pathToAdd ) )
paths.add( pathToAdd );
}
return paths;
}
/**
* Returns the installed JDK paths from the Windows Registry.
*
* @return - Windows Registry JDK paths.
*/
public static List< String > getInstalledJDKPaths() {
List< String > paths = new ArrayList< String >();
List< String > registryPaths = getRegistryPaths( JDK_INSTALL_CMD );
for( String regPath : registryPaths ) {
String pathToAdd = getJavaHomeDir( regPath );
if( !paths.contains( pathToAdd ) )
paths.add( pathToAdd );
}
return paths;
}
/**
* Returns true if VC2008 Runtime present in the Windows Registry.
*
* @return boolean
*/
public static boolean isVC2008RuntimeInstalled() {
String displayName = getRegistryPathString( VC2008_RUNTIME_CMD + VC2008_DISPLAYNAME_CMD );
if( displayName.indexOf( REGSTR_TOKEN ) != -1 ) {
return true;
}
return false;
}
private static List< String > getRegistryPaths( String key ) {
List< String > registryPaths = new ArrayList< String >();
String paths = getRegistryPathString( key );
String parsedPaths[] = paths.split( "\r\n" );
for( int i = 0; i < parsedPaths.length; i++ ) {
IPath check = new Path( parsedPaths[ i ] );
/*
* This check is to support reading in both XP and Vista. XP returns reg.exe version and root folder and paths as well
* as empty strings and Vista does not return any of these, simply returns the paths.
*/
if( check.segmentCount() >= 5 ) {
registryPaths.add( parsedPaths[ i ] );
}
}
return registryPaths;
}
private static String getInstalledDir( String regPath ) {
String result = getRegistryPathString( REGQUERY_UTIL + "\"" + regPath + "\"" + JDE_INSTALL_DIR_CMD );
int index = result.indexOf( REGSTR_TOKEN );
if( index == -1 )
return null;
return result.substring( index + REGSTR_TOKEN.length() ).trim();
}
private static String getJavaHomeDir( String regPath ) {
String result = getRegistryPathString( REGQUERY_UTIL + "\"" + regPath + "\"" + JDK_JAVA_HOME_DIR_CMD );
int index = result.indexOf( REGSTR_TOKEN );
if( index == -1 )
return null;
return result.substring( index + REGSTR_TOKEN.length() ).trim();
}
private static String getRegistryPathString( String path ) {
try {
Process process = Runtime.getRuntime().exec( path );
StreamReader reader = new StreamReader( process.getInputStream() );
reader.start();
process.waitFor();
reader.join();
String result = reader.getResult();
return result;
} catch( Exception e ) {
log.error( "Unable to Read Windows Registry." );
return null;
}
}
/*
* Private class to read inputStream.
*/
static class StreamReader extends Thread {
private InputStream is;
private StringWriter sw;
StreamReader( InputStream is ) {
this.is = is;
sw = new StringWriter();
}
public void run() {
try {
int c;
while( ( c = is.read() ) != -1 )
sw.write( c );
} catch( IOException e ) {
log.error( "Stream reaser failed to read from Windows Registry" );
}
}
String getResult() {
return sw.toString();
}
}
public static Map< String, CompatibilityVersion > getInstalledJDKMap() {
Map< String, CompatibilityVersion > paths = new HashMap< String, CompatibilityVersion >();
List< String > registryPaths = getRegistryPaths( JDK_INSTALL_CMD );
for( String regPath : registryPaths ) {
String pathToAdd = getJavaHomeDir( regPath );
IPath path = new Path( regPath );
try {
CompatibilityVersion compVer = new CompatibilityVersion( path.lastSegment() );
paths.put( pathToAdd, compVer );
} catch( IllegalArgumentException e ) {
log.error( "Invalid version format read from Registry", e );
}
}
return paths;
}
public CompatibilityVersion getJDEVersionFromPath( String JDEpath ) {
// Assuming map = Map<String, String>
for( Iterator< Map.Entry< String, CompatibilityVersion >> iter = installedJDEMap.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry< String, CompatibilityVersion > entry = iter.next();
String key = entry.getKey();
CompatibilityVersion value = entry.getValue();
if( key.equals( JDEpath ) ) {
return value;
}
}
return null;
}
public CompatibilityVersion getJDKVersionFromPath( String JDKpath ) {
// Assuming map = Map<String, String>
for( Iterator< Map.Entry< String, CompatibilityVersion >> iter = installedJDKMap.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry< String, CompatibilityVersion > entry = iter.next();
String key = entry.getKey();
CompatibilityVersion value = entry.getValue();
if( key.equals( JDKpath ) ) {
return value;
}
}
return null;
}
}