blob: ca52326d98affc0785080ee9041249faabfa1dac [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 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
* Benjamin Cabe <benjamin.cabe@anyware-tech.com> - bug 252329
*******************************************************************************/
package org.eclipse.pde.internal.ui.nls;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.pde.core.IBaseModel;
import org.eclipse.pde.core.plugin.*;
import org.eclipse.pde.internal.core.*;
import org.eclipse.pde.internal.core.ibundle.*;
import org.eclipse.pde.internal.core.ischema.*;
import org.eclipse.pde.internal.core.schema.SchemaRegistry;
import org.eclipse.pde.internal.core.text.IDocumentAttributeNode;
import org.eclipse.pde.internal.core.text.IDocumentElementNode;
import org.eclipse.pde.internal.core.text.plugin.PluginExtensionNode;
import org.eclipse.pde.internal.core.text.plugin.PluginExtensionPointNode;
import org.eclipse.pde.internal.ui.PDEUIMessages;
import org.eclipse.pde.internal.ui.util.ModelModification;
import org.eclipse.pde.internal.ui.util.PDEModelUtility;
public class GetNonExternalizedStringsOperation implements IRunnableWithProgress {
private ISelection fSelection;
private ArrayList fSelectedModels;
private ModelChangeTable fModelChangeTable;
private boolean fCanceled;
//Azure: To indicate that only selected plug-ins under <code>fSelection</code> are to be externalized.
private boolean fExternalizeSelectedPluginsOnly;
public GetNonExternalizedStringsOperation(ISelection selection, boolean externalizeSelectedPluginsOnly) {
fSelection = selection;
fExternalizeSelectedPluginsOnly = externalizeSelectedPluginsOnly;
}
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
if (fSelection instanceof IStructuredSelection) {
Object[] elems = ((IStructuredSelection) fSelection).toArray();
fSelectedModels = new ArrayList(elems.length);
for (int i = 0; i < elems.length; i++) {
if (elems[i] instanceof IFile)
elems[i] = ((IFile) elems[i]).getProject();
if (elems[i] instanceof IProject && WorkspaceModelManager.isPluginProject((IProject) elems[i]) && !WorkspaceModelManager.isBinaryProject((IProject) elems[i]))
fSelectedModels.add(elems[i]);
}
fModelChangeTable = new ModelChangeTable();
/*
* Azure: This will add only the preselected plug-ins to the ModelChangeTable
* instead of adding the list of all plug-ins in the workspace. This is useful
* when the Internationalize action is run on a set of non-externalized plug-ins
* where there is no need to display all non-externalized plug-ins in the
* workspace, but only those selected.
*/
if (fExternalizeSelectedPluginsOnly) {
monitor.beginTask(PDEUIMessages.GetNonExternalizedStringsOperation_taskMessage, fSelectedModels.size());
Iterator iterator = fSelectedModels.iterator();
while (iterator.hasNext() && !fCanceled) {
IProject project = (IProject) iterator.next();
if (!WorkspaceModelManager.isBinaryProject(project))
getUnExternalizedStrings(project, new SubProgressMonitor(monitor, 1));
}
} else {
IPluginModelBase[] pluginModels = PluginRegistry.getWorkspaceModels();
monitor.beginTask(PDEUIMessages.GetNonExternalizedStringsOperation_taskMessage, pluginModels.length);
for (int i = 0; i < pluginModels.length && !fCanceled; i++) {
IProject project = pluginModels[i].getUnderlyingResource().getProject();
if (!WorkspaceModelManager.isBinaryProject(project))
getUnExternalizedStrings(project, new SubProgressMonitor(monitor, 1));
}
}
}
}
private void getUnExternalizedStrings(IProject project, IProgressMonitor monitor) {
PDEModelUtility.modifyModel(new ModelModification(project) {
protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws CoreException {
if (model instanceof IBundlePluginModelBase)
inspectManifest((IBundlePluginModelBase) model, monitor);
if (monitor.isCanceled()) {
fCanceled = true;
return;
}
if (model instanceof IPluginModelBase)
inspectXML((IPluginModelBase) model, monitor);
if (monitor.isCanceled()) {
fCanceled = true;
return;
}
}
}, monitor);
monitor.done();
}
private void inspectManifest(IBundlePluginModelBase model, IProgressMonitor monitor) throws CoreException {
IFile manifestFile = (IFile) model.getBundleModel().getUnderlyingResource();
IBundle bundle = model.getBundleModel().getBundle();
for (int i = 0; i < ICoreConstants.TRANSLATABLE_HEADERS.length; i++) {
IManifestHeader header = bundle.getManifestHeader(ICoreConstants.TRANSLATABLE_HEADERS[i]);
if (header != null && isNotTranslated(header.getValue()))
fModelChangeTable.addToChangeTable(model, manifestFile, header, selected(manifestFile));
}
}
private void inspectXML(IPluginModelBase model, IProgressMonitor monitor) throws CoreException {
IFile file;
if (model instanceof IBundlePluginModelBase) {
ISharedExtensionsModel extModel = ((IBundlePluginModelBase) model).getExtensionsModel();
if (extModel == null)
return;
file = (IFile) extModel.getUnderlyingResource();
} else
file = (IFile) model.getUnderlyingResource();
IPluginBase base = model.getPluginBase();
if (base instanceof IDocumentElementNode) {
// old style xml plugin
// check xml name declaration
IDocumentAttributeNode attr = ((IDocumentElementNode) base).getDocumentAttribute(IPluginObject.P_NAME);
if (attr != null && isNotTranslated(attr.getAttributeValue()))
fModelChangeTable.addToChangeTable(model, file, attr, selected(file));
// check xml provider declaration
attr = ((IDocumentElementNode) base).getDocumentAttribute(IPluginBase.P_PROVIDER);
if (attr != null && isNotTranslated(attr.getAttributeValue()))
fModelChangeTable.addToChangeTable(model, file, attr, selected(file));
}
SchemaRegistry registry = PDECore.getDefault().getSchemaRegistry();
IPluginExtension[] extensions = model.getPluginBase().getExtensions();
for (int i = 0; i < extensions.length; i++) {
ISchema schema = registry.getSchema(extensions[i].getPoint());
if (schema != null)
inspectExtension(schema, extensions[i], model, file);
}
IPluginExtensionPoint[] extensionPoints = model.getPluginBase().getExtensionPoints();
for (int i = 0; i < extensionPoints.length; i++) {
inspectExtensionPoint(extensionPoints[i], model, file);
}
}
private void inspectExtension(ISchema schema, IPluginParent parent, IPluginModelBase memModel, IFile file) {
if (parent instanceof PluginExtensionNode) {
PluginExtensionNode parentNode = (PluginExtensionNode) parent;
IDocumentAttributeNode[] attributes = parentNode.getNodeAttributes();
ISchemaElement schemaElement = schema.findElement(parentNode.getXMLTagName());
for (int j = 0; j < attributes.length; j++) {
IPluginAttribute attr = (IPluginAttribute) attributes[j];
ISchemaAttribute attInfo = schemaElement.getAttribute(attr.getName());
if (attInfo != null && attInfo.isTranslatable())
if (isNotTranslated(attr.getValue()))
fModelChangeTable.addToChangeTable(memModel, file, attr, selected(file));
}
}
IPluginObject[] children = parent.getChildren();
for (int i = 0; i < children.length; i++) {
IPluginElement child = (IPluginElement) children[i];
ISchemaElement schemaElement = schema.findElement(child.getName());
if (schemaElement != null) {
if (schemaElement.hasTranslatableContent())
if (isNotTranslated(child.getText()))
fModelChangeTable.addToChangeTable(memModel, file, child, selected(file));
IPluginAttribute[] attributes = child.getAttributes();
for (int j = 0; j < attributes.length; j++) {
IPluginAttribute attr = attributes[j];
ISchemaAttribute attInfo = schemaElement.getAttribute(attr.getName());
if (attInfo != null && attInfo.isTranslatable())
if (isNotTranslated(attr.getValue()))
fModelChangeTable.addToChangeTable(memModel, file, attr, selected(file));
}
}
inspectExtension(schema, child, memModel, file);
}
}
private void inspectExtensionPoint(IPluginExtensionPoint extensionPoint, IPluginModelBase memModel, IFile file) {
if (extensionPoint instanceof PluginExtensionPointNode)
if (isNotTranslated(extensionPoint.getName()))
fModelChangeTable.addToChangeTable(memModel, file, ((PluginExtensionPointNode) extensionPoint).getNodeAttributesMap().get(IPluginObject.P_NAME), selected(file));
}
private boolean isNotTranslated(String value) {
if (value == null)
return false;
if (value.length() > 0 && value.charAt(0) == '%')
return false;
return true;
}
protected ModelChangeTable getChangeTable() {
return fModelChangeTable;
}
public boolean wasCanceled() {
return fCanceled;
}
private boolean selected(IFile file) {
return fSelectedModels.contains(file.getProject());
}
}