/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.soapui.integration.exporter; import com.eviware.soapui.SoapUI; import com.eviware.soapui.impl.wsdl.WsdlProject; import com.eviware.soapui.impl.wsdl.support.ExternalDependency; import com.eviware.soapui.model.project.ProjectFactoryRegistry; import com.eviware.soapui.support.SoapUIException; import org.apache.commons.io.FileUtils; import org.apache.xmlbeans.XmlException; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; /** * Project exporting means that copy of existing project with copies of all * external dependencies will be put in one directory and packed together. * <p/> * Project copy will resolve all its dependency to dependency copies. Paths have * to be relative to the project file. * * @author robert */ public class ProjectExporter { private static final int BUFFER = 1024; private WsdlProject project; private WsdlProject projectCopy; private final int TEMP_DIR_ATTEMPTS = 10000; private File tmpDir; public ProjectExporter(WsdlProject project) { this.project = project; } /** * Creates packed project on given path * * @param exportPath * @return * @throws SoapUIException * @throws XmlException * @throws IOException */ public boolean exportProject(String exportPath) throws IOException, XmlException, SoapUIException { boolean result = false; if ((tmpDir = createTemporaryDirectory()) != null) { if (createProjectCopy()) { if (copyDependencies()) { projectCopy.setResourceRoot("${projectDir}"); projectCopy.save(); if (packageAll(exportPath)) { result = true; } } } deleteDir(tmpDir); } return result; } /** * Compress temporary directory and save it on given path. * * @param exportPath * @return * @throws IOException */ private boolean packageAll(String exportPath) { if (!exportPath.endsWith(".zip")) { exportPath = exportPath + ".zip"; } BufferedInputStream origin = null; ZipOutputStream out; boolean result = true; try { FileOutputStream dest = new FileOutputStream(exportPath); out = new ZipOutputStream(new BufferedOutputStream(dest)); byte data[] = new byte[BUFFER]; // get a list of files from current directory String files[] = tmpDir.list(); for (int i = 0; i < files.length; i++) { // System.out.println( "Adding: " + files[i] ); FileInputStream fi = new FileInputStream(new File(tmpDir, files[i])); origin = new BufferedInputStream(fi, BUFFER); ZipEntry entry = new ZipEntry(files[i]); out.putNextEntry(entry); int count; while ((count = origin.read(data, 0, BUFFER)) != -1) { out.write(data, 0, count); } origin.close(); } out.close(); } catch (IOException e) { // TODO: handle exception result = false; SoapUI.logError(e, "Error packaging export"); } return result; } public static void unpackageAll(String archive, String path) { try { BufferedOutputStream dest = null; FileInputStream fis = new FileInputStream(archive); ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis)); ZipEntry entry; while ((entry = zis.getNextEntry()) != null) { int count; byte data[] = new byte[BUFFER]; // write the files to the disk FileOutputStream fos = new FileOutputStream(path + File.separator + entry.getName()); dest = new BufferedOutputStream(fos, BUFFER); while ((count = zis.read(data, 0, BUFFER)) != -1) { dest.write(data, 0, count); } dest.flush(); dest.close(); } zis.close(); } catch (Exception e) { SoapUI.logError(e); } } public static List<String> getZipContents(String archive) { List<String> contents = new ArrayList<String>(); try { ZipFile zipFile = new ZipFile(archive); for (Enumeration<? extends ZipEntry> em1 = zipFile.entries(); em1.hasMoreElements(); ) { contents.add(em1.nextElement().toString()); } } catch (ZipException ze) { SoapUI.logError(ze); } catch (IOException e) { SoapUI.logError(e); } return contents; } /** * Do actual dependency copying and update project's copy dependency path. * * @throws IOException */ private boolean copyDependencies() throws IOException { boolean result = true; projectCopy.setResourceRoot("${projectDir}"); List<ExternalDependency> dependencies = projectCopy.getExternalDependencies(); for (ExternalDependency dependency : dependencies) { switch (dependency.getType()) { case FILE: File originalDependency = new File(dependency.getPath()); if (originalDependency.exists()) { File targetDependency = new File(tmpDir, originalDependency.getName()); FileUtils.copyFile(originalDependency, targetDependency); dependency.updatePath(targetDependency.getPath()); } else { SoapUI.log.warn("Do not exists on local file system [" + originalDependency.getPath() + "]"); } break; case FOLDER: originalDependency = new File(dependency.getPath()); File targetDependency = new File(tmpDir, originalDependency.getName()); targetDependency.mkdir(); FileUtils.copyDirectory(originalDependency, targetDependency, false); dependency.updatePath(targetDependency.getPath()); break; default: break; } } return result; } /** * Creates project copy and save it in temporary directory. Set copy's * project path and resource root to ${projectDir} * * @return * @throws IOException * @throws SoapUIException * @throws XmlException */ private boolean createProjectCopy() throws IOException, XmlException, SoapUIException { project.saveIn(new File(tmpDir, project.getName() + "-soapui-project.xml")); projectCopy = (WsdlProject) ProjectFactoryRegistry.getProjectFactory("wsdl").createNew( new File(tmpDir, project.getName() + "-soapui-project.xml").getAbsolutePath());//new WsdlProject( new File( tmpDir, project.getName() + ".xml" ).getAbsolutePath() ); return projectCopy != null; } /** * Creates temporary directory where package will be created * * @return if operation is successuful */ private File createTemporaryDirectory() { File baseDir = new File(System.getProperty("java.io.tmpdir")); String baseName = System.currentTimeMillis() + "-"; for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) { File tempDir = new File(baseDir, baseName + counter); if (tempDir.mkdir()) { return tempDir; } } return null; } private boolean deleteDir(File dir) { if (dir.isDirectory()) { String[] children = dir.list(); for (int i = 0; i < children.length; i++) { boolean success = deleteDir(new File(dir, children[i])); if (!success) { return false; } } } // The directory is now empty so delete it return dir.delete(); } }