/******************************************************************************* * Copyright (c) 2004, 2010 BREDEX GmbH. * 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: * BREDEX GmbH - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.jubula.rc.common.components; import java.util.Collection; import java.util.Hashtable; import java.util.List; import java.util.Map; import org.eclipse.jubula.rc.common.AUTServerConfiguration; import org.eclipse.jubula.rc.common.Constants; import org.eclipse.jubula.rc.common.exception.UnsupportedComponentException; import org.eclipse.jubula.rc.common.logger.AutServerLogger; import org.eclipse.jubula.rc.common.tester.interfaces.ITester; import org.eclipse.jubula.tools.internal.constants.StringConstants; import org.eclipse.jubula.tools.internal.objects.IComponentIdentifier; /** * @author BREDEX GmbH * @created 31.08.2006 * * @param <COMPONENT_TYPE> * the type of the component */ public abstract class AUTHierarchy<COMPONENT_TYPE> { /** the logger */ private static final AutServerLogger LOG = new AutServerLogger(AUTHierarchy.class); /** * a hashtable to find the HierarchyContainer for a component from * the AUT: key=componentID, value=HierarchyContainer */ private volatile Map<AUTComponent<COMPONENT_TYPE>, HierarchyContainer<COMPONENT_TYPE>> m_hierarchyMap; /** * a hashtable to find the HierarchyContainer for a component from * the AUT: key=component.getRealComponent, value=AUTComponent */ private volatile Map<COMPONENT_TYPE, AUTComponent<COMPONENT_TYPE>> m_realHierarchyMap; /** * default constructor <br> * initializes the HashTables m_hierarchyMap and m_topLevelContainerMap; */ public AUTHierarchy() { m_hierarchyMap = new Hashtable<AUTComponent<COMPONENT_TYPE>, HierarchyContainer<COMPONENT_TYPE>>( Constants.INITIAL_CAPACITY_HIERARCHY); m_realHierarchyMap = new Hashtable<COMPONENT_TYPE, AUTComponent<COMPONENT_TYPE>>( Constants.INITIAL_CAPACITY_HIERARCHY); } /** * @return all hierarchyContainer */ public Map<? extends AUTComponent<COMPONENT_TYPE>, HierarchyContainer<COMPONENT_TYPE>> getHierarchyMap() { return m_hierarchyMap; } /** * @return all AUTcomponent */ protected Map<COMPONENT_TYPE, AUTComponent<COMPONENT_TYPE>> getRealMap() { return m_realHierarchyMap; } /** * Adds a HiearchyContainer to the HierarchyMap * @param hierarchyContainer the hierarchyContainer to add */ protected void addToHierachyMap( HierarchyContainer<COMPONENT_TYPE> hierarchyContainer) { final AUTComponent<COMPONENT_TYPE> autComponent = hierarchyContainer.getCompID(); final COMPONENT_TYPE realComponent = autComponent.getComponent(); m_hierarchyMap.put(autComponent, hierarchyContainer); m_realHierarchyMap.put(realComponent, autComponent); if (LOG.isDebugEnabled()) { LOG.debug("Add to HierarchyMap: " + String.valueOf(autComponent)); //$NON-NLS-1$ LOG.debug("HierarchyMap size: " + m_hierarchyMap.size()); //$NON-NLS-1$ LOG.debug("Add to RealHierarchyMap: " + String.valueOf(realComponent)); //$NON-NLS-1$ LOG.debug("RealHierarchyMap size: " + m_realHierarchyMap.size()); //$NON-NLS-1$ } } /** * Removes a HiearchyContainer from the HierarchyMap. * @param hierarchyContainer the hierarchContainer to remove */ protected void removeFromHierachyMap( HierarchyContainer<COMPONENT_TYPE> hierarchyContainer) { AUTComponent<COMPONENT_TYPE> autComponent = hierarchyContainer.getCompID(); Object realComponent = autComponent.getComponent(); m_hierarchyMap.remove(autComponent); m_realHierarchyMap.remove(realComponent); } /** * returns an array of all component identifier of (supported) components, * which are currently instantiated by the AUT. * @attention synchronized in subclasses!!! * @return array with ComponentIdentifier, may be empty but never null */ public abstract IComponentIdentifier[] getAllComponentId(); /** * Creates a name for the given component and the given postFix. <br> * The class name of the component is used. * * @param component the component to create a name for * @param postFix a string to append * @return the new name */ protected String createName (COMPONENT_TYPE component, int postFix) { return component.getClass().getName() + Constants.CLASS_NUMBER_SEPERATOR + postFix; } /** * Creates a name for the given component and the given postFix. <br> * The class name of the component is used. * * @param componentName the original component name * @param postFix a string to append * @return the new name */ protected String createName (String componentName, int postFix) { return componentName + Constants.CLASS_NUMBER_SEPERATOR + postFix; } /** * @return all hierarchyContainer of the hierarchyMap */ protected Collection<HierarchyContainer<COMPONENT_TYPE>> getHierarchyValues() { return m_hierarchyMap.values(); } /** * returns the context of a component. If there are other components in the * same container, their names will be added. * @param component component * @return List */ protected abstract List<String> getComponentContext( COMPONENT_TYPE component); /** * @param container the hierarchy container that corresponds to component * @param component the UI component that corresponds to the identifier * @param identifier the identifier to set alternative display name on it */ protected final void setAlternativeDisplayName( HierarchyContainer<COMPONENT_TYPE> container, COMPONENT_TYPE component, IComponentIdentifier identifier) { if (container != null) { String displayName = buildDisplayName(container, component); if ((displayName != null) && (!displayName.equals(identifier.getComponentName()))) { identifier.setAlternativeDisplayName(displayName); } } } /** * @param container the hierarchy container that corresponds to component * @param component the UI component to build a display name for * @return display name to be used for the UI component */ private final String buildDisplayName( HierarchyContainer<COMPONENT_TYPE> container, COMPONENT_TYPE component) { String containerName = container.getName(); boolean containerNameGenerated = container.isNameGenerated(); String[] componentTextArray = getTextArrayFromComponent(component); String improvedName = buildImprovedName(componentTextArray); if (containerNameGenerated) { containerName = AUTServerConfiguration.getInstance() .getComponentName(component); } String displayName = combineNames(containerName, containerNameGenerated, improvedName); return displayName; } /** * @param component the UI component to get the string array from * @return string array from the given UI component */ private String[] getTextArrayFromComponent(COMPONENT_TYPE component) { String[] componentTextArray = null; if (component != null) { try { Object implClass = AUTServerConfiguration .getInstance().prepareImplementationClass( component, component.getClass()); if (implClass instanceof ITester) { ITester baseImpl = (ITester)implClass; componentTextArray = baseImpl.getTextArrayFromComponent(); } } catch (UnsupportedComponentException uce) { LOG.warn(uce); } catch (IllegalArgumentException iae) { LOG.error(iae); } } return componentTextArray; } /** * @param componentTextArray the array containing none, one or many texts * representing a component * @return improved name builded from componentTextArray */ private String buildImprovedName(String[] componentTextArray) { final String improvedName; if ((componentTextArray == null) || (componentTextArray.length == 0) || ((componentTextArray.length == 1) && ((componentTextArray[0] == null) || (componentTextArray[0].length() == 0)))) { // improved name is unavailable improvedName = null; } else { StringBuffer buffer = new StringBuffer(); for (int i = 0; i < componentTextArray.length; i++) { if (i > 0) { buffer.append(","); //$NON-NLS-1$ if (i == 3) { // do not show more than three component texts buffer.append("..."); //$NON-NLS-1$ break; } } buffer.append(StringConstants.QUOTE); if (componentTextArray[i] != null) { buffer.append(String.valueOf(componentTextArray[i]).trim()); } buffer.append(StringConstants.QUOTE); } improvedName = buffer.toString(); } return improvedName; } /** * @param containerName the container name to be combined with improved name * @param containerNameGenerated indicates whether container name is a * generated name * @param improvedName the improved name to be combined with container name * @return combination of containerName and improvedName */ private String combineNames(String containerName, boolean containerNameGenerated, String improvedName) { String displayName; if (improvedName == null) { // show only normal name, because improved name is unavailable displayName = containerName; } else { // show normal name and improved name in brackets displayName = containerName + " (" + improvedName + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } if (displayName != null && displayName.length() > Constants.REC_MAX_NAME_LENGTH) { displayName = displayName.substring(0, Constants.REC_MAX_NAME_LENGTH - 1) + "..."; //$NON-NLS-1$ if (improvedName != null) { displayName = displayName + ")"; //$NON-NLS-1$ } } return displayName; } /** * @param component * The component to check. * @return true if the component is in the active window. */ public boolean isInActiveWindow(COMPONENT_TYPE component) { return false; } }