blob: cf741b7d7b13d6c9cfd8409814f82a8e26be1486 [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
 *
* Contributors:
* IBM Corporation - Initial API and implementation
**********************************************************************/
package org.eclipse.wst.server.core.internal;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.wst.server.core.*;
import org.eclipse.wst.server.core.model.*;
import org.eclipse.wst.server.core.resources.*;
/**
* Abstract class for publishing support.
*/
public abstract class AbstractPublisher implements IPublishManagerDelegate {
protected Map deleteMap;
protected Map publishMap;
protected List delete;
protected List publish;
protected IModule module;
protected Map resourceMap;
protected IPublishControl control;
private static final List EMPTY_LIST = new ArrayList(0);
/**
* AbstractPublisher constructor comment.
*/
public AbstractPublisher() {
super();
}
/**
*
*/
protected void deleteResources(IRemoteResource remote, List delete2, List visited, IProgressMonitor monitor) {
if (remote == null)
return;
/*if (!visited.contains(resource)) {
delete.add(resource);
}*/
IModuleResource resource = null;
try {
resource = (IModuleResource) resourceMap.get(remote.getPath());
} catch (Exception e) {
//Trace.trace("Error in abstract publisher", e);
}
if (shouldDelete(resource, null, remote, IRemoteResource.TIMESTAMP_UNKNOWN, control.getPublishedTimestamp(remote))) {
delete2.add(remote);
}
if (remote instanceof IRemoteFolder) {
IRemoteFolder folder = (IRemoteFolder) remote;
Iterator iterator = folder.getContents().iterator();
while (iterator.hasNext()) {
IRemoteResource sub = (IRemoteResource) iterator.next();
deleteResources(sub, delete2, visited, monitor);
}
}
}
protected IRemoteResource findRemoteResource(IRemoteFolder folder, IPath path) {
Iterator iterator = folder.getContents().iterator();
while (iterator.hasNext()) {
IRemoteResource remote = (IRemoteResource) iterator.next();
if (path.equals(remote.getPath()))
return remote;
if (remote instanceof IRemoteFolder) {
IRemoteFolder folder2 = (IRemoteFolder) remote;
IPath folderPath = folder2.getPath();
if (folderPath.isPrefixOf(path)) {
IRemoteResource rem = findRemoteResource(folder2, path);
if (rem != null)
return rem;
}
}
}
return null;
}
protected IRemoteResource findRemoteResource(IPath path) {
if (path == null)
return null;
IRemoteResource[] resources = control.getRemoteResources();
int size = resources.length;
for (int i = 0; i < size; i++) {
IRemoteResource remote = resources[i];
if (path.equals(remote.getPath()))
return remote;
if (remote instanceof IRemoteFolder) {
IRemoteFolder folder2 = (IRemoteFolder) remote;
IPath folderPath = folder2.getPath();
if (folderPath.isPrefixOf(path)) {
IRemoteResource rem = findRemoteResource(folder2, path);
if (rem != null)
return rem;
}
}
}
return null;
}
/**
* Returns the list of remote resources to delete from the
* remote machine.
*
* @return java.util.List
*/
public List getResourcesToDelete(IModule module2) {
try {
return (List) deleteMap.get(module2);
} catch (Exception e) {
return EMPTY_LIST;
}
}
/**
* Returns the list of resources to publish to the
* remote machine.
*
* @return java.util.List
*/
public List getResourcesToPublish(IModule module2) {
try {
return (List) publishMap.get(module2);
} catch (Exception e) {
return EMPTY_LIST;
}
}
/**
*
*/
protected void publishResources(IModuleResource resource, List publish2, List visited, IProgressMonitor monitor) {
if (resource == null)
return;
IPath path = control.getMappedLocation(resource);
resourceMap.put(path, resource);
if (path != null) {
IRemoteResource remote = findRemoteResource(path);
if (!(resource instanceof IModuleFolder && remote != null)) { // don't republish directories that already exist
if (shouldPublish(resource, path, remote, control.getPublishedTimestamp(resource), control.getPublishedTimestamp(remote))) {
publish2.add(resource);
}
}
}
if (resource instanceof IModuleFolder) {
IModuleFolder cont = (IModuleFolder) resource;
if (control.shouldMapMembers(cont)) {
try {
IModuleResource[] sub = cont.members();
if (sub != null) {
int size = sub.length;
for (int i = 0; i < size; i++)
publishResources(sub[i], publish2, visited, monitor);
}
} catch (Exception e) {
Trace.trace(Trace.SEVERE, "Error in abstract publisher", e);
}
}
}
}
/**
* Sets the publish control, used to obtain information about
* the publishing.
*
* Sets the publish state, used to determine the timestamps
* of the last publishing action.
*
* Resolve which resources to publish or delete.
*
* @param controls org.eclipse.wst.server.model.IPublishControl[]
* @param modules org.eclipse.wst.server.core.model.IModule[]
* @param monitor org.eclipse.core.runtime.IProgressMonitor
*/
public void resolve(IPublishControl[] controls, IModule[] modules, IProgressMonitor monitor) {
int size = controls.length;
Trace.trace(Trace.FINEST, "Abstract publisher starting " + size);
deleteMap = new HashMap(size);
publishMap = new HashMap(size);
for (int i = 0; i < size; i++) {
Trace.trace(Trace.FINEST, "Resolving: " + modules[i]);
this.control = controls[i];
this.module = modules[i];
delete = new ArrayList();
publish = new ArrayList();
resourceMap = new HashMap();
resolveModule(monitor);
Trace.trace(Trace.FINEST, "Deleting " + delete.size() + " resources");
Trace.trace(Trace.FINEST, "Publishing " + publish.size() + " resources");
deleteMap.put(modules[i], delete);
publishMap.put(modules[i], publish);
}
}
/**
* Resolve which resources to publish or delete. Both setXxx()
* methods will have been called before this method.
*/
protected void resolveModule(IProgressMonitor monitor) {
List visited = new ArrayList();
// first, decide which files to publish
Trace.trace(Trace.FINEST, "Resolving publish for " + module);
try {
publish = new ArrayList();
IModuleResource[] resources = module.members();
if (resources != null) {
int size = resources.length;
for (int i = 0; i < size; i++)
publishResources(resources[i], publish, visited, monitor);
}
sortPublishList(publish);
} catch (Exception e) {
}
// next, choose which files to delete
Trace.trace(Trace.FINEST, "Resolving delete for " + module);
delete = new ArrayList();
IRemoteResource[] resources = control.getRemoteResources();
if (resources != null) {
int size = resources.length;
for (int i = 0; i < size; i++) {
IRemoteResource remote = resources[i];
deleteResources(remote, delete, visited, monitor);
}
}
sortDeletionList(delete);
}
/**
* Returns true if the remote resource should be deleted, and false
* if it should be left on the server.
*
* @return boolean
* @param option int
*/
public abstract boolean shouldDelete(IModuleResource resource, IPath path, IRemoteResource remote, long resourceTimestamp, long remoteTimestamp);
/**
* Returns true if the resource should be published, and false
* if it should be left on the server.
*
* @return boolean
* @param option int
*/
public abstract boolean shouldPublish(IModuleResource resource, IPath path, IRemoteResource remote, long resourceTimestamp, long remoteTimestamp);
/**
* Sorts the deletions so that directories are last and
* appear in "reverse depth order".
*/
public static void sortDeletionList(List list) {
if (list == null)
return;
int size = list.size();
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < size; j++) {
Object a = list.get(i);
Object b = list.get(j);
boolean swap = false;
if (a instanceof IRemoteFolder && !(b instanceof IRemoteFolder))
swap = true;
else if (a instanceof IRemoteFolder && b instanceof IRemoteFolder) {
IRemoteFolder rfa = (IRemoteFolder) a;
IRemoteFolder rfb = (IRemoteFolder) b;
if (rfa.getPath().isPrefixOf(rfb.getPath()))
swap = true;
}
if (swap) {
list.set(i, b);
list.set(j, a);
}
}
}
}
/**
* Sorts the publishes so that directories are first and are
* in "depth order". (subdirectories appear after their parents)
*/
public static void sortPublishList(List list) {
if (list == null)
return;
int size = list.size();
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < size; j++) {
Object a = list.get(i);
Object b = list.get(j);
boolean swap = false;
if (!(a instanceof IModuleFolder) && b instanceof IModuleFolder)
swap = true;
else if (a instanceof IModuleFolder && b instanceof IModuleFolder) {
IModuleFolder ca = (IModuleFolder) a;
IModuleFolder cb = (IModuleFolder) b;
if (cb.getPath().isPrefixOf(ca.getPath()))
swap = true;
}
if (swap) {
list.set(i, b);
list.set(j, a);
}
}
}
}
}