blob: e99628d3f9f0701f0cb09aa3dcd0a1b156314cbc [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.importing.services;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.types.FileSet;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.XMLUtil;
import org.eclipse.epf.export.services.LibraryDocument;
import org.eclipse.epf.importing.ImportPlugin;
import org.eclipse.epf.importing.ImportResources;
import org.eclipse.epf.library.services.LibraryProcessor;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import com.ibm.uma.MethodConfiguration;
import com.ibm.uma.MethodPlugin;
/**
* Imports a method plug-in into the current library.
*
* @author Jinhua Xi
* @since 1.0
*/
public class PluginImportingService {
private PluginImportData data;
LibraryDocument importingLibDoc;
public PluginImportingService(PluginImportData data) {
this.data = data;
}
/**
* Validates the plug-in against the current library, collects all the
* informations including plug-in info, configuation info and error info.
* Call this method, then call getError(), getPlugins(), getConfigs().
*/
public void validate(IProgressMonitor monitor) {
try {
if (monitor != null) {
monitor.setTaskName(ImportResources
.getString("Import.PluginImportingService.MSG0")); //$NON-NLS-1$
}
if (this.data == null) {
return;
}
this.data.clear();
// Prepare the lib files.
File importingLibPath = new File(data.llData.getParentFolder()
+ File.separator + LibraryDocument.exportFile);
if (!importingLibPath.exists()) {
data
.getErrorInfo()
.addError(
ImportResources
.getString(
"Import.PluginImportingService.MSG1", importingLibPath.toString())); //$NON-NLS-1$
return;
}
importingLibDoc = new LibraryDocument(importingLibPath);
scanLibraryFile(importingLibDoc);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void performImport(IProgressMonitor monitor) {
try {
if (monitor != null) {
monitor.setTaskName(ImportResources
.getString("Import.PluginImportingService.MSG3")); //$NON-NLS-1$
}
// To import the plug-ins, we need to do the following:
// 1. Delete the plug-ins in the current library if user specify
// remove
// 2. Copy the selected plugin files to the destination
// 3. Update the library.xmi
// 4. Reload the library
File libFile = new File(LibraryProcessor.getInstance()
.getLibraryURI().toFileString());
LibraryDocument targetLibDoc = new LibraryDocument(libFile);
// Remove existing entries.
removeExistingEntries(targetLibDoc);
// Import entries and copy files.
importEntries(targetLibDoc);
// Save the updated library file.
targetLibDoc.save();
// Replace the guid of the old MethodLibrary with the new one.
fixLibraryGuid(libFile.getParentFile(), importingLibDoc
.getLibraryGuid(), targetLibDoc.getLibraryGuid());
// Reopen the library.
LibraryProcessor.getInstance().openLibrary(
libFile.getAbsolutePath());
} catch (Exception e) {
ImportPlugin.getDefault().getLogger().logError(e);
}
}
private void importEntries(LibraryDocument targetLibDoc) {
// 1. Find the entries to be removed.
List importList = new ArrayList();
PluginImportData.PluginInfo info;
for (Iterator it = data.getPlugins().iterator(); it.hasNext();) {
info = (PluginImportData.PluginInfo) it.next();
if (info.selected) {
importList.add(info.guid);
}
}
PluginImportData.ConfiguarationInfo cinfo;
for (Iterator it = data.getConfigs().iterator(); it.hasNext();) {
cinfo = (PluginImportData.ConfiguarationInfo) it.next();
if (cinfo.selected) {
importList.add(cinfo.guid);
}
}
// 2. Iterate the docuemnt and add the new entries.
importLibEntries(targetLibDoc, importList);
importResourceEntries(targetLibDoc, importList);
}
private void importLibEntries(LibraryDocument targetLibDoc, List importList) {
// Add plug-ins.
NodeList nodes = importingLibDoc.getPlugins();
for (int i = 0; i < nodes.getLength(); i++) {
Element node = (Element) nodes.item(i);
String guid = node.getAttribute("xmi:id"); //$NON-NLS-1$
if (importList.contains(guid)) {
targetLibDoc.addPlugin(node);
}
}
// Add configurations.
nodes = importingLibDoc.getConfigurations();
for (int i = 0; i < nodes.getLength(); i++) {
Element node = (Element) nodes.item(i);
String guid = node.getAttribute("xmi:id"); //$NON-NLS-1$
if (importList.contains(guid)) {
targetLibDoc.addConfiguration(node);
}
}
}
private void importResourceEntries(LibraryDocument targetLibDoc,
List importList) {
NodeList nodes = importingLibDoc.getResourceDescriptors();
for (int i = 0; i < nodes.getLength(); i++) {
Element node = (Element) nodes.item(i);
String guid = node.getAttribute(LibraryDocument.ATTR_id);
String uri = node.getAttribute(LibraryDocument.ATTR_uri);
if (importList.contains(guid)) {
targetLibDoc.addResource(node);
// Check the plugin.xmi file. If it exists, copy the folder to
// the destination directory.
File plugn_file = importingLibDoc.getFileFromUri(uri);
if (plugn_file.exists()) {
File plugn_target = targetLibDoc.getFileFromUri(uri);
copyDir(plugn_file.getParentFile(), plugn_target
.getParentFile());
}
}
}
// Add the resource sub managers.
nodes = importingLibDoc.getResourceSubManagers();
for (int i = 0; i < nodes.getLength(); i++) {
Element node = (Element) nodes.item(i);
String guid = LibraryDocument.getSubManagerBaseGuid(node
.getAttribute(LibraryDocument.ATTR_href));
if (importList.contains(guid)) {
targetLibDoc.addResource(node);
}
}
}
public static void copyDir(File fromDir, File toDir) {
Copy cp = new Copy();
cp.setOverwrite(true);
FileSet set = new FileSet();
set.setDir(fromDir);
cp.addFileset(set);
cp.setTodir(toDir);
cp.setProject(new Project());
cp.execute();
}
/**
* remove the plugin entry from the library document
*
* @param document
* LibraryDocument
* @param guid
* String guid of the plugin
*/
private void removeExistingEntries(LibraryDocument document) {
// 1. Find the entries to be removed.
List removeList = new ArrayList();
PluginImportData.PluginInfo info;
for (Iterator it = data.getPlugins().iterator(); it.hasNext();) {
info = (PluginImportData.PluginInfo) it.next();
if ((info.existingPlugin != null) && info.selected) {
removeList.add(info.guid);
}
}
PluginImportData.ConfiguarationInfo cinfo;
for (Iterator it = data.getConfigs().iterator(); it.hasNext();) {
cinfo = (PluginImportData.ConfiguarationInfo) it.next();
if ((cinfo.existingConfig != null) && cinfo.selected) {
removeList.add(cinfo.guid);
}
}
// 2. Iterate the docuemnt and remove the entries.
document.removePlugins(removeList);
document.removeConfigurations(removeList);
document.removeResourceEntries(removeList);
}
public String validateSelection() {
data.getErrorInfo().clear();
// Iterate the new plugins, make sure the base is included
// either as an importing plugin, or is in the current library
// get the method plugins in the current library.
List plugins = LibraryProcessor.getInstance().getMethodModels();
List pluginids = new ArrayList();
for (Iterator it = plugins.iterator(); it.hasNext();) {
pluginids.add(((MethodPlugin) it.next()).getGuid());
}
// The base plug-ins MUST be either a selected one or an existing one
// otherwise, can't import
List basePlugins = new ArrayList();
List newPlugins = new ArrayList();
for (Iterator it = data.getPlugins().iterator(); it.hasNext();) {
PluginImportData.PluginInfo info = (PluginImportData.PluginInfo) it
.next();
if (info.selected && (info.existingPlugin == null)) {
newPlugins.add(info.guid);
for (Iterator itb = info.usedPlugins.iterator(); itb.hasNext();) {
Object base = itb.next();
if (!basePlugins.contains(base)) {
basePlugins.add(base);
}
}
}
}
if (newPlugins.size() > 0) {
for (Iterator it = basePlugins.iterator(); it.hasNext();) {
String guid = (String) it.next();
String uri = (String) data.basePluginUrlMap.get(guid);
if (!newPlugins.contains(guid) && !pluginids.contains(guid)) {
String message;
if (uri != null && uri.length() > 0) {
message = ImportResources.getString(
"Import.PluginImportingService.MSG5", uri); //$NON-NLS-1$
} else {
message = ImportResources
.getString("Import.PluginImportingService.MSG6"); //$NON-NLS-1$
}
data.getErrorInfo().addError(message);
if (uri == null || uri.length() == 0) {
break;
}
}
}
}
return data.getErrorInfo().getError();
}
private void scanLibraryFile(LibraryDocument document) {
visitLibTag(document);
visitResourceTag(document);
data.validatePlugins();
// Check base plug-in dependencies.
for (Iterator it = data.getPlugins().iterator(); it.hasNext();) {
PluginImportData.PluginInfo info = (PluginImportData.PluginInfo) it
.next();
if (info.existingPlugin == null) {
for (Iterator itbase = info.usedPlugins.iterator(); itbase
.hasNext();) {
String guid = (String) itbase.next();
if (!data.basePluginUrlMap.containsKey(guid)) {
data.basePluginUrlMap.put(guid, "");
}
}
}
}
}
private void visitLibTag(LibraryDocument document) {
// Reload the element mapping.
NodeList nodes = document.getPlugins();
for (int i = 0; i < nodes.getLength(); i++) {
Element node = (Element) nodes.item(i);
PluginImportData.PluginInfo pi = data.new PluginInfo();
pi.guid = node.getAttribute("xmi:id"); //$NON-NLS-1$
data.getPlugins().add(pi);
// Check with the current library, get the related information.
loadExistingPluginInfo(pi);
}
// Remove the unneeded configurations.
nodes = document.getConfigurations();
for (int i = 0; i < nodes.getLength(); i++) {
Element node = (Element) nodes.item(i);
PluginImportData.ConfiguarationInfo ci = data.new ConfiguarationInfo();
ci.guid = node.getAttribute("xmi:id"); //$NON-NLS-1$
ci.name = node.getAttribute("name"); //$NON-NLS-1$
data.getConfigs().add(ci);
// Check with the current library, get the related information.
loadExistingConfigInfo(ci);
}
}
private void visitResourceTag(LibraryDocument document) {
NodeList nodes = document.getResourceDescriptors();
for (int i = 0; i < nodes.getLength(); i++) {
Element node = (Element) nodes.item(i);
String guid = node.getAttribute(LibraryDocument.ATTR_id);
PluginImportData.PluginInfo pi = data.getPluginInfo(guid);
if (pi != null) {
String uri = node.getAttribute(LibraryDocument.ATTR_uri);
// Load the plugin.xmi file for detail information.
File plugn_file = document.getFileFromUri(uri);
if (plugn_file.exists()) {
loadPluginInfo(plugn_file, pi);
} else {
// Remove the plug-in info entry since thias is not
// a valid plug-in to import.
data.removePluginInfo(guid);
}
}
}
}
protected void loadPluginInfo(File source, PluginImportData.PluginInfo info) {
try {
Document document = XMLUtil.loadXml(source);
Element root = document.getDocumentElement();
Element pluginTag = null;
if (root.getTagName().equals("com.ibm.uma:MethodPlugin")) //$NON-NLS-1$
{
pluginTag = root;
} else {
NodeList nodes = root
.getElementsByTagName("com.ibm.uma:MethodPlugin"); //$NON-NLS-1$
if (nodes.getLength() > 0) {
pluginTag = (Element) nodes.item(0);
}
}
if (pluginTag != null) {
info.name = pluginTag.getAttribute("name"); //$NON-NLS-1$
info.version = LibraryDocument.getChildValue(pluginTag,
"version"); //$NON-NLS-1$
info.brief_desc = LibraryDocument.getChildValue(pluginTag,
"briefDescription"); //$NON-NLS-1$
info.authors = LibraryDocument.getChildValue(pluginTag,
"authors"); //$NON-NLS-1$
info.changeDate = LibraryDocument.getChildValue(pluginTag,
"changeDate"); //$NON-NLS-1$
info.url = source.toString();
// Get the base plug-ins.
NodeList nodes = pluginTag.getElementsByTagName("bases"); //$NON-NLS-1$
for (int i = 0; i < nodes.getLength(); i++) {
Element node = (Element) nodes.item(i);
String guid = node.getAttribute(LibraryDocument.ATTR_href);
int indx = guid.indexOf("#"); //$NON-NLS-1$
if (indx > 0) {
guid = guid.substring(indx + 1);
} else {
indx = guid.indexOf("uma://"); //$NON-NLS-1$
if (indx >= 0) {
guid = guid.substring(indx + 6);
}
}
info.usedPlugins.add(guid);
}
}
} catch (Exception e) {
ImportPlugin.getDefault().getLogger().logError(e);
}
}
private void loadExistingPluginInfo(PluginImportData.PluginInfo info) {
List plugins = LibraryProcessor.getInstance().getMethodModels();
for (Iterator it = plugins.iterator(); it.hasNext();) {
MethodPlugin plugin = (MethodPlugin) it.next();
if (plugin.getGuid().equals(info.guid)) {
info.existingPlugin = plugin;
}
}
}
private void loadExistingConfigInfo(PluginImportData.ConfiguarationInfo info) {
MethodConfiguration[] configs = LibraryProcessor.getInstance()
.getConfigurations();
if (configs == null || configs.length == 0) {
return;
}
for (int i = 0; i < configs.length; i++) {
MethodConfiguration config = configs[i];
if (config.getGuid().equals(info.guid)) {
info.existingConfig = config;
}
}
}
/**
* Replaces the guid of the old method library with the new one.
* <p>
* Search for the following files: library.xmi, plugin.xmi, model.xmi.
*/
private void fixLibraryGuid(File path, String oldGuid, String newGuid) {
if (!path.isDirectory()) {
return;
}
File[] files = path.listFiles(new FileFilter() {
public boolean accept(File f) {
if (f.isDirectory()) {
return true;
}
String name = f.getName();
return name.equals("library.xmi") || name.equals("plugin.xmi") || name.equals("model.xmi"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
});
if (files == null || files.length == 0) {
return;
}
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
fixLibraryGuid(files[i], oldGuid, newGuid);
} else {
// Read in the file, update it and save the file.
try {
String source = FileUtil.readFile(files[i],
FileUtil.ENCODING_UTF_8).toString();
if (source.indexOf(oldGuid) >= 0) {
// TODO: This is a regexp repalcement, is it safe?
source = source.replaceAll(oldGuid, newGuid);
FileUtil.writeUTF8File(files[i].getAbsolutePath(),
source);
}
} catch (IOException e) {
ImportPlugin.getDefault().getLogger().logError(e);
}
}
}
}
}