// ============================================================================
//
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
//
// This source code is available under agreement available at
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
//
// You should have received a copy of the agreement
// along with this program; if not, write to Talend SA
// 9 rue Pages 92150 Suresnes, France
//
// ============================================================================
package org.talend.repository.ui.wizards.exportjob.scriptsmanager.petals;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
/**
* A set of utility methods used to create a Petals service assembly for the Talend SE.
*
* @author Vincent Zurczak - EBM WebSourcing
*/
public class SaUtils {
/**
* Creates a service assembly file for the Petals Talend SE.
* <p>
* The SU name and file name will be computed from the SA file path.
* </p>
*
* @param suFile the SU file
* @param saFilePath the path of the target SA
* @param jobDescription the job description (not null)
* @return the created SA file, or null if the creation failed
*/
public static File createSaForTalend(File suFile, String saFilePath, String jobDescription) {
IPath saPath = new Path(saFilePath);
String saName = saPath.lastSegment();
if (saName.endsWith(".zip")) //$NON-NLS-1$
saName = saName.substring(0, saName.length() - 4);
String suName = saName.replace("sa-", "su-"); //$NON-NLS-1$ //$NON-NLS-2$
String jbiXmlContent = generateJbiXmlForTalendSA(saName, jobDescription, suName);
Map<String, File> entries = new HashMap<String, File>(1);
entries.put(suName + ".zip", suFile); //$NON-NLS-1$
File saFile = null;
try {
saFile = createJbiArchive(saFilePath, jbiXmlContent, entries);
} catch (IOException e) {
e.printStackTrace();
}
return saFile;
}
/**
* Creates the jbi.xml content for a Petals SA.
*
* @param saName the SA name (not the service assembly file name).
* <p>
* Service assembly names look like <i>sa-Jsr181-<serviceName>-provide</i>.
* </p>
*
* @param jobDescription the job description (not null)
*
* @param suNames the SU names (not the service-unit file names).
* <p>
* Service unit names look like <i>su-Jsr181-<serviceName>-provide</i>.
* </p>
*
* @return the jbi.xml content
*/
public static String generateJbiXmlForTalendSA(String saName, String jobDescription, String... suNames) {
// Content of the jbi.xml file
StringBuilder sb = new StringBuilder();
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); //$NON-NLS-1$
sb.append("<jbi:jbi version=\"1.0\"\n"); //$NON-NLS-1$
sb.append("\txmlns=\"http://java.sun.com/xml/ns/jbi\"\n"); //$NON-NLS-1$
sb.append("\txmlns:jbi=\"http://java.sun.com/xml/ns/jbi\">\n\n"); //$NON-NLS-1$
sb.append("\t<jbi:service-assembly>\n\t\t<jbi:identification>\n"); //$NON-NLS-1$
sb.append("\t\t\t<jbi:name>" + saName + "</jbi:name>\n"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("\t\t\t<jbi:description>" + jobDescription + "</jbi:description>\n"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("\t\t</jbi:identification>\n"); //$NON-NLS-1$
for (String suName : suNames) {
sb.append("\n\t\t<!-- New service-unit -->\n"); //$NON-NLS-1$
sb.append("\t\t<jbi:service-unit>\n\t\t\t<jbi:identification>\n"); //$NON-NLS-1$
sb.append("\t\t\t\t<jbi:name>" + suName + "</jbi:name>\n"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("\t\t\t\t<jbi:description>" + jobDescription + "</jbi:description>\n"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("\t\t\t</jbi:identification>\n\n"); //$NON-NLS-1$
sb.append("\t\t\t<jbi:target>\n"); //$NON-NLS-1$
sb.append("\t\t\t\t<jbi:artifacts-zip>" + suName + ".zip</jbi:artifacts-zip>\n"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("\t\t\t\t<jbi:component-name>petals-se-talend</jbi:component-name>\n"); //$NON-NLS-1$
sb.append("\t\t\t</jbi:target>\n\t\t</jbi:service-unit>\n"); //$NON-NLS-1$
}
sb.append("\t</jbi:service-assembly>\n"); //$NON-NLS-1$
sb.append("</jbi:jbi>"); //$NON-NLS-1$
return sb.toString();
}
/**
* Creates a service-unit or a service assembly file.
*
* @param targetZipFile the path of the target ZIP file
* @param jbiXmlContent the jbi.xml file content, or null to not add a jbi.xml
* @param entries key = zip entry, value = file to zip (not null)
* @return the created archive in case of success, null otherwise
* @throws IOException
*/
public static File createJbiArchive(String targetZipFile, String jbiXmlContent, Map<String, File> entries) throws IOException {
File zipFile = new File(targetZipFile);
File temporaryFile = File.createTempFile("petalsTempFile-", null, null); //$NON-NLS-1$
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(temporaryFile));
// Files
for (Map.Entry<String, File> entry : entries.entrySet()) {
if (entry.getValue().exists()) {
InputStream in = new FileInputStream(entry.getValue());
addFileToZip(zos, in, entry.getKey());
}
}
// JBI descriptor
if (jbiXmlContent != null) {
ByteArrayInputStream in = new ByteArrayInputStream(jbiXmlContent.getBytes());
addFileToZip(zos, in, "META-INF/jbi.xml"); //$NON-NLS-1$
}
zos.close();
if (zipFile.exists() && !zipFile.delete())
zipFile.deleteOnExit();
if (!temporaryFile.renameTo(zipFile))
throw new IOException("Could not move temporary archive to target destination."); //$NON-NLS-1$
return zipFile;
}
/**
* Adds a file into a zip archive.
*
* @param out the zip file
* @param in the input stream to add into the zip
* @param entry the entry for the file to add into the zip (not null)
*/
private static void addFileToZip(ZipOutputStream out, InputStream in, String entry) {
byte[] buf = new byte[1024]; // Create a buffer for reading the files
ZipEntry ze = new ZipEntry(entry);
try {
out.putNextEntry(ze);
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.closeEntry();
} catch (Exception e) {
e.printStackTrace();
}
}
}