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.util.StringTokenizer;
17 import org.eclipse.core.resources.IMarker;
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.pde.core.IBaseModel;
20 import org.eclipse.pde.core.plugin.IPluginModelBase;
21 import org.eclipse.pde.core.plugin.ISharedExtensionsModel;
22 import org.eclipse.pde.internal.core.builders.PDEMarkerFactory;
23 import org.eclipse.pde.internal.core.builders.XMLErrorReporter;
24 import org.eclipse.pde.internal.core.ibundle.IBundle;
25 import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
26 import org.eclipse.pde.internal.core.text.IDocumentElementNode;
27 
28 public abstract class AbstractXMLMarkerResolution extends AbstractPDEMarkerResolution {
29 
30 	protected String fLocationPath;
31 
AbstractXMLMarkerResolution(int resolutionType, IMarker marker)32 	public AbstractXMLMarkerResolution(int resolutionType, IMarker marker) {
33 		super(resolutionType, marker);
34 		try {
35 			fLocationPath = (String) marker.getAttribute(PDEMarkerFactory.MPK_LOCATION_PATH);
36 		} catch (CoreException e) {
37 		}
38 	}
39 
createChange(IPluginModelBase model)40 	protected abstract void createChange(IPluginModelBase model);
41 
42 	@Override
createChange(IBaseModel model)43 	protected void createChange(IBaseModel model) {
44 		if (model instanceof IPluginModelBase)
45 			createChange((IPluginModelBase) model);
46 	}
47 
findNode(IPluginModelBase base)48 	protected Object findNode(IPluginModelBase base) {
49 		try {
50 			fLocationPath = (String) marker.getAttribute(PDEMarkerFactory.MPK_LOCATION_PATH);
51 		} catch (CoreException e) {
52 		}
53 		if (fLocationPath == null)
54 			return null;
55 
56 		// special case for externalizing strings in manifest.mf
57 		if (fLocationPath.charAt(0) != '(' && base instanceof IBundlePluginModelBase) {
58 			IBundle bundle = ((IBundlePluginModelBase) base).getBundleModel().getBundle();
59 			return bundle.getManifestHeader(fLocationPath);
60 		}
61 
62 		IDocumentElementNode node = null;
63 		StringTokenizer strtok = new StringTokenizer(fLocationPath, Character.toString(XMLErrorReporter.F_CHILD_SEP));
64 		while (strtok.hasMoreTokens()) {
65 			String token = strtok.nextToken();
66 			if (node != null) {
67 				IDocumentElementNode[] children = node.getChildNodes();
68 				int childIndex = Integer.parseInt(token.substring(1, token.indexOf(')')));
69 				if ((childIndex >= 0) || (childIndex < children.length)) {
70 					node = children[childIndex];
71 				}
72 				// when externalizing Strings in plugin.xml, we pass in both Manifest and plug-in file (bug 172080 comment #1)
73 			} else if (base instanceof IBundlePluginModelBase) {
74 				ISharedExtensionsModel sharedModel = ((IBundlePluginModelBase) base).getExtensionsModel();
75 				if (sharedModel instanceof IPluginModelBase)
76 					node = (IDocumentElementNode) ((IPluginModelBase) sharedModel).getPluginBase();
77 			} else
78 				node = (IDocumentElementNode) base.getPluginBase();
79 
80 			int attr = token.indexOf(XMLErrorReporter.F_ATT_PREFIX);
81 			if (attr != -1) {
82 				int valueIndex = token.indexOf(XMLErrorReporter.F_ATT_VALUE_PREFIX);
83 				if (valueIndex == -1)
84 					return node.getDocumentAttribute(token.substring(attr + 1));
85 				return node.getDocumentAttribute(token.substring(attr + 1, valueIndex));
86 			}
87 		}
88 		return node;
89 	}
90 
getNameOfNode()91 	protected String getNameOfNode() {
92 		int lastChild = fLocationPath.lastIndexOf(')');
93 		if (lastChild < 0)
94 			return fLocationPath;
95 		String item = fLocationPath.substring(lastChild + 1);
96 		lastChild = item.indexOf(XMLErrorReporter.F_ATT_PREFIX);
97 		if (lastChild == -1)
98 			return item;
99 		int valueIndex = item.indexOf(XMLErrorReporter.F_ATT_VALUE_PREFIX);
100 		if (valueIndex == -1)
101 			return item.substring(lastChild + 1);
102 		return item.substring(valueIndex + 1);
103 	}
104 
isAttrNode()105 	protected boolean isAttrNode() {
106 		return fLocationPath.indexOf(XMLErrorReporter.F_ATT_PREFIX) != -1;
107 	}
108 }
109