/** * Copyright (c) 2002-2006 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 - Initial API and implementation */ package org.eclipse.emf.mapping.command; import java.util.ArrayList; import java.util.Collection; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.command.CompoundCommand; import org.eclipse.emf.mapping.Mapping; import org.eclipse.emf.mapping.MappingPlugin; import org.eclipse.emf.mapping.MappingRoot; import org.eclipse.emf.mapping.domain.MappingDomain; public abstract class MatchMappingCommand extends CompoundCommand { /** * This keeps track of the mapping domain in which the command operates. */ protected MappingDomain domain; /** * This is the mapping that is being recursively matched. */ protected Mapping mapping; /** * This is the collection of inputs that have been matched by this command */ protected Collection<?> mappedInputs; /** * This caches the label. */ protected static final String LABEL = MappingPlugin.getPlugin().getString("_UI_MatchMappingCommand_label"); /** * This cachaes the description. */ protected static final String DESCRIPTION = MappingPlugin.getPlugin().getString("_UI_MatchMappingCommand_description"); public MatchMappingCommand(MappingDomain domain, Mapping mapping) { super(LABEL, DESCRIPTION); this.domain = domain; this.mapping = mapping; } @Override protected boolean prepare() { if (domain != null && mapping != null) { Collection<Object> inputChildren = new ArrayList<Object>(); for (Object input : mapping.getSenders()) { inputChildren.addAll(domain.getChildren(input)); } Collection<Object> outputChildren = new ArrayList<Object>(); for (Object output : mapping.getReceivers()) { outputChildren.addAll(domain.getChildren(output)); } matchChildren(inputChildren, outputChildren); } // We have done our preparation. Now ask the super to validate. // boolean result = super.prepare(); return result; } protected void matchChildren(Collection<?> inputChildren, Collection<?> outputChildren) { ArrayList<Object> newMappedInputs = new ArrayList<Object>(); mappedInputs = newMappedInputs; MappingRoot mappingRoot = domain.getMappingRoot(); boolean multipleMatchesAllowed = (domain.getMappingEnablementFlags() & MappingDomain.ENABLE_MULTIPLE_INPUT_MAPPINGS) != 0; for (Object childOutput : outputChildren) { if (mappingRoot.getMappings(childOutput).isEmpty()) { Collection<Object> mappedObjects = new ArrayList<Object>(); for (Object childInput : inputChildren) { boolean canCreateMapping = multipleMatchesAllowed || (!mappedInputs.contains(childInput) && mappingRoot.getMappings(childInput).isEmpty()); if (canCreateMapping && match(childInput, childOutput, mappedObjects)) { break; } } if (!mappedObjects.isEmpty()) { newMappedInputs.addAll(mappedObjects); mappedObjects.add(childOutput); Command mapCommand = CreateMappingCommand.create(domain, mappedObjects); appendIfCanExecute(mapCommand); } } } } protected abstract boolean match(Object inputObject, Object outputObject, Collection<Object> mappedObjects); /** * This gives an abbreviated name using this object's own class' name, without package qualification, * followed by a space separated list of <tt>field:value</tt> pairs. */ @Override public String toString() { StringBuffer result = new StringBuffer(super.toString()); result.append(" (domain: " + domain + ")"); result.append(" (mapping: " + mapping + ")"); return result.toString(); } }