/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.soapui.impl.rest.panels.component; import com.eviware.soapui.impl.rest.RestResource; import com.eviware.soapui.impl.rest.support.RestParamProperty; import com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder; import com.eviware.soapui.impl.rest.support.RestUtils; import com.eviware.soapui.support.DocumentListenerAdapter; import com.eviware.soapui.support.StringUtils; import com.eviware.soapui.support.UISupport; import org.apache.commons.lang.mutable.MutableBoolean; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.border.Border; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.text.Document; import java.awt.Color; import java.awt.Cursor; import java.awt.IllegalComponentStateException; import java.awt.Point; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; /** * Text field for editing a rest resource. Pops up a separate dialog to edit parts of the resource separately if the * rest resource has parents or children. */ public class RestResourceEditor extends JTextField { public static final String REST_RESOURCE_EDITOR_TEXT_FIELD = "RestResourceEditorTextField"; MouseListener mouseListener; private RestResource editingRestResource; private MutableBoolean updating; private int lastSelectedPosition; public RestResourceEditor(final RestResource editingRestResource, MutableBoolean updating) { super(editingRestResource.getFullPath()); this.editingRestResource = editingRestResource; this.updating = updating; setName(REST_RESOURCE_EDITOR_TEXT_FIELD); if (isResourceLonely(editingRestResource)) { getDocument().addDocumentListener(new LonelyDocumentListener()); addFocusListener(new FocusListener() { public void focusLost(FocusEvent e) { scanForTemplateParameters(editingRestResource); removeMatrixParameters(); } /** * Matrix parameters should not be added directly on the rest resource. * The parameter editor should be used. Hence they are removed from the rest resource editor * text field at this time. */ private void removeMatrixParameters() { setText(getText().split(";")[0]); } public void focusGained(FocusEvent e) { } }); } else { Color originalBackground = getBackground(); Border originalBorder = getBorder(); setEditable(false); setBackground(originalBackground); setBorder(originalBorder); setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); mouseListener = new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { final RestResource focusedResource = new RestResourceFinder(editingRestResource).findResourceAt(lastSelectedPosition); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { openPopup(focusedResource); } }); } }; addMouseListener(mouseListener); addCaretListener(new CaretListener() { @Override public void caretUpdate(final CaretEvent e) { lastSelectedPosition = e.getDot(); } }); } } static void scanForTemplateParameters(RestResource resource) { for (RestResource restResource : RestUtils.extractAncestorsParentFirst(resource)) { for (String p : RestUtils.extractTemplateParams(restResource.getPath())) { if (!resourceOrParentHasProperty(restResource, p)) { RestParamProperty property = restResource.addProperty(p); property.setStyle(RestParamsPropertyHolder.ParameterStyle.TEMPLATE); String value = UISupport.prompt("Specify default value for parameter [" + p + "]", "Add Parameter", ""); if (value != null) { property.setDefaultValue(value); property.setValue(value); } } } } } private static boolean resourceOrParentHasProperty(RestResource restResource, String name) { for (RestResource r = restResource; r != null; r = r.getParentResource()) { if (r.hasProperty(name)) { return true; } } return false; } private boolean isResourceLonely(RestResource restResource) { return restResource.getParentResource() == null && StringUtils.isNullOrEmpty(restResource.getInterface().getBasePath()); } public void openPopup(RestResource focusedResource) { RestResourceEditorPopupWindow popupWindow = new RestResourceEditorPopupWindow(editingRestResource, focusedResource); moveWindowBelowTextField(popupWindow); popupWindow.setVisible(true); } private class LonelyDocumentListener extends DocumentListenerAdapter { @Override public void update(Document document) { if (updating.booleanValue()) { return; } updating.setValue(true); editingRestResource.setPath(getText(document).trim()); updating.setValue(false); } } private void moveWindowBelowTextField(RestResourceEditorPopupWindow popupWindow) { try { Point textFieldLocation = this.getLocationOnScreen(); popupWindow.setLocation(textFieldLocation.x, textFieldLocation.y + this.getHeight()); } catch (IllegalComponentStateException ignore) { // this will happen when the desktop panel is being closed } } }