/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* Copyright (c) 2013, MPL CodeInside http://codeinside.ru
*/
package ru.codeinside.adm.ui;
import com.vaadin.ui.Table;
import com.vaadin.ui.Upload;
import com.vaadin.ui.Window;
import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import ru.codeinside.gses.webui.Configurator;
import ru.codeinside.gses.webui.manager.ManagerWorkplace;
import ru.codeinside.gses.webui.utils.Components;
import javax.xml.parsers.ParserConfigurationException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.jar.JarInputStream;
import java.util.zip.ZipEntry;
import static ru.codeinside.gses.webui.utils.JarParseUtils.getChildForNlByNames;
import static ru.codeinside.gses.webui.utils.JarParseUtils.isOsgiComponent;
import static ru.codeinside.gses.webui.utils.JarParseUtils.readXml;
final class UploadDeployer implements Upload.Receiver, Upload.SucceededListener {
private static final long serialVersionUID = 11324239231L;
String filename;
byte[] fileData;
final ServicesTable table;
public UploadDeployer(ServicesTable table) {
this.table = table;
}
@Override
public OutputStream receiveUpload(String name, String mimeType) {
filename = name;
return new ByteArrayOutputStream() {
@Override
public void close() throws IOException {
fileData = Arrays.copyOf(buf, count);
}
};
}
@Override
public void uploadSucceeded(Upload.SucceededEvent event) {
try {
checkSupportInterface(event, "ru.codeinside.gws.api.Server");
String name = filename.substring(0, filename.length() - 4);
Configurator.getDeployer().deploy(new ByteArrayInputStream(fileData), "--name=" + name, "--availabilityenabled=true", "--type=osgi", "--target=server");
table.reload();
} catch (Exception e) {
e.printStackTrace();
String errorMessage = e.getMessage() != null ? e.getMessage() : "Ошибка развертывания, смотрите лог файл";
Components.showMessage(event, errorMessage, Window.Notification.TYPE_ERROR_MESSAGE);
}
}
private void checkSupportInterface(Upload.SucceededEvent event, String supportedInterface) throws Exception {
if (!event.getFilename().endsWith(".jar")) {
throw new Exception("Нужен jar файл");
}
JarInputStream jarStream = null;
try {
jarStream = new JarInputStream(new ByteArrayInputStream(fileData));
if (!isOsgiComponent(jarStream)) {
throw new Exception("Нужен osgi компонент");
}
if (!hasApiServer(supportedInterface, jarStream)) {
throw new Exception("Не реализует интерфейс [" + supportedInterface + "]");
}
} finally {
if (jarStream != null) {
jarStream.close();
}
}
}
//TODO переделать for(некорректно работает с getNextEntry)
private boolean hasApiServer(String supportedInterface, JarInputStream jarStream) throws IOException, SAXException, ParserConfigurationException {
for (String xmlPath : jarStream.getManifest().getMainAttributes().getValue("Service-Component").split(",")) {
ZipEntry nextZipEntry = jarStream.getNextEntry();
while (nextZipEntry != null && !xmlPath.equals(nextZipEntry.getName())) {
nextZipEntry = jarStream.getNextEntry();
}
Document xmlDoc = readXml(jarStream);
Node node = getChildForNlByNames(xmlDoc.getChildNodes(), "component", "service", "provide");
if (node != null) {
String interfaceValue = node.getAttributes().getNamedItem("interface").getNodeValue();
if (StringUtils.isNotEmpty(interfaceValue) && supportedInterface.equals(interfaceValue.trim())) {
return true;
}
}
}
return false;
}
}