blob: d43d659b9d1a66d925bfb6bcc030adbc6d2dbe61 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2009 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.javaee.ltk.core.change;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
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.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.j2ee.application.internal.operations.UpdateManifestDataModelProperties;
import org.eclipse.jst.j2ee.application.internal.operations.UpdateManifestDataModelProvider;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.common.CreationConstants;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.javaee.ltk.core.nls.RefactoringResourceHandler;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.ChangeDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
public class NonEARModuleReferenceRemoveChange extends Change {
public NonEARModuleReferenceRemoveChange(IProject referencingEARProject, IProject projectToRemove) {
super();
this.referencingModuleProject = referencingEARProject;
this.projectToRemove = projectToRemove;
this.referencingModuleProjectComp = (VirtualComponent)ComponentCore.createComponent(referencingEARProject);
cachedRefs = referencingModuleProjectComp.getReferences();
this.projectToRemoveComp = ComponentCore.createComponent(projectToRemove);
}
IProject referencingModuleProject = null;
VirtualComponent referencingModuleProjectComp = null;
IProject projectToRemove = null;
IVirtualComponent projectToRemoveComp = null;
IVirtualReference[] cachedRefs = null;
@Override
public Object getModifiedElement() {
return null;
}
@Override
public String getName() {
String name = NLS.bind(
RefactoringResourceHandler.Remove_JavaEE_References,
new Object[] {projectToRemove.getName()});
name += referencingModuleProject.getName();
return name;
}
@Override
public void initializeValidationData(IProgressMonitor pm) {
}
@Override
public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException,
OperationCanceledException {
return null;
}
@Override
public Change perform(IProgressMonitor pm) throws CoreException {
try {
removeModuleDependency();
if(isEJBClientDeletion()){
updateEJBDDWithEJBClientDeletion();
}
} catch (ExecutionException e) {
J2EEPlugin.logError(e);
}
return null;
}
@Override
public ChangeDescriptor getDescriptor() {
return null;
}
private boolean isEJBClientDeletion(){
if(!JavaEEProjectUtilities.isEJBProject(referencingModuleProject))
return false;
Properties props = referencingModuleProjectComp.getMetaProperties();
String clientCompName = props.getProperty(CreationConstants.EJB_CLIENT_NAME);
if(clientCompName == null || clientCompName.length() == 0){
return false;
}
if(clientCompName.equals(projectToRemove.getName())){
return true;
}
return false;
}
/*
* Remove the client JAR entry from the deployment descriptor
* This method is to be used only to remove EJB Client jar entry from
* EJB DD
*/
private void updateEJBDDWithEJBClientDeletion() {
IModelProvider ejbModel = ModelProviderManager.getModelProvider(referencingModuleProject);
ejbModel.modify(new Runnable() {
public void run() {
IModelProvider writableEjbModel = ModelProviderManager.getModelProvider(referencingModuleProject);
Object modelObject = writableEjbModel.getModelObject();
if (modelObject instanceof org.eclipse.jst.javaee.ejb.EJBJar) {
org.eclipse.jst.javaee.ejb.EJBJar ejbres = (org.eclipse.jst.javaee.ejb.EJBJar) writableEjbModel.getModelObject();
if (ejbres != null)
ejbres.setEjbClientJar(null);
}
else {
org.eclipse.jst.j2ee.ejb.EJBJar ejbres = (org.eclipse.jst.j2ee.ejb.EJBJar) writableEjbModel.getModelObject();
ejbres.setEjbClientJar(null);
}
Properties props = referencingModuleProjectComp.getMetaProperties();
props.remove(CreationConstants.CLIENT_JAR_URI);
props.remove(CreationConstants.EJB_CLIENT_NAME);
referencingModuleProjectComp.clearMetaProperties();
referencingModuleProjectComp.setMetaProperties(props);
}
},null);
}
protected void removeModuleDependency() throws ExecutionException {
// create IVirtualComponents for the dependent and the refactored project
final IVirtualComponent refactoredComp = projectToRemoveComp;
final IProgressMonitor monitor = new NullProgressMonitor();
// Does the dependent project have a .component reference on the refactored project?
// remove the component reference on the deleted project
if (refactoredComp != null) {
removeReferencedComponents(monitor);
}
// update the manifest
updateManifestDependency(true);
}
protected void updateManifestDependency(final boolean remove) throws ExecutionException {
final IVirtualComponent dependentComp = referencingModuleProjectComp;
IProject project= dependentComp.getProject();
if(project.isAccessible()){
final String dependentProjName = referencingModuleProject.getName();
final String refactoredProjName = projectToRemove.getName();
final IVirtualFile vf = dependentComp.getRootFolder().getFile(new Path(J2EEConstants.MANIFEST_URI) );
final IFile manifestmf = vf.getUnderlyingFile();
// adding this check for https://bugs.eclipse.org/bugs/show_bug.cgi?id=170074
// (some adopters have non-jst.ear module projects that are missing manifests)
if (!manifestmf.exists()) {
return;
}
final IProgressMonitor monitor = new NullProgressMonitor();
final IDataModel updateManifestDataModel = DataModelFactory.createDataModel(new UpdateManifestDataModelProvider());
updateManifestDataModel.setProperty(UpdateManifestDataModelProperties.PROJECT_NAME, dependentProjName);
updateManifestDataModel.setBooleanProperty(UpdateManifestDataModelProperties.MERGE, false);
updateManifestDataModel.setProperty(UpdateManifestDataModelProperties.MANIFEST_FILE, manifestmf);
final ArchiveManifest manifest = J2EEProjectUtilities.readManifest(manifestmf);
String[] cp = manifest.getClassPathTokenized();
List cpList = new ArrayList();
String newjarCp = refactoredProjName + IJ2EEModuleConstants.JAR_EXT;
String newrarCp = refactoredProjName + IJ2EEModuleConstants.RAR_EXT;
for (int i = 0; i < cp.length; i++) {
if (!cp[i].equals(newjarCp) && !cp[i].equals(newrarCp)) {
cpList.add(cp[i]);
}
}
updateManifestDataModel.setProperty(UpdateManifestDataModelProperties.JAR_LIST, cpList);
try {
updateManifestDataModel.getDefaultOperation().execute(monitor, null );
} catch (org.eclipse.core.commands.ExecutionException e) {
J2EEPlugin.logError(e);
}
}
}
protected void removeReferencedComponents(IProgressMonitor monitor) {
if (referencingModuleProjectComp == null || !referencingModuleProjectComp.getProject().isAccessible() || referencingModuleProjectComp.isBinary()) return;
IVirtualReference [] existingReferencesArray = cachedRefs;
if(existingReferencesArray == null || existingReferencesArray.length == 0){
return;
}
List existingReferences = new ArrayList();
for(int i=0;i<existingReferencesArray.length; i++){
existingReferences.add(existingReferencesArray[i]);
}
List targetprojectList = new ArrayList();
if (projectToRemoveComp==null )
return;
IVirtualReference ref = findMatchingReference(existingReferences, projectToRemoveComp, null);
//if a ref was found matching the specified deployPath, then remove it
if(ref != null){
removeRefereneceInComponent(referencingModuleProjectComp, ref);
existingReferences.remove(ref);
//after removing the ref, check to see if it was the last ref removed to that component
//and if it was, then also remove the project reference
ref = findMatchingReference(existingReferences, projectToRemoveComp);
if(ref == null){
IProject targetProject = projectToRemoveComp.getProject();
targetprojectList.add(targetProject);
}
}
try {
ProjectUtilities.removeReferenceProjects(referencingModuleProjectComp.getProject(),targetprojectList);
} catch (CoreException e) {
J2EEPlugin.logError(e);
}
}
private IVirtualReference findMatchingReference(List existingReferences, IVirtualComponent comp) {
return findMatchingReference(existingReferences, comp, null);
}
protected void removeRefereneceInComponent(IVirtualComponent component, IVirtualReference reference) {
((VirtualComponent)component.getComponent()).removeReference(reference);
}
private IVirtualReference findMatchingReference(List existingReferences, IVirtualComponent comp, IPath path) {
for(int i=0;i<existingReferences.size(); i++){
IVirtualReference ref = (IVirtualReference)existingReferences.get(i);
IVirtualComponent c = ref.getReferencedComponent();
if(c != null && c.getName().equals(comp.getName())){
if(path == null){
return ref;
} else if(path.equals(ref.getRuntimePath())){
return ref;
}
}
}
return null;
}
/**
* Does the dependent project have a .component reference on the refactored project?
* @return IVirtualReference or null if one didn't exist.
*/
protected IVirtualReference hadReference() {
final IVirtualComponent refactoredComp = projectToRemoveComp;
if (refactoredComp == null) {
return null;
}
final IVirtualReference[] refs = cachedRefs;
IVirtualReference ref = null;
for (int i = 0; i < refs.length; i++) {
if (refs[i].getReferencedComponent().equals(refactoredComp)) {
ref = refs[i];
break;
}
}
return ref;
}
/**
* Does the dependent project have a .project reference on the refactored project?
* (dynamic project refs don't count)
* @return True if a project reference exists.
*/
protected boolean hadProjectReference() {
try {
final IProject[] refs = referencingModuleProject.getDescription().getReferencedProjects();
final IProject refactoredProject= projectToRemove;
for (int i = 0; i < refs.length; i++) {
if (refs[i].equals(refactoredProject)) {
return true;
}
}
} catch (CoreException ce) {
J2EEPlugin.logError(ce);
}
return false;
}
/**
* Returns true if the dependency was a web library dependency.
* @param ref
* @return
*/
protected static boolean hasWebLibDependency(final IVirtualReference ref) {
if (ref == null) {
return false;
}
return ref.getRuntimePath().equals(new Path("/WEB-INF/lib")); //$NON-NLS-1$
}
}