001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.nls;
011:
012: import java.lang.reflect.InvocationTargetException;
013: import java.util.ArrayList;
014:
015: import org.eclipse.core.resources.IFile;
016: import org.eclipse.core.resources.IProject;
017: import org.eclipse.core.runtime.CoreException;
018: import org.eclipse.core.runtime.IProgressMonitor;
019: import org.eclipse.core.runtime.SubProgressMonitor;
020: import org.eclipse.jface.operation.IRunnableWithProgress;
021: import org.eclipse.jface.viewers.ISelection;
022: import org.eclipse.jface.viewers.IStructuredSelection;
023: import org.eclipse.pde.core.IBaseModel;
024: import org.eclipse.pde.core.plugin.IPluginAttribute;
025: import org.eclipse.pde.core.plugin.IPluginBase;
026: import org.eclipse.pde.core.plugin.IPluginElement;
027: import org.eclipse.pde.core.plugin.IPluginExtension;
028: import org.eclipse.pde.core.plugin.IPluginModelBase;
029: import org.eclipse.pde.core.plugin.IPluginObject;
030: import org.eclipse.pde.core.plugin.IPluginParent;
031: import org.eclipse.pde.core.plugin.ISharedExtensionsModel;
032: import org.eclipse.pde.core.plugin.PluginRegistry;
033: import org.eclipse.pde.internal.core.ICoreConstants;
034: import org.eclipse.pde.internal.core.PDECore;
035: import org.eclipse.pde.internal.core.WorkspaceModelManager;
036: import org.eclipse.pde.internal.core.ibundle.IBundle;
037: import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
038: import org.eclipse.pde.internal.core.ibundle.IManifestHeader;
039: import org.eclipse.pde.internal.core.ischema.ISchema;
040: import org.eclipse.pde.internal.core.ischema.ISchemaAttribute;
041: import org.eclipse.pde.internal.core.ischema.ISchemaElement;
042: import org.eclipse.pde.internal.core.schema.SchemaRegistry;
043: import org.eclipse.pde.internal.core.text.IDocumentAttributeNode;
044: import org.eclipse.pde.internal.core.text.IDocumentElementNode;
045: import org.eclipse.pde.internal.ui.PDEUIMessages;
046: import org.eclipse.pde.internal.ui.util.ModelModification;
047: import org.eclipse.pde.internal.ui.util.PDEModelUtility;
048:
049: public class GetNonExternalizedStringsOperation implements
050: IRunnableWithProgress {
051:
052: private ISelection fSelection;
053: private ArrayList fSelectedModels;
054: private ModelChangeTable fModelChangeTable;
055: private boolean fCanceled;
056:
057: public GetNonExternalizedStringsOperation(ISelection selection) {
058: fSelection = selection;
059: }
060:
061: public void run(IProgressMonitor monitor)
062: throws InvocationTargetException, InterruptedException {
063:
064: if (fSelection instanceof IStructuredSelection) {
065: Object[] elems = ((IStructuredSelection) fSelection)
066: .toArray();
067: fSelectedModels = new ArrayList(elems.length);
068: for (int i = 0; i < elems.length; i++) {
069: if (elems[i] instanceof IFile)
070: elems[i] = ((IFile) elems[i]).getProject();
071:
072: if (elems[i] instanceof IProject
073: && WorkspaceModelManager
074: .isPluginProject((IProject) elems[i])
075: && !WorkspaceModelManager
076: .isBinaryProject((IProject) elems[i]))
077: fSelectedModels.add(elems[i]);
078: }
079:
080: fModelChangeTable = new ModelChangeTable();
081:
082: IPluginModelBase[] pluginModels = PluginRegistry
083: .getWorkspaceModels();
084: monitor
085: .beginTask(
086: PDEUIMessages.GetNonExternalizedStringsOperation_taskMessage,
087: pluginModels.length);
088: for (int i = 0; i < pluginModels.length && !fCanceled; i++) {
089: IProject project = pluginModels[i]
090: .getUnderlyingResource().getProject();
091: if (!WorkspaceModelManager.isBinaryProject(project))
092: getUnExternalizedStrings(project,
093: new SubProgressMonitor(monitor, 1));
094: }
095: }
096: }
097:
098: private void getUnExternalizedStrings(IProject project,
099: IProgressMonitor monitor) {
100: PDEModelUtility.modifyModel(new ModelModification(project) {
101: protected void modifyModel(IBaseModel model,
102: IProgressMonitor monitor) throws CoreException {
103: if (model instanceof IBundlePluginModelBase)
104: inspectManifest((IBundlePluginModelBase) model,
105: monitor);
106:
107: if (monitor.isCanceled()) {
108: fCanceled = true;
109: return;
110: }
111:
112: if (model instanceof IPluginModelBase)
113: inspectXML((IPluginModelBase) model, monitor);
114:
115: if (monitor.isCanceled()) {
116: fCanceled = true;
117: return;
118: }
119: }
120: }, monitor);
121: monitor.done();
122: }
123:
124: private void inspectManifest(IBundlePluginModelBase model,
125: IProgressMonitor monitor) throws CoreException {
126: IFile manifestFile = (IFile) model.getBundleModel()
127: .getUnderlyingResource();
128: IBundle bundle = model.getBundleModel().getBundle();
129: for (int i = 0; i < ICoreConstants.TRANSLATABLE_HEADERS.length; i++) {
130: IManifestHeader header = bundle
131: .getManifestHeader(ICoreConstants.TRANSLATABLE_HEADERS[i]);
132: if (header != null && isNotTranslated(header.getValue()))
133: fModelChangeTable.addToChangeTable(model, manifestFile,
134: header, selected(manifestFile));
135: }
136: }
137:
138: private void inspectXML(IPluginModelBase model,
139: IProgressMonitor monitor) throws CoreException {
140: IFile file;
141: if (model instanceof IBundlePluginModelBase) {
142: ISharedExtensionsModel extModel = ((IBundlePluginModelBase) model)
143: .getExtensionsModel();
144: if (extModel == null)
145: return;
146: file = (IFile) extModel.getUnderlyingResource();
147: } else
148: file = (IFile) model.getUnderlyingResource();
149:
150: IPluginBase base = model.getPluginBase();
151: if (base instanceof IDocumentElementNode) {
152: // old style xml plugin
153: // check xml name declaration
154: IDocumentAttributeNode attr = ((IDocumentElementNode) base)
155: .getDocumentAttribute(IPluginObject.P_NAME);
156: if (attr != null
157: && isNotTranslated(attr.getAttributeValue()))
158: fModelChangeTable.addToChangeTable(model, file, attr,
159: selected(file));
160:
161: // check xml provider declaration
162: attr = ((IDocumentElementNode) base)
163: .getDocumentAttribute(IPluginBase.P_PROVIDER);
164: if (attr != null
165: && isNotTranslated(attr.getAttributeValue()))
166: fModelChangeTable.addToChangeTable(model, file, attr,
167: selected(file));
168: }
169:
170: SchemaRegistry registry = PDECore.getDefault()
171: .getSchemaRegistry();
172: IPluginExtension[] extensions = model.getPluginBase()
173: .getExtensions();
174: for (int i = 0; i < extensions.length; i++) {
175: ISchema schema = registry.getSchema(extensions[i]
176: .getPoint());
177: if (schema != null)
178: inspectExtension(schema, extensions[i], model, file);
179: }
180: }
181:
182: private void inspectExtension(ISchema schema, IPluginParent parent,
183: IPluginModelBase memModel, IFile file) {
184: IPluginObject[] children = parent.getChildren();
185: for (int i = 0; i < children.length; i++) {
186: IPluginElement child = (IPluginElement) children[i];
187: ISchemaElement schemaElement = schema.findElement(child
188: .getName());
189: if (schemaElement != null) {
190: if (schemaElement.hasTranslatableContent())
191: if (isNotTranslated(child.getText()))
192: fModelChangeTable.addToChangeTable(memModel,
193: file, child, selected(file));
194:
195: IPluginAttribute[] attributes = child.getAttributes();
196: for (int j = 0; j < attributes.length; j++) {
197: IPluginAttribute attr = attributes[j];
198: ISchemaAttribute attInfo = schemaElement
199: .getAttribute(attr.getName());
200: if (attInfo != null && attInfo.isTranslatable())
201: if (isNotTranslated(attr.getValue()))
202: fModelChangeTable.addToChangeTable(
203: memModel, file, attr,
204: selected(file));
205: }
206: }
207: inspectExtension(schema, child, memModel, file);
208: }
209: }
210:
211: private boolean isNotTranslated(String value) {
212: if (value == null)
213: return false;
214: if (value.length() > 0 && value.charAt(0) == '%')
215: return false;
216: return true;
217: }
218:
219: protected ModelChangeTable getChangeTable() {
220: return fModelChangeTable;
221: }
222:
223: public boolean wasCanceled() {
224: return fCanceled;
225: }
226:
227: private boolean selected(IFile file) {
228: return fSelectedModels.contains(file.getProject());
229: }
230: }
|