package com.mobilesorcery.sdk.core;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
public class MoSyncExtensionManager {
public static class ExtensionAlreadyExistsException extends IOException {
private MoSyncExtension existing;
public ExtensionAlreadyExistsException(MoSyncExtension existing) {
this.existing = existing;
}
public MoSyncExtension getExisting() {
return existing;
}
}
private static final MoSyncExtensionManager INSTANCE = new MoSyncExtensionManager();
private TreeMap<String, MoSyncExtension> extensions = new TreeMap<String, MoSyncExtension>();
private MoSyncExtensionManager() {
refresh();
}
public void refresh() {
IPath extensionsPath = MoSyncTool.getDefault().getMoSyncExtensions();
File[] extensionPaths = extensionsPath.toFile().listFiles();
if (extensionPaths != null) {
for (File extensionPath : extensionPaths) {
MoSyncExtension extension = MoSyncExtension.findExtension(extensionPath.getName());
if (extension != null) {
String name = extension.getName();
extensions.put(name, extension);
}
}
}
}
public static MoSyncExtensionManager getDefault() {
return INSTANCE;
}
/**
* Returns the extension with a given name.
* @param extensionName
* @return {@code null} if the extension does not exist
*/
public MoSyncExtension getExtension(String extensionName) {
return extensions.get(extensionName);
}
/**
* Returns the {@code MoSyncExtension}s a project makes use of.
* @param project
* @return Never {@code null}
*/
public List<MoSyncExtension> getUsedExtensions(MoSyncProject project, IBuildVariant variant) {
IPropertyOwner properties = MoSyncBuilder.getPropertyOwner(project, variant.getConfigurationId());
ArrayList<MoSyncExtension> result = new ArrayList<MoSyncExtension>();
String[] extensionNames = PropertyUtil.getStrings(properties, MoSyncBuilder.EXTENSIONS);
for (String extensionName : extensionNames) {
MoSyncExtension extension = getExtension(extensionName);
if (extension != null) {
result.add(extension);
}
}
return result;
}
public List<MoSyncExtension> getExtensions() {
return new ArrayList<MoSyncExtension>(extensions.values());
}
/**
* Installs or updates an extension into MoSync
* @param extension The extension file, either a directory or a zip file
* @param forceUpdate If {@code true}, any existing extension with the same name will
* be overwritten
* @return
* @throws IOException
*/
public MoSyncExtension install(File extension, boolean forceUpdate) throws IOException {
if (!extension.exists()) {
throw new IOException("Extension does not exist at " + extension.getAbsolutePath());
}
String extensionInstallName = Util.getNameWithoutExtension(extension.getName());
if (!forceUpdate && MoSyncExtension.findExtension(extensionInstallName) != null) {
throw new ExtensionAlreadyExistsException(MoSyncExtension.findExtension(extensionInstallName));
}
File installLocation = MoSyncTool.getDefault()
.getMoSyncExtensions().append(new Path(extensionInstallName)).toFile();
MoSyncExtension.validateInExtensionsDir(installLocation);
removeExtensionDir(installLocation);
if (extension.isDirectory()) {
validateExtensionToBeInstalled(extension);
Util.copy(new NullProgressMonitor(), extension,
installLocation, null);
} else {
File tmp = new File(installLocation.getAbsoluteFile() + "~");
removeExtensionDir(tmp);
Util.unzip(extension, tmp);
try {
validateExtensionToBeInstalled(tmp);
} catch (Exception e) {
removeExtensionDir(tmp);
}
tmp.renameTo(installLocation);
}
MoSyncExtension result = MoSyncExtension.findExtension(extensionInstallName);
if (result == null) {
throw new IOException("Installation of extension failed");
}
refresh();
return result;
}
private void validateExtensionToBeInstalled(File extension) throws IOException {
MoSyncExtension.validateInstallable(extension);
}
public void uninstall(MoSyncExtension extension) throws IOException {
if (!removeExtensionDir(extension.getExtensionRoot().toFile())) {
throw new IOException("Unable to install extension " + extension);
}
extensions.remove(extension.getName());
}
private boolean removeExtensionDir(File installLocation) {
return Util.deleteFiles(installLocation, null, 8, new NullProgressMonitor());
}
public static boolean supportsExtensions() {
return MoSyncTool.getDefault().getBinary("extcomp").toFile().exists();
}
}