blob: 7adecfa6e77c68164219cbd962ec47f46fe73b96 (
plain) (
blame)
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
|
/*******************************************************************************
* Copyright (c) 2011 protos software gmbh (http://www.protos.de).
* 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:
* Henrik Rentz-Reichert (initial contribution)
*
*******************************************************************************/
package org.eclipse.etrice.core.ui.handlers
import org.eclipse.core.commands.AbstractHandler
import org.eclipse.core.commands.ExecutionEvent
import org.eclipse.core.commands.ExecutionException
import org.eclipse.etrice.core.fsm.fSM.FSMFactory
import org.eclipse.etrice.core.fsm.fSM.TriggeredTransition
import org.eclipse.etrice.core.room.Message
import org.eclipse.etrice.core.room.MessageData
import org.eclipse.etrice.core.room.RoomModel
import org.eclipse.jface.dialogs.MessageDialog
import org.eclipse.swt.widgets.Display
import org.eclipse.xtext.resource.XtextResource
import org.eclipse.xtext.ui.editor.utils.EditorUtils
import org.eclipse.xtext.util.concurrent.IUnitOfWork
import org.eclipse.etrice.core.fsm.fSM.DetailCode
import org.eclipse.emf.ecore.EObject
import org.eclipse.etrice.core.room.MessageHandler
import com.google.inject.Inject
import org.eclipse.xtext.formatting.IWhitespaceInformationProvider
class MigrateTransitionData extends AbstractHandler {
public static final String genericDataName = "transitionData"
@Inject
IWhitespaceInformationProvider whitespaceProvider;
String lineSep
int actionCodeReplacements = 0
int messageNamesRemoved = 0
override Object execute(ExecutionEvent event) throws ExecutionException {
val proceed = MessageDialog.openQuestion(
Display.current.activeShell,
"Migrate to new style of transition data",
"This migration will\n"
+ "* remove all names of message data\n"
+ "* replace textual occurrences of old data names with the generic name '" + genericDataName + "'\n\n"
+ "Proceed?"
)
if (proceed) {
val editor = EditorUtils.getActiveXtextEditor(event)
if (editor!==null) {
editor.getDocument().modify(new IUnitOfWork.Void<XtextResource>() {
override void process(XtextResource state) throws Exception {
lineSep = whitespaceProvider.getLineSeparatorInformation(state.URI).lineSeparator
for (model : state.getContents()) {
if (model instanceof RoomModel) {
migrateModel(model)
}
}
}
});
MessageDialog.openInformation(
Display.current.activeShell,
"Migrate to new style of transition data",
"Did replacements in " + actionCodeReplacements + " action codes.\n"
+ "In " + messageNamesRemoved + " messages the data names have been removed."
)
}
}
return null;
}
private def void migrateModel(RoomModel model) {
// (1) parse detail code and make replacements (before names are nulled in (2))
// consider only TriggeredTransition (which is not quite accurate)
model.eAllContents.toIterable.filter(TriggeredTransition).forEach[action = makeActionCodeReplacements(triggers.head?.msgFromIfPairs.head?.message, action)]
model.eAllContents.toIterable.filter(MessageHandler).forEach[detailCode = makeActionCodeReplacements(msg, detailCode)]
// (2) remove names of message data
model.eAllContents.toIterable.filter(MessageData).forEach[
deprecatedName = null
messageNamesRemoved++
]
}
private def makeActionCodeReplacements(EObject msg, DetailCode action) {
// inaccurate assumption: we can look at the first trigger message only
if (msg instanceof Message) {
if (msg.data!==null && msg.data.deprecatedName!==null && action!==null && !action.lines.empty) {
// we turn a multiline detail code into a single line one. Otherwise the serializer will fail because of the CC_STRING
if (action.lines.join.contains(msg.data.deprecatedName)) {
actionCodeReplacements++
return FSMFactory.eINSTANCE.createDetailCode => [
val replaced = action.lines.map[replace(msg.data.deprecatedName, genericDataName)].join(lineSep)
lines.add(replaced)
used = false
]
}
}
}
// return the unchanged code
return action
}
}
|