blob: 87b06137ca3fd5d747e1b25b09af76035107aa39 [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.web.operations;
import static org.eclipse.jst.j2ee.application.internal.operations.IAnnotationsDataModel.USE_ANNOTATIONS;
import java.util.Set;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jst.common.internal.annotations.controller.AnnotationsController;
import org.eclipse.jst.common.internal.annotations.controller.AnnotationsControllerManager;
import org.eclipse.jst.common.internal.annotations.controller.AnnotationsControllerManager.Descriptor;
import org.eclipse.jst.j2ee.internal.common.operations.NewJavaEEArtifactClassOperation;
import org.eclipse.jst.j2ee.internal.web.plugin.WebPlugin;
import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.datamodel.FacetInstallDataModelProvider;
import org.eclipse.wst.common.componentcore.datamodel.FacetProjectCreationDataModelProvider;
import org.eclipse.wst.common.componentcore.datamodel.properties.IFacetDataModelProperties;
import org.eclipse.wst.common.componentcore.datamodel.properties.IFacetProjectCreationDataModelProperties;
import org.eclipse.wst.common.componentcore.datamodel.properties.IFacetProjectCreationDataModelProperties.FacetDataModelMap;
import org.eclipse.wst.common.componentcore.internal.operation.ArtifactEditProviderOperation;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.internal.enablement.nonui.WFTWrappedException;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
/**
* The NewWebClassOperation 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 AbstractDataModelOperation to provide web artifact specific java
* class generation.
* @see AbstractDataModelOperation
*
* This operation is used by the AddWebClassOperation to generate either an
* annotated or non annotated java class for an added web artifact. It shares
* the NewWebClassDataModelProvider with the AddWebClassOperation to store the
* appropriate properties required to generate the new web artifact.
*
* @see AddWebClassOperation
* @see NewWebClassDataModelProvider
*
* In the annotated case, a WTPJetEmitter listener template is created and used
* to generate the listener java class with the embedded annotated tags.
* @see org.eclipse.jst.j2ee.internal.project.WTPJETEmitter
* @see CreateWebClassTemplateModel
*
* In the non annotated case, the same emitter is used to create the class with
* the non annotated web artifact template so the annotated tags are omitted.
*
* Subclasses may extend this operation to provide their own specific web
* artifact java class generation. The execute method may be extended to do so.
* Also, generateUsingTemplates is exposed.
*
* The use of this class is EXPERIMENTAL and is subject to substantial changes.
*/
public abstract class NewWebClassOperation extends NewJavaEEArtifactClassOperation {
/**
* XDoclet facet constants
*/
private static final String JST_WEB_XDOCLET_VERSION = "1.2.3"; //$NON-NLS-1$
/**
* variable for the web plugin
*/
protected static final String WEB_PLUGIN = "WEB_PLUGIN"; //$NON-NLS-1$
/**
* This is the constructor which should be used when creating a
* NewWebClassOperation. An instance of the NewWebClassDataModel should be
* passed in. This does not accept null parameter. It will not return null.
*
* @see ArtifactEditProviderOperation#ArtifactEditProviderOperation(IDataModel)
* @see NewListenerClassDataModel
*
* @param dataModel
* @return NewListenerClassOperation
*/
public NewWebClassOperation(IDataModel dataModel) {
super(dataModel);
}
/**
* Subclasses may extend this method to provide their own template based
* creation of an annotated web artifact java class file. This implementation
* uses the creation of a CreateWebClassTemplateModel 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 CreateWebClassTemplateModel
* @see #generateTemplateSource(CreateWebClassTemplateModel, IProgressMonitor)
*
* @param monitor
* @param fragment
* @throws CoreException
* @throws WFTWrappedException
*/
protected void generateUsingTemplates(IProgressMonitor monitor, IPackageFragment fragment) throws WFTWrappedException, CoreException {
// Create the web artifact template model
CreateWebClassTemplateModel tempModel = createTemplateModel();
IProject project = getTargetProject();
String source;
// Using the WTPJetEmitter, generate the java source based on the listener template model
try {
source = generateTemplateSource(WebPlugin.getPlugin(), tempModel, getTemplateFile(), monitor);
} catch (Exception e) {
throw new WFTWrappedException(e);
}
if (fragment != null) {
// Create the java file
String javaFileName = tempModel.getClassName() + DOT_JAVA;
ICompilationUnit cu = fragment.getCompilationUnit(javaFileName);
// Add the compilation unit to the java file
if (cu == null || !cu.exists())
cu = fragment.createCompilationUnit(javaFileName, source, true, monitor);
IFile aFile = (IFile) cu.getResource();
// Let the annotations controller process the annotated resource
AnnotationsController controller = AnnotationsControllerManager.INSTANCE.getAnnotationsController(project);
if (controller != null)
controller.process(aFile);
}
// Add the xdoclet facet, if necessary, for xdoclet listener creation
try {
installXDocletFacetIfNecessary(monitor, project);
} catch (Exception e) {
throw new WFTWrappedException(e);
}
}
/**
* This method is intended for internal use only. This will add an webdoclet facet to the project.
*
* @throws CoreException
* @throws ExecutionException
*/
private void installXDocletFacet(IProgressMonitor monitor, IProject project) throws CoreException, ExecutionException {
IFacetedProject facetedProject = ProjectFacetsManager.create(project);
Set fixedFacets = facetedProject.getFixedProjectFacets();
IDataModel dm = DataModelFactory.createDataModel(new FacetInstallDataModelProvider());
dm.setProperty(IFacetDataModelProperties.FACET_ID, IJ2EEFacetConstants.DYNAMIC_WEB_XDOCLET);
dm.setProperty(IFacetDataModelProperties.FACET_PROJECT_NAME, project.getName());
dm.setProperty(IFacetDataModelProperties.FACET_VERSION_STR, JST_WEB_XDOCLET_VERSION);
IDataModel fdm = DataModelFactory.createDataModel(new FacetProjectCreationDataModelProvider());
fdm.setProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME, project.getName());
FacetDataModelMap map = (FacetDataModelMap) fdm.getProperty(IFacetProjectCreationDataModelProperties.FACET_DM_MAP);
map.add(dm);
fdm.getDefaultOperation().execute(monitor, null);
facetedProject.setFixedProjectFacets(fixedFacets);
}
/**
* This method is intended for internal use only. This will check to see if it needs to add an
* webdoclet facet to the project.
*
* @throws CoreException
* @throws ExecutionException
*/
private void installXDocletFacetIfNecessary(IProgressMonitor monitor, IProject project) throws CoreException, ExecutionException {
// If not using annotations, ignore the xdoclet facet
if (!model.getBooleanProperty(USE_ANNOTATIONS))
return;
// If an extended annotations processor is added, ignore the default xdoclet one
Descriptor descriptor = AnnotationsControllerManager.INSTANCE.getDescriptor(getTargetComponent().getProject());
if (descriptor != null)
return;
// Otherwise check and see if the xdoclet facet is on the project yet
IFacetedProject facetedProject = ProjectFacetsManager.create(project);
if (!facetedProject.hasProjectFacet(WebFacetUtils.WEB_XDOCLET_FACET))
return;
// Install xdoclet facet
installXDocletFacet(monitor, project);
}
/**
* This method will create an instance of the CreateWebClassTemplateModel to
* be used in conjunction with the WTPJETEmitter. This method will not
* return null.
*
* @see CreateWebClassTemplateModel
* @see NewWebClassOperation#generateUsingTemplates(IProgressMonitor,
* IPackageFragment)
*
* @return CreateWebClassTemplateModel
*/
protected abstract CreateWebClassTemplateModel createTemplateModel();
protected abstract String getTemplateFile();
private IVirtualComponent getTargetComponent() {
return ComponentCore.createComponent(getTargetProject());
}
}