blob: 7109eb85c4d2779c771c7f87fd633b49b8ebd6f9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 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.pde.internal.ui.wizards.product;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.core.IBaseModel;
import org.eclipse.pde.core.plugin.*;
import org.eclipse.pde.internal.core.TargetPlatformHelper;
import org.eclipse.pde.internal.core.iproduct.IProduct;
import org.eclipse.pde.internal.core.plugin.WorkspacePluginModelBase;
import org.eclipse.pde.internal.ui.PDEPlugin;
import org.eclipse.pde.internal.ui.PDEUIMessages;
import org.eclipse.pde.internal.ui.util.ModelModification;
import org.eclipse.pde.internal.ui.util.PDEModelUtility;
import org.eclipse.pde.internal.ui.wizards.templates.ControlStack;
import org.eclipse.pde.ui.templates.IVariableProvider;
import org.eclipse.swt.widgets.Shell;
public class ProductIntroOperation extends BaseManifestOperation implements IVariableProvider {
protected String fIntroId;
private Shell fShell;
private IProduct fProduct;
private IProject fProject;
private static final String INTRO_POINT = "org.eclipse.ui.intro"; //$NON-NLS-1$
private static final String INTRO_CONFIG_POINT = "org.eclipse.ui.intro.config"; //$NON-NLS-1$
private static final String INTRO_CLASS = "org.eclipse.ui.intro.config.CustomizableIntroPart"; //$NON-NLS-1$
private static final String KEY_PRODUCT_NAME = "productName"; //$NON-NLS-1$
public ProductIntroOperation(IProduct product, String pluginId, String introId, Shell shell) {
super(shell, pluginId);
fIntroId = introId;
fProduct = product;
fProject = PluginRegistry.findModel(pluginId).getUnderlyingResource().getProject();
}
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
IFile file = getFile();
if (!file.exists()) {
createNewFile(file);
} else {
modifyExistingFile(file, monitor);
}
updateSingleton(monitor);
generateFiles(monitor);
} catch (CoreException e) {
throw new InvocationTargetException(e);
}
}
private void createNewFile(IFile file) throws CoreException {
WorkspacePluginModelBase model = (WorkspacePluginModelBase) getModel(file);
IPluginBase base = model.getPluginBase();
base.setSchemaVersion(TargetPlatformHelper.getSchemaVersion());
base.add(createIntroExtension(model));
base.add(createIntroConfigExtension(model));
model.save();
}
private IPluginExtension createIntroExtension(IPluginModelBase model) throws CoreException {
IPluginExtension extension = model.getFactory().createExtension();
extension.setPoint(INTRO_POINT);
extension.add(createIntroExtensionContent(extension));
extension.add(createIntroBindingExtensionContent(extension));
return extension;
}
private IPluginExtension createIntroConfigExtension(IPluginModelBase model) throws CoreException {
IPluginExtension extension = model.getFactory().createExtension();
extension.setPoint(INTRO_CONFIG_POINT);
extension.add(createIntroConfigExtensionContent(extension));
return extension;
}
private IPluginElement createIntroExtensionContent(IPluginExtension extension) throws CoreException {
IPluginElement element = extension.getModel().getFactory().createElement(extension);
element.setName("intro"); //$NON-NLS-1$
element.setAttribute("id", fIntroId); //$NON-NLS-1$
element.setAttribute("class", INTRO_CLASS); //$NON-NLS-1$
return element;
}
private IPluginElement createIntroBindingExtensionContent(IPluginExtension extension) throws CoreException {
IPluginElement element = extension.getModel().getFactory().createElement(extension);
element.setName("introProductBinding"); //$NON-NLS-1$
element.setAttribute("productId", fProduct.getId()); //$NON-NLS-1$
element.setAttribute("introId", fIntroId); //$NON-NLS-1$
return element;
}
private IPluginElement createIntroConfigExtensionContent(IPluginExtension extension) throws CoreException {
IPluginElement element = extension.getModel().getFactory().createElement(extension);
element.setName("config"); //$NON-NLS-1$
element.setAttribute("id", fPluginId + ".introConfigId"); //$NON-NLS-1$ //$NON-NLS-2$
element.setAttribute("introId", fIntroId); //$NON-NLS-1$
element.setAttribute("content", "introContent.xml"); //$NON-NLS-1$ //$NON-NLS-2$
element.add(createPresentationElement(element));
return element;
}
private IPluginElement createPresentationElement(IPluginElement parent) throws CoreException {
IPluginElement presentation = null;
IPluginElement implementation = null;
IExtensionsModelFactory factory = parent.getModel().getFactory();
presentation = factory.createElement(parent);
presentation.setName("presentation"); //$NON-NLS-1$
presentation.setAttribute("home-page-id", "root"); //$NON-NLS-1$ //$NON-NLS-2$
implementation = factory.createElement(presentation);
implementation.setName("implementation"); //$NON-NLS-1$
implementation.setAttribute("kind", "html"); //$NON-NLS-1$ //$NON-NLS-2$
implementation.setAttribute("style", "content/shared.css"); //$NON-NLS-1$ //$NON-NLS-2$
implementation.setAttribute("os", "win32,linux,macosx"); //$NON-NLS-1$ //$NON-NLS-2$
presentation.add(implementation);
return presentation;
}
private void modifyExistingFile(IFile file, IProgressMonitor monitor) throws CoreException {
IStatus status = PDEPlugin.getWorkspace().validateEdit(new IFile[] {file}, fShell);
if (status.getSeverity() != IStatus.OK)
throw new CoreException(new Status(IStatus.ERROR, "org.eclipse.pde.ui", IStatus.ERROR, NLS.bind(PDEUIMessages.ProductDefinitionOperation_readOnly, fPluginId), null)); //$NON-NLS-1$
ModelModification mod = new ModelModification(file) {
protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws CoreException {
if (!(model instanceof IPluginModelBase))
return;
IPluginModelBase pluginModel = (IPluginModelBase) model;
IPluginExtension extension = getExtension(pluginModel, INTRO_POINT);
if (extension == null) {
extension = createIntroExtension(pluginModel);
pluginModel.getPluginBase().add(extension);
} else {
extension.add(createIntroExtensionContent(extension));
extension.add(createIntroBindingExtensionContent(extension));
}
extension = getExtension(pluginModel, INTRO_CONFIG_POINT);
if (extension == null) {
extension = createIntroConfigExtension(pluginModel);
pluginModel.getPluginBase().add(extension);
} else {
extension.add(createIntroConfigExtensionContent(extension));
}
}
};
PDEModelUtility.modifyModel(mod, monitor);
}
private IPluginExtension getExtension(IPluginModelBase model, String tPoint) throws CoreException {
IPluginExtension[] extensions = model.getPluginBase().getExtensions();
for (int i = 0; i < extensions.length; i++) {
String point = extensions[i].getPoint();
if (tPoint.equals(point)) {
return extensions[i];
}
}
return null;
}
protected void generateFiles(IProgressMonitor monitor) throws CoreException {
monitor.setTaskName(PDEUIMessages.AbstractTemplateSection_generating);
URL locationUrl = null;
try {
locationUrl = new URL(PDEPlugin.getDefault().getInstallURL(), "templates_3.1/intro/"); //$NON-NLS-1$
} catch (MalformedURLException e1) {
return;
}
if (locationUrl == null) {
return;
}
try {
locationUrl = FileLocator.resolve(locationUrl);
locationUrl = FileLocator.toFileURL(locationUrl);
} catch (IOException e) {
return;
}
if ("file".equals(locationUrl.getProtocol())) { //$NON-NLS-1$
File templateDirectory = new File(locationUrl.getFile());
if (!templateDirectory.exists())
return;
generateFiles(templateDirectory, fProject, true, false, monitor);
}
monitor.subTask(""); //$NON-NLS-1$
monitor.worked(1);
}
private void generateFiles(File src, IContainer dst, boolean firstLevel, boolean binary, IProgressMonitor monitor) throws CoreException {
File[] members = src.listFiles();
for (int i = 0; i < members.length; i++) {
File member = members[i];
if (member.getName().equals("ext.xml") || //$NON-NLS-1$
member.getName().equals("java") || //$NON-NLS-1$
member.getName().equals("concept3.xhtml") || //$NON-NLS-1$
member.getName().equals("extContent.xhtml")) //$NON-NLS-1$
continue;
else if (member.isDirectory()) {
IContainer dstContainer = null;
if (firstLevel) {
binary = false;
if (member.getName().equals("bin")) { //$NON-NLS-1$
binary = true;
dstContainer = dst;
}
}
if (dstContainer == null) {
dstContainer = dst.getFolder(new Path(member.getName()));
}
if (dstContainer instanceof IFolder && !dstContainer.exists())
((IFolder) dstContainer).create(true, true, monitor);
generateFiles(member, dstContainer, false, binary, monitor);
} else {
if (firstLevel)
binary = false;
InputStream in = null;
try {
in = new FileInputStream(member);
copyFile(member.getName(), in, dst, binary, monitor);
} catch (IOException ioe) {
} finally {
if (in != null)
try {
in.close();
} catch (IOException ioe2) {
}
}
}
}
}
private void copyFile(String fileName, InputStream input, IContainer dst, boolean binary, IProgressMonitor monitor) throws CoreException {
monitor.subTask(fileName);
IFile dstFile = dst.getFile(new Path(fileName));
try {
InputStream stream = getProcessedStream(fileName, input, binary);
if (dstFile.exists()) {
dstFile.setContents(stream, true, true, monitor);
} else {
dstFile.create(stream, true, monitor);
}
stream.close();
} catch (IOException e) {
}
}
private InputStream getProcessedStream(String fileName, InputStream stream, boolean binary) throws IOException, CoreException {
if (binary)
return stream;
InputStreamReader reader = new InputStreamReader(stream);
int bufsize = 1024;
char[] cbuffer = new char[bufsize];
int read = 0;
StringBuffer keyBuffer = new StringBuffer();
StringBuffer outBuffer = new StringBuffer();
ControlStack preStack = new ControlStack();
preStack.setValueProvider(this);
boolean replacementMode = false;
while (read != -1) {
read = reader.read(cbuffer);
for (int i = 0; i < read; i++) {
char c = cbuffer[i];
if (preStack.getCurrentState() == false) {
continue;
}
if (c == '$') {
if (replacementMode) {
replacementMode = false;
String key = keyBuffer.toString();
String value = key.length() == 0 ? "$" //$NON-NLS-1$
: getReplacementString(fileName, key);
outBuffer.append(value);
keyBuffer.delete(0, keyBuffer.length());
} else {
replacementMode = true;
}
} else {
if (replacementMode)
keyBuffer.append(c);
else {
outBuffer.append(c);
}
}
}
}
return new ByteArrayInputStream(outBuffer.toString().getBytes(fProject.getDefaultCharset()));
}
private String getReplacementString(String fileName, String key) {
if (key.equals(KEY_PRODUCT_NAME)) {
return fProduct.getName();
}
return key;
}
public Object getValue(String variable) {
return null;
}
}