blob: dea672af9054f3c823dbc2099ebdca5da95ab8d3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 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.internal.ejb.archiveoperations;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jem.internal.adapters.jdom.JDOMSearchHelper;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit;
import org.eclipse.jst.j2ee.ejb.EJBJar;
import org.eclipse.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.ejb.Entity;
import org.eclipse.jst.j2ee.ejb.componentcore.util.EJBArtifactEdit;
import org.eclipse.jst.j2ee.internal.ejb.project.operations.ClientJARCreationConstants;
import org.eclipse.wst.common.componentcore.ComponentCore;
public class EJBClientJarCreationHelper {
protected static final String SERVICE_LOCATOR_JAR_NAME = "serviceLocatorMgr.jar"; //$NON-NLS-1$
private IProject ejbProject = null;
protected Map javaFilesToMove = new HashMap();
protected Set visitedJavaTypes = new HashSet();
protected int moveResourceCount = 0;
protected SearchEngine searchEngine = new SearchEngine();
private MySearchHelper searchHelper = null;
public EJBClientJarCreationHelper(IProject aEjbProject){
ejbProject = aEjbProject;
}
public Map getFilesToMove() {
searchHelper = new MySearchHelper(searchEngine, computeBeanTypeNames());
if( ejbProject.exists() && ejbProject.isAccessible()){
EJBArtifactEdit edit = null;
try {
edit = EJBArtifactEdit.getEJBArtifactEditForRead(ejbProject);
EJBJar ejbJar = edit.getEJBJar();
if (ejbJar != null) {
List enterpriseBeans = ejbJar.getEnterpriseBeans();
for (int i = 0; i < enterpriseBeans.size(); i++) {
EnterpriseBean ejb = (EnterpriseBean) enterpriseBeans.get(i);
computeJavaTypes(ejb);
}
}
computeRMICJavaTypes();
} finally {
if(edit != null)
edit.dispose();
}
}
return javaFilesToMove;
}
public static void copyOutgoingClasspathEntries(IProject source, IProject target, boolean filterServiceLocator) throws JavaModelException {
IJavaProject sourceJProject = JemProjectUtilities.getJavaProject(source);
IJavaProject targetJProject = JemProjectUtilities.getJavaProject(target);
IClasspathEntry[] sourceCp = sourceJProject.getRawClasspath();
List targetCp = new ArrayList(Arrays.asList(targetJProject.getRawClasspath()));
for (int i = 0; i < sourceCp.length; i++) {
IClasspathEntry entry = sourceCp[i];
if (!isContainedInProject(entry, source) && !contains(targetCp, entry) && (!isServiceLocator(entry) || !filterServiceLocator))
targetCp.add(entry);
}
IClasspathEntry[] newCp = (IClasspathEntry[]) targetCp.toArray(new IClasspathEntry[targetCp.size()]);
targetJProject.setRawClasspath(newCp, null);
}
private static boolean isContainedInProject(IClasspathEntry entry, IProject project) {
return !entry.getPath().isEmpty() && project.getName().equals(entry.getPath().segment(0));
}
private static boolean contains(List cp, IClasspathEntry entry) {
for (int i = 0; i < cp.size(); i++) {
IClasspathEntry elmt = (IClasspathEntry) cp.get(i);
if (elmt.getEntryKind() == entry.getEntryKind() && elmt.getPath().equals(entry.getPath()))
return true;
}
return false;
}
private static boolean isServiceLocator(IClasspathEntry entry) {
IPath path = entry.getPath();
return path != null && SERVICE_LOCATOR_JAR_NAME.equals(path.lastSegment());
}
public static List normalize(String[] mfEntries, IProject earProject, IProject ejbProject,
boolean filterServiceLocator) {
String jarURI = null;
EARArtifactEdit edit = null;
try {
edit = EARArtifactEdit.getEARArtifactEditForRead( earProject );
if (edit != null){
jarURI = edit.getModuleURI( ComponentCore.createComponent( ejbProject ));
if (jarURI == null)
return Collections.EMPTY_LIST;
}
} finally {
if(edit != null)
edit.dispose();
}
List result = new ArrayList(mfEntries.length);
for (int i = 0; i < mfEntries.length; i++) {
String norm = ArchiveUtil.deriveEARRelativeURI(mfEntries[i], jarURI);
if (norm == null)
norm = mfEntries[i];
//We know this is an implementation dependency so we don't want to move it
if (!SERVICE_LOCATOR_JAR_NAME.equals(norm) || !filterServiceLocator)
result.add(norm);
}
return result;
}
private void computeJavaTypes(EnterpriseBean ejb) {
computeJavaTypes(ejb.getHomeInterface());
computeJavaTypes(ejb.getRemoteInterface());
computeJavaTypes(ejb.getLocalInterface());
computeJavaTypes(ejb.getLocalHomeInterface());
if (ejb.isEntity())
computeJavaTypes(((Entity)ejb).getPrimaryKey());
}
private void computeJavaTypes(JavaClass javaClass) {
if (javaClass == null)
return;
//javaClass.isInterface();//force reflection prior to the move.
IJavaProject jProj = JemProjectUtilities.getJavaProject(ejbProject);
IType type = JDOMSearchHelper.findType(javaClass.getJavaPackage().getName(), javaClass.getSimpleName(), jProj);
computeJavaTypes(type);
}
private void computeJavaTypes(IType type) {
if (type == null || visitedJavaTypes.contains(type))
return;
visitedJavaTypes.add(type);
//String qualifiedName = type.getFullyQualifiedName();
try {
IFile file = (IFile)type.getUnderlyingResource();
if (file != null && ejbProject.equals(file.getProject())) {
if (!file.isDerived())
cacheType(type, file);
computeRequiredReferencedJavaTypes(type);
}
} catch (JavaModelException e) {
Logger.getLogger().logError(e);
return;
}
}
private void cacheType(IType type, IFile file) {
this.moveResourceCount++;
IPackageFragmentRoot root = (IPackageFragmentRoot) type.getPackageFragment().getParent();
cacheFile(root, file);
}
private void cacheFile(IPackageFragmentRoot root, IFile file) {
Set files = (Set) javaFilesToMove.get(root);
if (files == null) {
files = new HashSet();
javaFilesToMove.put(root, files);
}
files.add(file);
}
private void computeRequiredReferencedJavaTypes(IType type) throws JavaModelException {
Collection result = new HashSet();
searchHelper.searchForReferences(type, result);
if (!result.isEmpty()) {
Iterator iter = result.iterator();
while (iter.hasNext())
computeJavaTypes(((IType)iter.next()));
}
}
private Collection computeBeanTypeNames() {
Collection names = null;
if( ejbProject.exists() && ejbProject.isAccessible()){
EJBArtifactEdit edit = null;
try {
edit = EJBArtifactEdit.getEJBArtifactEditForRead(ejbProject);
EJBJar ejbJar = edit.getEJBJar();
if (ejbJar != null) {
List beans = ejbJar.getEnterpriseBeans();
if (!beans.isEmpty()) {
names = new HashSet(beans.size());
for (int i = 0; i < beans.size(); i++) {
EnterpriseBean bean = (EnterpriseBean) beans.get(i);
names.add(bean.getEjbClassName());
}
}
}
} finally {
if(edit != null)
edit.dispose();
}
}
if (names == null)
names = Collections.EMPTY_LIST;
return names;
}
private void computeRMICJavaTypes() {
try{
List roots = getResourcePackageFragmentRoots();
for (int i = 0; i < roots.size(); i++) {
IPackageFragmentRoot root = (IPackageFragmentRoot) roots.get(i);
computeRMICJavaTypes(root);
}
}catch(CoreException e){
Logger.getLogger().logError(e);
}
}
private List getResourcePackageFragmentRoots() throws JavaModelException {
IJavaProject javaProj = JemProjectUtilities.getJavaProject(ejbProject);
List result = new ArrayList();
IPackageFragmentRoot[] roots = javaProj.getPackageFragmentRoots();
for (int i = 0; i < roots.length; i++) {
IPackageFragmentRoot root = roots[i];
if (root.getKind() == IPackageFragmentRoot.K_SOURCE || isClassesFolder(root))
result.add(root);
}
return result;
}
private boolean isClassesFolder(IPackageFragmentRoot root) throws JavaModelException {
return root.getKind() == IPackageFragmentRoot.K_BINARY &&
!root.isArchive() && !root.isExternal();
}
private void computeRMICJavaTypes(IPackageFragmentRoot root) throws JavaModelException {
IJavaElement[] pkgFragments = root.getChildren();
IFile aFile = null;
for (int i = 0; i < pkgFragments.length; i++) {
IJavaElement[] elements = ((IPackageFragment)pkgFragments[i]).getChildren();
for (int j = 0; j < elements.length; j++) {
IJavaElement unit = elements[j];
aFile = (IFile)unit.getUnderlyingResource();
if (isRMICStub(aFile) && isFileForClientJar(aFile))
cacheFile(root, aFile);
}
}
}
private boolean isRMICStub(IFile aFile) {
String name = aFile.getName();
String ext = aFile.getFileExtension();
if (name != null && ext != null)
name = name.substring(0, name.length()-ext.length()-1);
return name != null &&
name.startsWith(ClientJARCreationConstants.UNDERSCORE) &&
name.endsWith(ClientJARCreationConstants._STUB);
}
private boolean isFileForClientJar(IFile aFile){
String name = aFile.getName();
// special case the was stubs that is needed in the server side
if(name.startsWith("_EJS") || (name.startsWith("_") && name.indexOf("InternalHome_") > 0 )) //$NON-NLS-1$ //$NON-NLS-2$
return false;
return true;
}
private static class MySearchHelper extends SearchRequestor {
SearchEngine engine;
Collection results;
Collection beanTypeNames;
MySearchHelper(SearchEngine engine, Collection beanTypeNames) {
this.engine = engine;
this.beanTypeNames = beanTypeNames;
}
void searchForReferences(IType type, Collection results) throws JavaModelException {
this.results = results;
//Hack because of a bug in the search engine in eclipse 2.1.1
try {
engine.searchDeclarationsOfReferencedTypes(type, this, null);
} catch (ClassCastException ex) {
Logger.getLogger().logError(ex);
}
}
public void acceptSearchMatch(SearchMatch match) throws CoreException {
if(match.getAccuracy() == SearchMatch.A_ACCURATE && !(match.isInsideDocComment() || isBeanType((IType) match.getElement())))
results.add(match.getElement());
}
/**
* @param type
* @return
*/
private boolean isBeanType(IType type) {
return beanTypeNames.contains(type.getFullyQualifiedName());
}
}
}