| /******************************************************************************* |
| * Copyright (c) 2003, 2004, 2005 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.wst.common.componentcore.internal.builder; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Stack; |
| |
| import org.eclipse.core.internal.events.ResourceDelta; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IncrementalProjectBuilder; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.wst.common.componentcore.ComponentCore; |
| import org.eclipse.wst.common.componentcore.UnresolveableURIException; |
| import org.eclipse.wst.common.componentcore.datamodel.properties.IProjectComponentsBuilderDataModelProperties; |
| import org.eclipse.wst.common.componentcore.datamodel.properties.IReferencedComponentBuilderDataModelProperties; |
| import org.eclipse.wst.common.componentcore.datamodel.properties.IWorkbenchComponentBuilderDataModelProperties; |
| import org.eclipse.wst.common.componentcore.internal.ComponentType; |
| import org.eclipse.wst.common.componentcore.internal.ReferencedComponent; |
| import org.eclipse.wst.common.componentcore.internal.StructureEdit; |
| import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent; |
| import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants; |
| import org.eclipse.wst.common.componentcore.resources.ComponentHandle; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualReference; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualResource; |
| import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelProvider; |
| import org.eclipse.wst.common.frameworks.datamodel.IDataModel; |
| import org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation; |
| import org.eclipse.wst.common.frameworks.internal.enablement.DataModelEnablementFactory; |
| |
| public class ProjectComponentsBuilderDataModelProvider extends AbstractDataModelProvider implements IProjectComponentsBuilderDataModelProperties { |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider#getPropertyNames() |
| */ |
| public String[] getPropertyNames() { |
| return new String[]{PROJECT, BUILD_KIND, PROJECT_DETLA, CHANGED_RESOURCES_DELTA, ADDITIONAL_REFERENCED_BUILDER_DM_LIST, COMPONENT_CORE, COMPONENT_BUILDER_DM_LIST}; |
| } |
| |
| public void init() { |
| super.init(); |
| model.setProperty(ADDITIONAL_REFERENCED_BUILDER_DM_LIST, new ArrayList()); |
| model.setIntProperty(BUILD_KIND, IncrementalProjectBuilder.FULL_BUILD); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.common.frameworks.internal.operations.WTPOperationDataModel#doSetProperty(java.lang.String, |
| * java.lang.Object) |
| */ |
| public boolean propertySet(String propertyName, Object propertyValue) { |
| if (PROJECT.equals(propertyName)) { |
| model.setProperty(COMPONENT_BUILDER_DM_LIST, populateModuleBuilderDataModelList()); |
| if (model.getIntProperty(BUILD_KIND) == (IncrementalProjectBuilder.INCREMENTAL_BUILD) && model.isPropertySet(CHANGED_RESOURCES_DELTA)) { |
| createAdditionalBuildersIfNecessary(); |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * @return |
| */ |
| private Object populateModuleBuilderDataModelList() { |
| List moduleDMList = null; |
| switch (model.getIntProperty(BUILD_KIND)) { |
| case IncrementalProjectBuilder.CLEAN_BUILD : |
| case IncrementalProjectBuilder.FULL_BUILD : |
| moduleDMList = populateFullModuleBuilderDataModelList(); |
| break; |
| case IncrementalProjectBuilder.INCREMENTAL_BUILD : |
| moduleDMList = populateDeltaModuleBuilderDataModelList((ResourceDelta) getProperty(PROJECT_DETLA)); |
| break; |
| default : |
| moduleDMList = populateFullModuleBuilderDataModelList(); |
| break; |
| } |
| return moduleDMList; |
| } |
| |
| private void createAdditionalBuildersIfNecessary() { |
| List deltaResources = (List) model.getProperty(CHANGED_RESOURCES_DELTA); |
| IVirtualResource[] vResources = null; |
| for (int i = 0; i < deltaResources.size(); i++) { |
| vResources = ComponentCore.createResources((IResource) deltaResources.get(i)); |
| createAdditionalBuildersForVResoures(vResources); |
| } |
| } |
| |
| private void createAdditionalBuildersForVResoures(IVirtualResource[] resources) { |
| IVirtualComponent vReferencingComponent; |
| IVirtualComponent vReferencedComponent; |
| |
| ComponentHandle referencedComponentHandle; |
| ComponentHandle[] referencingComponentHandles; |
| for (int i = 0; i < resources.length; i++) { |
| vReferencedComponent = resources[i].getComponent(); |
| referencedComponentHandle = ComponentHandle.create(vReferencedComponent.getProject(), vReferencedComponent.getName()); |
| referencingComponentHandles = DependencyGraphManager.getInstance().getDependencyGraph().getReferencingComponents(referencedComponentHandle); |
| for (int j = 0; j < referencingComponentHandles.length; j++) { |
| vReferencingComponent = ComponentCore.createComponent(referencingComponentHandles[j].getProject(), referencingComponentHandles[j].getName()); |
| createAdditionalReferencedBuilders(vReferencingComponent, vReferencedComponent); |
| } |
| } |
| } |
| |
| private void createAdditionalReferencedBuilders(IVirtualComponent containingComponent, IVirtualComponent depComponent) { |
| List depModulesDataModels = (List) model.getProperty(ADDITIONAL_REFERENCED_BUILDER_DM_LIST); |
| IDataModel dependentDataModel = null; |
| StructureEdit moduleCore = (StructureEdit) model.getProperty(COMPONENT_CORE); |
| IProject project = (IProject) model.getProperty(PROJECT); |
| dependentDataModel = DataModelEnablementFactory.createDataModel(IModuleConstants.DEPENDENT_MODULE + ".builder", project); |
| if (dependentDataModel != null) { |
| IVirtualReference virtualReference = ComponentCore.createReference(containingComponent, depComponent); |
| dependentDataModel.setProperty(IReferencedComponentBuilderDataModelProperties.VIRTUAL_REFERENCE, virtualReference); |
| depModulesDataModels.add(dependentDataModel); |
| } |
| model.setProperty(ADDITIONAL_REFERENCED_BUILDER_DM_LIST, depModulesDataModels); |
| } |
| |
| /** |
| * Sorts the wbModules such that the returned list |
| * |
| * @param wbModule |
| * @param sortedModuleList |
| * @param wbModuleList |
| * @return |
| * @throws UnresolveableURIException |
| */ |
| private List computeModuleBuildOrder(WorkbenchComponent wbModule, List sortedModuleList, List wbModuleList, Stack callStack) throws UnresolveableURIException { |
| if (callStack.contains(wbModule)) { |
| // TODO do something meaningful with this. |
| throw new RuntimeException("Cyclical module dependency detected."); |
| } |
| try { |
| callStack.push(wbModule); |
| EList depModules = wbModule.getReferencedComponents(); |
| for (int i = 0; i < depModules.size(); i++) { |
| ReferencedComponent depModule = (ReferencedComponent) depModules.get(i); |
| if (((StructureEdit) model.getProperty(COMPONENT_CORE)).isLocalDependency(depModule)) { |
| WorkbenchComponent depWBModule = ((StructureEdit) model.getProperty(COMPONENT_CORE)).findComponentByURI(depModule.getHandle()); |
| if (!sortedModuleList.contains(depWBModule)) { |
| computeModuleBuildOrder(depWBModule, sortedModuleList, null, callStack); |
| } |
| } |
| } |
| if (!sortedModuleList.contains(wbModule)) { |
| sortedModuleList.add(wbModule); |
| } |
| if (null != wbModuleList && !wbModuleList.isEmpty()) { |
| wbModule = (WorkbenchComponent) wbModuleList.remove(wbModuleList.size() - 1); |
| return computeModuleBuildOrder(wbModule, sortedModuleList, wbModuleList, callStack); |
| } |
| return sortedModuleList; |
| } finally { |
| callStack.pop(); |
| } |
| } |
| |
| /** |
| * Returns the list of WorkbenchModules in a sorted build order |
| * |
| * @param wbModules |
| * @return |
| */ |
| private List computeModuleBuildOrder(WorkbenchComponent[] wbModules) { |
| ArrayList unsortedList = new ArrayList(wbModules.length - 1); |
| for (int i = 1; i < wbModules.length; i++) { |
| unsortedList.add(wbModules[i]); |
| } |
| WorkbenchComponent firstModule = wbModules[0]; |
| if (firstModule == null) |
| return null; |
| List sortedList = new ArrayList(wbModules.length); |
| try { |
| sortedList = computeModuleBuildOrder(firstModule, sortedList, unsortedList, new Stack()); |
| // for(int i=0;i<sortedList.size(); i++){ |
| // System.out.println(sortedList.get(i)); |
| // } |
| } catch (UnresolveableURIException e) { |
| // TODO Auto-generated catch block |
| e.printStackTrace(); |
| } |
| return sortedList; |
| } |
| |
| |
| private List populateFullModuleBuilderDataModelList() { |
| StructureEdit moduleCore = (StructureEdit) model.getProperty(COMPONENT_CORE); |
| List moduleBuilderDataModelList = new ArrayList(); |
| WorkbenchComponent[] wbModules = moduleCore.getWorkbenchModules(); |
| |
| if (wbModules == null || wbModules.length == 0) { |
| return null; |
| } |
| |
| List sortedList = computeModuleBuildOrder(wbModules); |
| if (sortedList == null) |
| return moduleBuilderDataModelList; |
| IDataModel dataModel = null; |
| IProject curProject = (IProject) model.getProperty(PROJECT); |
| |
| String builderType = null; |
| for (int i = 0; i < sortedList.size(); i++) { |
| WorkbenchComponent wbComponent = (WorkbenchComponent) sortedList.get(i); |
| ComponentType type = wbComponent.getComponentType(); |
| if (type == null) |
| continue; |
| String typeId = type.getComponentTypeId(); |
| if (typeId == null) |
| continue; |
| builderType = typeId + ".builder"; |
| dataModel = DataModelEnablementFactory.createDataModel(builderType, curProject); |
| if (dataModel != null) { |
| IVirtualComponent vComponent = ComponentCore.createComponent(curProject, wbComponent.getName()); |
| dataModel.setProperty(IWorkbenchComponentBuilderDataModelProperties.BUILD_KIND_FOR_DEP, model.getProperty(BUILD_KIND)); |
| dataModel.setProperty(IWorkbenchComponentBuilderDataModelProperties.VIRTUAL_COMPONENT, vComponent); |
| moduleBuilderDataModelList.add(dataModel); |
| } |
| } |
| return moduleBuilderDataModelList; |
| } |
| |
| private List populateDeltaModuleBuilderDataModelList(ResourceDelta delta) { |
| // TODO: handle delta information correcty |
| return populateFullModuleBuilderDataModelList(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.common.frameworks.internal.operations.WTPOperationDataModel#getDefaultOperation() |
| */ |
| public IDataModelOperation getDefaultOperation() { |
| return new ProjectComponentsBuilderOperation(model); |
| } |
| |
| } |