blob: 545be28f0ccd5e5faad4764e8d121e180d17f6d0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 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 API and implementation
*******************************************************************************/
package org.eclipse.equinox.internal.provisional.p2.ui;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Vector;
import javax.xml.parsers.*;
import org.eclipse.core.commands.*;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.internal.p2.ui.ProvUIActivator;
import org.eclipse.equinox.internal.p2.ui.ProvUIMessages;
import org.eclipse.equinox.internal.provisional.p2.director.ProvisioningPlan;
import org.eclipse.equinox.internal.provisional.p2.engine.InstallableUnitOperand;
import org.eclipse.equinox.internal.provisional.p2.engine.Operand;
import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.internal.provisional.p2.ui.model.ElementUtils;
import org.eclipse.equinox.internal.provisional.p2.ui.model.MetadataRepositoryElement;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.statushandlers.StatusManager;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
/**
* Utility methods involving compatibility with the Eclipse Update Manager.
*
* @since 3.4
*
*/
public class UpdateManagerCompatibility {
// This value was copied from MetadataGeneratorHelper. Must be the same.
private static final String ECLIPSE_INSTALL_HANDLER_PROP = "org.eclipse.update.installHandler"; //$NON-NLS-1$
// These values rely on the command markup in org.eclipse.ui.ide that defines the update commands
private static final String UPDATE_MANAGER_FIND_AND_INSTALL = "org.eclipse.ui.update.findAndInstallUpdates"; //$NON-NLS-1$
private static final String UPDATE_MANAGER_MANAGE_CONFIGURATION = "org.eclipse.ui.update.manageConfiguration"; //$NON-NLS-1$
private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
private static void parse(String fileName, Vector bookmarks) {
File file = new File(fileName);
if (!file.exists())
return;
try {
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder parser = documentBuilderFactory.newDocumentBuilder();
Document doc = parser.parse(file);
Node root = doc.getDocumentElement();
processRoot(root, bookmarks);
} catch (ParserConfigurationException e) {
logFail(e);
} catch (SAXException e) {
logFail(e);
} catch (IOException e) {
logFail(e);
}
}
private static MetadataRepositoryElement[] getSites(Vector bookmarks) {
ArrayList result = new ArrayList();
for (int i = 0; i < bookmarks.size(); i++) {
if (bookmarks.get(i) instanceof MetadataRepositoryElement)
result.add(bookmarks.get(i));
}
return (MetadataRepositoryElement[]) result.toArray(new MetadataRepositoryElement[result.size()]);
}
private static void processRoot(Node root, Vector bookmarks) {
if (root.getNodeName().equals("bookmarks")) { //$NON-NLS-1$
NodeList children = root.getChildNodes();
processChildren(children, bookmarks);
}
}
private static void processChildren(NodeList children, Vector bookmarks) {
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
if (child.getNodeName().equals("site")) { //$NON-NLS-1$
createSite(child, bookmarks);
} else if (child.getNodeName().equals("folder")) { //$NON-NLS-1$
createFolder(child, bookmarks);
}
}
}
}
private static void createSite(Node child, Vector bookmarks) {
URL url = null;
try {
url = new URL(getAttribute(child, "url")); //$NON-NLS-1$
} catch (MalformedURLException e) {
logFail(e);
return;
}
String sel = getAttribute(child, "selected"); //$NON-NLS-1$
boolean selected = (sel != null && sel.equals("true")); //$NON-NLS-1$
bookmarks.add(new MetadataRepositoryElement(url, selected));
}
private static void createFolder(Node child, Vector bookmarks) {
if (child.hasChildNodes())
processChildren(child.getChildNodes(), bookmarks);
}
private static String getAttribute(Node node, String name) {
NamedNodeMap atts = node.getAttributes();
Node att = atts.getNamedItem(name);
if (att != null) {
return att.getNodeValue();
}
return ""; //$NON-NLS-1$
}
private static void store(String fileName, Vector bookmarks) {
FileOutputStream fos = null;
OutputStreamWriter osw = null;
PrintWriter writer = null;
try {
fos = new FileOutputStream(fileName);
osw = new OutputStreamWriter(fos, "UTF8"); //$NON-NLS-1$
writer = new PrintWriter(osw);
writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
writer.println("<bookmarks>"); //$NON-NLS-1$
for (int i = 0; i < bookmarks.size(); i++) {
Object obj = bookmarks.get(i);
writeObject(" ", obj, writer); //$NON-NLS-1$
}
} catch (IOException e) {
logFail(e);
} finally {
writer.println("</bookmarks>"); //$NON-NLS-1$
writer.flush();
writer.close();
try {
if (osw != null)
osw.close();
} catch (IOException e1) {
logFail(e1);
}
try {
if (fos != null)
fos.close();
} catch (IOException e2) {
logFail(e2);
}
}
}
private static void writeObject(String indent, Object obj, PrintWriter writer) {
if (obj instanceof MetadataRepositoryElement) {
MetadataRepositoryElement element = (MetadataRepositoryElement) obj;
String sel = element.isEnabled() ? "true" : "false"; //$NON-NLS-1$ //$NON-NLS-2$
String name = element.getName();
writer.print(indent + "<site url=\"" + element.getLocation() + "\" selected=\"" + sel + "\" name=\"" + getWritableXMLString(name) + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
writer.println("/>"); //$NON-NLS-1$
}
}
public static boolean requiresInstallHandlerSupport(ProvisioningPlan plan) {
Operand[] operands = plan.getOperands();
for (int i = 0; i < operands.length; i++) {
if (operands[i] instanceof InstallableUnitOperand) {
IInstallableUnit iu = ((InstallableUnitOperand) operands[i]).second();
if (iu != null && iu.getProperty(ECLIPSE_INSTALL_HANDLER_PROP) != null)
return true;
}
}
return false;
}
/**
* Prompt the user for a file and import the sites specified in that
* file.
* @param shell the shell used to parent any dialogs used.
*/
public static void importSites(Shell shell) {
FileDialog dialog = new FileDialog(shell);
dialog.setText(ProvUIMessages.UpdateManagerCompatibility_ImportSitesTitle);
dialog.setFilterExtensions(new String[] {"*.xml", "*"}); //$NON-NLS-1$ //$NON-NLS-2$
MetadataRepositoryElement[] sites = null;
String bookmarksFile = dialog.open();
while (bookmarksFile != null && sites == null) {
File file = new File(bookmarksFile);
Vector bookmarks = new Vector();
parse(file.getAbsolutePath(), bookmarks);
sites = getSites(bookmarks);
if (sites == null || sites.length == 0) {
MessageDialog.openInformation(shell, ProvUIMessages.UpdateManagerCompatibility_InvalidSitesTitle, ProvUIMessages.UpdateManagerCompatibility_InvalidSiteFileMessage);
bookmarksFile = dialog.open();
} else {
ElementUtils.updateRepositoryUsingElements(getSites(bookmarks), shell);
}
}
}
/**
* Export the specified list of sites to a bookmarks file that
* can be read later.
*
* @param shell the shell used to parent the export dialog
* @param sites the sites to export
*/
public static void exportSites(Shell shell, MetadataRepositoryElement[] sites) {
FileDialog dialog = new FileDialog(shell, SWT.SAVE);
dialog.setText(ProvUIMessages.UpdateManagerCompatibility_ExportSitesTitle);
dialog.setFileName("bookmarks.xml"); //$NON-NLS-1$
String bookmarksFile = dialog.open();
if (bookmarksFile == null)
return;
Vector bookmarks = new Vector(sites.length);
for (int i = 0; i < sites.length; i++)
bookmarks.add(sites[i]);
store(bookmarksFile, bookmarks);
}
/**
* Open the old UpdateManager installer UI using the specified shell.
* We do not call the UpdateManagerUI class directly because we want to be able to be configured
* without requiring those plug-ins. Instead, we invoke a known command.
*/
public static void openInstaller() {
runCommand(UPDATE_MANAGER_FIND_AND_INSTALL, ProvUIMessages.UpdateManagerCompatibility_UnableToOpenFindAndInstall);
}
/**
* Open the old UpdateManager configuration manager UI using the specified shell.
* We do not call the UpdateManagerUI class directly because we want to be able to be configured
* without requiring those plug-ins. Instead, we invoke a known command.
*/
public static void openConfigurationManager() {
runCommand(UPDATE_MANAGER_MANAGE_CONFIGURATION, ProvUIMessages.UpdateManagerCompatibility_UnableToOpenManageConfiguration);
}
private static void runCommand(String commandId, String errorMessage) {
ICommandService commandService = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
Command command = commandService.getCommand(commandId);
if (!command.isDefined()) {
return;
}
IHandlerService handlerService = (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class);
try {
handlerService.executeCommand(commandId, null);
} catch (ExecutionException e) {
reportFail(errorMessage, e);
} catch (NotDefinedException e) {
reportFail(errorMessage, e);
} catch (NotEnabledException e) {
reportFail(errorMessage, e);
} catch (NotHandledException e) {
reportFail(errorMessage, e);
}
}
private static void logFail(Throwable t) {
Status failStatus = new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, t.getLocalizedMessage(), t);
ProvUI.reportStatus(failStatus, StatusManager.LOG);
}
private static void reportFail(String message, Throwable t) {
Status failStatus = new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, message, t);
ProvUI.reportStatus(failStatus, StatusManager.BLOCK | StatusManager.LOG);
}
private static String getWritableXMLString(String value) {
StringBuffer buf = new StringBuffer();
if (value == null)
return buf.toString();
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
switch (c) {
case '&' :
buf.append("&amp;"); //$NON-NLS-1$
break;
case '<' :
buf.append("&lt;"); //$NON-NLS-1$
break;
case '>' :
buf.append("&gt;"); //$NON-NLS-1$
break;
case '\'' :
buf.append("&apos;"); //$NON-NLS-1$
break;
case '\"' :
buf.append("&quot;"); //$NON-NLS-1$
break;
default :
buf.append(c);
break;
}
}
return buf.toString();
}
}