-
Notifications
You must be signed in to change notification settings - Fork 0
/
PluginXmlLoader.xtend
182 lines (158 loc) · 5.35 KB
/
PluginXmlLoader.xtend
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*******************************************************************************
* Copyright (c) 2016 RCP Vision (http://www.rcp-vision.com) 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:
* Lorenzo Bettini - initial API and implementation
*******************************************************************************/
package org.eclipse.emf.parsley.dsl.pluginxml
import java.util.List
import org.eclipse.core.runtime.CoreException
import org.eclipse.jface.text.Document
import org.eclipse.pde.internal.core.text.DocumentElementNode
import org.eclipse.pde.internal.core.text.IDocumentAttributeNode
import org.eclipse.pde.internal.core.text.plugin.PluginAttribute
import org.eclipse.pde.internal.core.text.plugin.PluginElementNode
import org.eclipse.pde.internal.core.text.plugin.PluginExtensionNode
import org.eclipse.pde.internal.core.text.plugin.PluginModel
class PluginXmlLoader extends PluginModel {
var List<PluginExtensionNode> pluginExtensionNodes;
var List<PluginElementNode> pluginExtensionElementNodes;
new(String source) {
super(new Document(source), true)
}
/**
* The nodes corresponding to <extension> elements in the plugin.xml file
*/
def getExtensionNodes() {
if (pluginExtensionNodes == null)
initializeExtensionNodes()
return pluginExtensionNodes
}
protected def initializeExtensionNodes() {
pluginExtensionNodes = plugin.extensions.filter(PluginExtensionNode).toList
}
/**
* The nodes corresponding to elements inside <extension>, for example,
* <view>, <editor>
*/
def getExtensionElements() {
if (pluginExtensionElementNodes == null)
initializeExtensionElements()
return pluginExtensionElementNodes
}
protected def initializeExtensionElements() {
pluginExtensionElementNodes = getExtensionNodes().map[mapToNodes].flatten.toList
}
private def mapToNodes(DocumentElementNode it) {
childNodes.filter(PluginElementNode)
}
def getExtensionChildren(PluginElementNode node) {
node.mapToNodes.toList
}
def getPluginAttributesEntrySet(PluginElementNode node) {
PluginXmlUtils.getPluginAttributesEntrySet(node)
}
def getExtensionByPoint(String p) {
getExtensionNodes().findFirst[point == p]
}
def getElementExtension(PluginElementNode node) {
(node.parent as PluginExtensionNode).point
}
def getElementByTagAndId(String xmlTag, String id) {
extensionElements.
filter[XMLTagName == xmlTag].
findFirst[
val v = getId
if (v != null) {
getAttributeAsString(v) == id
} else {
false
}
]
}
def getId(DocumentElementNode node) {
PluginXmlUtils.getId(node)
}
def getAttributeAsString(IDocumentAttributeNode a) {
(a as PluginAttribute).value
}
/**
* Copies all the extension and extension elements from the source
* plugin xml into this plugin xml. Attributes with the same id
* will be overwritten in this plugin xml.
*/
def copyFromPluginXml(String source) throws CoreException {
for (e : new PluginXmlLoader(source).extensionElements) {
copy(e)
}
}
/**
* Assumes that the source has an id. If a corresponding element
* in this plugin xml file is not found it will be inserted first.
*/
def copy(PluginElementNode source) throws CoreException {
val xmlTagName = source.XMLTagName
var target = getElementByTagAndId(xmlTagName, source.getId.attributeAsString)
if (target == null) {
target = insertExtensionElement(source.getElementExtension, xmlTagName)
}
copy(source, target)
}
/**
* This assumes that both the source and the target are not null
*/
def void copy(PluginElementNode source, PluginElementNode target) throws CoreException {
val atts = source.getAttributes();
for (a : atts) {
val att = a as PluginAttribute;
val copy = new PluginAttribute
copy.name = att.name
copy.value = att.value
PluginXmlUtils.getNodeAttributesMap(target).put(att.getName(), copy);
}
val children = target.childNodes
for (c : source.childNodes) {
var myChild = children.findFirst[XMLTagName == c.XMLTagName]
if (myChild == null) {
val newChild = pluginFactory.createElement(target) as PluginElementNode
newChild.XMLTagName = c.XMLTagName
target.addChildNode(newChild)
copy(c as PluginElementNode, newChild)
} else {
copy(c as PluginElementNode, myChild as PluginElementNode)
}
}
}
def insertExtension(String point) throws CoreException {
val e = pluginFactory.createExtension()
e.setPoint(point)
plugin.add(e)
initializeExtensionNodes
return e as PluginExtensionNode
}
/**
* If there is no extension element with the specified point, it
* will be automatically inserted.
*/
def insertExtensionElement(String point, String xmlTag) throws CoreException {
var ext = getExtensionByPoint(point)
if (ext == null)
ext = insertExtension(point)
val element = pluginFactory.createElement(ext) as PluginElementNode
ext.addChildNode(element)
element.XMLTagName = xmlTag
initializeExtensionElements
return element
}
def String getContentsAsString() {
// it would be nice to use the Document contents, but these are not synchronized
// with the plugin model changes
'''
«plugin.toString.replaceFirst("(<plugin)\\r?\\n(>)", "<plugin>")»
'''
}
}