1 /*******************************************************************************
2  *  Copyright (c) 2005, 2019 IBM Corporation and others.
3  *
4  *  This program and the accompanying materials
5  *  are made available under the terms of the Eclipse Public License 2.0
6  *  which accompanies this distribution, and is available at
7  *  https://www.eclipse.org/legal/epl-2.0/
8  *
9  *  SPDX-License-Identifier: EPL-2.0
10  *
11  *  Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.pde.internal.ui.correction;
15 
16 import java.io.ByteArrayInputStream;
17 import java.io.IOException;
18 import org.eclipse.core.filebuffers.*;
19 import org.eclipse.core.resources.*;
20 import org.eclipse.core.runtime.*;
21 import org.eclipse.jface.text.BadLocationException;
22 import org.eclipse.jface.text.IDocument;
23 import org.eclipse.osgi.util.NLS;
24 import org.eclipse.pde.core.IBaseModel;
25 import org.eclipse.pde.core.plugin.IPluginModelBase;
26 import org.eclipse.pde.internal.core.ICoreConstants;
27 import org.eclipse.pde.internal.core.PDEManager;
28 import org.eclipse.pde.internal.core.ibundle.IBundle;
29 import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
30 import org.eclipse.pde.internal.core.project.PDEProject;
31 import org.eclipse.pde.internal.core.util.CoreUtility;
32 import org.eclipse.pde.internal.ui.PDEPlugin;
33 import org.eclipse.pde.internal.ui.PDEUIMessages;
34 import org.eclipse.pde.internal.ui.nls.*;
35 import org.eclipse.pde.internal.ui.util.ModelModification;
36 import org.eclipse.pde.internal.ui.util.PDEModelUtility;
37 import org.eclipse.text.edits.MalformedTreeException;
38 import org.osgi.framework.Constants;
39 
40 public class ExternalizeResolution extends AbstractXMLMarkerResolution {
41 
ExternalizeResolution(int resolutionType, IMarker marker)42 	public ExternalizeResolution(int resolutionType, IMarker marker) {
43 		super(resolutionType, marker);
44 	}
45 
46 	@Override
createChange(IPluginModelBase model)47 	protected void createChange(IPluginModelBase model) {
48 		Object node = findNode(model);
49 		ModelChange change = new ModelChange(model, true);
50 		ModelChangeElement element = new ModelChangeElement(change, node);
51 		if (element.updateValue()) {
52 			String localization = PDEManager.getBundleLocalization(model);
53 			if (localization == null)
54 				addLocalization(model, localization = "plugin"); //$NON-NLS-1$
55 			IProject project = model.getUnderlyingResource().getProject();
56 			IFile file = PDEProject.getLocalizationFile(project);
57 			checkPropertiesFile(file);
58 			try {
59 				ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
60 				manager.connect(file.getFullPath(), LocationKind.IFILE, null);
61 				ITextFileBuffer buffer = manager.getTextFileBuffer(file.getFullPath(), LocationKind.IFILE);
62 				if (buffer.isDirty())
63 					buffer.commit(null, true);
64 
65 				IDocument document = buffer.getDocument();
66 				ExternalizeStringsOperation.getPropertiesInsertEdit(document, element).apply(document);
67 				buffer.commit(null, true);
68 			} catch (CoreException | MalformedTreeException | BadLocationException e) {
69 				PDEPlugin.log(e);
70 			} finally {
71 				try {
72 					FileBuffers.getTextFileBufferManager().disconnect(file.getFullPath(), LocationKind.IFILE, null);
73 				} catch (CoreException e) {
74 					PDEPlugin.log(e);
75 				}
76 			}
77 		}
78 	}
79 
80 	@Override
getLabel()81 	public String getLabel() {
82 		if (isAttrNode())
83 			return NLS.bind(PDEUIMessages.ExternalizeResolution_attrib, getNameOfNode());
84 		if (fLocationPath.charAt(0) == '(')
85 			return NLS.bind(PDEUIMessages.ExternalizeResolution_text, getNameOfNode());
86 		return NLS.bind(PDEUIMessages.ExternalizeResolution_header, fLocationPath);
87 	}
88 
addLocalization(IPluginModelBase model, String localizationValue)89 	private void addLocalization(IPluginModelBase model, String localizationValue) {
90 		// should always be IBundlePluginModelBase.  Only time wasn't was when we only passed in plugin.xml to ModelModification contructor.
91 		// Now that we pass in both the Manifest and plugin.xml if we are externalizing the a plugin.xml string (see run(IMarker)),
92 		// model should always be IBundlePluginModelBase
93 		if (model instanceof IBundlePluginModelBase) {
94 			IBundle bundle = ((IBundlePluginModelBase) model).getBundleModel().getBundle();
95 			bundle.setHeader(Constants.BUNDLE_LOCALIZATION, localizationValue);
96 		}
97 	}
98 
99 	@Override
run(IMarker marker)100 	public void run(IMarker marker) {
101 		fResource = marker.getResource();
102 		IFile file = ((IFile) marker.getResource());
103 		ModelModification modification = null;
104 		// if file we are externalizing is not manifest, try to pass manifest in if it exists
105 		if (!file.getName().equals(ICoreConstants.MANIFEST_FILENAME)) {
106 			IFile manifest = PDEProject.getManifest(file.getProject());
107 			if (manifest.exists()) {
108 				modification = new ModelModification(manifest, file) {
109 					@Override
110 					protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws CoreException {
111 						createChange(model);
112 					}
113 				};
114 			}
115 		}
116 		if (modification == null) {
117 			modification = new ModelModification(file) {
118 				@Override
119 				protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws CoreException {
120 					createChange(model);
121 				}
122 			};
123 		}
124 		PDEModelUtility.modifyModel(modification, null);
125 	}
126 
127 	@Override
findOtherMarkers(IMarker[] markers)128 	public IMarker[] findOtherMarkers(IMarker[] markers) {
129 		return new IMarker[0];
130 	}
131 
checkPropertiesFile(IFile file)132 	private void checkPropertiesFile(IFile file) {
133 		if (!file.exists()) {
134 			String propertiesFileComment = ExternalizeStringsOperation.getPropertiesFileComment(file);
135 			try (ByteArrayInputStream pStream = new ByteArrayInputStream(propertiesFileComment.getBytes())) {
136 				IContainer container = file.getParent();
137 				if (!container.exists())
138 					// project will exists, therefore we can assume if !IContainer.exist(), the object is an IFolder
139 					CoreUtility.createFolder((IFolder) container);
140 				file.create(pStream, true, new NullProgressMonitor());
141 			} catch (CoreException | IOException e1) {
142 			}
143 		}
144 	}
145 }
146