blob: 002f0bfa0f71758fc511fe216469f53610d0c7d5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2005 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.eclipse.jst.j2ee.internal.web.archive.operations;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.File;
import org.eclipse.jst.j2ee.commonarchivecore.internal.WARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.SaveFailureException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveConstants;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.FileIterator;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.archive.operations.FlexibleJ2EESaveStrategyImpl;
import org.eclipse.jst.j2ee.internal.plugin.LibCopyBuilder;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
public class FlexibleJ2EEWebSaveStrategyImpl extends FlexibleJ2EESaveStrategyImpl {
private HashMap filesToSave; // container a mapping from the File.getURI() to the target path
private HashSet filesNotToSave;
public FlexibleJ2EEWebSaveStrategyImpl(IVirtualComponent vComponent) {
super(vComponent);
}
public void save(File aFile, FileIterator iterator) throws SaveFailureException {
if (aFile.isArchive() && shouldIterateOver((Archive) aFile)) {
save((Archive) aFile);
} else {
InputStream in = null;
if (!aFile.isDirectoryEntry()) {
try {
in = iterator.getInputStream(aFile);
} catch (IOException ex) {
throw new SaveFailureException(aFile.getURI(), ex);
}
}
IPath path = (IPath) filesToSave.get(aFile.getURI());
if (path != null) {
try {
saveToWorkbenchPath(path, in);
} catch (Exception e) {
throw new SaveFailureException(e.getMessage(), e);
}
}
}
}
protected void saveFiles() throws SaveFailureException {
WARFile warFile = (WARFile) getArchive();
// First go through the classes in the WEB-INF/classes directory and try
// to find a source file for each one file there. If a source file is
// found, copy
// it to the source directory, if not, copy the .class file to the
// imported_classes directory.
List classesFiles = getClassesFiles();
Iterator classesIterator = classesFiles.iterator();
filesToSave = new HashMap();
HashMap libModuleFiles = new HashMap();
boolean hasSource = false;
boolean hasClasses = false;
while (classesIterator.hasNext()) {
File classFile = (File) classesIterator.next();
if (WTProjectStrategyUtils.isClassFile(classFile.getURI())) {
hasClasses = true;
File sourceFile = warFile.getSourceFile(classFile);
IPath path = null;
if (sourceFile != null) {
hasSource = true;
// TODO can this be optimized?
IPath sourcePath = new Path(sourceFile.getURI());
IPath relClassPath = new Path(WTProjectStrategyUtils.makeRelative(classFile.getURI(), ArchiveConstants.WEBAPP_CLASSES_URI));
String relSourceURI = sourcePath.removeFirstSegments(sourcePath.segmentCount() - relClassPath.segmentCount()).toString();
path = convertToSourcePath(relSourceURI);
filesToSave.put(classFile.getURI(), null); // don't save the .class file
filesToSave.put(sourceFile.getURI(), path);
} else {
path = convertToImportedClassesPath(classFile.getURI());
filesToSave.put(classFile.getURI(), path);
}
}
}
// If there were no class files, then put any other resource in the
// classes
// directory to the source folder.
if (!hasClasses)
hasSource = true;
// Next go through the classes directory again saving all of the files
// that were
// not previously saved. This handles the resource files.
classesIterator = classesFiles.iterator();
while (classesIterator.hasNext()) {
File classFile = (File) classesIterator.next();
if (!filesToSave.containsKey(classFile.getURI())) {
File copyFile = warFile.getSourceFile(classFile);
// If its a java file, put it into the source directory
if (!hasSource && WTProjectStrategyUtils.isSourceFile(classFile.getURI()))
hasSource = true;
IPath path = null;
if (!hasSource) {
path = convertToImportedClassesPath(classFile.getURI());
} else {
IPath sourcePath = new Path(classFile.getURI());
IPath relClassPath = new Path(WTProjectStrategyUtils.makeRelative(classFile.getURI(), ArchiveConstants.WEBAPP_CLASSES_URI));
String relSourceURI = sourcePath.removeFirstSegments(sourcePath.segmentCount() - relClassPath.segmentCount()).toString();
path = convertToSourcePath(relSourceURI);
}
filesToSave.put(classFile.getURI(), path);
if (copyFile != null)
filesToSave.put(copyFile.getURI(), null);
}
}
// Finally, make a pass through all of the files now, saving them to the
// appropriate place
// if they have not yet been saved.
List allFiles = getArchive().getFiles();
for (Iterator iter = allFiles.iterator(); iter.hasNext();) {
File file = (File) iter.next();
if (!filesToSave.containsKey(file.getURI())) {
if (!libModuleFiles.containsKey(file.getURI())) {
IPath path = convertToContentPath(file.getURI());
filesToSave.put(file.getURI(), path);
}
}
}
super.saveFiles();
}
protected List getClassesFiles() {
return ((WARFile) getArchive()).getClasses();
}
private IPath importedClassesPath;
protected IPath convertToImportedClassesPath(String uri) {
if (importedClassesPath == null) {
IPath javaPath = getJavaSourcePath();
importedClassesPath = javaPath.removeLastSegments(1).append(LibCopyBuilder.IMPORTED_CLASSES_PATH);
try {
IPath workspacePath = vComponent.getProject().getFullPath().append(importedClassesPath);
mkdirs(workspacePath, ResourcesPlugin.getWorkspace().getRoot());
IVirtualFolder javaSourceFolder = vComponent.getFolder(new Path("/" + J2EEConstants.WEB_INF + "/classes"));
javaSourceFolder.createLink(workspacePath.removeFirstSegments(1), 0, null);
} catch (CoreException e) {
// TODO
}
}
return importedClassesPath.append(WTProjectStrategyUtils.makeRelative(uri, ArchiveConstants.WEBAPP_CLASSES_URI));
}
private IPath javaSourcePath;
private void loadJavaSource() {
IVirtualResource[] resources = vComponent.getResources("java");
IVirtualFolder vJavaSourceFolder = (IVirtualFolder) resources[0];
IFolder javaSource = vJavaSourceFolder.getUnderlyingFolder();
javaSourcePath = javaSource.getProjectRelativePath();
}
protected IPath getJavaSourcePath() {
if (javaSourcePath == null) {
loadJavaSource();
}
return javaSourcePath;
}
protected IPath convertToSourcePath(String uri) {
return getJavaSourcePath().append(uri);
}
private IPath webContentPath;
protected IPath convertToContentPath(String uri) {
if (webContentPath == null) {
webContentPath = vComponent.getFolder("/").getUnderlyingResource().getProjectRelativePath();
}
return webContentPath.append(uri);
}
}