/*******************************************************************************
* Copyright (c) 2007, 2011 Intel 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:
* Intel Corporation - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.internal.core;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IModificationStatus;
import org.eclipse.cdt.managedbuilder.core.IResourceInfo;
import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
public class ToolListModificationInfo {
private ToolInfo[] fResultingTools;
private ToolInfo[] fAddedTools;
private ToolInfo[] fRemovedTools;
private IResourceInfo fRcInfo;
ToolListModificationInfo(IResourceInfo rcInfo, ToolInfo[] resultingTools, ToolInfo[] added, ToolInfo[] removed, ToolInfo[] remaining){
fResultingTools = resultingTools;
fRemovedTools = removed;
fAddedTools = added;
fRcInfo = rcInfo;
}
public IResourceInfo getResourceInfo(){
return fRcInfo;
}
public List<ITool> getResultingToolList(List<ITool> list) {
if(list == null)
list = new ArrayList<ITool>(fResultingTools.length);
for(int i = 0; i < fResultingTools.length; i++){
list.add(fResultingTools[i].getResultingTool());
}
return list;
}
public ITool[] getResultingTools() {
ITool[] tools = new ITool[fResultingTools.length];
for(int i = 0; i < fResultingTools.length; i++){
tools[i] = fResultingTools[i].getResultingTool();
}
return tools;
}
public ITool[] getRemovedTools() {
return toToolArray(fRemovedTools, true);
}
public ITool[] getAddedTools(boolean resulting) {
return toToolArray(fAddedTools, !resulting);
}
public ITool[] getRemainedTools() {
return toToolArray(fAddedTools, true);
}
private static ITool[] toToolArray(ToolInfo[] infos, boolean initialTools){
ITool[] tools = new ITool[infos.length];
for(int i = 0; i < infos.length; i++){
tools[i] = initialTools ? infos[i].getInitialTool() : infos[i].getResultingTool();
}
return tools;
}
private static ITool[][] toToolArray(ToolInfo[][] infos, boolean initialTools){
ITool[][] tools = new ITool[infos.length][];
for(int i = 0; i < infos.length; i++){
tools[i] = toToolArray(infos[i], initialTools);
}
return tools;
}
public MultiStatus getModificationStatus(){
List<IModificationStatus> statusList = new ArrayList<IModificationStatus>();
ToolInfo[][] conflictInfos = calculateConflictingTools(fResultingTools);
ITool[][] conflicting = toToolArray(conflictInfos, true);
Map<String, String> unspecifiedRequiredProps = new HashMap<String, String>();
Map<String, String> unspecifiedProps = new HashMap<String, String>();
Set<String> undefinedSet = new HashSet<String>();
IConfiguration cfg = fRcInfo.getParent();
ITool[] nonManagedTools = null;
if(cfg.isManagedBuildOn() && cfg.supportsBuild(true)){
List<ITool> list = new ArrayList<ITool>();
for(int i = 0; i < fResultingTools.length; i++){
if(!fResultingTools[i].getInitialTool().supportsBuild(true)){
list.add(fResultingTools[i].getInitialTool());
}
}
if(list.size() != 0){
nonManagedTools = list.toArray(new Tool[list.size()]);
}
}
IModificationStatus status = new ModificationStatus(unspecifiedRequiredProps, unspecifiedProps, undefinedSet, conflicting, nonManagedTools);
if(status.getSeverity() != IStatus.OK)
statusList.add(status);
for(int i = 0; i < fResultingTools.length; i++){
status = fResultingTools[i].getModificationStatus();
if(status.getSeverity() != IStatus.OK)
statusList.add(status);
}
if(statusList.size() != 0)
return new MultiStatus(ManagedBuilderCorePlugin.getUniqueIdentifier(), IStatus.INFO, "", null); //$NON-NLS-1$
return new MultiStatus(ManagedBuilderCorePlugin.getUniqueIdentifier(), IStatus.ERROR, "", null); //$NON-NLS-1$
}
private ToolInfo[][] calculateConflictingTools(ToolInfo[] infos){
infos = filterInfos(infos);
return doCalculateConflictingTools(infos);
}
private ToolInfo[] filterInfos(ToolInfo[] infos){
if(fRcInfo instanceof FolderInfo){
Map<ITool, ToolInfo> map = createInitialToolToToolInfoMap(infos);
ITool[] tools = new ArrayList<ITool>(map.keySet()).toArray(new ITool[map.size()]);
tools = ((FolderInfo)fRcInfo).filterTools(tools, fRcInfo.getParent().getManagedProject());
if(tools.length < infos.length){
infos = new ToolInfo[tools.length];
for(int i = 0; i < infos.length; i++){
infos[i] = map.get(tools[i]);
}
}
}
return infos;
}
private static Map<ITool, ToolInfo> createInitialToolToToolInfoMap(ToolInfo[] infos){
Map<ITool, ToolInfo> map = new LinkedHashMap<ITool, ToolInfo>();
for(int i = 0; i < infos.length; i++){
map.put(infos[i].getInitialTool(), infos[i]);
}
return map;
}
private ToolInfo[][] doCalculateConflictingTools(ToolInfo[] infos){
HashSet<ToolInfo> set = new HashSet<ToolInfo>();
set.addAll(Arrays.asList(infos));
List<ToolInfo[]> result = new ArrayList<ToolInfo[]>();
for(Iterator<ToolInfo> iter = set.iterator(); iter.hasNext();){
ToolInfo ti = iter.next();
ITool t = ti.getInitialTool();
iter.remove();
@SuppressWarnings("unchecked")
HashSet<ToolInfo> tmp = (HashSet<ToolInfo>)set.clone();
List<ITool> list = new ArrayList<ITool>();
for(Iterator<ToolInfo> tmpIt = tmp.iterator(); tmpIt.hasNext();){
ToolInfo otherTi = tmpIt.next();
ITool other = otherTi.getInitialTool();
String conflicts[] = getConflictingInputExts(t, other);
if(conflicts.length != 0){
list.add(other);
tmpIt.remove();
}
}
if(list.size() != 0){
list.add(t);
ToolInfo[] arr = list.toArray(new ToolInfo[list.size()]);
result.add(arr);
}
set = tmp;
iter = set.iterator();
}
return result.toArray(new ToolInfo[result.size()][]);
}
private String[] getConflictingInputExts(ITool tool1, ITool tool2){
IProject project = fRcInfo.getParent().getOwner().getProject();
String ext1[] = ((Tool)tool1).getAllInputExtensions(project);
String ext2[] = ((Tool)tool2).getAllInputExtensions(project);
Set<String> set1 = new HashSet<String>(Arrays.asList(ext1));
Set<String> result = new HashSet<String>();
for(int i = 0; i < ext2.length; i++){
if(set1.remove(ext2[i]))
result.add(ext2[i]);
}
return result.toArray(new String[result.size()]);
}
public void apply(){
((ResourceInfo)fRcInfo).doApply(this);
}
}