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