/******************************************************************************
* Copyright (c) 2009-2013, Linagora
*
* 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:
* Linagora - initial API and implementation
*******************************************************************************/
package com.ebmwebsourcing.petals.server;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.wst.server.core.IRuntimeType;
import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
import org.eclipse.wst.server.core.ServerCore;
import org.eclipse.wst.server.core.model.RuntimeLocatorDelegate;
import com.ebmwebsourcing.petals.server.runtime.IPetalsRuntimeWorkingCopy;
/**
* @author Vincent Zurczak - EBM WebSourcing
*/
public class PetalsRuntimeLocator extends RuntimeLocatorDelegate {
/*
* (non-Javadoc)
* @see org.eclipse.wst.server.core.model.RuntimeLocatorDelegate
* #searchForRuntimes(org.eclipse.core.runtime.IPath,
* org.eclipse.wst.server.core.model.RuntimeLocatorDelegate.IRuntimeSearchListener,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public void searchForRuntimes(
IPath path,
IRuntimeSearchListener listener,
IProgressMonitor monitor ) {
File rootFile = path == null ? null : path.toFile();
searchDirectory( rootFile, true, monitor, 0, listener );
}
private static final Pattern SEARCH_PATTERN = Pattern.compile( ".*petals.*", Pattern.CASE_INSENSITIVE );
/**
* Gets all the Petals runtime contained in this directory.
*
* @param rootFile the root file to introspect (null to search from the disk roots)
* @param searchRecursively true to search sub-folders
* @param monitor a progress monitor
* @param depth the file depth with respect to the root file (should be zero, then used internally)
* @param listener the search listener (may be null)
* @return a list (never null) of {@link IRuntimeWorkingCopy}
*/
public static List<IRuntimeWorkingCopy> searchDirectory(
File rootFile,
boolean searchRecursively,
IProgressMonitor monitor,
int depth,
IRuntimeSearchListener listener ) {
List<IRuntimeWorkingCopy> result = new ArrayList<IRuntimeWorkingCopy> ();
if( monitor.isCanceled())
return result;
// Get the directories
File[] files = new File[ 0 ];
if( rootFile == null ) {
files = File.listRoots();
depth = 0;
} else if( rootFile.exists()) {
files = rootFile.listFiles( new FileFilter() {
public boolean accept( File pathname ) {
return pathname.isDirectory();
}
});
}
// Check every directory
for( File f : files ) {
if( SEARCH_PATTERN.matcher( f.getName()).matches()
&& new File( f, "conf/server.properties" ).exists()
&& new File( f, "conf/topology.xml" ).exists()) {
monitor.subTask( "Checking " + f.getAbsolutePath() + "..." );
IRuntimeWorkingCopy wc = getRuntimeFromDir( f, monitor );
if( wc != null ) {
result.add( wc );
if( listener != null )
listener.runtimeFound( wc );
}
} else if( searchRecursively ) {
// Limit the message display to "high" directories - so that it is readable
if( depth < 2 )
monitor.subTask( "Inspecting " + f.getAbsolutePath() + "..." );
List<IRuntimeWorkingCopy> res = searchDirectory( f, true, monitor, depth + 1, listener );
result.addAll( res );
}
}
return result;
}
/**
* Creates a {@link IRuntimeWorkingCopy} from a directory.
* <p>
* The returned instance is initialized:
* </p>
* <ul>
* <li>No name (default one, or set one).</li>
* <li>Install path is set.</li>
* <li>Default VM.</li>
* </ul>
*
* @param dir a directory that meets the criteria to be a Petals install directory
* @param monitor a progress monitor
* @return an instance of {@link IRuntimeWorkingCopy}, or null if none was found
*/
private static IRuntimeWorkingCopy getRuntimeFromDir( File dir, IProgressMonitor monitor ) {
IRuntimeWorkingCopy runtime = null;
String runtimeTypeId = "com.ebmwebsourcing.petals.server.runtime.";
// Get the version from the directory name
Pattern pattern = Pattern.compile( "\\d\\.\\d", Pattern.CASE_INSENSITIVE );
Matcher matcher = pattern.matcher( dir.getName());
if( matcher.find()) {
// Keep only the first digit (3x instead of 3.0)
String version = matcher.group().charAt( 0 ) + "x";
runtimeTypeId += version;
} else {
PetalsServerPlugin.log(
"Could not determine the Petals version from the directory name ("
+ dir.getAbsolutePath() + ").",
IStatus.WARNING );
}
// Instantiate a runtime working copy
IRuntimeType runtimeType = ServerCore.findRuntimeType( runtimeTypeId );
if( runtimeType != null ) {
String absolutePath = dir.getAbsolutePath();
String id = absolutePath.replace( File.separatorChar,'_' ).replace( ':','-' );
try {
runtime = runtimeType.createRuntime( id, monitor );
runtime.setLocation( new Path( dir.getAbsolutePath()));
IPetalsRuntimeWorkingCopy wc =
(IPetalsRuntimeWorkingCopy) runtime.loadAdapter( IPetalsRuntimeWorkingCopy.class, null );
if( wc != null )
wc.setVMInstall( JavaRuntime.getDefaultVMInstall());
} catch( CoreException e ) {
PetalsServerPlugin.log( e, IStatus.WARNING );
}
}
return runtime;
}
}