| /******************************************************************************* |
| * Copyright (c) 2003, 2004 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.deployables; |
| |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Properties; |
| |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jdt.core.IClasspathEntry; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jem.util.logger.proxy.Logger; |
| import org.eclipse.jem.workbench.utility.JemProjectUtilities; |
| import org.eclipse.jst.common.componentcore.util.ComponentUtilities; |
| import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit; |
| import org.eclipse.jst.j2ee.ejb.EJBJar; |
| import org.eclipse.jst.j2ee.internal.EjbModuleExtensionHelper; |
| import org.eclipse.jst.j2ee.internal.IEJBModelExtenderManager; |
| import org.eclipse.jst.j2ee.internal.J2EEConstants; |
| import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants; |
| import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; |
| import org.eclipse.jst.server.core.IApplicationClientModule; |
| import org.eclipse.jst.server.core.IConnectorModule; |
| import org.eclipse.jst.server.core.IEJBModule; |
| import org.eclipse.jst.server.core.IEnterpriseApplication; |
| import org.eclipse.jst.server.core.IJ2EEModule; |
| import org.eclipse.jst.server.core.IWebModule; |
| import org.eclipse.wst.common.componentcore.ArtifactEdit; |
| import org.eclipse.wst.common.componentcore.ComponentCore; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualContainer; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualFolder; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualReference; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualResource; |
| import org.eclipse.wst.server.core.IModule; |
| import org.eclipse.wst.server.core.internal.ModuleFile; |
| import org.eclipse.wst.server.core.internal.ModuleFolder; |
| import org.eclipse.wst.server.core.model.IModuleFolder; |
| import org.eclipse.wst.server.core.model.IModuleResource; |
| import org.eclipse.wst.server.core.util.ProjectModule; |
| |
| /** |
| * J2EE deployable superclass. |
| */ |
| public class J2EEFlexProjDeployable extends ProjectModule implements IJ2EEModule, IEnterpriseApplication, IApplicationClientModule, IConnectorModule, IEJBModule, IWebModule { |
| |
| private String factoryId; |
| protected IVirtualComponent component = null; |
| private boolean outputMembersAdded = false; |
| private List members = new ArrayList(); |
| |
| /** |
| * Constructor for J2EEFlexProjDeployable. |
| * |
| * @param project |
| */ |
| public J2EEFlexProjDeployable(IProject project, String aFactoryId, IVirtualComponent aComponent) { |
| super(project); |
| factoryId = aFactoryId; |
| component = aComponent; |
| } |
| |
| public String getJ2EESpecificationVersion() { |
| return J2EEProjectUtilities.getJ2EEProjectVersion(component.getProject()); |
| } |
| |
| /* |
| * @see IModule#getFactoryId() |
| */ |
| public String getFactoryId() { |
| return factoryId; |
| } |
| |
| /** |
| * @see com.ibm.etools.server.j2ee.IJ2EEModule#isBinary() |
| */ |
| public boolean isBinary() { |
| return false; |
| } |
| |
| public String getType() { |
| return J2EEProjectUtilities.getJ2EEProjectType(component.getProject()); |
| } |
| |
| /** |
| * Return the module resources for both the component meta folder and the java output folder |
| * |
| * @return IModuleResource[] |
| */ |
| public IModuleResource[] members() throws CoreException { |
| outputMembersAdded = false; |
| members.clear(); |
| if (component == null) |
| return new IModuleResource[] {}; |
| try { |
| // Retrieve the module resources from the virtual component's root folder |
| IVirtualFolder componentRoot = component.getRootFolder(); |
| if (componentRoot!=null && componentRoot.exists()) { |
| IModuleResource[] rootResources = getModuleResources(Path.EMPTY, componentRoot); |
| members.addAll(Arrays.asList(rootResources)); |
| } |
| |
| } catch (CoreException ce) { |
| throw ce; |
| } |
| //Return the combined array of the meta resources and java class files |
| return (IModuleResource[]) members.toArray(new IModuleResource[members.size()]); |
| } |
| |
| /** |
| * Helper method to check a given list of resource trees for the given resource. It will return the |
| * already existing instance of the module Resource if found, or it will return null. |
| * |
| * @param List moduleResources |
| * @param IModuleResource aModuleResource |
| * @return existing module resource or null |
| */ |
| private IModuleResource getExistingModuleResource(List moduleResources, IModuleResource aModuleResource) { |
| IModuleResource result = null; |
| // If the list is empty, return null |
| if (moduleResources==null || moduleResources.isEmpty()) |
| return null; |
| // Otherwise recursively check to see if given resource matches current resource or if it is a child |
| int i=0; |
| do { |
| IModuleResource moduleResource = (IModuleResource) moduleResources.get(i); |
| if (moduleResource.equals(aModuleResource)) |
| result = moduleResource; |
| // if it is a folder, check its children for the resource path |
| else if (moduleResource instanceof IModuleFolder) { |
| result = getExistingModuleResource(Arrays.asList(((IModuleFolder)moduleResource).members()),aModuleResource); |
| } |
| i++; |
| } while (result == null && i<moduleResources.size() ); |
| return result; |
| } |
| |
| /** |
| * This is a helper method for J2EE deployables to gather the module resources for a J2EE module |
| * using the virtual component API. it ensures the non java meta files are represented by |
| * appropriate module resource files. |
| * |
| * @param path |
| * @param container |
| * @return array of IModuleResources |
| * @throws CoreException |
| */ |
| protected IModuleResource[] getModuleResources(IPath path, IVirtualContainer container) throws CoreException { |
| List result = new ArrayList(); |
| IVirtualResource[] resources = container.members(); |
| if (resources != null) { |
| int size = resources.length; |
| for (int i = 0; i < size; i++) { |
| IVirtualResource resource = resources[i]; |
| // If the resource is a folder, we need to add it and recursively add its members |
| if (resource!=null && resource.getType()==IVirtualResource.FOLDER) |
| addFolderModuleResources(path,container,resource,result); |
| // If the resource is a file, then make sure it does not exist in module resources, then add |
| else if (resource!=null && resource.getType()==IVirtualResource.FILE) |
| addFileModuleResource(path,container,resource,result); |
| } |
| } |
| // return the result list as a ModuleResource array |
| return (IModuleResource[]) result.toArray(new IModuleResource[result.size()]); |
| } |
| |
| /** |
| * Helper method to add module resources for the given folder and its children |
| * |
| * @param path |
| * @param container |
| * @param resource |
| * @param result |
| * @throws CoreException |
| */ |
| private void addFolderModuleResources(IPath path, IVirtualContainer container, IVirtualResource resource, List result) throws CoreException { |
| IVirtualContainer container2 = (IVirtualContainer) resource; |
| if (container2 != null && container2.exists()) { |
| ModuleFolder mf = new ModuleFolder((IContainer)container.getUnderlyingResource(), container2.getName(), path); |
| //If the folder does not exist yet in module resources, let's create it |
| if (getExistingModuleResource(members,mf)==null && getExistingModuleResource(result,mf)==null) { |
| mf.setMembers(getModuleResources(path.append(container2.getName()), container2)); |
| result.add(mf); |
| } |
| // if folder exists, we need to retreive the existing module folder and update |
| else { |
| // first try to retrieve from cached list |
| ModuleFolder matchingMf = (ModuleFolder) getExistingModuleResource(members,mf); |
| // if still null, retrieve from current result set which has not been added to cache |
| if (matchingMf==null) |
| matchingMf = (ModuleFolder) getExistingModuleResource(result,mf); |
| // update the members on the existing module resource to have the new children |
| List currentMembers = new ArrayList(); |
| List membersList = Arrays.asList(matchingMf.members()); |
| List newMembers = Arrays.asList(getModuleResources(path.append(container2.getName()), container2)); |
| currentMembers.addAll(membersList); |
| currentMembers.addAll(newMembers); |
| matchingMf.setMembers((IModuleResource[])currentMembers.toArray(new IModuleResource[currentMembers.size()])); |
| } |
| } |
| } |
| |
| /** |
| * Helper method to add a module resource for the given file |
| * |
| * @param path |
| * @param container |
| * @param resource |
| * @param result |
| */ |
| private void addFileModuleResource(IPath path, IVirtualContainer container, IVirtualResource resource, List result) { |
| IFile file = null; |
| String runtimePath = resource.getRuntimePath().toString(); |
| // temporary hack because virtual component API returns .java rather than .class files |
| if (runtimePath.endsWith(".java")) { //$NON-NLS-1$ |
| IContainer output = ComponentUtilities.getOutputContainers(container.getComponent())[0]; |
| runtimePath = resource.getRuntimePath().lastSegment().toString(); |
| String className = runtimePath.substring(0,runtimePath.length()-4)+"class"; //$NON-NLS-1$ |
| file = findClassFileInOutput(output,className); |
| } else |
| file = (IFile) resource.getUnderlyingResource(); |
| if (file == null) |
| return; |
| ModuleFile moduleFile = new ModuleFile(file, file.getName(), path, file.getModificationStamp()); |
| // we have to be sure its not in cache and current result group waiting to be added to cache |
| if (file != null && file.exists() && getExistingModuleResource(result,moduleFile)==null && getExistingModuleResource(members,moduleFile)==null) |
| result.add(moduleFile); |
| } |
| |
| private IFile findClassFileInOutput(IContainer container, String className) { |
| IFile result = null; |
| result = (IFile) container.findMember(className); |
| if (result == null) { |
| try { |
| IResource[] currentMembers = container.members(); |
| for (int i=0; i<currentMembers.length; i++) { |
| if (currentMembers[i].getType()==IResource.FOLDER) { |
| result = findClassFileInOutput((IContainer)currentMembers[i],className); |
| if (result != null) |
| break; |
| } |
| } |
| } catch (Exception e) {} |
| } |
| return result; |
| } |
| |
| protected IContainer getContainerResource(IResource resource){ |
| if(resource instanceof IFolder) { |
| IJavaElement element =JavaCore.create((IFolder)resource); |
| if (element != null && element.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT) |
| //means this is a source folder add output once and only once |
| return addOutputFolderIfNecessary(element); |
| } |
| return (IContainer)resource; |
| } |
| |
| private IContainer addOutputFolderIfNecessary(IJavaElement je) { |
| if(!outputMembersAdded){ |
| outputMembersAdded = true; |
| IPath javaOutputPath = null; |
| try { |
| if (je.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT) { |
| IPackageFragmentRoot packRoot = (IPackageFragmentRoot) je; |
| if (packRoot.getKind() == IPackageFragmentRoot.K_SOURCE) { |
| IClasspathEntry ce = packRoot.getRawClasspathEntry(); |
| javaOutputPath = ce.getOutputLocation(); |
| javaOutputPath = javaOutputPath.removeFirstSegments(1); |
| return getProject().getFolder(javaOutputPath); |
| } |
| } |
| } catch (JavaModelException e) { |
| Logger.getLogger().log(e.getMessage()); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the classpath as a list of absolute IPaths. |
| * |
| * @param java.util.List |
| */ |
| public IPath[] getClasspath() { |
| List paths = new ArrayList(); |
| IJavaProject proj = JemProjectUtilities.getJavaProject(getProject()); |
| URL[] urls = JemProjectUtilities.getClasspathAsURLArray(proj); |
| for (int i = 0; i < urls.length; i++) { |
| URL url = urls[i]; |
| paths.add(Path.fromOSString(url.getPath())); |
| } |
| return (IPath[]) paths.toArray(new IPath[paths.size()]); |
| } |
| |
| public String getJNDIName(String ejbName) { |
| if (!J2EEProjectUtilities.isEJBProject(component.getProject())) |
| return null; |
| EjbModuleExtensionHelper modHelper = null; |
| EJBJar jar = null; |
| ArtifactEdit ejbEdit = null; |
| try { |
| ejbEdit = ComponentUtilities.getArtifactEditForRead(component); |
| if (ejbEdit != null) { |
| jar = (EJBJar) ejbEdit.getContentModelRoot(); |
| modHelper = IEJBModelExtenderManager.INSTANCE.getEJBModuleExtension(null); |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } finally { |
| if (ejbEdit != null) |
| ejbEdit.dispose(); |
| } |
| return modHelper == null ? null : modHelper.getJNDIName(jar, jar.getEnterpriseBeanNamed(ejbName)); |
| } |
| |
| /** |
| * Returns the child modules of this module. |
| * |
| * @return org.eclipse.wst.server.core.model.IModule[] |
| */ |
| public IModule[] getChildModules() { |
| return getModules(); |
| } |
| |
| public IModule[] getModules() { |
| List modules = new ArrayList(); |
| IVirtualReference[] components = component.getReferences(); |
| for (int i=0; i<components.length; i++) { |
| IVirtualReference reference = components[i]; |
| IVirtualComponent virtualComp = reference.getReferencedComponent(); |
| Object module = FlexibleProjectServerUtil.getModule(virtualComp.getProject()); |
| if (module!=null) |
| modules.add(module); |
| } |
| return (IModule[]) modules.toArray(new IModule[modules.size()]); |
| } |
| |
| public String getURI(IModule module) { |
| IVirtualComponent comp = ComponentCore.createComponent(module.getProject()); |
| if (J2EEProjectUtilities.isEARProject(comp.getProject())) { |
| EARArtifactEdit earEdit = null; |
| String aURI = null; |
| try { |
| earEdit = EARArtifactEdit.getEARArtifactEditForRead(component); |
| if (earEdit != null) { |
| aURI = earEdit.getModuleURI(comp); |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } finally { |
| if (earEdit != null) |
| earEdit.dispose(); |
| } |
| return aURI; |
| } |
| else if (J2EEProjectUtilities.isDynamicWebProject(comp.getProject())) { |
| String result = null; |
| if (!comp.isBinary()) { |
| IVirtualReference ref = component.getReference(comp.getName()); |
| result = ref.getRuntimePath().append(comp.getName()+IJ2EEModuleConstants.JAR_EXT).toString(); |
| } |
| return result; |
| } |
| return null; |
| } |
| |
| public String getContextRoot() { |
| Properties props = component.getMetaProperties(); |
| if(props.containsKey(J2EEConstants.CONTEXTROOT)) |
| return props.getProperty(J2EEConstants.CONTEXTROOT); |
| return component.getName(); |
| } |
| } |