blob: cbd71901b40c605311d36d0b697f0cc90d9ac5bb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2008 SAP AG 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:
* Kaloyan Raev, kaloyan.raev@sap.com - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.j2ee.ejb.internal.operations;
import static org.eclipse.jst.j2ee.ejb.internal.operations.INewSessionBeanClassDataModelProperties.LOCAL_HOME;
import static org.eclipse.jst.j2ee.ejb.internal.operations.INewSessionBeanClassDataModelProperties.REMOTE_HOME;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.INTERFACES;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.JAVA_PACKAGE;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.JAVA_PACKAGE_FRAGMENT_ROOT;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.codegen.jet.JETException;
import org.eclipse.jdt.core.IClasspathEntry;
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.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.j2ee.ejb.internal.plugin.EjbPlugin;
import org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.project.EJBUtilities;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.wst.common.componentcore.internal.operation.ArtifactEditProviderOperation;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.internal.enablement.nonui.WFTWrappedException;
/**
* The NewSessionBeanClassOperation is an IDataModelOperation following the
* IDataModel wizard and operation framework.
*
* @see org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation
* @see org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider
*
* It extends ArtifactEditProviderOperation to provide enterprise bean specific java
* class generation.
* @see org.eclipse.wst.common.componentcore.internal.operation.ArtifactEditProviderOperation
*
* This operation is used by the AddSessionBeanOperation to generate an
* non annotated java class for an added enterprise bean. It shares the
* NewSessionBeanClassDataModelProvider with the AddSessionBeanOperation to store the
* appropriate properties required to generate the new enterprise bean.
* @see org.eclipse.jst.j2ee.ejb.internal.operations.AddSessionBeanOperation
* @see org.eclipse.jst.j2ee.ejb.internal.operations.NewSessionBeanClassDataModelProvider
*
* A WTPJetEmitter bean template is used to create the class with the bean template.
* @see org.eclipse.jst.j2ee.internal.project.WTPJETEmitter
* @see org.eclipse.jst.j2ee.ejb.internal.operations.CreateSessionBeanTemplateModel
*
* Subclasses may extend this operation to provide their own specific bean
* java class generation. The execute method may be extended to do so. Also,
* generateUsingTemplates is exposed.
*
*/
public class NewSessionBeanClassOperation extends NewEnterpriseBeanClassOperation {
/**
* folder location of the enterprise bean creation templates directory
*/
protected static final String TEMPLATE_FILE = "/templates/sessionBean.javajet"; //$NON-NLS-1$
protected static final String TEMPLATE_LOCAL_FILE = "/templates/localBusinessInterface.javajet"; //$NON-NLS-1$
protected static final String TEMPLATE_REMOTE_FILE = "/templates/remoteBusinessInterface.javajet"; //$NON-NLS-1$
protected static final String TEMPLATE_LOCALHOME_FILE = "/templates/localHomeInterface.javajet"; //$NON-NLS-1$
protected static final String TEMPLATE_REMOTEHOME_FILE = "/templates/remoteHomeInterface.javajet"; //$NON-NLS-1$
protected static final String TEMPLATE_LOCALCOMPONENT_FILE = "/templates/localComponentInterface.javajet"; //$NON-NLS-1$
protected static final String TEMPLATE_REMOTECOMPONENT_FILE = "/templates/remoteComponentInterface.javajet"; //$NON-NLS-1$
protected IPackageFragment clientPack;
protected IPackageFragment pack;
/**
* This is the constructor which should be used when creating a
* NewSessionBeanClassOperation. An instance of the NewSessionBeanClassDataModelProvider
* should be passed in. This does not accept null parameter. It will not
* return null.
*
* @see ArtifactEditProviderOperation#ArtifactEditProviderOperation(IDataModel)
* @see NewBeansClassDataModel
*
* @param dataModel
* @return NewBeanClassOperation
*/
public NewSessionBeanClassOperation(IDataModel dataModel) {
super(dataModel);
}
/**
* Subclasses may extend this method to add their own actions during
* execution. The implementation of the execute method drives the running of
* the operation. This implementation will create the java source folder,
* create the java package, and then the enterprise bean java class file will be created
* using templates. Optionally, subclasses may extend the
* generateUsingTemplates or createJavaFile method rather than extend the
* execute method. This method will accept a null parameter.
*
* @see org.eclipse.wst.common.frameworks.internal.operation.WTPOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
* @see NewSessionBeanClassOperation#generateUsingTemplates(IProgressMonitor,
* IPackageFragment)
*
* @param monitor
* @throws CoreException
* @throws InterruptedException
* @throws InvocationTargetException
*/
@Override
public IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
// Retrieve the package name from the java class data model
String packageName = model.getStringProperty(JAVA_PACKAGE);
// Create java package if it does not exist
pack = createJavaPackage(packageName);
if (hasInterfacesToGenerate() && EJBUtilities.hasEJBClientJARProject(getTargetProject())) {
createJavaSourceFolderInClientJar();
clientPack = createJavaPackageInClientJar(packageName);
}
return super.doExecute(monitor, info);
}
@Override
protected void generateUsingTemplates(IProgressMonitor monitor, IPackageFragment fragment)
throws WFTWrappedException, CoreException {
this.generateUsingTemplates(monitor, pack, clientPack);
}
/**
* Subclasses may extend this method to provide their own template based
* creation of an annotated bean java class file. This implementation uses
* the creation of a CreateSessionBeanTemplateModel and the WTPJetEmitter to
* create the java class with the annotated tags. This method accepts null
* for monitor, it does not accept null for fragment. If annotations are not
* being used the tags will be omitted from the class.
*
* @see CreateSessionBeanTemplateModel
* @see NewSessionBeanClassOperation#generateTemplateSource(CreateSessionBeanTemplateModel,
* IProgressMonitor)
*
* @param monitor
* @param fragment
* @throws CoreException
* @throws WFTWrappedException
*/
protected void generateUsingTemplates(IProgressMonitor monitor, IPackageFragment fragment, IPackageFragment clientFragment) throws WFTWrappedException, CoreException {
// Create the enterprise bean template model
CreateSessionBeanTemplateModel tempModel = createTemplateModel();
getTargetProject();
// Using the WTPJetEmitter, generate the java source based on the bean template model
try {
if (fragment != null) {
if (hasInterfacesToGenerate() && EJBUtilities.hasEJBClientJARProject(getTargetProject())) {
generateInterfacesUsingTemplates(monitor, clientFragment, tempModel);
} else {
generateInterfacesUsingTemplates(monitor, fragment, tempModel);
}
// Create the session bean java file
SessionBeanTemplate tempImpl = SessionBeanTemplate.create(null);
String source = generateTemplateSource(EjbPlugin.getPlugin(), tempModel, TEMPLATE_FILE, tempImpl, monitor);
String javaFileName = tempModel.getClassName() + DOT_JAVA;
createJavaFile(monitor, fragment, source, javaFileName);
}
} catch (Exception e) {
throw new WFTWrappedException(e);
}
}
protected void generateInterfacesUsingTemplates(IProgressMonitor monitor, IPackageFragment fragment, CreateSessionBeanTemplateModel tempModel)
throws JETException, JavaModelException {
IProject project = getTargetProject();
boolean useClientJar = false;
if (JavaEEProjectUtilities.isEJBProject(project))
{
useClientJar = EJBUtilities.hasEJBClientJARProject(getTargetProject());
}
List<BusinessInterface> interfaces = tempModel.getBusinessInterfaces();
for (BusinessInterface iface : interfaces) {
if (!iface.exists()) {
tempModel.setCurrentBusinessInterface(iface);
if (iface.isLocal()) {
// Create the java files for the non-exising Local Business interfaces
LocalBusinessInterfaceTemplate tempImpl = LocalBusinessInterfaceTemplate.create(null);
String src = generateTemplateSource(EjbPlugin.getPlugin(), tempModel, TEMPLATE_LOCAL_FILE, tempImpl, monitor);
String fileName = iface.getSimpleName() + DOT_JAVA;
createJavaFile(monitor, getPackageFragment(useClientJar, iface.getFullyQualifiedName()), src, fileName);
} else if (iface.isRemote()) {
// Create the java files for the non-exising Remote Business interfaces
RemoteBusinessInterfaceTemplate tempImpl = RemoteBusinessInterfaceTemplate.create(null);
String src = generateTemplateSource(EjbPlugin.getPlugin(), tempModel, TEMPLATE_REMOTE_FILE, tempImpl, monitor);
String fileName = iface.getSimpleName() + DOT_JAVA;
createJavaFile(monitor, getPackageFragment(useClientJar, iface.getFullyQualifiedName()), src, fileName);
}
}
}
// Create the EJB 2.x compatible Remote Home and Component interface java files
if (model.getBooleanProperty(REMOTE_HOME)) {
String remoteFullName = model.getStringProperty(INewSessionBeanClassDataModelProperties.REMOTE_HOME_INTERFACE);
String remoteComponentFullName = model.getStringProperty(INewSessionBeanClassDataModelProperties.REMOTE_COMPONENT_INTERFACE);
IJavaProject javaProject = JavaCore.create(project);
IType type = javaProject.findType(remoteFullName);
IPackageFragment remoteFragment = null;
String fileName = Signature.getSimpleName(remoteFullName)+ DOT_JAVA;
tempModel.setRemoteHomeClassName(remoteFullName);
tempModel.setRemoteComponentClassName(remoteComponentFullName);
String src = ""; //$NON-NLS-1$
if(type == null){
remoteFragment = getPackageFragment(useClientJar, remoteFullName);
RemoteHomeInterfaceTemplate tempImpl = RemoteHomeInterfaceTemplate.create(null);
src = generateTemplateSource(EjbPlugin.getPlugin(), tempModel, TEMPLATE_REMOTEHOME_FILE, tempImpl, monitor);
createJavaFile(monitor, remoteFragment, src, fileName);
}
String fileComponentName = Signature.getSimpleName(remoteComponentFullName)+ DOT_JAVA;
type = javaProject.findType(remoteComponentFullName);
if(type == null){
IPackageFragment remoteComponentFragment = getPackageFragment(useClientJar, remoteComponentFullName);
RemoteComponentInterfaceTemplate tempImpl = RemoteComponentInterfaceTemplate.create(null);
src = generateTemplateSource(EjbPlugin.getPlugin(), tempModel, TEMPLATE_REMOTECOMPONENT_FILE, tempImpl, monitor);
createJavaFile(monitor, remoteComponentFragment, src, fileComponentName);
}
}
// Create the EJB 2.x compatible Local Home and Component interface java files
if (model.getBooleanProperty(LOCAL_HOME)) {
String localFullName = model.getStringProperty(INewSessionBeanClassDataModelProperties.LOCAL_HOME_INTERFACE);
String localComponentFullName = model.getStringProperty(INewSessionBeanClassDataModelProperties.LOCAL_COMPONENT_INTERFACE);
IJavaProject javaProject = JavaCore.create(project);
IType type = javaProject.findType(localFullName);
IPackageFragment localFragment = null;
String fileName = Signature.getSimpleName(localFullName)+ DOT_JAVA;
tempModel.setLocalHomeClassName(localFullName);
tempModel.setLocalComponentClassName(localComponentFullName);
String src = ""; //$NON-NLS-1$
if(type == null){
localFragment = getPackageFragment(useClientJar, localFullName);
LocalHomeInterfaceTemplate tempImpl = LocalHomeInterfaceTemplate.create(null);
src = generateTemplateSource(EjbPlugin.getPlugin(), tempModel, TEMPLATE_LOCALHOME_FILE, tempImpl, monitor);
createJavaFile(monitor, localFragment, src, fileName);
}
String fileComponentName = Signature.getSimpleName(localComponentFullName)+ DOT_JAVA;
type = javaProject.findType(localComponentFullName);
if(type == null){
IPackageFragment localComponentFragment = getPackageFragment(useClientJar, localComponentFullName);
LocalComponentInterfaceTemplate tempImpl = LocalComponentInterfaceTemplate.create(null);
src = generateTemplateSource(EjbPlugin.getPlugin(), tempModel, TEMPLATE_LOCALCOMPONENT_FILE, tempImpl, monitor);
createJavaFile(monitor, localComponentFragment, src, fileComponentName);
}
}
}
protected IPackageFragment getPackageFragment(boolean useClientJar, String fullName) {
IPackageFragment fragment;
String packageName = Signature.getQualifier(fullName);
if (useClientJar) {
fragment = createJavaPackageInClientJar(packageName);
}
else
{
fragment = createJavaPackage(packageName);
}
return fragment;
}
protected IFolder createJavaSourceFolderInClientJar() {
// Get the source folder name from the data model
IFolder folder = getClientSourceFolder();
// If folder does not exist, create the folder with the specified path
if (!folder.exists()) {
try {
createFolder( folder, false );
} catch (CoreException e) {
EjbPlugin.logError(e);
}
IProject clientProject = EJBUtilities.getEJBClientJar(getTargetProject()).getProject();
IJavaProject jProject = JavaCore.create( clientProject );
if( jProject != null ){
IClasspathEntry newEntry = JavaCore.newSourceEntry( folder.getFullPath() );
List<IClasspathEntry> cp = new ArrayList<IClasspathEntry>();
IClasspathEntry[] classPath;
try {
classPath = jProject.getRawClasspath();
cp.addAll( Arrays.asList( classPath ) );
cp.add( newEntry );
jProject.setRawClasspath( cp.toArray( new IClasspathEntry[ cp.size() ] ), null );
} catch (JavaModelException e) {
EjbPlugin.logError(e);
}
}
}
// Return the source folder
return folder;
}
protected IPackageFragment createJavaPackageInClientJar(String packageName) {
IPackageFragmentRoot packRoot = getClientPackageFragmentRoot();
IPackageFragment pack = packRoot.getPackageFragment(packageName);
// Handle default package
if (pack == null) {
pack = packRoot.getPackageFragment(""); //$NON-NLS-1$
}
// Create the package fragment if it does not exist
if (!pack.exists()) {
String packName = pack.getElementName();
try {
pack = packRoot.createPackageFragment(packName, true, null);
} catch (JavaModelException e) {
EjbPlugin.logError(e);
}
}
// Return the package
return pack;
}
/**
* This method is intended for internal use only. This method will create an
* instance of the CreateSessionBeanTemplate model to be used in conjunction
* with the WTPJETEmitter. This method will not return null.
*
* @see CreateSessionBeanTemplateModel
* @see NewSessionBeanClassOperation#generateUsingTemplates(IProgressMonitor,
* IPackageFragment)
*
* @return CreateBeanTemplateModel
*/
private CreateSessionBeanTemplateModel createTemplateModel() {
// Create the CreateBeanTemplateModel instance with the new bean
// class data model
CreateSessionBeanTemplateModel templateModel = new CreateSessionBeanTemplateModel(model);
return templateModel;
}
private boolean hasInterfacesToGenerate() {
List<BusinessInterface> businessInterfaces = (List<BusinessInterface>) model.getProperty(INTERFACES);
boolean remoteHome = model.getBooleanProperty(REMOTE_HOME);
boolean localHome = model.getBooleanProperty(LOCAL_HOME);
return businessInterfaces.size() > 0 || remoteHome || localHome;
}
private IFolder getClientSourceFolder() {
IFolder folder = getSourceFolder();
IPath folderRelativePath = folder.getProjectRelativePath();
IPath clientProjectPath = EJBUtilities.getEJBClientJar(getTargetProject()).getProject().getFullPath();
return ResourcesPlugin.getWorkspace().getRoot().getFolder(clientProjectPath.append(folderRelativePath));
}
private IPackageFragmentRoot getClientPackageFragmentRoot() {
IFolder folder = getClientSourceFolder();
IProject clientProject = EJBUtilities.getEJBClientJar(getTargetProject()).getProject();
IJavaProject clientJavaProject = JavaCore.create(clientProject);
return clientJavaProject.getPackageFragmentRoot(folder);
}
/**
* This method will return the java package as specified by the new java
* class data model. If the package does not exist, it will create the
* package. This method should not return null.
*
* @see INewJavaClassDataModelProperties#JAVA_PACKAGE
* @see IPackageFragmentRoot#createPackageFragment(java.lang.String,
* boolean, org.eclipse.core.runtime.IProgressMonitor)
*
* @return IPackageFragment the java package
*/
protected IPackageFragment createJavaPackage(String packageName) {
IPackageFragmentRoot packRoot = (IPackageFragmentRoot) model.getProperty(JAVA_PACKAGE_FRAGMENT_ROOT);
IPackageFragment pack = packRoot.getPackageFragment(packageName);
// Handle default package
if (pack == null) {
pack = packRoot.getPackageFragment(""); //$NON-NLS-1$
}
// Create the package fragment if it does not exist
if (!pack.exists()) {
String packName = pack.getElementName();
try {
pack = packRoot.createPackageFragment(packName, true, null);
} catch (JavaModelException e) {
J2EEPlugin.logError(e);
}
}
// Return the package
return pack;
}
private static void createFolder( final IFolder folder,
final boolean isDerived ) throws CoreException {
if( ! folder.exists() ){
final IContainer parent = folder.getParent();
if( parent instanceof IFolder ){
createFolder( (IFolder) parent, isDerived );
}
folder.create( true, true, null );
folder.setDerived( isDerived );
}
}
}