| /******************************************************************************* |
| * 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)); |
| } |
| |
| } |