blob: c16c1ad2732715ebbbc64f5773c708555c81f6d6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 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.internal.common.operations;
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 static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.SOURCE_FOLDER;
import static org.eclipse.wst.common.componentcore.internal.operation.IArtifactEditOperationDataModelProperties.PROJECT_NAME;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.emf.codegen.jet.JETException;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.WTPJETEmitter;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.internal.WTPPlugin;
import org.eclipse.wst.common.frameworks.internal.enablement.nonui.WFTWrappedException;
public abstract class NewJavaEEArtifactClassOperation extends AbstractDataModelOperation {
/**
* The extension name for a java class
*/
protected static final String DOT_JAVA = ".java"; //$NON-NLS-1$
/**
* Method name of template implementation classes.
*/
protected static final String GENERATE_METHOD = "generate"; //$NON-NLS-1$
public NewJavaEEArtifactClassOperation(IDataModel dataModel) {
super(dataModel);
}
@Override
public IStatus execute(IProgressMonitor monitor, IAdaptable info)
throws ExecutionException {
return doExecute(monitor, info);
}
/**
* 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 if using annotations, will use
* templates to generate an annotated web artifact java class, or if it is
* not annotated, the web artifact java class file will be created without
* the annotated tags 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 NewWebClassOperation#generateUsingTemplates(IProgressMonitor,
* IPackageFragment)
*
* @param monitor
* @throws CoreException
* @throws InterruptedException
* @throws InvocationTargetException
*/
public IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
// Create source folder if it does not exist
createJavaSourceFolder();
// Create java package if it does not exist
IPackageFragment pack = createJavaPackage();
// Generate using templates
try {
generateUsingTemplates(monitor, pack);
} catch (Exception e) {
return J2EEPlugin.createStatus(IStatus.ERROR, e.getMessage(), e);
}
return OK_STATUS;
}
protected abstract void generateUsingTemplates(IProgressMonitor monitor,
IPackageFragment fragment) throws WFTWrappedException,
CoreException;
/**
* 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 #JAVA_PACKAGE
* @see IPackageFragmentRoot#createPackageFragment(java.lang.String,
* boolean, org.eclipse.core.runtime.IProgressMonitor)
*
* @return IPackageFragment the java package
*/
protected final IPackageFragment createJavaPackage() {
// Retrieve the package name from the java class data model
String packageName = model.getStringProperty(JAVA_PACKAGE);
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;
}
/**
* This method checks the
* {@link J2EEPlugin#DYNAMIC_TRANSLATION_OF_JET_TEMPLATES_PREF_KEY}
* preference to determine the method for generating the source code of the
* Java EE artifact:
* <ul>
* <li>dynamically using the provided JET template file, or</li>
* <li>using the statically build-in template implementation class. </li>
* </ul>
*
* @param plugin
* - the plugin which calls the current method
* @param templateModel
* - a template model that is used by the JET template file or
* the template implementation class
* @param templateFile
* - a Java JET template file
* @param templateImpl
* - a Java JET template implementation class
* @param monitor
* - a monitor to report the progress of the code generation
* @param templateImpl
* - a Java JET template implementation class
*
* @return a String object with the generated source code
*
* @throws JETException
* if a problem occurs in during code generation
*
* @see #generateTemplateSource(WTPPlugin,
* CreateJavaEEArtifactTemplateModel, String, IProgressMonitor)
* @see #generateTemplateSource(CreateJavaEEArtifactTemplateModel, Object)
*/
protected String generateTemplateSource(WTPPlugin plugin, CreateJavaEEArtifactTemplateModel templateModel, String templateFile, Object templateImpl, IProgressMonitor monitor)
throws JETException {
Preferences preferences = J2EEPlugin.getDefault().getPluginPreferences();
boolean dynamicTranslation = preferences.getBoolean(J2EEPlugin.DYNAMIC_TRANSLATION_OF_JET_TEMPLATES_PREF_KEY);
if (dynamicTranslation) {
return generateTemplateSource(plugin, templateModel, templateFile, monitor);
}
return generateTemplateSource(templateModel, templateImpl);
}
/**
* This method uses the statically built-in template implementation class to
* generate the source code of the Java EE artifact with the given template
* model.
*
* @param templateModel
* - a template model that is used by the template implementation
* class
* @param templateImpl
* - a Java JET template implementation class
*
* @return a String object with the generated source code
*
* @throws JETException
* if a problem occurs in during code generation
*/
protected String generateTemplateSource(CreateJavaEEArtifactTemplateModel templateModel, Object templateImpl)
throws JETException {
try {
Method method = templateImpl.getClass().getMethod(GENERATE_METHOD, new Class[] { Object.class });
return (String) method.invoke(templateImpl, templateModel);
} catch (SecurityException e) {
throw new JETException(e);
} catch (NoSuchMethodException e) {
throw new JETException(e);
} catch (IllegalArgumentException e) {
throw new JETException(e);
} catch (IllegalAccessException e) {
throw new JETException(e);
} catch (InvocationTargetException e) {
throw new JETException(e);
}
}
/**
* This method uses the WTPJETEmitter to generate the source code of the
* Java EE artifact with the given template model and template file.
*
* @param plugin
* - the plugin which calls the current method
* @param templateModel
* - a template model that is used by the JET template file
* @param templateFile
* - a Java JET template file
* @param monitor
* - a monitor to report the progress of the code generation
*
* @return a String object with the generated source code
*
* @throws JETException
* if a problem occurs in the JET emitter
*/
protected String generateTemplateSource(WTPPlugin plugin, CreateJavaEEArtifactTemplateModel templateModel, String templateFile, IProgressMonitor monitor)
throws JETException {
URL templateURL = FileLocator.find(plugin.getBundle(), new Path(templateFile), null);
cleanUpOldEmitterProject();
WTPJETEmitter emitter = new WTPJETEmitter(templateURL.toString(), this.getClass().getClassLoader());
emitter.setIntelligentLinkingEnabled(true);
emitter.addVariable(J2EEPlugin.getPlugin().getPluginID(), J2EEPlugin.getPlugin().getPluginID());
emitter.addVariable(plugin.getPluginID(), plugin.getPluginID());
return emitter.generate(monitor, new Object[] { templateModel });
}
protected void cleanUpOldEmitterProject() {
IProject project = ProjectUtilities.getProject(WTPJETEmitter.PROJECT_NAME);
if (project == null || !project.exists())
return;
try {
IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
for (int i = 0, l = markers.length; i < l; i++) {
if (((Integer) markers[i].getAttribute(IMarker.SEVERITY)).intValue() == IMarker.SEVERITY_ERROR) {
project.delete(true, new NullProgressMonitor());
break;
}
}
} catch (Exception e) {
J2EEPlugin.logError(e);
}
}
/**
* This method will return the java source folder as specified in the java
* class data model. It will create the java source folder if it does not
* exist. This method may return null.
*
* @see #SOURCE_FOLDER
* @see IFolder#create(boolean, boolean,
* org.eclipse.core.runtime.IProgressMonitor)
*
* @return IFolder the java source folder
*/
protected final IFolder createJavaSourceFolder() {
// Get the source folder name from the data model
IFolder folder = getSourceFolder();
// If folder does not exist, create the folder with the specified path
if (!folder.exists()) {
try {
folder.create(true, true, null);
} catch (CoreException e) {
J2EEPlugin.logError(e);
}
}
// Return the source folder
return folder;
}
public IProject getTargetProject() {
String projectName = model.getStringProperty(PROJECT_NAME);
return ProjectUtilities.getProject(projectName);
}
protected IFolder getSourceFolder() {
String folderFullPath = model.getStringProperty(SOURCE_FOLDER);
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
return root.getFolder(new Path(folderFullPath));
}
}