/* * 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.launching; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.PrintWriter; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import net.rim.ejde.internal.launching.JavaVMChecker.JavaVMCheckResult; import net.rim.ejde.internal.util.CompatibilityVersion; import net.rim.ejde.internal.util.Messages; import org.apache.log4j.Logger; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.objectweb.asm.ClassReader; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.tree.ClassNode; /** * A utility class to check MDS-CS version and Java version, and determine if the MDS-CS can be launched. It also updates the * MDS-CS launch batch file. * * @author dmeng * */ public class MDSCSChecker { // OK: launch MDS-CS without problem // CANCEL: stop launching // DISABLE_MDSCS: launching with disabled MDS-CS public static enum MDSCSCheckResult { OK, CANCEL, DISABLE_MDSCS } private static Logger _logger = Logger.getLogger( MDSCSChecker.class ); private static int _userDecision = -1; private static String _currentVersion; /*** * Check if required version of Java can be found for launching MDS-CS * * @param MDSHomePath * The MDS-CS home path * @return <code>true</code> continue this launching session, otherwise <code>false</code>. */ public static MDSCSCheckResult checkMDSCS( File MDSHomePath ) { String dialogTitle = "", dialogMessage = ""; //$NON-NLS-1$ JavaVMCheckResult javaVMResult = null; // Get version of current MDS-CS CompatibilityVersion mdscsVersion = getMDSCSVersion( MDSHomePath ); // if MDS-CS version is null, warn user that MDS-CS can not be found if( mdscsVersion == null ) { dialogTitle = Messages.FledgeLaunchConfigurationDelegate_noMDSCSMsg; } else { // if versions of MDS-CS is equal or greater than 4.1.5, Java 1.6 is // required CompatibilityVersion mdscs415Version = new CompatibilityVersion( "4.1.5" ); //$NON-NLS-1$ String requiredJavaVersion; if( mdscsVersion.compareTo( mdscs415Version ) >= 0 ) { requiredJavaVersion = "1.6"; //$NON-NLS-1$ } else { requiredJavaVersion = "1.5"; //$NON-NLS-1$ } javaVMResult = JavaVMChecker.getInstance().checkJavaVM( requiredJavaVersion, JavaVMChecker.CHECK_TYPE_GREATEROREQUAL ); //$NON-NLS-1$ if( javaVMResult == null ) { // required version of Java can not be found in system. dialogTitle = Messages.FledgeLaunchConfigurationDelegate_noLaunchMDSCSMsg; dialogMessage = NLS.bind( Messages.FledgeLaunchConfigurationDelegate_noJavaMDSCSMsg, requiredJavaVersion ); } } if( javaVMResult == null ) { // either MDS-CS is not found or required Java to run MDS-CS is not // found dialogMessage = dialogMessage + NLS.bind( Messages.FledgeLaunchConfigurationDelegate_clickNoMDSCSMsg, IDialogConstants.PROCEED_LABEL, IDialogConstants.STOP_LABEL ); askUserDecision( dialogTitle, dialogMessage ); if( _userDecision == 0 ) { // continue launching return MDSCSCheckResult.DISABLE_MDSCS; } else { return MDSCSCheckResult.CANCEL; } } // required version of Java has been found if( javaVMResult.getLocationType() != JavaVMCheckResult.LOCATION_ENV_JAVA_HOME ) { if( !isJavaHomeEnvEmpty() || ( javaVMResult.getLocationType() != JavaVMCheckResult.LOCATION_ENV_PATH ) ) { updateBatchFiles( MDSHomePath, javaVMResult ); } } return MDSCSCheckResult.OK; } private static boolean isJavaHomeEnvEmpty() { String javaHomeDir = System.getenv( "JAVA_HOME" ); //$NON-NLS-1$ if( javaHomeDir != null ) { javaHomeDir = javaHomeDir.trim(); } return ( javaHomeDir == null ) || ( javaHomeDir.length() == 0 ); } private static void updateBatchFiles( File MDSHome, JavaVMCheckResult javaVMResult ) { try { String javaExePath; if( javaVMResult.getLocationType() == JavaVMCheckResult.LOCATION_ENV_PATH ) { // required Java is found in path environment variable. javaExePath = "java.exe"; //$NON-NLS-1$ } else { // required Java must be found in window registry javaExePath = javaVMResult.getJavaHomeDir() + "\\bin\\java.exe"; //$NON-NLS-1$ } // for run.bat String runBatFilePath = MDSHome.getCanonicalPath() + "\\run.bat"; //$NON-NLS-1$ backup( runBatFilePath ); PrintWriter runBatWriter = new PrintWriter( new FileOutputStream( runBatFilePath ) ); runBatWriter.println( "@ECHO OFF" ); //$NON-NLS-1$ runBatWriter.println( "call setBMDSEnv" ); //$NON-NLS-1$ runBatWriter .println( "start cmd /v:on /c \"" //$NON-NLS-1$ + javaExePath + "\" -classpath !BMDS_CLASSPATH!;!BMDS_CLASSPATH2! -Xmx512M -Djava.endorsed.dirs=classpath\\endorsed -DKeystore.Password=password net.rim.application.ipproxyservice.IPProxyServiceApplication -log.console.dump" ); //$NON-NLS-1$ runBatWriter.println( ":END" ); //$NON-NLS-1$ runBatWriter.flush(); runBatWriter.close(); // for event.bat String eventBatFilePath = MDSHome.getCanonicalPath() + "\\event.bat"; //$NON-NLS-1$ backup( eventBatFilePath ); PrintWriter eventBatWriter = new PrintWriter( new FileOutputStream( eventBatFilePath ) ); eventBatWriter.println( "@ECHO OFF" ); //$NON-NLS-1$ eventBatWriter.println( "IF /I NOT [%BMDS_ENV_SET%] == [true] call setBMDSEnv" ); //$NON-NLS-1$ eventBatWriter .println( "\"" //$NON-NLS-1$ + javaExePath + "\" -classpath %BMDS_CLASSPATH% net.rim.application.ipproxyservice.IPProxyEvent %1 %2 %3 %4 %5 %6 %7 %8 %9" ); //$NON-NLS-1$ eventBatWriter.flush(); eventBatWriter.close(); } catch( Exception ex ) { _logger.error( "updateBatchFiles exception:" //$NON-NLS-1$ + ex.getMessage() ); } } private static void backup( String originalFilePath ) throws Exception { String backupFilePath = originalFilePath + ".ori"; File backupFile = new File( backupFilePath ); if( !backupFile.exists() ) { FileInputStream input = new FileInputStream( originalFilePath ); FileOutputStream output = new FileOutputStream( backupFile ); byte[] buffer = new byte[ 1024 * 4 ]; int len; while( ( len = input.read( buffer ) ) != -1 ) { output.write( buffer, 0, len ); } input.close(); output.close(); } } /*** * * @return return null if MDS-CS can not be found. Otherwise, corresponding version is returned */ private static CompatibilityVersion getMDSCSVersion( File MDSHome ) { CompatibilityVersion mdscsVersion = null; try { String bmdsJarPath = MDSHome.getPath() + File.separator + "classpath" + File.separator + "bmds.jar"; //$NON-NLS-1$ File bmdsJarFile = new File( bmdsJarPath ); if( bmdsJarFile.exists() ) { ZipFile zipFile = new ZipFile( bmdsJarFile ); Enumeration< ? > entries = zipFile.entries(); while( entries.hasMoreElements() ) { ZipEntry entry = (ZipEntry) entries.nextElement(); if( !entry.isDirectory() ) { _logger.debug( entry.getName() ); if( entry.getName().equalsIgnoreCase( "net/rim/application/ipproxyservice/Version.class" ) ) { //$NON-NLS-1$ // find Version class InputStream is = zipFile.getInputStream( entry ); String versionStr = getMDSCSVersion( is ); if( versionStr != null ) { org.osgi.framework.Version osgiVersion = new org.osgi.framework.Version( versionStr ); mdscsVersion = new CompatibilityVersion( osgiVersion.getMajor(), osgiVersion.getMinor(), osgiVersion.getMicro() ); } break; } } } // end of while } } catch( Exception ex ) { _logger.error( "getMDSCSVersion error:" + ex.getMessage() ); ////$NON-NLS-1$ } return mdscsVersion; } private static String getMDSCSVersion( InputStream inputStream ) { _currentVersion = null; // reset the value try { ClassReader classReader = new ClassReader( inputStream ); ClassNode myVisitor = new ClassNode() { public FieldVisitor visitField( int access, String name, String desc, String signature, Object value ) { if( value instanceof String ) { String[] parts = ( (String) value ).split( "\\." ); if( parts.length > 2 ) { _currentVersion = (String) value; } } return super.visitField( access, name, desc, signature, value ); } }; classReader.accept( myVisitor, ClassReader.SKIP_FRAMES ); } catch( Throwable ex ) { _logger.error( "", ex ); } return _currentVersion; } private static void askUserDecision( final String title, final String message ) { Display.getDefault().syncExec( new Runnable() { public void run() { Shell shell = new Shell(); MessageDialog dialog = new MessageDialog( shell, title, null, // accept the default window icon message, MessageDialog.WARNING, new String[] { IDialogConstants.PROCEED_LABEL, IDialogConstants.STOP_LABEL }, 0 ); // proceed // is the default _userDecision = dialog.open(); shell.dispose(); } } ); } }