blob: ef1a103a351edd0ec89b0e7e2b222cb90a47600d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2006 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.commonarchivecore.internal.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveResourceHandler;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchivePackage;
import org.eclipse.jst.j2ee.commonarchivecore.internal.File;
import org.eclipse.jst.j2ee.commonarchivecore.internal.WARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.DeploymentDescriptorLoadException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.DuplicateObjectException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveConstants;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.RuntimeClasspathEntry;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.WarFileDynamicClassLoader;
import org.eclipse.jst.j2ee.commonarchivecore.looseconfig.internal.LooseLibrary;
import org.eclipse.jst.j2ee.commonarchivecore.looseconfig.internal.LooseWARFile;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.common.XMLResource;
import org.eclipse.jst.j2ee.webapplication.WebApp;
import org.eclipse.jst.j2ee.webapplication.WebapplicationPackage;
/**
* @generated
*/
public class WARFileImpl extends ModuleFileImpl implements WARFile {
/**
* @generated This field/method will be replaced during code generation.
*/
/**
* @generated This field/method will be replaced during code generation.
*/
protected WebApp deploymentDescriptor = null;
protected List sourceFiles;
public WARFileImpl() {
super();
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
* @generated
*/
protected EClass eStaticClass() {
return CommonarchivePackage.Literals.WAR_FILE;
}
/**
* @see com.ibm.etools.commonarchive.WARFile
*/
public File addCopyClass(File aFile) throws DuplicateObjectException {
if (aFile.isReadOnlyDirectory())
throw new IllegalArgumentException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.add_copy_class_dir_EXC_, (new Object[]{aFile.getURI()}))); // = "Method addCopyClass not supported for directories :"
return addCopyFileAddingPrefix(aFile, ArchiveConstants.WEBAPP_CLASSES_URI);
}
protected File addCopyFileAddingPrefix(File aFile, String uriPrefix) throws DuplicateObjectException {
String swizzledUri = aFile.getURI();
if (!swizzledUri.startsWith(uriPrefix)) {
swizzledUri = ArchiveUtil.concatUri(uriPrefix, swizzledUri, '/');
}
checkAddValid(swizzledUri);
File copy = copy(aFile);
copy.setURI(swizzledUri);
getFiles().add(copy);
return copy;
}
/**
* @see com.ibm.etools.commonarchive.WARFile
*/
public File addCopyLib(File aFile) throws DuplicateObjectException {
if (aFile.isReadOnlyDirectory())
throw new IllegalArgumentException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.add_copy_lib_dir_EXC_, (new Object[]{aFile.getURI()}))); // = "Method addCopyLib not supported for directories :"
return addCopyFileAddingPrefix(aFile, ArchiveConstants.WEBAPP_LIB_URI);
}
protected RuntimeClasspathEntry createLibClasspathEntry(String libPath) {
RuntimeClasspathEntry entry = createRuntimeClasspathEntry(libPath);
entry.setWarFile(this);
return entry;
}
/**
* Used internally for building the runtime class path
*
* @return List of Strings, the absolute paths of all file entries (no directories)
*/
protected List getAllFileEntriesRecursive(java.io.File aFile, List aList) {
if (!aFile.exists())
return aList;
//modified for botp 126140 05.29.02
String name = aFile.getName();
if (name.regionMatches(true, name.length() - 4, ".jar", 0, 4)) {//$NON-NLS-1$
aList.add(aFile.getAbsolutePath());
} else if (aFile.isDirectory()) {
java.io.File[] children = aFile.listFiles();
for (int i = 0; i < children.length; i++) {
getAllFileEntriesRecursive(children[i], aList);
}
}
return aList;
}
/**
* @see com.ibm.etools.commonarchive.WARFile
*/
public java.util.List getClasses() {
return filterFilesByPrefix(ArchiveConstants.WEBAPP_CLASSES_URI);
}
/**
* @throws DeploymentDescriptorLoadException -
* is a runtime exception, because we can't override the signature of the generated
* methods
*/
public WebApp getDeploymentDescriptor() throws DeploymentDescriptorLoadException {
WebApp dd = this.getDeploymentDescriptorGen();
if (dd == null && canLazyInitialize())
try {
getImportStrategy().importMetaData();
} catch (Exception e) {
throw new DeploymentDescriptorLoadException(getDeploymentDescriptorUri(), e);
}
return this.getDeploymentDescriptorGen();
}
public String getDeploymentDescriptorUri() {
return J2EEConstants.WEBAPP_DD_URI;
}
/**
* @see com.ibm.etools.commonarchive.WARFile
*/
public java.util.List getLibs() {
return filterFilesByPrefix(ArchiveConstants.WEBAPP_LIB_URI);
}
/**
* @see com.ibm.etools.commonarchive.WARFile
*/
public List getLibArchives() {
return filterFiles(ArchiveConstants.WEBAPP_LIB_URI, new String[]{"jar", "zip"}); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* @see com.ibm.etools.commonarchive.WARFile
*/
public java.util.List getResources() {
String[] prefixes = {J2EEConstants.META_INF, J2EEConstants.WEB_INF};
return filterFilesWithoutPrefix(prefixes);
}
/**
* Overridden from superclass to include the claseses and libs of a WARFile There also is an
* assumption that this is an exploded war file The following is what should be returned:
*
* 1) WAR directory + /WEB-INF/classes 2) all JAR files contained in [WAR directory +
* /WEB-INF/lib] 3) WAR directory
*/
public RuntimeClasspathEntry[] getLocalRuntimeClassPath() {
String absolutePath;
try {
absolutePath = getLoadStrategy().getBinariesPath();
} catch (IOException ex) {
return new RuntimeClasspathEntry[0];
}
List entries = new ArrayList();
if (getLoadStrategy().isDirectory()) {
String classesPath = ArchiveUtil.getOSUri(absolutePath, ArchiveConstants.WEBAPP_CLASSES_URI);
entries.add(createRuntimeClasspathEntry(classesPath));
addWebLibs(absolutePath, entries);
}
entries.add(createRuntimeClasspathEntry(absolutePath));
return (RuntimeClasspathEntry[]) entries.toArray(new RuntimeClasspathEntry[entries.size()]);
}
protected RuntimeClasspathEntry[] getDependencyClassPathAtThisLevel() {
String absolutePath = internalGetBinariesPath();
if (absolutePath == null)
return emptyClasspath();
RuntimeClasspathEntry[] mfEntries = super.getDependencyClassPathAtThisLevel();
List entries = new ArrayList();
entries.addAll(Arrays.asList(mfEntries));
return (RuntimeClasspathEntry[]) entries.toArray(new RuntimeClasspathEntry[entries.size()]);
}
protected void addWebLibs(String absolutePath, List entries) {
/*******************************************************************************************
* Optimization*********** We could have used the helper getlibs here; however, that could
* drag down performance as the full file list would have to get built, and this is runtime;
* if the classes portion is huge then building the file list would be slow; moreover, we
* would then have to clear the index from this war file. therefore, we'll do a little extra
* work to get the libs
******************************************************************************************/
java.io.File aFile = new java.io.File(ArchiveUtil.getOSUri(absolutePath, ArchiveConstants.WEBAPP_LIB_URI));
List libs = getAllFileEntriesRecursive(aFile, new ArrayList());
for (int i = 0; i < libs.size(); i++) {
String libPath = (String) libs.get(i);
entries.add(createLibClasspathEntry(libPath));
}
addLooseLibsToRuntimeClasspath(entries);
}
protected void addLooseLibsToRuntimeClasspath(List entries) {
LooseWARFile loose = (LooseWARFile) getLoadStrategy().getLooseArchive();
if (loose == null)
return;
List looseLibs = loose.getLooseLibs();
for (int i = 0; i < looseLibs.size(); i++) {
LooseLibrary lib = (LooseLibrary) looseLibs.get(i);
entries.add(createLibClasspathEntry(lib.getBinariesPath()));
}
}
protected List calculateSourceCandidateFiles() {
List filesList = getFiles();
List retFiles = new Vector();
for (Iterator iter = filesList.iterator(); iter.hasNext();) {
File file = (File) iter.next();
String aUri = file.getURI();
if (aUri.startsWith(J2EEConstants.WEB_INF) && !aUri.startsWith(ArchiveConstants.WEBAPP_LIB_URI))
retFiles.add(file);
}
return retFiles;
}
protected List getSourceCandidateFiles() {
if (sourceFiles == null) {
sourceFiles = calculateSourceCandidateFiles();
}
return sourceFiles;
}
protected String makeRelative(String pathString, String relToPathString) {
if (pathString.startsWith(relToPathString))
return ArchiveUtil.truncateFromFrontIgnoreCase(pathString, relToPathString);
return pathString;
}
/**
* Return the source file that matches the output file passed in
*
* @param aClassFile
* The .class file or other output file to find the source for
* @return String The matching source. Null if there is no matching source found
*/
public File getSourceFile(File aClassFile) {
List sourceFilesList = getSourceCandidateFiles();
String classURI = aClassFile.getURI();
String convertedClassURI = classURI;
if (classURI.endsWith(".class")) //$NON-NLS-1$
convertedClassURI = ArchiveUtil.classUriToJavaUri(aClassFile.getURI());
else
return null;
convertedClassURI = makeRelative(convertedClassURI, ArchiveConstants.WEBAPP_CLASSES_URI);
int bestLength = 32767;
File bestMatch = null;
File file = null;
String aUri = null;
for (Iterator iter = sourceFilesList.iterator(); iter.hasNext();) {
file = (File) iter.next();
aUri = file.getURI();
if (aUri.endsWith(convertedClassURI) && !aUri.equals(classURI)) {
int excessLength = aUri.length() - convertedClassURI.length();
if (excessLength < bestLength) {
bestMatch = file;
bestLength = excessLength;
}
}
}
return bestMatch;
}
/**
* Return the DeployementDescriptor.
*/
public EObject getStandardDeploymentDescriptor() throws DeploymentDescriptorLoadException {
return getDeploymentDescriptor();
}
public boolean isDeploymentDescriptorSet() {
return deploymentDescriptor != null;
}
/**
* @see com.ibm.etools.commonarchive.File
*/
public boolean isWARFile() {
return true;
}
/**
* @see com.ibm.etools.commonarchive.impl.ModuleFileImpl
*/
public org.eclipse.emf.ecore.EObject makeDeploymentDescriptor(XMLResource resource) {
WebApp webApp = ((WebapplicationPackage) EPackage.Registry.INSTANCE.getEPackage(WebapplicationPackage.eNS_URI)).getWebapplicationFactory().createWebApp();
resource.setID(webApp, J2EEConstants.WEBAPP_ID);
setDeploymentDescriptorGen(webApp);
resource.getContents().add(webApp);
return webApp;
}
public void setDeploymentDescriptor(WebApp l) {
this.setDeploymentDescriptorGen(l);
replaceRoot(getMofResourceMakeIfNecessary(getDeploymentDescriptorUri()), l);
}
/**
* @generated This field/method will be replaced during code generation
*/
public WebApp getDeploymentDescriptorGen() {
if (deploymentDescriptor != null && deploymentDescriptor.eIsProxy()) {
InternalEObject oldDeploymentDescriptor = (InternalEObject)deploymentDescriptor;
deploymentDescriptor = (WebApp)eResolveProxy(oldDeploymentDescriptor);
if (deploymentDescriptor != oldDeploymentDescriptor) {
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.RESOLVE, CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR, oldDeploymentDescriptor, deploymentDescriptor));
}
}
return deploymentDescriptor;
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
* @generated
*/
public WebApp basicGetDeploymentDescriptor() {
return deploymentDescriptor;
}
/**
* @generated This field/method will be replaced during code generation.
*/
public void setDeploymentDescriptorGen(WebApp newDeploymentDescriptor) {
WebApp oldDeploymentDescriptor = deploymentDescriptor;
deploymentDescriptor = newDeploymentDescriptor;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR, oldDeploymentDescriptor, deploymentDescriptor));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public Object eGet(int featureID, boolean resolve, boolean coreType) {
switch (featureID) {
case CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR:
if (resolve) return getDeploymentDescriptor();
return basicGetDeploymentDescriptor();
}
return super.eGet(featureID, resolve, coreType);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void eSet(int featureID, Object newValue) {
switch (featureID) {
case CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR:
setDeploymentDescriptor((WebApp)newValue);
return;
}
super.eSet(featureID, newValue);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void eUnset(int featureID) {
switch (featureID) {
case CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR:
setDeploymentDescriptor((WebApp)null);
return;
}
super.eUnset(featureID);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public boolean eIsSet(int featureID) {
switch (featureID) {
case CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR:
return deploymentDescriptor != null;
}
return super.eIsSet(featureID);
}
public ClassLoader createDynamicClassLoader(ClassLoader parentCl, ClassLoader extraCl) {
return new WarFileDynamicClassLoader(this, parentCl, extraCl);
}
}