summaryrefslogtreecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/VirtConfigEditorWindow.java
blob: be06f8aea9e5bc4d491327836c18c133033fbea0 (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
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
package org.openslx.dozmod.gui.window;

import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;

import org.apache.log4j.Logger;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.TextChangeListener;
import org.openslx.dozmod.gui.helper.UiFeedback;
import org.openslx.dozmod.gui.window.layout.VirtConfigEditorWindowLayout;
import org.openslx.dozmod.thrift.ImageDetailsActions;
import org.openslx.dozmod.thrift.ImageDetailsActions.VirtConfCallback;
import org.openslx.dozmod.thrift.cache.MetaDataCache;
import org.openslx.util.XmlHelper;
import org.openslx.util.vm.VboxMetaData;
import org.openslx.util.vm.VmMetaData;
import org.openslx.util.vm.VmwareConfig;

@SuppressWarnings("serial")
public class VirtConfigEditorWindow extends VirtConfigEditorWindowLayout implements UiFeedback {

	private final static Logger LOGGER = Logger.getLogger(VirtConfigEditorWindow.class);

	public interface VirtConfigChanged {
		public void virtConfigChanged(String newVmx);
	}

	private final String imageVersionId;
	private final String originalMachineDescription;
	private final VirtConfigEditorWindow me = this;
	private final ImageDetailsActions actionHandler;

	private boolean configWasSaved = false;

	protected VirtConfigEditorWindow(Window modalParent, final ImageDetailsActions actionHandler,
			final String imageVersionId, final String currentMachineDescription,
			final String originalmachineDescription) {
		super(modalParent);

		this.actionHandler = actionHandler;
		this.imageVersionId = imageVersionId;
		// listener for the text fields
		pnlEditor.getDocument().addDocumentListener(new TextChangeListener() {
			@Override
			public void changed() {
				btnSave.setEnabled(!originalMachineDescription.equals(pnlEditor.getText()));
			}
		});

		btnSave.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				saveClicked();
			}
		});

		btnCancel.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				safeClose();
			}
		});
		// for vbox, originalMachineDescription is unformatted, the new one will be though
		// save original description for later use
		this.originalMachineDescription = XmlHelper.getFormattedXml(
				new ByteArrayInputStream(originalmachineDescription.getBytes(StandardCharsets.UTF_8)));
		pnlEditor.setText(currentMachineDescription);
		pnlEditor.setCaretPosition(0);
	}

	private void saveClicked() {
		// we make use of the fact that we saved the BB here!
		final String userInput = pnlEditor.getText();
		byte[] uiBytes = userInput.getBytes(StandardCharsets.ISO_8859_1);
		Charset cs = VmwareConfig.getCharset(uiBytes, uiBytes.length);
		// cs is now either the detected encoding, or latin1 as a default
		uiBytes = userInput.getBytes(cs);
		// now we should have the correct bytes...
		VmMetaData<?, ?, ?, ?, ?> metaCandidate = null;
		try {
			metaCandidate = VmMetaData.getInstance(MetaDataCache.getOperatingSystems(), uiBytes,
					uiBytes.length);
		} catch (IOException e) {
			LOGGER.error("Could not get VmMetaData instance from given machine description: ", e);
		}
		if (metaCandidate == null) {
			dispose();
			return;
		}

		byte[] uiBytesFiltered = metaCandidate.getDefinitionArray();
		final String userInputFiltered;
		if (metaCandidate instanceof VboxMetaData) {
			userInputFiltered = XmlHelper.getFormattedXml(new ByteArrayInputStream(uiBytesFiltered));
		} else {
			userInputFiltered = new String(uiBytesFiltered, cs);
		}
		// So here we have:
		// - uiBytes is the unfiltered user input
		// - uiBytesFiltered is the user input filtered by VmwareMetaData
		TreeSet<String> unfilteredSet = stringToTreeSet(userInput);
		TreeSet<String> filteredSet = stringToTreeSet(userInputFiltered);
		if (!filteredSet.equals(unfilteredSet)) {
			unfilteredSet.removeAll(filteredSet);
			// not equals, means there was some invalid input
			String errorText = "Invalide Eingaben:\n";
			for (String s : unfilteredSet) {
				errorText += s + "\n";
			}
			errorText += System.lineSeparator()
					+ "Wollen Sie trotzdem speichern? (Die invaliden Zeilen werden dabei automatisch gelöscht.)";
			if (!Gui.showMessageBox(errorText, MessageType.ERROR_RETRY, LOGGER, null))
				return;
		}
		ByteBuffer toSave;
		if (metaCandidate instanceof VboxMetaData) {
			String unformattedInput = XmlHelper.getUnformattedXml(new ByteArrayInputStream(uiBytesFiltered));
			toSave = ByteBuffer.wrap(unformattedInput.getBytes(cs));
		} else {
			toSave = ByteBuffer.wrap(uiBytesFiltered);
		}
		// we have a valid vmx or the user accepted to push the filtered input
		actionHandler.setVirtualizerConfig(imageVersionId, toSave, new VirtConfCallback() {
			@Override
			public void virtConfCallback(boolean success) {
				if (success) {
					configWasSaved = true;
					dispose();
				}
			}
		});
	}

	private TreeSet<String> stringToTreeSet(final String s) {
		String[] split = s.split("[\\r\\n]+");
		List<String> splitList = new ArrayList<String>(Arrays.asList(split));
		splitList.removeAll(Arrays.asList("", null));
		TreeSet<String> set = new TreeSet<String>(splitList);
		return set;
	}

	public static boolean open(Window modalParent, final ImageDetailsActions handler,
			final String imageVersionId, final String currentmachineDescription,
			final String originalMachineDescription) {
		VirtConfigEditorWindow win = new VirtConfigEditorWindow(modalParent, handler, imageVersionId,
				currentmachineDescription, originalMachineDescription);
		win.setVisible(true);
		return win.configWasSaved;
	}

	private void safeClose() {
		if (originalMachineDescription.equals(pnlEditor.getText()) || Gui.showMessageBox(me,
				"Ihre Änderungen, in diesem Fenster, werden verloren gehen, wollen Sie trotzdem abbrechen?",
				MessageType.QUESTION_YESNO, null, null))
			dispose();
	}

	@Override
	public boolean wantConfirmQuit() {
		return !originalMachineDescription.equals(pnlEditor.getText());
	}

	@Override
	public void escapePressed() {
		safeClose();
	}
}