Author: rob.stryker(a)jboss.com
Date: 2009-04-16 05:22:04 -0400 (Thu, 16 Apr 2009)
New Revision: 14768
Added:
trunk/as/plugins/org.jboss.ide.eclipse.archives.webtools/src/org/jboss/ide/eclipse/archives/webtools/modules/TestPublisher.java
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/publishers/PublishUtil.java
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/xpl/PublishCopyUtil.java
Removed:
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/xpl/PublishUtil.java
Modified:
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/publishers/JstPublisher.java
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/DeployableServerBehavior.java
Log:
JBIDE-4193
Added:
trunk/as/plugins/org.jboss.ide.eclipse.archives.webtools/src/org/jboss/ide/eclipse/archives/webtools/modules/TestPublisher.java
===================================================================
---
trunk/as/plugins/org.jboss.ide.eclipse.archives.webtools/src/org/jboss/ide/eclipse/archives/webtools/modules/TestPublisher.java
(rev 0)
+++
trunk/as/plugins/org.jboss.ide.eclipse.archives.webtools/src/org/jboss/ide/eclipse/archives/webtools/modules/TestPublisher.java 2009-04-16
09:22:04 UTC (rev 14768)
@@ -0,0 +1,290 @@
+package org.jboss.ide.eclipse.archives.webtools.modules;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+import org.eclipse.wst.server.core.IModule;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.internal.Server;
+import org.eclipse.wst.server.core.model.IModuleFile;
+import org.eclipse.wst.server.core.model.IModuleFolder;
+import org.eclipse.wst.server.core.model.IModuleResource;
+import org.eclipse.wst.server.core.model.IModuleResourceDelta;
+import org.jboss.ide.eclipse.archives.core.util.internal.TrueZipUtil;
+import org.jboss.ide.eclipse.archives.webtools.IntegrationPlugin;
+import org.jboss.ide.eclipse.as.core.JBossServerCorePlugin;
+import org.jboss.ide.eclipse.as.core.extensions.events.IEventCodes;
+import org.jboss.ide.eclipse.as.core.publishers.PublishUtil;
+import org.jboss.ide.eclipse.as.core.server.IDeployableServer;
+import org.jboss.ide.eclipse.as.core.server.IJBossServerPublisher;
+import org.jboss.ide.eclipse.as.core.server.internal.DeployableServerBehavior;
+import org.jboss.ide.eclipse.as.core.util.FileUtil;
+import org.jboss.ide.eclipse.as.core.util.FileUtil.IFileUtilListener;
+
+import de.schlichtherle.io.ArchiveDetector;
+
+public class TestPublisher extends PublishUtil implements IJBossServerPublisher {
+ private int moduleState = IServer.PUBLISH_STATE_NONE;
+ public boolean accepts(IServer server, IModule[] module) {
+ // TODO check for zip preference
+ return ModuleCoreNature.isFlexibleProject(module[0].getProject());
+ }
+
+ public int getPublishState() {
+ return moduleState;
+ }
+
+ protected IDeployableServer getDeployableServer(IServer server) {
+ return (IDeployableServer)server.loadAdapter(IDeployableServer.class, new
NullProgressMonitor());
+ }
+ protected DeployableServerBehavior getBehaviour(IServer server) {
+ return (DeployableServerBehavior)server.loadAdapter(DeployableServerBehavior.class, new
NullProgressMonitor());
+ }
+
+ protected List<IModule[]> getRemovedModules(IServer s) {
+ return getBehaviour(s).getRemovedModules();
+ }
+
+ public boolean isNew(IModule[] module, IServer s) {
+ return !getBehaviour(s).hasBeenPublished(module);
+ }
+
+
+ public IStatus publishModule(IServer server, IModule[] module,
+ int publishType, IModuleResourceDelta[] delta,
+ IProgressMonitor monitor) throws CoreException {
+ if( module.length > 1 ) {
+ return Status.OK_STATUS;
+ }
+
+ IStatus[] returnStatus;
+ // Am I a removal? If yes, remove me, and return
+ if( publishType == IJBossServerPublisher.REMOVE_PUBLISH)
+ returnStatus = removeModule(server, module);
+
+ // Am I a full publish? If yes, full publish me, and return
+ else if( publishType == IJBossServerPublisher.FULL_PUBLISH)
+ returnStatus = fullPublish(server, module);
+
+ else {
+ // Am I changed? If yes, handle my changes
+ ArrayList<IStatus> results = new ArrayList<IStatus>();
+ if( countChanges(delta) > 0) {
+ results.addAll(Arrays.asList(publishChanges(server, module)));
+ }
+
+ IModule[] children = server.getChildModules(module, new NullProgressMonitor());
+ results.addAll(Arrays.asList(handleChildrenDeltas(server, module, children)));
+
+ // Handle the removed children that are not returned by getChildModules
+ List<IModule[]> removed = getBehaviour(server).getRemovedModules();
+ Iterator<IModule[]> i = removed.iterator();
+ while(i.hasNext()) {
+ IModule[] removedArray = i.next();
+ if( removedArray[0].getId().equals(module[0].getId())) {
+ results.addAll(Arrays.asList(removeModule(server, removedArray)));
+ }
+ }
+ returnStatus = (IStatus[]) results.toArray(new IStatus[results.size()]);
+ }
+ TrueZipUtil.umount();
+
+ IStatus finalStatus;
+ if( returnStatus.length > 0 ) {
+ MultiStatus ms = new MultiStatus(JBossServerCorePlugin.PLUGIN_ID,
IEventCodes.JST_PUB_INC_FAIL,
+ "Publish Failed for module " + module[0].getName(), null); //$NON-NLS-1$
+ for( int i = 0; i < returnStatus.length; i++ )
+ ms.add(returnStatus[i]);
+ finalStatus = ms;
+ } else
+ finalStatus = Status.OK_STATUS;
+
+ return finalStatus;
+ }
+
+ protected IStatus[] handleChildrenDeltas(IServer server, IModule[] module, IModule[]
children) {
+ // For each child:
+ ArrayList<IStatus> results = new ArrayList<IStatus>();
+ for( int i = 0; i < children.length; i++ ) {
+ IModule[] combinedChild = combine(module, children[i]);
+ // if it's new, full publish it
+ if( !getBehaviour(server).hasBeenPublished(combinedChild)) {
+ results.addAll(Arrays.asList(fullPublish(server, combinedChild)));
+ }
+ // else if it's removed, full remove it
+ else if( isRemoved(server, combinedChild)) {
+ results.addAll(Arrays.asList(removeModule(server, combinedChild)));
+ }
+ // else
+ else {
+ // handle changed resources
+ results.addAll(Arrays.asList(publishChanges(server, combinedChild)));
+
+ // recurse
+ IModule[] children2 = server.getChildModules(combinedChild, new
NullProgressMonitor());
+ results.addAll(Arrays.asList(handleChildrenDeltas(server, children, children2)));
+ }
+ }
+ return (IStatus[]) results.toArray(new IStatus[results.size()]);
+ }
+
+ protected boolean isRemoved(IServer server, IModule[] child) {
+ List<IModule[]> removed = getBehaviour(server).getRemovedModules();
+ Iterator<IModule[]> i = removed.iterator();
+ while(i.hasNext()) {
+ IModule[] next = i.next();
+ if( next.length == child.length) {
+ for( int j = 0; j < next.length; j++ ) {
+ if( !next[j].getId().equals(child[j].getId())) {
+ continue;
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected IStatus[] removeModule(IServer server, IModule[] module) {
+ String depFolder = getDeployableServer(server).getDeployFolder();
+ IPath deployPath = getDeployPath(module, depFolder);
+ final ArrayList<IStatus> status = new ArrayList<IStatus>();
+ IFileUtilListener listener = new IFileUtilListener() {
+ public void fileCopied(File source, File dest, boolean result,Exception e) {}
+ public void fileDeleted(File file, boolean result, Exception e) {
+ if( result == false || e != null ) {
+ status.add(new Status(IStatus.ERROR, JBossServerCorePlugin.PLUGIN_ID,
IEventCodes.JST_PUB_FILE_DELETE_FAIL,
+ "Attempt to delete " + file.getAbsolutePath() + " failed",e));
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ public void folderDeleted(File file, boolean result, Exception e) {
+ if( result == false || e != null ) {
+ status.add(new Status(IStatus.ERROR, JBossServerCorePlugin.PLUGIN_ID,
IEventCodes.JST_PUB_FILE_DELETE_FAIL,
+ "Attempt to delete " + file.getAbsolutePath() + " failed",e));
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ };
+ FileUtil.safeDelete(deployPath.toFile(), listener);
+ return (IStatus[]) status.toArray(new IStatus[status.size()]);
+ }
+
+ protected IStatus[] fullPublish(IServer server, IModule[] module) {
+ ArrayList<IStatus> results = new ArrayList<IStatus>();
+ try {
+ String depFolder = getDeployableServer(server).getDeployFolder();
+ IPath path = getDeployPath(module, depFolder);
+ // Get rid of the old
+ path.toFile().delete();
+
+ TrueZipUtil.createArchive(path);
+ de.schlichtherle.io.File root = TrueZipUtil.getFile(path,
TrueZipUtil.getJarArchiveDetector());
+ IModuleResource[] resources = getResources(module);
+ results.addAll(Arrays.asList(copy(root, resources)));
+
+ IModule[] children = server.getChildModules(module, new NullProgressMonitor());
+ for( int i = 0; i < children.length; i++ )
+ results.addAll(Arrays.asList(fullPublish(server, combine(module, children[i]))));
+ return (IStatus[]) results.toArray(new IStatus[results.size()]);
+ } catch( CoreException ce) {
+ results.add(generateCoreExceptionStatus(ce));
+ return (IStatus[]) results.toArray(new IStatus[results.size()]);
+ }
+ }
+
+ protected IStatus[] publishChanges(IServer server, IModule[] module) {
+ String depFolder = getDeployableServer(server).getDeployFolder();
+ IPath path = getDeployPath(module, depFolder);
+ de.schlichtherle.io.File root = TrueZipUtil.getFile(path,
TrueZipUtil.getJarArchiveDetector());
+ IModuleResourceDelta[] deltas = ((Server)server).getPublishedResourceDelta(module);
+ return publishChanges(server, deltas, root);
+ }
+
+ protected IStatus[] publishChanges(IServer server, IModuleResourceDelta[] deltas,
de.schlichtherle.io.File root) {
+ ArrayList<IStatus> results = new ArrayList<IStatus>();
+ if( deltas == null || deltas.length == 0 )
+ return new IStatus[]{};
+ int dKind;
+ IModuleResource resource;
+ for( int i = 0; i < deltas.length; i++ ) {
+ dKind = deltas[i].getKind();
+ resource = deltas[i].getModuleResource();
+ if( dKind == IModuleResourceDelta.ADDED ) {
+ results.addAll(Arrays.asList(copy(root, new IModuleResource[]{resource})));
+ } else if( dKind == IModuleResourceDelta.CHANGED ) {
+ if( resource instanceof IModuleFile )
+ results.addAll(Arrays.asList(copy(root, new IModuleResource[]{resource})));
+ results.addAll(Arrays.asList(publishChanges(server, deltas[i].getAffectedChildren(),
root)));
+ } else if( dKind == IModuleResourceDelta.REMOVED) {
+ de.schlichtherle.io.File f = getFileInArchive(root,
+ resource.getModuleRelativePath().append(
+ resource.getName()));
+ boolean b = f.deleteAll();
+ if( !b )
+ results.add(generateDeleteFailedStatus(f));
+ } else if( dKind == IModuleResourceDelta.NO_CHANGE ) {
+ results.addAll(Arrays.asList(publishChanges(server, deltas[i].getAffectedChildren(),
root)));
+ }
+ }
+
+ return (IStatus[]) results.toArray(new IStatus[results.size()]);
+ }
+
+
+ protected IStatus[] copy(de.schlichtherle.io.File root, IModuleResource[] children) {
+ ArrayList<IStatus> results = new ArrayList<IStatus>();
+ for( int i = 0; i < children.length; i++ ) {
+ if( children[i] instanceof IModuleFile ) {
+ IModuleFile mf = (IModuleFile)children[i];
+ java.io.File source = getFile(mf);
+ de.schlichtherle.io.File destination = getFileInArchive(root,
mf.getModuleRelativePath().append(mf.getName()));
+ boolean b = new de.schlichtherle.io.File(source).copyAllTo(destination);
+ if( !b )
+ results.add(generateCopyFailStatus(source, destination));
+ } else if( children[i] instanceof IModuleFolder ) {
+ de.schlichtherle.io.File destination = getFileInArchive(root,
children[i].getModuleRelativePath().append(children[i].getName()));
+ destination.mkdirs();
+ IModuleFolder mf = (IModuleFolder)children[i];
+ results.addAll(Arrays.asList(copy(root, mf.members())));
+ }
+ }
+ return (IStatus[]) results.toArray(new IStatus[results.size()]);
+ }
+
+ protected IStatus generateDeleteFailedStatus(java.io.File file) {
+ return new Status(IStatus.ERROR, IntegrationPlugin.PLUGIN_ID, "Could not delete
file " + file); //$NON-NLS-1$
+ }
+ protected IStatus generateCoreExceptionStatus(CoreException ce) {
+ return new Status(IStatus.ERROR, IntegrationPlugin.PLUGIN_ID, ce.getMessage(), ce);
+ }
+ protected IStatus generateCopyFailStatus(java.io.File source, java.io.File destination)
{
+ return new Status(IStatus.ERROR, IntegrationPlugin.PLUGIN_ID, "Copy of " +
source + " to " + destination + " has
failed");//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ }
+
+ protected de.schlichtherle.io.File getFileInArchive(de.schlichtherle.io.File root, IPath
relative) {
+ while(relative.segmentCount() > 0 ) {
+ root = new de.schlichtherle.io.File(root,
+ relative.segment(0), ArchiveDetector.DEFAULT);
+ relative = relative.removeFirstSegments(1);
+ }
+ return root;
+ }
+
+ private IModule[] combine(IModule[] module, IModule newMod) {
+ IModule[] retval = new IModule[module.length + 1];
+ for( int i = 0; i < module.length; i++ )
+ retval[i]=module[i];
+ retval[retval.length-1] = newMod;
+ return retval;
+ }
+}
Modified:
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/publishers/JstPublisher.java
===================================================================
---
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/publishers/JstPublisher.java 2009-04-16
07:48:52 UTC (rev 14767)
+++
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/publishers/JstPublisher.java 2009-04-16
09:22:04 UTC (rev 14768)
@@ -34,25 +34,22 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.internal.DeletedModule;
-import org.eclipse.wst.server.core.model.IModuleFile;
import org.eclipse.wst.server.core.model.IModuleFolder;
import org.eclipse.wst.server.core.model.IModuleResource;
import org.eclipse.wst.server.core.model.IModuleResourceDelta;
-import org.eclipse.wst.server.core.model.ModuleDelegate;
import org.eclipse.wst.server.core.util.ProjectModule;
import org.jboss.ide.eclipse.as.core.JBossServerCorePlugin;
import org.jboss.ide.eclipse.as.core.extensions.events.IEventCodes;
import org.jboss.ide.eclipse.as.core.server.IDeployableServer;
import org.jboss.ide.eclipse.as.core.server.IJBossServerPublisher;
import org.jboss.ide.eclipse.as.core.server.xpl.ModulePackager;
-import org.jboss.ide.eclipse.as.core.server.xpl.PublishUtil;
+import org.jboss.ide.eclipse.as.core.server.xpl.PublishCopyUtil;
import org.jboss.ide.eclipse.as.core.util.FileUtil;
import org.jboss.ide.eclipse.as.core.util.ServerConverter;
import org.jboss.ide.eclipse.as.core.util.FileUtil.FileUtilListener;
@@ -64,7 +61,7 @@
*
* @author rob.stryker(a)jboss.com
*/
-public class JstPublisher implements IJBossServerPublisher {
+public class JstPublisher extends PublishUtil implements IJBossServerPublisher {
protected IModuleResourceDelta[] delta;
@@ -74,15 +71,6 @@
public JstPublisher() {
}
-
- protected String getModulePath(IModule[] module ) {
- String modulePath = "";
- for( int i = 0; i < module.length; i++ ) {
- modulePath += module[i].getName() + Path.SEPARATOR;
- }
- modulePath = modulePath.substring(0, modulePath.length()-1);
- return modulePath;
- }
public IStatus publishModule(IServer server, IModule[] module,
int publishType, IModuleResourceDelta[] delta, IProgressMonitor monitor) throws
CoreException {
@@ -114,9 +102,8 @@
protected IStatus fullPublish(IModule[] moduleTree, IModule module, IProgressMonitor
monitor) throws CoreException {
- IPath deployPath = getDeployPath(moduleTree);
- ModuleDelegate md = (ModuleDelegate)module.loadAdapter(ModuleDelegate.class, monitor);
- IModuleResource[] members = md.members();
+ IPath deployPath = getDeployPath(moduleTree, server.getDeployFolder());
+ IModuleResource[] members = getResources(module);
ArrayList<IStatus> list = new ArrayList<IStatus>();
// if the module we're publishing is a project, not a binary, clean it's
folder
@@ -124,7 +111,7 @@
list.addAll(Arrays.asList(localSafeDelete(deployPath)));
if( !deployPackaged(moduleTree) && !isBinaryObject(moduleTree))
- list.addAll(Arrays.asList(new PublishUtil(server.getServer()).publishFull(members,
deployPath, monitor)));
+ list.addAll(Arrays.asList(new PublishCopyUtil(server.getServer()).publishFull(members,
deployPath, monitor)));
else if( isBinaryObject(moduleTree))
list.addAll(Arrays.asList(copyBinaryModule(moduleTree)));
else
@@ -157,9 +144,9 @@
protected IStatus incrementalPublish(IModule[] moduleTree, IModule module,
IProgressMonitor monitor) throws CoreException {
IStatus[] results = new IStatus[] {};
- IPath deployPath = getDeployPath(moduleTree);
+ IPath deployPath = getDeployPath(moduleTree, server.getDeployFolder());
if( !deployPackaged(moduleTree) && !isBinaryObject(moduleTree))
- results = new PublishUtil(server.getServer()).publishDelta(delta, deployPath,
monitor);
+ results = new PublishCopyUtil(server.getServer()).publishDelta(delta, deployPath,
monitor);
else if( delta.length > 0 ) {
if( isBinaryObject(moduleTree))
results = copyBinaryModule(moduleTree);
@@ -181,7 +168,7 @@
protected IStatus unpublish(IDeployableServer jbServer, IModule[] module,
IProgressMonitor monitor) throws CoreException {
IModule mod = module[module.length-1];
- IStatus[] errors = localSafeDelete(getDeployPath(module));
+ IStatus[] errors = localSafeDelete(getDeployPath(module, server.getDeployFolder()));
if( errors.length > 0 ) {
publishState = IServer.PUBLISH_STATE_FULL;
MultiStatus ms = new MultiStatus(JBossServerCorePlugin.PLUGIN_ID,
IEventCodes.JST_PUB_REMOVE_FAIL,
@@ -195,48 +182,13 @@
return ret;
}
- protected IPath getDeployPath(IModule[] moduleTree) {
- IPath root = new Path( server.getDeployFolder() );
- String type, name;
- for( int i = 0; i < moduleTree.length; i++ ) {
- type = moduleTree[i].getModuleType().getId();
- name = moduleTree[i].getName();
- if( new Path(name).segmentCount() > 1 )
- // we strongly suspect this is a binary object and not a project
- return root.append(new Path(name).lastSegment());
- if( "jst.ear".equals(type))
- root = root.append(name + ".ear");
- else if( "jst.web".equals(type))
- root = root.append(name + ".war");
- else if( "jst.utility".equals(type) && i >= 1 &&
"jst.web".equals(moduleTree[i-1].getModuleType().getId()))
- root = root.append("WEB-INF").append("lib").append(name +
".jar");
- else if( "jst.connector".equals(type)) {
- root = root.append(name + ".rar");
- } else if( "jst.jboss.esb".equals(type)){
- root = root.append(name + ".esb");
- }else
- root = root.append(name + ".jar");
- }
- return root;
- }
+
- protected boolean isBinaryObject(IModule[] moduleTree) {
- String name;
- for( int i = 0; i < moduleTree.length; i++ ) {
- name = moduleTree[i].getName();
- if( new Path(name).segmentCount() > 1 )
- // we strongly suspect this is a binary object and not a project
- return true;
- }
- return false;
- }
-
protected IStatus[] copyBinaryModule(IModule[] moduleTree) {
try {
- IPath deployPath = getDeployPath(moduleTree);
+ IPath deployPath = getDeployPath(moduleTree, server.getDeployFolder());
FileUtilListener listener = new FileUtilListener();
- ModuleDelegate deployable
=(ModuleDelegate)moduleTree[moduleTree.length-1].loadAdapter(ModuleDelegate.class, new
NullProgressMonitor());
- IModuleResource[] members = deployable.members();
+ IModuleResource[] members = getResources(moduleTree);
File source = (File)members[0].getAdapter(File.class);
if( source == null ) {
IFile ifile = (IFile)members[0].getAdapter(IFile.class);
@@ -285,7 +237,7 @@
FileUtil.safeDelete(deployPath.toFile(), listener);
return (IStatus[]) status.toArray(new IStatus[status.size()]);
}
- protected boolean deployPackaged(IModule[] moduleTree) {
+ public static boolean deployPackaged(IModule[] moduleTree) {
if(
moduleTree[moduleTree.length-1].getModuleType().getId().equals("jst.utility"))
return true;
if(
moduleTree[moduleTree.length-1].getModuleType().getId().equals("jst.appclient"))
return true;
return false;
@@ -349,40 +301,6 @@
}
}
}
-
- protected int countChanges(IModuleResourceDelta[] deltas) {
- IModuleResource res;
- int count = 0;
- if( deltas == null ) return 0;
- for( int i = 0; i < deltas.length; i++ ) {
- res = deltas[i].getModuleResource();
- if( res != null && res instanceof IModuleFile)
- count++;
- count += countChanges(deltas[i].getAffectedChildren());
- }
- return count;
- }
-
- protected int countMembers(IModule module) {
- try {
- ModuleDelegate delegate = (ModuleDelegate)module.loadAdapter(ModuleDelegate.class, new
NullProgressMonitor());
- return delegate == null ? 0 : countMembers(delegate.members());
- } catch( CoreException ce ) {}
- return 0;
- }
- protected int countMembers(IModuleResource[] resources) {
- int count = 0;
- if( resources == null ) return 0;
- for( int i = 0; i < resources.length; i++ ) {
- if( resources[i] instanceof IModuleFile ) {
- count++;
- } else if( resources[i] instanceof IModuleFolder ) {
- count += countMembers(((IModuleFolder)resources[i]).members());
- }
- }
- return count;
- }
-
public boolean accepts(IServer server, IModule[] module) {
return ModuleCoreNature.isFlexibleProject(module[0].getProject());
}
Added:
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/publishers/PublishUtil.java
===================================================================
---
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/publishers/PublishUtil.java
(rev 0)
+++
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/publishers/PublishUtil.java 2009-04-16
09:22:04 UTC (rev 14768)
@@ -0,0 +1,101 @@
+package org.jboss.ide.eclipse.as.core.publishers;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.wst.server.core.IModule;
+import org.eclipse.wst.server.core.model.IModuleFile;
+import org.eclipse.wst.server.core.model.IModuleFolder;
+import org.eclipse.wst.server.core.model.IModuleResource;
+import org.eclipse.wst.server.core.model.IModuleResourceDelta;
+import org.eclipse.wst.server.core.model.ModuleDelegate;
+
+public class PublishUtil {
+ public static int countChanges(IModuleResourceDelta[] deltas) {
+ IModuleResource res;
+ int count = 0;
+ if( deltas == null ) return 0;
+ for( int i = 0; i < deltas.length; i++ ) {
+ res = deltas[i].getModuleResource();
+ if( res != null && res instanceof IModuleFile)
+ count++;
+ count += countChanges(deltas[i].getAffectedChildren());
+ }
+ return count;
+ }
+
+
+ public static int countMembers(IModule module) {
+ try {
+ ModuleDelegate delegate = (ModuleDelegate)module.loadAdapter(ModuleDelegate.class, new
NullProgressMonitor());
+ return delegate == null ? 0 : countMembers(delegate.members());
+ } catch( CoreException ce ) {}
+ return 0;
+ }
+ public static int countMembers(IModuleResource[] resources) {
+ int count = 0;
+ if( resources == null ) return 0;
+ for( int i = 0; i < resources.length; i++ ) {
+ if( resources[i] instanceof IModuleFile ) {
+ count++;
+ } else if( resources[i] instanceof IModuleFolder ) {
+ count += countMembers(((IModuleFolder)resources[i]).members());
+ }
+ }
+ return count;
+ }
+
+ public static IPath getDeployPath(IModule[] moduleTree, String deployFolder) {
+ // TODO This should probably change once 241466 is solved
+ IPath root = new Path( deployFolder );
+ String type, name;
+ for( int i = 0; i < moduleTree.length; i++ ) {
+ type = moduleTree[i].getModuleType().getId();
+ name = moduleTree[i].getName();
+ if( new Path(name).segmentCount() > 1 )
+ // we strongly suspect this is a binary object and not a project
+ return root.append(new Path(name).lastSegment());
+ if( "jst.ear".equals(type))
+ root = root.append(name + ".ear");
+ else if( "jst.web".equals(type))
+ root = root.append(name + ".war");
+ else if( "jst.utility".equals(type) && i >= 1 &&
"jst.web".equals(moduleTree[i-1].getModuleType().getId()))
+ root = root.append("WEB-INF").append("lib").append(name +
".jar");
+ else if( "jst.connector".equals(type)) {
+ root = root.append(name + ".rar");
+ } else if( "jst.jboss.esb".equals(type)){
+ root = root.append(name + ".esb");
+ }else
+ root = root.append(name + ".jar");
+ }
+ return root;
+ }
+
+ public static boolean isBinaryObject(IModule[] moduleTree) {
+ String name;
+ for( int i = 0; i < moduleTree.length; i++ ) {
+ name = moduleTree[i].getName();
+ if( new Path(name).segmentCount() > 1 )
+ // we strongly suspect this is a binary object and not a project
+ return true;
+ }
+ return false;
+ }
+
+ public static IModuleResource[] getResources(IModule module) throws CoreException {
+ ModuleDelegate md = (ModuleDelegate)module.loadAdapter(ModuleDelegate.class, new
NullProgressMonitor());
+ IModuleResource[] members = md.members();
+ return members;
+ }
+ public static IModuleResource[] getResources(IModule[] tree) throws CoreException {
+ return getResources(tree[tree.length-1]);
+ }
+
+ public static java.io.File getFile(IModuleFile mf) {
+ return (IFile)mf.getAdapter(IFile.class) != null ?
+ ((IFile)mf.getAdapter(IFile.class)).getLocation().toFile() :
+ (java.io.File)mf.getAdapter(java.io.File.class);
+ }
+}
Modified:
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/DeployableServerBehavior.java
===================================================================
---
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/DeployableServerBehavior.java 2009-04-16
07:48:52 UTC (rev 14767)
+++
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/DeployableServerBehavior.java 2009-04-16
09:22:04 UTC (rev 14768)
@@ -21,6 +21,8 @@
*/
package org.jboss.ide.eclipse.as.core.server.internal;
+import java.util.List;
+
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
@@ -29,6 +31,7 @@
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.IServerListener;
import org.eclipse.wst.server.core.ServerEvent;
+import org.eclipse.wst.server.core.model.IModuleResourceDelta;
import org.eclipse.wst.server.core.model.ServerBehaviourDelegate;
import org.jboss.ide.eclipse.as.core.ExtensionManager;
import org.jboss.ide.eclipse.as.core.extensions.events.ServerLogger;
@@ -79,12 +82,16 @@
int publishType = getPublishType(kind, deltaKind, modulePublishState);
IJBossServerPublisher publisher;
- if( module.length > 0 && publishType != IJBossServerPublisher.NO_PUBLISH) {
+ // Let the publisher decide what to do
+ if( module.length > 0 ) {
publisher = ExtensionManager.getDefault().getPublisher(getServer(), module);
+ IModuleResourceDelta[] deltas = new IModuleResourceDelta[]{};
+ if( deltaKind != ServerBehaviourDelegate.REMOVED)
+ deltas = getPublishedResourceDelta(module);
if( publisher != null ) {
try {
- IStatus result = publisher.publishModule(getServer(), module, publishType,
- getPublishedResourceDelta(module), monitor);
+ IStatus result = publisher.publishModule(getServer(), module,
+ publishType, deltas, monitor);
if( result != null )
ServerLogger.getDefault().log(getServer(), result);
} catch( CoreException ce ) {
@@ -109,6 +116,22 @@
return IJBossServerPublisher.NO_PUBLISH;
}
+ // Expose
+ public List<IModule[]> getRemovedModules() {
+ final List<IModule[]> moduleList = getAllModules();
+ int size = moduleList.size();
+ super.addRemovedModules(moduleList, null);
+ for( int i = 0; i < size; i++ )
+ moduleList.remove(0);
+ return moduleList;
+ }
+
+ public boolean hasBeenPublished(IModule[] module) {
+ return super.hasBeenPublished(module);
+ }
+
+
+
/*
* Change the state of the server
* Also, cache the state we think we're setting it to.
Copied:
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/xpl/PublishCopyUtil.java
(from rev 14008,
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/xpl/PublishUtil.java)
===================================================================
---
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/xpl/PublishCopyUtil.java
(rev 0)
+++
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/xpl/PublishCopyUtil.java 2009-04-16
09:22:04 UTC (rev 14768)
@@ -0,0 +1,782 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ *
http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.jboss.ide.eclipse.as.core.server.xpl;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.internal.Messages;
+import org.eclipse.wst.server.core.internal.ProgressUtil;
+import org.eclipse.wst.server.core.internal.ServerPlugin;
+import org.eclipse.wst.server.core.internal.Trace;
+import org.eclipse.wst.server.core.model.IModuleFile;
+import org.eclipse.wst.server.core.model.IModuleFolder;
+import org.eclipse.wst.server.core.model.IModuleResource;
+import org.eclipse.wst.server.core.model.IModuleResourceDelta;
+import org.jboss.ide.eclipse.as.core.server.IDeployableServer;
+import org.jboss.ide.eclipse.as.core.server.internal.ServerAttributeHelper;
+import org.jboss.ide.eclipse.as.core.util.ServerConverter;
+/**
+ * Utility class with an assortment of useful file methods.
+ * <p>
+ * This class provides all its functionality through static members.
+ * It is not intended to be subclassed or instantiated.
+ * </p>
+ * <p>
+ * <b>Note:</b> This class/interface is part of an interim API that is still
under development and expected to
+ * change significantly before reaching stability. It is being made available at this
early stage to solicit feedback
+ * from pioneering adopters on the understanding that any code that uses this API will
almost certainly be broken
+ * (repeatedly) as the API evolves.
+ * </p>
+ * @since 2.0
+ */
+public final class PublishCopyUtil {
+ // size of the buffer
+ private static final int BUFFER = 65536;
+
+ // the buffer
+ private static byte[] buf = new byte[BUFFER];
+
+ private static final IStatus[] EMPTY_STATUS = new IStatus[0];
+
+ private static final File tempDir =
ServerPlugin.getInstance().getStateLocation().toFile();
+
+ private static final String TEMPFILE_PREFIX = "tmp";
+
+ /**
+ * PublishUtil cannot be created. Use static methods.
+ */
+ private IServer server;
+ public PublishCopyUtil(IServer server) {
+ this.server = server;
+ }
+
+ /**
+ * Copy a file from a to b. Closes the input stream after use.
+ *
+ * @param in an input stream
+ * @param to a path to copy to. the directory must already exist
+ * @param ts timestamp
+ * @throws CoreException if anything goes wrong
+ */
+ private void copyFile(InputStream in, IPath to, long ts, IModuleFile mf) throws
CoreException {
+ OutputStream out = null;
+
+ File tempFile = null;
+ try {
+ File file = to.toFile();
+
+ // Change from original PublishUtil, will require
+ tempFile = File.createTempFile(TEMPFILE_PREFIX, "." + to.getFileExtension(),
getTempFolder());
+
+ out = new FileOutputStream(tempFile);
+
+ int avail = in.read(buf);
+ while (avail > 0) {
+ out.write(buf, 0, avail);
+ avail = in.read(buf);
+ }
+
+ out.close();
+ out = null;
+
+ moveTempFile(tempFile, file);
+
+ if (ts != IResource.NULL_STAMP && ts != 0)
+ file.setLastModified(ts);
+ } catch (CoreException e) {
+ throw e;
+ } catch (Exception e) {
+ IPath path = mf.getModuleRelativePath().append(mf.getName());
+ Trace.trace(Trace.SEVERE, "Error copying file: " + to.toOSString() + "
to " + path.toOSString(), e);
+ throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorCopyingFile, path.toOSString(), e.getLocalizedMessage()), null));
+ } finally {
+ if (tempFile != null && tempFile.exists())
+ tempFile.deleteOnExit();
+ try {
+ if (in != null)
+ in.close();
+ } catch (Exception ex) {
+ // ignore
+ }
+ try {
+ if (out != null)
+ out.close();
+ } catch (Exception ex) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Utility method to recursively delete a directory.
+ *
+ * @param dir a directory
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting and cancellation are not desired
+ * @return a possibly-empty array of error and warning status
+ */
+ public IStatus[] deleteDirectory(File dir, IProgressMonitor monitor) {
+ if (!dir.exists() || !dir.isDirectory())
+ return new IStatus[] { new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorNotADirectory, dir.getAbsolutePath()), null) };
+
+ List status = new ArrayList(2);
+
+ try {
+ File[] files = dir.listFiles();
+ int size = files.length;
+ monitor = ProgressUtil.getMonitorFor(monitor);
+ monitor.beginTask(NLS.bind(Messages.deletingTask, new String[] { dir.getAbsolutePath()
}), size * 10);
+
+ // cycle through files
+ boolean deleteCurrent = true;
+ for (int i = 0; i < size; i++) {
+ File current = files[i];
+ if (current.isFile()) {
+ if (!current.delete()) {
+ status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, files[i].getAbsolutePath()), null));
+ deleteCurrent = false;
+ }
+ monitor.worked(10);
+ } else if (current.isDirectory()) {
+ monitor.subTask(NLS.bind(Messages.deletingTask, new String[]
{current.getAbsolutePath()}));
+ IStatus[] stat = deleteDirectory(current, ProgressUtil.getSubMonitorFor(monitor,
10));
+ if (stat != null && stat.length > 0) {
+ deleteCurrent = false;
+ addArrayToList(status, stat);
+ }
+ }
+ }
+ if (deleteCurrent && !dir.delete())
+ status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, dir.getAbsolutePath()), null));
+ monitor.done();
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "Error deleting directory " +
dir.getAbsolutePath(), e);
+ status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
e.getLocalizedMessage(), null));
+ }
+
+ IStatus[] stat = new IStatus[status.size()];
+ status.toArray(stat);
+ return stat;
+ }
+
+ /**
+ * Smart copy the given module resources to the given path.
+ *
+ * @param resources an array of module resources
+ * @param path an external path to copy to
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting and cancellation are not desired
+ * @return a possibly-empty array of error and warning status
+ */
+ public IStatus[] publishSmart(IModuleResource[] resources, IPath path, IProgressMonitor
monitor) {
+ if (resources == null)
+ return EMPTY_STATUS;
+
+ monitor = ProgressUtil.getMonitorFor(monitor);
+
+ List status = new ArrayList(2);
+ File toDir = path.toFile();
+ int fromSize = resources.length;
+ String[] fromFileNames = new String[fromSize];
+ for (int i = 0; i < fromSize; i++)
+ fromFileNames[i] = resources[i].getName();
+
+ // cache files and file names for performance
+ File[] toFiles = null;
+ String[] toFileNames = null;
+
+ boolean foundExistingDir = false;
+ if (toDir.exists()) {
+ if (toDir.isDirectory()) {
+ foundExistingDir = true;
+ toFiles = toDir.listFiles();
+ int toSize = toFiles.length;
+ toFileNames = new String[toSize];
+
+ // check if this exact file exists in the new directory
+ for (int i = 0; i < toSize; i++) {
+ toFileNames[i] = toFiles[i].getName();
+ boolean isDir = toFiles[i].isDirectory();
+ boolean found = false;
+ for (int j = 0; j < fromSize; j++) {
+ if (toFileNames[i].equals(fromFileNames[j]) && isDir == resources[j]
instanceof IModuleFolder)
+ found = true;
+ }
+
+ // delete file if it can't be found or isn't the correct type
+ if (!found) {
+ if (isDir) {
+ IStatus[] stat = deleteDirectory(toFiles[i], null);
+ addArrayToList(status, stat);
+ } else {
+ if (!toFiles[i].delete())
+ status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, toFiles[i].getAbsolutePath()), null));
+ }
+ toFiles[i] = null;
+ toFileNames[i] = null;
+ }
+ }
+ } else { //if (toDir.isFile())
+ if (!toDir.delete()) {
+ status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, toDir.getAbsolutePath()), null));
+ IStatus[] stat = new IStatus[status.size()];
+ status.toArray(stat);
+ return stat;
+ }
+ }
+ }
+ if (!foundExistingDir && !toDir.mkdirs()) {
+ status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorMkdir, toDir.getAbsolutePath()), null));
+ IStatus[] stat = new IStatus[status.size()];
+ status.toArray(stat);
+ return stat;
+ }
+
+ if (monitor.isCanceled())
+ return new IStatus[] { Status.CANCEL_STATUS };
+
+ monitor.worked(50);
+
+ // cycle through files and only copy when it doesn't exist
+ // or is newer
+ if (toFiles == null)
+ toFiles = toDir.listFiles();
+ int toSize = 0;
+ if (toFiles != null)
+ toSize = toFiles.length;
+
+ int dw = 0;
+ if (toSize > 0)
+ dw = 500 / toSize;
+
+ // cache file names and last modified dates for performance
+ if (toFileNames == null)
+ toFileNames = new String[toSize];
+ long[] toFileMod = new long[toSize];
+ for (int i = 0; i < toSize; i++) {
+ if (toFiles[i] != null) {
+ if (toFileNames[i] != null)
+ toFileNames[i] = toFiles[i].getName();
+ toFileMod[i] = toFiles[i].lastModified();
+ }
+ }
+
+ for (int i = 0; i < fromSize; i++) {
+ IModuleResource current = resources[i];
+ String name = fromFileNames[i];
+ boolean currentIsDir = current instanceof IModuleFolder;
+
+ if (!currentIsDir) {
+ // check if this is a new or newer file
+ boolean copy = true;
+ IModuleFile mf = (IModuleFile) current;
+
+ long mod = -1;
+ IFile file = (IFile) mf.getAdapter(IFile.class);
+ if (file != null) {
+ mod = file.getLocalTimeStamp();
+ } else {
+ File file2 = (File) mf.getAdapter(File.class);
+ mod = file2.lastModified();
+ }
+
+ for (int j = 0; j < toSize; j++) {
+ if (name.equals(toFileNames[j]) && mod == toFileMod[j])
+ copy = false;
+ }
+
+ if (copy) {
+ try {
+ copyFile(mf, path.append(name));
+ } catch (CoreException ce) {
+ status.add(ce.getStatus());
+ }
+ }
+ monitor.worked(dw);
+ } else { //if (currentIsDir) {
+ IModuleFolder folder = (IModuleFolder) current;
+ IModuleResource[] children = folder.members();
+ monitor.subTask(NLS.bind(Messages.copyingTask, new String[] {name, name}));
+ IStatus[] stat = publishSmart(children, path.append(name),
ProgressUtil.getSubMonitorFor(monitor, dw));
+ addArrayToList(status, stat);
+ }
+ }
+ if (monitor.isCanceled())
+ return new IStatus[] { Status.CANCEL_STATUS };
+
+ monitor.worked(500 - dw * toSize);
+ monitor.done();
+
+ IStatus[] stat = new IStatus[status.size()];
+ status.toArray(stat);
+ return stat;
+ }
+
+ /**
+ * Handle a delta publish.
+ *
+ * @param delta a module resource delta
+ * @param path the path to publish to
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting and cancellation are not desired
+ * @return a possibly-empty array of error and warning status
+ */
+ public IStatus[] publishDelta(IModuleResourceDelta[] delta, IPath path, IProgressMonitor
monitor) {
+ if (delta == null)
+ return EMPTY_STATUS;
+
+ monitor = ProgressUtil.getMonitorFor(monitor);
+
+ List status = new ArrayList(2);
+ int size2 = delta.length;
+ for (int i = 0; i < size2; i++) {
+ IStatus[] stat = publishDelta(delta[i], path, monitor);
+ addArrayToList(status, stat);
+ }
+
+ IStatus[] stat = new IStatus[status.size()];
+ status.toArray(stat);
+ return stat;
+ }
+
+ /**
+ * Handle a delta publish.
+ *
+ * @param delta a module resource delta
+ * @param path the path to publish to
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting and cancellation are not desired
+ * @return a possibly-empty array of error and warning status
+ */
+ public IStatus[] publishDelta(IModuleResourceDelta delta, IPath path, IProgressMonitor
monitor) {
+ List status = new ArrayList(2);
+
+ IModuleResource resource = delta.getModuleResource();
+ int kind2 = delta.getKind();
+
+ if (resource instanceof IModuleFile) {
+ IModuleFile file = (IModuleFile) resource;
+ try {
+ if (kind2 == IModuleResourceDelta.REMOVED)
+ deleteFile2(path, file);
+ else {
+ IPath path2 = path.append(file.getModuleRelativePath()).append(file.getName());
+ File f = path2.toFile().getParentFile();
+ if (!f.exists())
+ f.mkdirs();
+
+ copyFile(file, path2);
+ }
+ } catch (CoreException ce) {
+ status.add(ce.getStatus());
+ }
+ IStatus[] stat = new IStatus[status.size()];
+ status.toArray(stat);
+ return stat;
+ }
+
+ if (kind2 == IModuleResourceDelta.ADDED) {
+ IPath path2 =
path.append(resource.getModuleRelativePath()).append(resource.getName());
+ File file = path2.toFile();
+ if (!file.exists() && !file.mkdirs()) {
+ status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorMkdir, path2), null));
+ IStatus[] stat = new IStatus[status.size()];
+ status.toArray(stat);
+ return stat;
+ }
+ }
+
+ IModuleResourceDelta[] childDeltas = delta.getAffectedChildren();
+ int size = childDeltas.length;
+ for (int i = 0; i < size; i++) {
+ IStatus[] stat = publishDelta(childDeltas[i], path, monitor);
+ addArrayToList(status, stat);
+ }
+
+ if (kind2 == IModuleResourceDelta.REMOVED) {
+ IPath path2 =
path.append(resource.getModuleRelativePath()).append(resource.getName());
+ File file = path2.toFile();
+ if (file.exists() && !file.delete()) {
+ status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, path2), null));
+ }
+ }
+
+ IStatus[] stat = new IStatus[status.size()];
+ status.toArray(stat);
+ return stat;
+ }
+
+ private void deleteFile2(IPath path, IModuleFile file) throws CoreException {
+ Trace.trace(Trace.PUBLISHING, "Deleting: " + file.getName() + " from
" + path.toString());
+ IPath path2 = path.append(file.getModuleRelativePath()).append(file.getName());
+ if (path2.toFile().exists() && !path2.toFile().delete())
+ throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, path2), null));
+ }
+
+ private void copyFile(IModuleFile mf, IPath path) throws CoreException {
+ Trace.trace(Trace.PUBLISHING, "Copying: " + mf.getName() + " to " +
path.toString());
+
+ IFile file = (IFile) mf.getAdapter(IFile.class);
+ if (file != null)
+ copyFile(file.getContents(), path, file.getLocalTimeStamp(), mf);
+ else {
+ File file2 = (File) mf.getAdapter(File.class);
+ InputStream in = null;
+ try {
+ in = new FileInputStream(file2);
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorReading, file2.getAbsolutePath()), e));
+ }
+ copyFile(in, path, file2.lastModified(), mf);
+ }
+ }
+
+ /**
+ * Publish the given module resources to the given path.
+ *
+ * @param resources an array of module resources
+ * @param path a path to publish to
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting and cancellation are not desired
+ * @return a possibly-empty array of error and warning status
+ */
+ public IStatus[] publishFull(IModuleResource[] resources, IPath path, IProgressMonitor
monitor) {
+ if (resources == null)
+ return EMPTY_STATUS;
+
+ monitor = ProgressUtil.getMonitorFor(monitor);
+
+ List status = new ArrayList(2);
+ int size = resources.length;
+ for (int i = 0; i < size; i++) {
+ IStatus[] stat = copy(resources[i], path, monitor);
+ addArrayToList(status, stat);
+ }
+
+ IStatus[] stat = new IStatus[status.size()];
+ status.toArray(stat);
+ return stat;
+ }
+
+ private IStatus[] copy(IModuleResource resource, IPath path, IProgressMonitor monitor)
{
+ String name = resource.getName();
+ Trace.trace(Trace.PUBLISHING, "Copying: " + name + " to " +
path.toString());
+ List status = new ArrayList(2);
+ if (resource instanceof IModuleFolder) {
+ IModuleFolder folder = (IModuleFolder) resource;
+ IStatus[] stat = publishFull(folder.members(), path, monitor);
+ addArrayToList(status, stat);
+ } else {
+ IModuleFile mf = (IModuleFile) resource;
+ path = path.append(mf.getModuleRelativePath()).append(name);
+ File f = path.toFile().getParentFile();
+ if (!f.exists())
+ f.mkdirs();
+ try {
+ copyFile(mf, path);
+ } catch (CoreException ce) {
+ status.add(ce.getStatus());
+ }
+ }
+ IStatus[] stat = new IStatus[status.size()];
+ status.toArray(stat);
+ return stat;
+ }
+
+ /**
+ * Creates a new zip file containing the given module resources. Deletes the existing
file
+ * (and doesn't create a new one) if resources is null or empty.
+ *
+ * @param resources an array of module resources
+ * @param path the path where the zip file should be created
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting and cancellation are not desired
+ * @return a possibly-empty array of error and warning status
+ */
+ public IStatus[] publishZip(IModuleResource[] resources, IPath path, IProgressMonitor
monitor) {
+ if (resources == null || resources.length == 0) {
+ // should also check if resources consists of all empty directories
+ File file = path.toFile();
+ if (file.exists())
+ file.delete();
+ return EMPTY_STATUS;
+ }
+
+ monitor = ProgressUtil.getMonitorFor(monitor);
+
+ File tempFile = null;
+ try {
+ File file = path.toFile();
+ tempFile = File.createTempFile(TEMPFILE_PREFIX, "." +
path.getFileExtension(), getTempFolder());
+ BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(tempFile));
+ ZipOutputStream zout = new ZipOutputStream(bout);
+ addZipEntries(zout, resources);
+ zout.close();
+
+ moveTempFile(tempFile, file);
+ } catch (CoreException e) {
+ return new IStatus[] { e.getStatus() };
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "Error zipping", e);
+ return new Status[] { new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorCreatingZipFile, path.lastSegment(), e.getLocalizedMessage()), e)
};
+ } finally {
+ if (tempFile != null && tempFile.exists())
+ tempFile.deleteOnExit();
+ }
+ return EMPTY_STATUS;
+ }
+
+ private void addZipEntries(ZipOutputStream zout, IModuleResource[] resources) throws
Exception {
+ if (resources == null)
+ return;
+
+ int size = resources.length;
+ for (int i = 0; i < size; i++) {
+ if (resources[i] instanceof IModuleFolder) {
+ IModuleFolder mf = (IModuleFolder) resources[i];
+ IModuleResource[] res = mf.members();
+
+ IPath path = mf.getModuleRelativePath().append(mf.getName());
+ String entryPath = path.toPortableString();
+ if (!entryPath.endsWith("/"))
+ entryPath += '/';
+
+ ZipEntry ze = new ZipEntry(entryPath);
+
+ long ts = 0;
+ IContainer folder = (IContainer) mf.getAdapter(IContainer.class);
+ if (folder != null)
+ ts = folder.getLocalTimeStamp();
+
+ if (ts != IResource.NULL_STAMP && ts != 0)
+ ze.setTime(ts);
+
+ zout.putNextEntry(ze);
+ zout.closeEntry();
+
+ addZipEntries(zout, res);
+ continue;
+ }
+
+ IModuleFile mf = (IModuleFile) resources[i];
+ IPath path = mf.getModuleRelativePath().append(mf.getName());
+
+ ZipEntry ze = new ZipEntry(path.toPortableString());
+
+ InputStream in = null;
+ long ts = 0;
+ IFile file = (IFile) mf.getAdapter(IFile.class);
+ if (file != null) {
+ ts = file.getLocalTimeStamp();
+ in = file.getContents();
+ } else {
+ File file2 = (File) mf.getAdapter(File.class);
+ ts = file2.lastModified();
+ in = new FileInputStream(file2);
+ }
+
+ if (ts != IResource.NULL_STAMP && ts != 0)
+ ze.setTime(ts);
+
+ zout.putNextEntry(ze);
+
+ try {
+ int n = 0;
+ while (n > -1) {
+ n = in.read(buf);
+ if (n > 0)
+ zout.write(buf, 0, n);
+ }
+ } finally {
+ in.close();
+ }
+
+ zout.closeEntry();
+ }
+ }
+
+ /**
+ * Utility method to move a temp file into position by deleting the original and
+ * swapping in a new copy.
+ *
+ * @param tempFile
+ * @param file
+ * @throws CoreException
+ */
+ private void moveTempFile(File tempFile, File file) throws CoreException {
+ if (file.exists()) {
+ if (!safeDelete(file, 2)) {
+ // attempt to rewrite an existing file with the tempFile contents if
+ // the existing file can't be deleted to permit the move
+ try {
+ InputStream in = new FileInputStream(tempFile);
+ IStatus status = copyFile(in, file.getPath());
+ if (!status.isOK()) {
+ MultiStatus status2 = new MultiStatus(ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, file.toString()), null);
+ status2.add(status);
+ throw new CoreException(status2);
+ }
+ return;
+ } catch (FileNotFoundException e) {
+ // shouldn't occur
+ } finally {
+ tempFile.delete();
+ }
+ /*if (!safeDelete(file, 8)) {
+ tempFile.delete();
+ throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, file.toString()), null));
+ }*/
+ }
+ }
+ if (!safeRename(tempFile, file, 10))
+ throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorRename, tempFile.toString()), null));
+ }
+
+ /**
+ * Copy a file from a to b. Closes the input stream after use.
+ *
+ * @param in java.io.InputStream
+ * @param to java.lang.String
+ * @return a status
+ */
+ private IStatus copyFile(InputStream in, String to) {
+ OutputStream out = null;
+
+ try {
+ out = new FileOutputStream(to);
+
+ int avail = in.read(buf);
+ while (avail > 0) {
+ out.write(buf, 0, avail);
+ avail = in.read(buf);
+ }
+ return Status.OK_STATUS;
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "Error copying file", e);
+ return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorCopyingFile, new String[] {to, e.getLocalizedMessage()}), e);
+ } finally {
+ try {
+ if (in != null)
+ in.close();
+ } catch (Exception ex) {
+ // ignore
+ }
+ try {
+ if (out != null)
+ out.close();
+ } catch (Exception ex) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Safe delete. Tries to delete multiple times before giving up.
+ *
+ * @param f
+ * @return <code>true</code> if it succeeds, <code>false</code>
otherwise
+ */
+ private boolean safeDelete(File f, int retrys) {
+ int count = 0;
+ while (count < retrys) {
+ if (!f.exists())
+ return true;
+
+ f.delete();
+
+ if (!f.exists())
+ return true;
+
+ count++;
+ // delay if we are going to try again
+ if (count < retrys) {
+ try {
+ Thread.sleep(100);
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Safe rename. Will try multiple times before giving up.
+ *
+ * @param from
+ * @param to
+ * @param retrys number of times to retry
+ * @return <code>true</code> if it succeeds, <code>false</code>
otherwise
+ */
+ private boolean safeRename(File from, File to, int retrys) {
+ // make sure parent dir exists
+ File dir = to.getParentFile();
+ if (dir != null && !dir.exists())
+ dir.mkdirs();
+
+ int count = 0;
+ while (count < retrys) {
+ if (from.renameTo(to))
+ return true;
+
+ count++;
+ // delay if we are going to try again
+ if (count < retrys) {
+ try {
+ Thread.sleep(100);
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+ return false;
+ }
+
+ private void addArrayToList(List list, IStatus[] a) {
+ if (list == null || a == null || a.length == 0)
+ return;
+
+ int size = a.length;
+ for (int i = 0; i < size; i++)
+ list.add(a[i]);
+ }
+
+ protected File getTempFolder() {
+ if( server == null ) return tempDir;
+ String path = ServerConverter.getDeployableServer(server).getTempDeployFolder();
+ File f = new File(path);
+ if( !f.exists() )
+ f.mkdirs();
+ return new File(path);
+ }
+}
\ No newline at end of file
Deleted:
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/xpl/PublishUtil.java
===================================================================
---
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/xpl/PublishUtil.java 2009-04-16
07:48:52 UTC (rev 14767)
+++
trunk/as/plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/xpl/PublishUtil.java 2009-04-16
09:22:04 UTC (rev 14768)
@@ -1,782 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- *
http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - Initial API and implementation
- *******************************************************************************/
-package org.jboss.ide.eclipse.as.core.server.xpl;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.wst.server.core.IServer;
-import org.eclipse.wst.server.core.internal.Messages;
-import org.eclipse.wst.server.core.internal.ProgressUtil;
-import org.eclipse.wst.server.core.internal.ServerPlugin;
-import org.eclipse.wst.server.core.internal.Trace;
-import org.eclipse.wst.server.core.model.IModuleFile;
-import org.eclipse.wst.server.core.model.IModuleFolder;
-import org.eclipse.wst.server.core.model.IModuleResource;
-import org.eclipse.wst.server.core.model.IModuleResourceDelta;
-import org.jboss.ide.eclipse.as.core.server.IDeployableServer;
-import org.jboss.ide.eclipse.as.core.server.internal.ServerAttributeHelper;
-import org.jboss.ide.eclipse.as.core.util.ServerConverter;
-/**
- * Utility class with an assortment of useful file methods.
- * <p>
- * This class provides all its functionality through static members.
- * It is not intended to be subclassed or instantiated.
- * </p>
- * <p>
- * <b>Note:</b> This class/interface is part of an interim API that is still
under development and expected to
- * change significantly before reaching stability. It is being made available at this
early stage to solicit feedback
- * from pioneering adopters on the understanding that any code that uses this API will
almost certainly be broken
- * (repeatedly) as the API evolves.
- * </p>
- * @since 2.0
- */
-public final class PublishUtil {
- // size of the buffer
- private static final int BUFFER = 65536;
-
- // the buffer
- private static byte[] buf = new byte[BUFFER];
-
- private static final IStatus[] EMPTY_STATUS = new IStatus[0];
-
- private static final File tempDir =
ServerPlugin.getInstance().getStateLocation().toFile();
-
- private static final String TEMPFILE_PREFIX = "tmp";
-
- /**
- * PublishUtil cannot be created. Use static methods.
- */
- private IServer server;
- public PublishUtil(IServer server) {
- this.server = server;
- }
-
- /**
- * Copy a file from a to b. Closes the input stream after use.
- *
- * @param in an input stream
- * @param to a path to copy to. the directory must already exist
- * @param ts timestamp
- * @throws CoreException if anything goes wrong
- */
- private void copyFile(InputStream in, IPath to, long ts, IModuleFile mf) throws
CoreException {
- OutputStream out = null;
-
- File tempFile = null;
- try {
- File file = to.toFile();
-
- // Change from original PublishUtil, will require
- tempFile = File.createTempFile(TEMPFILE_PREFIX, "." + to.getFileExtension(),
getTempFolder());
-
- out = new FileOutputStream(tempFile);
-
- int avail = in.read(buf);
- while (avail > 0) {
- out.write(buf, 0, avail);
- avail = in.read(buf);
- }
-
- out.close();
- out = null;
-
- moveTempFile(tempFile, file);
-
- if (ts != IResource.NULL_STAMP && ts != 0)
- file.setLastModified(ts);
- } catch (CoreException e) {
- throw e;
- } catch (Exception e) {
- IPath path = mf.getModuleRelativePath().append(mf.getName());
- Trace.trace(Trace.SEVERE, "Error copying file: " + to.toOSString() + "
to " + path.toOSString(), e);
- throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorCopyingFile, path.toOSString(), e.getLocalizedMessage()), null));
- } finally {
- if (tempFile != null && tempFile.exists())
- tempFile.deleteOnExit();
- try {
- if (in != null)
- in.close();
- } catch (Exception ex) {
- // ignore
- }
- try {
- if (out != null)
- out.close();
- } catch (Exception ex) {
- // ignore
- }
- }
- }
-
- /**
- * Utility method to recursively delete a directory.
- *
- * @param dir a directory
- * @param monitor a progress monitor, or <code>null</code> if progress
- * reporting and cancellation are not desired
- * @return a possibly-empty array of error and warning status
- */
- public IStatus[] deleteDirectory(File dir, IProgressMonitor monitor) {
- if (!dir.exists() || !dir.isDirectory())
- return new IStatus[] { new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorNotADirectory, dir.getAbsolutePath()), null) };
-
- List status = new ArrayList(2);
-
- try {
- File[] files = dir.listFiles();
- int size = files.length;
- monitor = ProgressUtil.getMonitorFor(monitor);
- monitor.beginTask(NLS.bind(Messages.deletingTask, new String[] { dir.getAbsolutePath()
}), size * 10);
-
- // cycle through files
- boolean deleteCurrent = true;
- for (int i = 0; i < size; i++) {
- File current = files[i];
- if (current.isFile()) {
- if (!current.delete()) {
- status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, files[i].getAbsolutePath()), null));
- deleteCurrent = false;
- }
- monitor.worked(10);
- } else if (current.isDirectory()) {
- monitor.subTask(NLS.bind(Messages.deletingTask, new String[]
{current.getAbsolutePath()}));
- IStatus[] stat = deleteDirectory(current, ProgressUtil.getSubMonitorFor(monitor,
10));
- if (stat != null && stat.length > 0) {
- deleteCurrent = false;
- addArrayToList(status, stat);
- }
- }
- }
- if (deleteCurrent && !dir.delete())
- status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, dir.getAbsolutePath()), null));
- monitor.done();
- } catch (Exception e) {
- Trace.trace(Trace.SEVERE, "Error deleting directory " +
dir.getAbsolutePath(), e);
- status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
e.getLocalizedMessage(), null));
- }
-
- IStatus[] stat = new IStatus[status.size()];
- status.toArray(stat);
- return stat;
- }
-
- /**
- * Smart copy the given module resources to the given path.
- *
- * @param resources an array of module resources
- * @param path an external path to copy to
- * @param monitor a progress monitor, or <code>null</code> if progress
- * reporting and cancellation are not desired
- * @return a possibly-empty array of error and warning status
- */
- public IStatus[] publishSmart(IModuleResource[] resources, IPath path, IProgressMonitor
monitor) {
- if (resources == null)
- return EMPTY_STATUS;
-
- monitor = ProgressUtil.getMonitorFor(monitor);
-
- List status = new ArrayList(2);
- File toDir = path.toFile();
- int fromSize = resources.length;
- String[] fromFileNames = new String[fromSize];
- for (int i = 0; i < fromSize; i++)
- fromFileNames[i] = resources[i].getName();
-
- // cache files and file names for performance
- File[] toFiles = null;
- String[] toFileNames = null;
-
- boolean foundExistingDir = false;
- if (toDir.exists()) {
- if (toDir.isDirectory()) {
- foundExistingDir = true;
- toFiles = toDir.listFiles();
- int toSize = toFiles.length;
- toFileNames = new String[toSize];
-
- // check if this exact file exists in the new directory
- for (int i = 0; i < toSize; i++) {
- toFileNames[i] = toFiles[i].getName();
- boolean isDir = toFiles[i].isDirectory();
- boolean found = false;
- for (int j = 0; j < fromSize; j++) {
- if (toFileNames[i].equals(fromFileNames[j]) && isDir == resources[j]
instanceof IModuleFolder)
- found = true;
- }
-
- // delete file if it can't be found or isn't the correct type
- if (!found) {
- if (isDir) {
- IStatus[] stat = deleteDirectory(toFiles[i], null);
- addArrayToList(status, stat);
- } else {
- if (!toFiles[i].delete())
- status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, toFiles[i].getAbsolutePath()), null));
- }
- toFiles[i] = null;
- toFileNames[i] = null;
- }
- }
- } else { //if (toDir.isFile())
- if (!toDir.delete()) {
- status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, toDir.getAbsolutePath()), null));
- IStatus[] stat = new IStatus[status.size()];
- status.toArray(stat);
- return stat;
- }
- }
- }
- if (!foundExistingDir && !toDir.mkdirs()) {
- status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorMkdir, toDir.getAbsolutePath()), null));
- IStatus[] stat = new IStatus[status.size()];
- status.toArray(stat);
- return stat;
- }
-
- if (monitor.isCanceled())
- return new IStatus[] { Status.CANCEL_STATUS };
-
- monitor.worked(50);
-
- // cycle through files and only copy when it doesn't exist
- // or is newer
- if (toFiles == null)
- toFiles = toDir.listFiles();
- int toSize = 0;
- if (toFiles != null)
- toSize = toFiles.length;
-
- int dw = 0;
- if (toSize > 0)
- dw = 500 / toSize;
-
- // cache file names and last modified dates for performance
- if (toFileNames == null)
- toFileNames = new String[toSize];
- long[] toFileMod = new long[toSize];
- for (int i = 0; i < toSize; i++) {
- if (toFiles[i] != null) {
- if (toFileNames[i] != null)
- toFileNames[i] = toFiles[i].getName();
- toFileMod[i] = toFiles[i].lastModified();
- }
- }
-
- for (int i = 0; i < fromSize; i++) {
- IModuleResource current = resources[i];
- String name = fromFileNames[i];
- boolean currentIsDir = current instanceof IModuleFolder;
-
- if (!currentIsDir) {
- // check if this is a new or newer file
- boolean copy = true;
- IModuleFile mf = (IModuleFile) current;
-
- long mod = -1;
- IFile file = (IFile) mf.getAdapter(IFile.class);
- if (file != null) {
- mod = file.getLocalTimeStamp();
- } else {
- File file2 = (File) mf.getAdapter(File.class);
- mod = file2.lastModified();
- }
-
- for (int j = 0; j < toSize; j++) {
- if (name.equals(toFileNames[j]) && mod == toFileMod[j])
- copy = false;
- }
-
- if (copy) {
- try {
- copyFile(mf, path.append(name));
- } catch (CoreException ce) {
- status.add(ce.getStatus());
- }
- }
- monitor.worked(dw);
- } else { //if (currentIsDir) {
- IModuleFolder folder = (IModuleFolder) current;
- IModuleResource[] children = folder.members();
- monitor.subTask(NLS.bind(Messages.copyingTask, new String[] {name, name}));
- IStatus[] stat = publishSmart(children, path.append(name),
ProgressUtil.getSubMonitorFor(monitor, dw));
- addArrayToList(status, stat);
- }
- }
- if (monitor.isCanceled())
- return new IStatus[] { Status.CANCEL_STATUS };
-
- monitor.worked(500 - dw * toSize);
- monitor.done();
-
- IStatus[] stat = new IStatus[status.size()];
- status.toArray(stat);
- return stat;
- }
-
- /**
- * Handle a delta publish.
- *
- * @param delta a module resource delta
- * @param path the path to publish to
- * @param monitor a progress monitor, or <code>null</code> if progress
- * reporting and cancellation are not desired
- * @return a possibly-empty array of error and warning status
- */
- public IStatus[] publishDelta(IModuleResourceDelta[] delta, IPath path, IProgressMonitor
monitor) {
- if (delta == null)
- return EMPTY_STATUS;
-
- monitor = ProgressUtil.getMonitorFor(monitor);
-
- List status = new ArrayList(2);
- int size2 = delta.length;
- for (int i = 0; i < size2; i++) {
- IStatus[] stat = publishDelta(delta[i], path, monitor);
- addArrayToList(status, stat);
- }
-
- IStatus[] stat = new IStatus[status.size()];
- status.toArray(stat);
- return stat;
- }
-
- /**
- * Handle a delta publish.
- *
- * @param delta a module resource delta
- * @param path the path to publish to
- * @param monitor a progress monitor, or <code>null</code> if progress
- * reporting and cancellation are not desired
- * @return a possibly-empty array of error and warning status
- */
- public IStatus[] publishDelta(IModuleResourceDelta delta, IPath path, IProgressMonitor
monitor) {
- List status = new ArrayList(2);
-
- IModuleResource resource = delta.getModuleResource();
- int kind2 = delta.getKind();
-
- if (resource instanceof IModuleFile) {
- IModuleFile file = (IModuleFile) resource;
- try {
- if (kind2 == IModuleResourceDelta.REMOVED)
- deleteFile2(path, file);
- else {
- IPath path2 = path.append(file.getModuleRelativePath()).append(file.getName());
- File f = path2.toFile().getParentFile();
- if (!f.exists())
- f.mkdirs();
-
- copyFile(file, path2);
- }
- } catch (CoreException ce) {
- status.add(ce.getStatus());
- }
- IStatus[] stat = new IStatus[status.size()];
- status.toArray(stat);
- return stat;
- }
-
- if (kind2 == IModuleResourceDelta.ADDED) {
- IPath path2 =
path.append(resource.getModuleRelativePath()).append(resource.getName());
- File file = path2.toFile();
- if (!file.exists() && !file.mkdirs()) {
- status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorMkdir, path2), null));
- IStatus[] stat = new IStatus[status.size()];
- status.toArray(stat);
- return stat;
- }
- }
-
- IModuleResourceDelta[] childDeltas = delta.getAffectedChildren();
- int size = childDeltas.length;
- for (int i = 0; i < size; i++) {
- IStatus[] stat = publishDelta(childDeltas[i], path, monitor);
- addArrayToList(status, stat);
- }
-
- if (kind2 == IModuleResourceDelta.REMOVED) {
- IPath path2 =
path.append(resource.getModuleRelativePath()).append(resource.getName());
- File file = path2.toFile();
- if (file.exists() && !file.delete()) {
- status.add(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, path2), null));
- }
- }
-
- IStatus[] stat = new IStatus[status.size()];
- status.toArray(stat);
- return stat;
- }
-
- private void deleteFile2(IPath path, IModuleFile file) throws CoreException {
- Trace.trace(Trace.PUBLISHING, "Deleting: " + file.getName() + " from
" + path.toString());
- IPath path2 = path.append(file.getModuleRelativePath()).append(file.getName());
- if (path2.toFile().exists() && !path2.toFile().delete())
- throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, path2), null));
- }
-
- private void copyFile(IModuleFile mf, IPath path) throws CoreException {
- Trace.trace(Trace.PUBLISHING, "Copying: " + mf.getName() + " to " +
path.toString());
-
- IFile file = (IFile) mf.getAdapter(IFile.class);
- if (file != null)
- copyFile(file.getContents(), path, file.getLocalTimeStamp(), mf);
- else {
- File file2 = (File) mf.getAdapter(File.class);
- InputStream in = null;
- try {
- in = new FileInputStream(file2);
- } catch (IOException e) {
- throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorReading, file2.getAbsolutePath()), e));
- }
- copyFile(in, path, file2.lastModified(), mf);
- }
- }
-
- /**
- * Publish the given module resources to the given path.
- *
- * @param resources an array of module resources
- * @param path a path to publish to
- * @param monitor a progress monitor, or <code>null</code> if progress
- * reporting and cancellation are not desired
- * @return a possibly-empty array of error and warning status
- */
- public IStatus[] publishFull(IModuleResource[] resources, IPath path, IProgressMonitor
monitor) {
- if (resources == null)
- return EMPTY_STATUS;
-
- monitor = ProgressUtil.getMonitorFor(monitor);
-
- List status = new ArrayList(2);
- int size = resources.length;
- for (int i = 0; i < size; i++) {
- IStatus[] stat = copy(resources[i], path, monitor);
- addArrayToList(status, stat);
- }
-
- IStatus[] stat = new IStatus[status.size()];
- status.toArray(stat);
- return stat;
- }
-
- private IStatus[] copy(IModuleResource resource, IPath path, IProgressMonitor monitor)
{
- String name = resource.getName();
- Trace.trace(Trace.PUBLISHING, "Copying: " + name + " to " +
path.toString());
- List status = new ArrayList(2);
- if (resource instanceof IModuleFolder) {
- IModuleFolder folder = (IModuleFolder) resource;
- IStatus[] stat = publishFull(folder.members(), path, monitor);
- addArrayToList(status, stat);
- } else {
- IModuleFile mf = (IModuleFile) resource;
- path = path.append(mf.getModuleRelativePath()).append(name);
- File f = path.toFile().getParentFile();
- if (!f.exists())
- f.mkdirs();
- try {
- copyFile(mf, path);
- } catch (CoreException ce) {
- status.add(ce.getStatus());
- }
- }
- IStatus[] stat = new IStatus[status.size()];
- status.toArray(stat);
- return stat;
- }
-
- /**
- * Creates a new zip file containing the given module resources. Deletes the existing
file
- * (and doesn't create a new one) if resources is null or empty.
- *
- * @param resources an array of module resources
- * @param path the path where the zip file should be created
- * @param monitor a progress monitor, or <code>null</code> if progress
- * reporting and cancellation are not desired
- * @return a possibly-empty array of error and warning status
- */
- public IStatus[] publishZip(IModuleResource[] resources, IPath path, IProgressMonitor
monitor) {
- if (resources == null || resources.length == 0) {
- // should also check if resources consists of all empty directories
- File file = path.toFile();
- if (file.exists())
- file.delete();
- return EMPTY_STATUS;
- }
-
- monitor = ProgressUtil.getMonitorFor(monitor);
-
- File tempFile = null;
- try {
- File file = path.toFile();
- tempFile = File.createTempFile(TEMPFILE_PREFIX, "." +
path.getFileExtension(), getTempFolder());
- BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(tempFile));
- ZipOutputStream zout = new ZipOutputStream(bout);
- addZipEntries(zout, resources);
- zout.close();
-
- moveTempFile(tempFile, file);
- } catch (CoreException e) {
- return new IStatus[] { e.getStatus() };
- } catch (Exception e) {
- Trace.trace(Trace.SEVERE, "Error zipping", e);
- return new Status[] { new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorCreatingZipFile, path.lastSegment(), e.getLocalizedMessage()), e)
};
- } finally {
- if (tempFile != null && tempFile.exists())
- tempFile.deleteOnExit();
- }
- return EMPTY_STATUS;
- }
-
- private void addZipEntries(ZipOutputStream zout, IModuleResource[] resources) throws
Exception {
- if (resources == null)
- return;
-
- int size = resources.length;
- for (int i = 0; i < size; i++) {
- if (resources[i] instanceof IModuleFolder) {
- IModuleFolder mf = (IModuleFolder) resources[i];
- IModuleResource[] res = mf.members();
-
- IPath path = mf.getModuleRelativePath().append(mf.getName());
- String entryPath = path.toPortableString();
- if (!entryPath.endsWith("/"))
- entryPath += '/';
-
- ZipEntry ze = new ZipEntry(entryPath);
-
- long ts = 0;
- IContainer folder = (IContainer) mf.getAdapter(IContainer.class);
- if (folder != null)
- ts = folder.getLocalTimeStamp();
-
- if (ts != IResource.NULL_STAMP && ts != 0)
- ze.setTime(ts);
-
- zout.putNextEntry(ze);
- zout.closeEntry();
-
- addZipEntries(zout, res);
- continue;
- }
-
- IModuleFile mf = (IModuleFile) resources[i];
- IPath path = mf.getModuleRelativePath().append(mf.getName());
-
- ZipEntry ze = new ZipEntry(path.toPortableString());
-
- InputStream in = null;
- long ts = 0;
- IFile file = (IFile) mf.getAdapter(IFile.class);
- if (file != null) {
- ts = file.getLocalTimeStamp();
- in = file.getContents();
- } else {
- File file2 = (File) mf.getAdapter(File.class);
- ts = file2.lastModified();
- in = new FileInputStream(file2);
- }
-
- if (ts != IResource.NULL_STAMP && ts != 0)
- ze.setTime(ts);
-
- zout.putNextEntry(ze);
-
- try {
- int n = 0;
- while (n > -1) {
- n = in.read(buf);
- if (n > 0)
- zout.write(buf, 0, n);
- }
- } finally {
- in.close();
- }
-
- zout.closeEntry();
- }
- }
-
- /**
- * Utility method to move a temp file into position by deleting the original and
- * swapping in a new copy.
- *
- * @param tempFile
- * @param file
- * @throws CoreException
- */
- private void moveTempFile(File tempFile, File file) throws CoreException {
- if (file.exists()) {
- if (!safeDelete(file, 2)) {
- // attempt to rewrite an existing file with the tempFile contents if
- // the existing file can't be deleted to permit the move
- try {
- InputStream in = new FileInputStream(tempFile);
- IStatus status = copyFile(in, file.getPath());
- if (!status.isOK()) {
- MultiStatus status2 = new MultiStatus(ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, file.toString()), null);
- status2.add(status);
- throw new CoreException(status2);
- }
- return;
- } catch (FileNotFoundException e) {
- // shouldn't occur
- } finally {
- tempFile.delete();
- }
- /*if (!safeDelete(file, 8)) {
- tempFile.delete();
- throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorDeleting, file.toString()), null));
- }*/
- }
- }
- if (!safeRename(tempFile, file, 10))
- throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorRename, tempFile.toString()), null));
- }
-
- /**
- * Copy a file from a to b. Closes the input stream after use.
- *
- * @param in java.io.InputStream
- * @param to java.lang.String
- * @return a status
- */
- private IStatus copyFile(InputStream in, String to) {
- OutputStream out = null;
-
- try {
- out = new FileOutputStream(to);
-
- int avail = in.read(buf);
- while (avail > 0) {
- out.write(buf, 0, avail);
- avail = in.read(buf);
- }
- return Status.OK_STATUS;
- } catch (Exception e) {
- Trace.trace(Trace.SEVERE, "Error copying file", e);
- return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorCopyingFile, new String[] {to, e.getLocalizedMessage()}), e);
- } finally {
- try {
- if (in != null)
- in.close();
- } catch (Exception ex) {
- // ignore
- }
- try {
- if (out != null)
- out.close();
- } catch (Exception ex) {
- // ignore
- }
- }
- }
-
- /**
- * Safe delete. Tries to delete multiple times before giving up.
- *
- * @param f
- * @return <code>true</code> if it succeeds, <code>false</code>
otherwise
- */
- private boolean safeDelete(File f, int retrys) {
- int count = 0;
- while (count < retrys) {
- if (!f.exists())
- return true;
-
- f.delete();
-
- if (!f.exists())
- return true;
-
- count++;
- // delay if we are going to try again
- if (count < retrys) {
- try {
- Thread.sleep(100);
- } catch (Exception e) {
- // ignore
- }
- }
- }
- return false;
- }
-
- /**
- * Safe rename. Will try multiple times before giving up.
- *
- * @param from
- * @param to
- * @param retrys number of times to retry
- * @return <code>true</code> if it succeeds, <code>false</code>
otherwise
- */
- private boolean safeRename(File from, File to, int retrys) {
- // make sure parent dir exists
- File dir = to.getParentFile();
- if (dir != null && !dir.exists())
- dir.mkdirs();
-
- int count = 0;
- while (count < retrys) {
- if (from.renameTo(to))
- return true;
-
- count++;
- // delay if we are going to try again
- if (count < retrys) {
- try {
- Thread.sleep(100);
- } catch (Exception e) {
- // ignore
- }
- }
- }
- return false;
- }
-
- private void addArrayToList(List list, IStatus[] a) {
- if (list == null || a == null || a.length == 0)
- return;
-
- int size = a.length;
- for (int i = 0; i < size; i++)
- list.add(a[i]);
- }
-
- protected File getTempFolder() {
- if( server == null ) return tempDir;
- String path = ServerConverter.getDeployableServer(server).getTempDeployFolder();
- File f = new File(path);
- if( !f.exists() )
- f.mkdirs();
- return new File(path);
- }
-}
\ No newline at end of file