blob: fb2d9260ad10904c224fdfa0fa37665feccb130d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2010 Sybase, Inc. and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Sybase, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.jsf.test.util;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import junit.framework.Assert;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.wst.validation.ValidationFramework;
import org.osgi.framework.Bundle;
/**
* Test utility to create project and its files.
*
* @author Yang Liu, Xiao-guang Zhang
*
* @version
*/
public class TestUtil
{
/**
*
* @param prjname
* @param path
* relative to this plugin's root folder.
* @return
* @throws Exception
*/
public static IProject createProjectFromZip(Bundle bundle, String prjname,
String path) throws Exception
{
URL url = FileLocator.find(bundle, new Path(path), null);
// if this fails, it most likely that path is wrong.
Assert.assertNotNull(url);
return createProjectFromZip(prjname, url);
}
public static IProject createProjectFromZip(File file, String prjname)
throws Exception
{
URL url = file.toURL();
// if this fails, it most likely that path is wrong.
Assert.assertNotNull(url);
return createProjectFromZip(prjname, url);
}
/**
* build a project
*
* @param project
* @param monitor
*/
public static void buildProject(IProject project, IProgressMonitor monitor)
{
try
{
project.build(IncrementalProjectBuilder.FULL_BUILD, monitor);
} catch (CoreException e)
{
e.printStackTrace(System.err);
}
}
/**
* expand the zip stream into the specified folder.
*
* @param url
* @param dir
* @throws Exception
*/
private static void expandZip(URL url, IContainer dir) throws Exception
{
ZipInputStream zis = null;
try
{
// first, count number of items in zip file
zis = new ZipInputStream(url.openStream());
String prefix = getPrefix(zis);
zis = new ZipInputStream(url.openStream());
ZipEntry ze = zis.getNextEntry();
while (ze != null)
{
String name = ze.getName();
if (!name.startsWith(prefix))
{
ze = zis.getNextEntry();
continue;
}
name = name.substring(prefix.length());
if (ze.isDirectory())
{
IFolder folder = dir.getFolder(new Path(name));
if (!folder.exists())
{
ensurePath(folder);
folder.create(true, true, null);
}
} else
{
IFile file = dir.getFile(new Path(name));
ensurePath(file);
// use ZipStreamWrapper to prevent zis being closed
if (file.exists())
{
file.setContents(new ZipStreamWrapper(zis),
IResource.NONE, null);
} else
{
file.create(new ZipStreamWrapper(zis), true, null);
}
}
ze = zis.getNextEntry();
}
} finally
{
try
{
if (zis != null)
zis.close();
} catch (Exception ex)
{
// ignore
}
}
}
private static String getPrefix(ZipInputStream zipStream)
throws IOException
{
ZipEntry ze = zipStream.getNextEntry();
while (ze != null)
{
String name = ze.getName();
if (name != null && name.endsWith(".project") && !ze.isDirectory())
{
int index = name.lastIndexOf(".project");
return name.substring(0, index);
}
ze = zipStream.getNextEntry();
}
// if we get to here, then nothing to prepend
return "";
}
/**
* @param file
* @throws CoreException
*/
private static void ensurePath(IResource file) throws CoreException
{
IContainer container = file.getParent();
if (!container.exists())
{
ensurePath(container);
((IFolder) container).create(true, true, null);
}
}
/**
* this method will copy file from the sourcePath folder of this plugin into
* the target path related with the destination project.
*
* @param project
* @param sourcePath
* - Source path, must be a relative path to test plugin
* @param targetPath
* - Target path, must be relative path to eclispe project.
*
* @return
*/
public static IFile copyFile(Bundle bundle, IProject project,
String targetPath, String sourcePath) throws Exception
{
URL url = FileLocator.find(bundle, new Path(sourcePath), null);
InputStream stream = url.openStream();
IFile file = null;
IPath path = new Path(sourcePath);
if (targetPath != null && targetPath.length() > 0)
{
IFolder folder = project.getFolder(targetPath);
file = folder.getFile(path.lastSegment());
} else
{
file = project.getFile(path.lastSegment());
}
if (!file.exists())
{
ensurePath(file);
file.create(stream, true, null);
} else
{
file.setContents(stream, IFile.FORCE, null);
}
return file;
}
/**
* this method will create page file from the "pages" folder of this plugin
* into the webroot folder of the destination project.
*
* @param filePath
* - file path, must be relative path to destination project.
*
* @return
*/
public static IFile createFile(IProject project, String filePath,
String content) throws Exception
{
IFile file = project.getFile(filePath);
ensurePath(file);
ByteArrayInputStream stream = new ByteArrayInputStream(
content.getBytes());
file.create(stream, true, null);
return file;
}
/**
* this method will get the page file from the "pages" folder of this plugin
* as a string.
*
* @param path
* - related with plugin
* @return
* @throws Exception
*/
public static String getFileAsString(String path) throws Exception
{
URL url = FileLocator.find(Activator.getDefault().getBundle(),
new Path(path), null);
InputStream stream = url.openStream();
BufferedReader reader = new BufferedReader(
new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
char[] temp = new char[256];
int count;
while ((count = reader.read(temp)) > 0)
{
buffer.append(temp, 0, count);
}
reader.close();
stream.close();
return buffer.toString();
}
/**
* create a project from a zip file.
*
* @param prjname
* @param zipStream
* @throws Exception
*/
private static IProject createProjectFromZip(final String prjname,
final URL url) throws Exception
{
final IProject[] holder = new IProject[1];
IWorkspaceRunnable r = new IWorkspaceRunnable()
{
public void run(IProgressMonitor monitor) throws CoreException
{
IProject prj = ResourcesPlugin.getWorkspace().getRoot()
.getProject(prjname);
if (!prj.exists())
{
prj.create(null);
}
prj.open(null);
ValidationFramework.getDefault().suspendValidation(prj, true);
try
{
expandZip(url, prj);
} catch (Exception ex)
{
throw new CoreException(new Status(0, Activator.PLUGIN_ID,
0, ex.getMessage(), ex));
}
holder[0] = prj;
}
};
ResourcesPlugin.getWorkspace().run(r, null);
return holder[0];
}
public static String removeAllWhitespace(String s)
{
StringBuffer buffer = new StringBuffer(s.length());
for (int i = 0, length = s.length(); i < length; i++)
{
if (!Character.isWhitespace(s.charAt(i)))
{
buffer.append(s.charAt(i));
}
}
return buffer.toString();
}
/**
* remove resource, following schedule rule.
*
* @param prj
* @throws CoreException
*/
public static void removeResource(final IResource prj) throws CoreException
{
if (prj instanceof IFile)
{
((IFile) prj).delete(true, false, null);
return;
}
Job job = new Job("DeleteProject")
{
protected IStatus run(IProgressMonitor monitor)
{
try
{
prj.delete(true, monitor);
} catch (CoreException e)
{
return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
}
};
job.setPriority(Job.SHORT);
job.setRule(ResourcesPlugin.getWorkspace().getRoot());
job.schedule();
// wait
try
{
job.join();
} catch (InterruptedException e)
{
}
}
private final static boolean PROJECT_IS_OPEN = true;
public static boolean verifyProjectStatus(final IProject project,
final boolean isOpenCondition, final int waitTimeInMs)
{
return TestUtil.waitForCondition(
createProjectStatusCondition(project, isOpenCondition),
waitTimeInMs, 20);
}
public static TestCondition createProjectStatusCondition(
final IProject project, final boolean isOpenCondition)
{
return new TestCondition()
{
@Override
public boolean test()
{
return project.isOpen() == isOpenCondition;
}
};
}
public static boolean openProject(final IProject project,
final int waitTimeInMs) throws CoreException
{
project.open(null);
return verifyProjectStatus(project, PROJECT_IS_OPEN, waitTimeInMs);
}
public static boolean closeProject(final IProject project,
final int waitTimeInMs) throws CoreException
{
project.close(null);
return verifyProjectStatus(project, !PROJECT_IS_OPEN, waitTimeInMs);
}
public static boolean waitForCondition(final TestCondition condition,
final int maxTime, final int numIntervals)
{
int curIteration = 0;
int waitPerInterval = maxTime / numIntervals;
if (waitPerInterval < 1)
{
Assert.fail("Your wait interval is less than 1");
}
do
{
if (condition.test())
{
return true;
}
try
{
Thread.sleep(waitPerInterval);
} catch (InterruptedException e)
{
// ignore.
}
} while (curIteration++ < numIntervals);
// if we get to here, then the condition was not satisified in the
// time alloted
return false;
}
public static abstract class TestCondition
{
public abstract boolean test();
}
public static class CompositeTestCondition extends TestCondition
{
protected final List<? extends TestCondition> _conditions;
public CompositeTestCondition(
final List<? extends TestCondition> conditions)
{
super();
_conditions = Collections
.unmodifiableList(new ArrayList<TestCondition>(conditions));
}
public void dispose()
{
// do nothing by default
}
@Override
public boolean test()
{
boolean isSatisfied = true;
for (final TestCondition condition : _conditions)
{
isSatisfied &= condition.test();
}
return isSatisfied;
}
}
}