/* ====================================================================
*
* The ObjectStyle Group Software License, Version 1.0
*
* Copyright (c) 2002 - 2006 The ObjectStyle Group
* and individual authors of the software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* ObjectStyle Group (http://objectstyle.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "ObjectStyle Group" and "Cayenne"
* must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact andrus@objectstyle.org.
*
* 5. Products derived from this software may not be called "ObjectStyle"
* nor may "ObjectStyle" appear in their names without prior written
* permission of the ObjectStyle Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the ObjectStyle Group. For more
* information on the ObjectStyle Group, please see
* <http://objectstyle.org/>.
*
*/
package org.objectstyle.wolips.builder.internal;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.objectstyle.wolips.baseforplugins.AbstractBaseActivator;
import org.objectstyle.wolips.baseforplugins.util.FileUtilities;
import org.objectstyle.wolips.builder.BuilderPlugin;
import org.objectstyle.wolips.core.resources.types.project.ProjectAdapter;
/**
* @author Harald Niesche
*/
public abstract class BuildHelper extends ResourceUtilities implements IResourceDeltaVisitor, IResourceVisitor {
private IProject _project;
private IPath _distPath;
private List _buildTasks = new ArrayList();
private int _buildWork = 0;
/**
* @author Harald Niesche
*
* A single resource-related task (copy or delete a resource, see
* subclasses)
*/
public static interface Buildtask {
/**
* @return
*/
public int amountOfWork();
/**
* @param m
* @throws CoreException
*/
public void doWork(IProgressMonitor m) throws CoreException;
}
/**
* @author Harald Niesche
*
*/
public static abstract class BuildtaskAbstract implements Buildtask {
/*
* (non-Javadoc)
*
* @see
* org.objectstyle.wolips.projectbuild.builder.WOIncrementalBuilder.
* WOBuildHelper.Buildtask#amountOfWork()
*/
/**
* @return Returns the amount of work.
*/
public int amountOfWork() {
return (_workAmount);
}
protected int _workAmount = 1000;
protected AbstractBaseActivator _getLogger() {
return BuilderPlugin.getDefault();
}
}
/**
* @author Harald Niesche
*
*/
public static class CopyTask extends BuildtaskAbstract {
/**
* @param res
* @param destination
* @param msgPrefix
*/
public CopyTask(IResource res, IPath destination, String msgPrefix) {
_res = res;
_dest = destination;
_msgPrefix = msgPrefix;
_workAmount = 1000;
// if (res instanceof IFile) {
// File localFile = ((IFile)res).getLocation().toFile();
//
// if (localFile.exists()) {
// _workAmount = (int)localFile.length(); // if the file is
// larger than 2G, we have a problem anyway
// }
// }
}
/*
* (non-Javadoc)
*
* @see
* org.objectstyle.wolips.projectbuild.builder.WOIncrementalBuilder.
* WOBuildHelper
* .Buildtask#doWork(org.eclipse.core.runtime.IProgressMonitor)
*/
public void doWork(IProgressMonitor m) throws CoreException {
String error = null;
try {
int n = _dest.segmentCount() - 3;
IPath dstShortened = _dest;
if (n > 0) {
dstShortened = _dest.removeFirstSegments(n);
}
m.subTask("create " + dstShortened);
ResourceUtilities.copyDerived(_res, _dest, m);
_getLogger().debug("copy " + _res + " -> " + _dest);
} catch (CoreException up) {
error = " *failed* to copy resource " + _res + " -> " + _dest + " (" + up.getMessage() + ")";
_getLogger().debug(_msgPrefix + error, up);
// up.printStackTrace();
// m.setCanceled(true);
// throw up;
} catch (RuntimeException up) {
error = " *failed* to copy resource " + _res + " -> " + _dest + " (" + up.getMessage() + ")";
_getLogger().log(_msgPrefix + error, up);
// up.printStackTrace();
// throw up;
}
if (null == error) {
// _res.deleteMarkers(IMarker.PROBLEM, true, 1);
_res.deleteMarkers(BuilderPlugin.MARKER_BUILD_PROBLEM, true, 0);
} else {
markResource(_res, BuilderPlugin.MARKER_BUILD_PROBLEM, IMarker.SEVERITY_ERROR, error, _dest.toString());
}
}
IResource _res;
IPath _dest;
String _msgPrefix;
}
/**
* @author Harald Niesche
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public static class DeleteTask extends BuildtaskAbstract {
/**
* @param path
* @param msgPrefix
*/
public DeleteTask(IPath path, String msgPrefix) {
_workAmount = 1000;
_path = path;
_msgPrefix = msgPrefix;
}
/*
* (non-Javadoc)
*
* @see
* org.objectstyle.wolips.projectbuild.builder.WOIncrementalBuilder.
* WOBuildHelper
* .Buildtask#doWork(org.eclipse.core.runtime.IProgressMonitor)
*/
public void doWork(IProgressMonitor m) throws CoreException {
if (_path == null) {
// this really really should not happen! (again ...)
throw new OperationCanceledException("(deleting a null path wipes the workspace)");
}
boolean deletedUnderlyingFile = false;
IResource res = getWorkspaceRoot().findMember(_path);
if (res != null) {
// IContainer parentFolder = res.getParent();
File file = res.getLocation().toFile();
if (file.exists()) {
FileUtilities.deleteRecursively(file);
deletedUnderlyingFile = true;
}
res.refreshLocal(IResource.DEPTH_ONE, m);
}
if (!deletedUnderlyingFile) {
IFile theFile = getWorkspaceRoot().getFile(_path);
IContainer theFolder = getWorkspaceRoot().getFolder(_path);
if (theFolder instanceof IFolder && theFolder.exists()) {
_getLogger().debug(_msgPrefix + " delete " + _path);
m.subTask("delete " + _path);
((IFolder) theFolder).delete(true, true, null);
} else if (theFile != null && theFile.exists()) {
_getLogger().debug(_msgPrefix + " delete " + _path);
m.subTask("delete " + _path);
theFile.delete(true, true, null);
}
}
}
IPath _path;
String _msgPrefix;
}
/**
* The constructor
*/
public BuildHelper() {
super();
}
/**
* @param project
*/
public void reinitForNextBuild(IProject project) {
_project = project;
_distPath = new Path("dist");
_buildWork = 0;
_buildTasks = new ArrayList();
}
/**
* @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(IResourceDelta)
*/
public boolean visit(IResourceDelta delta) throws CoreException {
return _visitResource(delta.getResource(), delta);
}
/**
* @see org.eclipse.core.resources.IResourceVisitor#visit(IResource)
*/
public boolean visit(IResource resource) throws CoreException {
return _visitResource(resource, null);
}
private boolean _visitResource(IResource res, IResourceDelta delta) throws CoreException {
IPath resPath = res.getProjectRelativePath();
if (this.getBuildPath().isPrefixOf(resPath) || _distPath.isPrefixOf(resPath)) {
return false;
}
boolean handleResourceChildren = handleResource(res, delta);
return handleResourceChildren;
}
/**
* @param task
*/
public synchronized void addTask(Buildtask task) {
_buildTasks.add(task);
_buildWork += task.amountOfWork();
}
/**
* @param m
* @throws CoreException
*/
public void executeTasks(IProgressMonitor progressMonitor) throws CoreException {
SubProgressMonitor subProgressMonitor = new SubProgressMonitor(progressMonitor, 41);
subProgressMonitor.beginTask("building ...", _buildWork);
Iterator iter = _buildTasks.iterator();
while (iter.hasNext()) {
Buildtask thisTask = (Buildtask) iter.next();
thisTask.doWork(subProgressMonitor);
subProgressMonitor.worked(thisTask.amountOfWork());
if (subProgressMonitor.isCanceled()) {
throw new OperationCanceledException();
}
}
subProgressMonitor.done();
}
protected AbstractBaseActivator _getLogger() {
return BuilderPlugin.getDefault();
}
public abstract boolean handleResource(IResource res, IResourceDelta delta) throws CoreException;
public IProject getProject() {
return _project;
}
/**
* @return
*
*/
public IJavaProject getJavaProject() {
return JavaCore.create(getProject());
}
/**
* @return
*/
// public String getStringProperty(String key) {
// String result = "";
// try {
// result =
// getProject().getPersistentProperty(new QualifiedName("", key));
// } catch (CoreException up) {
// up.printStackTrace();
// }
//
// return (result);
// }
//
// public void setStringProperty(String key, String value) {
// try {
// getProject().setPersistentProperty(
// new QualifiedName("", key),
// value);
// } catch (CoreException up) {
// up.printStackTrace();
// }
//
// }
//
// public boolean getBooleanProperty(String key) {
// return ("true".equals(getStringProperty(key)));
// }
//
// public void setBooleanProperty(String key, boolean value) {
// setStringProperty(key, value ? "true" : "false");
// }
public boolean isFramework() {
// return (getBooleanProperty(FRAMEWORK_PROPERTY));
ProjectAdapter project = (ProjectAdapter) (this.getProject()).getAdapter(ProjectAdapter.class);
return (project.isFramework());
}
// public void setIsFramework(boolean isFramework) {
// setBooleanProperty(FRAMEWORK_PROPERTY, isFramework);
// }
/**
* either name.woa or name.framework
*
* @return
*/
public String getResultName() {
String name = getProject().getName();
if (isFramework()) {
return (name + ".framework");
}
return (name + ".woa");
}
/**
* @return
*/
public IPath getBuildPath() {
return (getProject().getFullPath().append("build"));
}
/**
* @return
*/
public IPath getResultPath() {
return (getBuildPath().append(getResultName()));
}
/**
* @return
*/
public IPath getInfoPath() {
if (isFramework()) {
return (getResultPath().append("Resources"));
}
return (getResultPath().append(APPINFO_PATH));
}
/**
* @return
*/
public IPath _getResultPath() {
if (isFramework()) {
return (getResultPath());
}
return (getResultPath().append(APPINFO_PATH));
}
/**
* @return
*/
public IPath getResourceOutputPath() {
return (_getResultPath().append(RESOURCE_PATH));
}
/**
* @return
*/
public IPath getJavaOutputPath() {
return (_getResultPath().append(JAVA_PATH));
}
/**
* @return
*/
public IPath getWebResourceOutputPath() {
return (_getResultPath().append(WEBRESOURCE_PATH));
}
/**
* @return
*/
public String getResourceName() {
String result = "";
if (!isFramework()) {
result += APPINFO_PATH + "/";
}
result += RESOURCE_PATH;
return (result);
}
/**
* @return
*/
public String getWebResourceName() {
String result = "";
if (!isFramework()) {
result += APPINFO_PATH + "/";
}
result += WEBRESOURCE_PATH;
return (result);
}
/* ************************************************************************ */
// public IPath getDestinationPath(IResource res) {
//
// IPath fullPath = res.getFullPath();
//
// if (getBuildPath().isPrefixOf(fullPath)) {
// return (null);
// }
//
// try {
// if (!getJavaProject()
// .getOutputLocation()
// .equals(getJavaProject().getPath())
// && getJavaProject().getOutputLocation().isPrefixOf(fullPath)) {
// return (null);
// }
// } catch (CoreException up) {
// up.printStackTrace();
// }
//
// IPath result = asResourcePath(fullPath, res);
// if (null == result)
// result = asWebResourcePath(fullPath, res);
//
// return (result);
// }
private IPath _appendSpecial(IPath destinationPrefix, IPath source) {
String segments[] = source.segments();
int n = segments.length - 1;
for (int i = n; i >= 0; --i) {
if (segments[i].endsWith(".lproj")) {
n = i;
if (segments[i].toLowerCase().startsWith("nonlocalized")) {
n = i + 1;
}
}
}
IPath tmp = destinationPrefix;
while (n < segments.length) {
tmp = tmp.append(segments[n++]);
}
return (tmp);
}
/**
* @param path
* @param res
* @return
*/
public IPath asResourcePath(IPath path, IResource res) {
if (IResource.FILE == res.getType() || IResource.FOLDER == res.getType()) {
String lastSegment = path.lastSegment();
if ((-1 == path.toString().indexOf(".eomodeld/")) && (-1 == path.toString().indexOf(".wo/"))) {
return (_appendSpecial(getResourceOutputPath(), path));
}
String parentName = res.getParent().getName();
if (parentName.endsWith(".wo") || parentName.endsWith(".eomodeld")) {
return (_appendSpecial(getResourceOutputPath(), res.getParent().getProjectRelativePath()).append(lastSegment));
// return
// (getResourceOutputPath().append(parentName).append(lastSegment));
}
}
return (null);
}
/**
* @param path
* @param res
* @return
*/
public IPath asWebResourcePath(IPath path, IResource res) {
if (IResource.FILE == res.getType() || IResource.FOLDER == res.getType()) {
return _appendSpecial(getWebResourceOutputPath(), path);
}
return (null);
}
/* ************************************************************************ */
// public static IncrementalNature s_getNature(IProject project) {
// try {
// if (project.hasNature(INCREMENTAL_APPLICATION_NATURE_ID)) {
// return (IncrementalNature) project.getNature(
// INCREMENTAL_APPLICATION_NATURE_ID
// );
// } else if (project.hasNature(INCREMENTAL_FRAMEWORK_NATURE_ID)) {
// return (IncrementalNature) project.getNature(
// INCREMENTAL_FRAMEWORK_NATURE_ID
// );
// }
//
// } catch (CoreException exception) {
// WOLipsLog.log(exception);
// }
// return null;
// }
// public static String getNature(boolean isFramework) {
// if (isFramework)
// return INCREMENTAL_FRAMEWORK_NATURE_ID;
// return INCREMENTAL_APPLICATION_NATURE_ID;
// }
//
// public static void s_addToProject(IProject project, boolean isFramework)
// throws CoreException {
// IProjectDescription desc = project.getDescription();
//
// String natures_array[] = desc.getNatureIds();
//
// List natures = new ArrayList(Arrays.asList(natures_array));
// if (!natures.contains(getNature(isFramework))) {
// natures.add(getNature(isFramework));
// natures_array =
// (String[]) natures.toArray(new String[natures.size()]);
// desc.setNatureIds(natures_array);
// s_setDescription(project, desc);
// }
// }
//
// public static void s_removeFromProject(
// IProject project,
// boolean isFramework)
// throws CoreException {
// IProjectDescription desc = project.getDescription();
//
// String natures_array[] = desc.getNatureIds();
//
// List natures = new ArrayList(Arrays.asList(natures_array));
//
// if (natures.contains(getNature(isFramework))) {
// natures.remove(getNature(isFramework));
// natures_array =
// (String[]) natures.toArray(new String[natures.size()]);
// desc.setNatureIds(natures_array);
// s_setDescription(project, desc);
// }
// }
//
// private static void s_setDescription(
// final IProject f_project,
// final IProjectDescription f_desc) {
// s_showProgress(new IRunnableWithProgress() {
// public void run(IProgressMonitor pm) {
// try {
// f_project.setDescription(f_desc, pm);
// } catch (CoreException up) {
// pm.done();
// }
// }
// });
// }
//
// public static void s_showProgress(IRunnableWithProgress rwp) {
// IWorkbench workbench = PlatformUI.getWorkbench();
// Shell shell = null;
// if (null != workbench) {
// IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
// if (null != window) {
// shell = window.getShell();
// }
// }
//
// ProgressMonitorDialog pmd = new ProgressMonitorDialog(shell);
//
// try {
// pmd.run(true, true, rwp);
// } catch (InvocationTargetException e) {
// // handle exception
// e.printStackTrace();
// } catch (InterruptedException e) {
// // handle cancelation
// e.printStackTrace();
// }
// }
private static final String APPINFO_PATH = "Contents";
private static final String RESOURCE_PATH = "Resources";
private static final String WEBRESOURCE_PATH = "WebServerResources";
private static final String JAVA_PATH = "Resources/Java";
}