/******************************************************************************* * 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.client.ui.rcp.widgets; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.eclipse.jface.fieldassist.IContentProposal; import org.eclipse.jface.fieldassist.IContentProposalProvider; import org.eclipse.jubula.client.core.model.INodePO; import org.eclipse.jubula.client.core.model.IParamDescriptionPO; import org.eclipse.jubula.client.core.model.ISpecTestCasePO; import org.eclipse.jubula.tools.internal.constants.TestDataConstants; /** * Provides proposals for parameter values based on parameter type and * editing context. * * @author BREDEX GmbH * @created Apr 7, 2010 */ public class ParamProposalProvider implements IContentProposalProvider { /** prefix for parameter reference content proposals */ private static final String PARAMETER_PREFIX = "="; //$NON-NLS-1$ /** * @author BREDEX GmbH * @created Feb 5, 2009 */ public static class ParamProposal implements IContentProposal { /** display value */ private String m_displayValue; /** the content that will be inserted if this proposal is selected */ private String m_content; /** * Constructor * * @param content The content of the proposal. */ public ParamProposal(String content) { this(content, null); } /** * Constructor * * @param content The content of the proposal. * @param displayValue The label for the proposal. */ public ParamProposal(String content, String displayValue) { m_content = content; m_displayValue = displayValue; } /** * {@inheritDoc} */ public String getContent() { return m_content; } /** * {@inheritDoc} */ public int getCursorPosition() { return m_content.length(); } /** * {@inheritDoc} */ public String getDescription() { return null; } /** * {@inheritDoc} */ public String getLabel() { return m_displayValue; } } /** fixed values */ private String[] m_valueSet; /** the node for which to provide proposals */ private INodePO m_node; /** the param description for which to provide proposals */ private IParamDescriptionPO m_paramDesc; /** delegate provider for Function proposals */ private FunctionProposalProvider m_functionProposalProvider = new FunctionProposalProvider(); /** * Constructor * * @param valueSet Fixed values to propose (for example, "true" and "false" * for a boolean parameter). * @param node The node to use as a base for dynamically generating * proposals. * @param paramDesc The param description to use as a base for dynamically * generating proposals. */ public ParamProposalProvider(String[] valueSet, INodePO node, IParamDescriptionPO paramDesc) { m_valueSet = valueSet; m_node = node; m_paramDesc = paramDesc; } /** * {@inheritDoc} */ public IContentProposal[] getProposals(String contents, int position) { IContentProposal[] functionProposals = m_functionProposalProvider.getProposals(contents, position); if (!ArrayUtils.isEmpty(functionProposals)) { return functionProposals; } if (position != contents.length()) { // no proposals when in text return new IContentProposal[0]; } List<IContentProposal> proposals = new ArrayList<IContentProposal>(20); // if there are predefined values offer them first if (m_valueSet != null) { proposals.addAll(getValueSetProposals(contents, position)); } proposals.addAll(getParentParamProposals(contents)); return proposals.toArray(new IContentProposal[proposals.size()]); } /** * Creates and returns content proposals based on the Parameters available * from the parent node. * * @param contents The text for which to generate content proposals. * @return the proposals for the given arguments. */ private Collection<IContentProposal> getParentParamProposals( String contents) { List<IContentProposal> proposals = new ArrayList<IContentProposal>(); // find a SpecTestCase INodePO node = m_node; while ((node != null) && !(node instanceof ISpecTestCasePO)) { node = node.getParentNode(); } if (node == null) { return proposals; } ISpecTestCasePO paramNode = (ISpecTestCasePO)node; if (!(m_node instanceof ISpecTestCasePO)) { // add the parameter name as a suggestion if (m_paramDesc != null && paramNode != null) { if (!paramNode.isInterfaceLocked() && !paramNode.getParamNames().contains( m_paramDesc.getName())) { String p = PARAMETER_PREFIX + m_paramDesc.getName(); p = StringUtils.replaceChars(p, ' ', '_'); p = StringUtils.replaceChars(p, '-', '_'); p = p.toUpperCase(); if (p.startsWith(contents)) { proposals.add(new ParamProposal( p.substring(contents.length()), p)); } } } if (paramNode != null) { List<IParamDescriptionPO> params = paramNode.getParameterList(); for (IParamDescriptionPO param : params) { String parType = m_paramDesc.getType(); if ("java.lang.String".equals(parType) //$NON-NLS-1$ || param.getType().equals(parType)) { String p = PARAMETER_PREFIX + param.getName(); if (p.startsWith(contents)) { proposals.add(new ParamProposal( p.substring(contents.length()), p)); } } } } } return proposals; } /** * * @param contents The text for which to generate content proposals. * @param position The current position in the text for which to generate * proposals. * @return the proposals for the given arguments. */ private Collection<IContentProposal> getValueSetProposals( String contents, int position) { List<IContentProposal> proposals = new ArrayList<IContentProposal>(); StringBuilder sb = new StringBuilder(contents); sb.delete(position, sb.length()); sb.delete(0, sb.lastIndexOf(TestDataConstants.COMBI_VALUE_SEPARATOR) + 1); for (String predefValue : m_valueSet) { if (predefValue.startsWith(sb.toString())) { proposals.add(new ParamProposal( predefValue.substring(sb.length()), predefValue)); } else if (predefValue.startsWith(contents)) { proposals.add(new ParamProposal( predefValue.substring( contents.length()), predefValue)); } } return proposals; } }