/******************************************************************************* * 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 */ @Override 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(); } @Override 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 */ @Override 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()]); } @Override 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(); } @Override public boolean isDeploymentDescriptorSet() { return deploymentDescriptor != null; } /** * @see com.ibm.etools.commonarchive.File */ @Override public boolean isWARFile() { return true; } /** * @see com.ibm.etools.commonarchive.impl.ModuleFileImpl */ @Override 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 */ @Override 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 */ @Override 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 */ @Override 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 */ @Override public boolean eIsSet(int featureID) { switch (featureID) { case CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR: return deploymentDescriptor != null; } return super.eIsSet(featureID); } @Override public ClassLoader createDynamicClassLoader(ClassLoader parentCl, ClassLoader extraCl) { return new WarFileDynamicClassLoader(this, parentCl, extraCl); } }