/* * Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Business Objects nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * TemplateStringDialog.java * Created: 26-Apr-2004 * By: Rick Cameron */ package org.openquark.samples.bam.ui; import java.awt.Component; import java.awt.Dimension; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.AbstractAction; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import org.openquark.cal.compiler.TypeExpr; import org.openquark.cal.services.BasicCALServices; import org.openquark.cal.services.GemEntity; import org.openquark.samples.bam.MetricGemFilter; import org.openquark.samples.bam.MonitorApp; import org.openquark.samples.bam.model.InputBinding; import org.openquark.samples.bam.model.MetricBinding; import org.openquark.samples.bam.model.MetricDescription; import org.openquark.samples.bam.model.PropertyBinding; import org.openquark.samples.bam.model.TemplateStringBinding; import org.openquark.samples.bam.model.MessageSourceDescription.MessagePropertyDescription; import org.openquark.util.ui.DialogBase; /** * * */ class TemplateStringDialog extends DialogBase { private static final long serialVersionUID = 3414194428514988569L; private static class MessagePropertyItem { final MessagePropertyDescription propertyDescription; /** * Constructor MessagePropertyItem * * @param propertyDescription */ MessagePropertyItem (final MessagePropertyDescription propertyDescription) { this.propertyDescription = propertyDescription; } /** * @see java.lang.Object#toString() */ @Override public String toString () { return propertyDescription.name; } } private static class MetricItem { final MetricDescription metricDescription; /** * Constructor MetricItem * * @param metricDescription */ MetricItem (final MetricDescription metricDescription) { this.metricDescription = metricDescription; } /** * @see java.lang.Object#toString() */ @Override public String toString () { return metricDescription.getDescription(); } } private final Collection<MessagePropertyDescription> messagePropertyDescriptions; private String template = ""; private List<InputBinding> argumentBindings = new ArrayList<InputBinding> (); private JList argumentJList; private JTextArea templateTextArea; private JButton insertArgumentButton; private Map<String, InputBinding> argumentNameToBindingMap=null; /** * Constructor TemplateStringDialog * * @param owner */ public TemplateStringDialog (Frame owner, TemplateStringBinding binding, Collection<MessagePropertyDescription> messagePropertyInfos) { super (owner, "Edit Template String"); this.messagePropertyDescriptions = messagePropertyInfos; initialise (binding); } /** * Method initialize * * @param binding */ private void initialise (TemplateStringBinding binding) { if (binding != null) { template = binding.getTemplate (); argumentBindings.addAll(binding.getArgumentBindings()); } createControls (); } /** * Method getTemplate * * @return Returns the template string */ String getTemplate () { return template; } /** * Method getArgumentBindings * * @return Returns the argument bindings */ List<InputBinding> getArgumentBindings () { return Collections.unmodifiableList(argumentBindings); } /** * Method createControls * * */ private void createControls () { JPanel topPanel = getTopPanel (); GridBagConstraints constraints = new GridBagConstraints (); constraints.anchor = GridBagConstraints.NORTHWEST; constraints.fill = GridBagConstraints.HORIZONTAL; constraints.insets = new Insets (2, 2, 2, 2); constraints.gridx = 0; constraints.gridy = 0; topPanel.add (new JLabel ("Properties and Metrics"), constraints); constraints.gridx = 0; constraints.gridy = 1; constraints.fill = GridBagConstraints.BOTH; constraints.weighty = 1.0; topPanel.add (new JScrollPane (getArgumentJList ()), constraints); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.weighty = 0.0; constraints.gridx = 1; constraints.gridy = 1; constraints.anchor = GridBagConstraints.CENTER; topPanel.add (getInsertArgumentButton (), constraints); constraints.anchor = GridBagConstraints.NORTHWEST; constraints.gridx = 2; constraints.gridy = 0; topPanel.add (new JLabel ("Template string"), constraints); constraints.gridx = 2; constraints.gridy = 1; constraints.fill = GridBagConstraints.BOTH; constraints.weightx = 1.0; constraints.weighty = 1.0; topPanel.add (new JScrollPane (getTemplateTextArea ()), constraints); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.weightx = 0.0; constraints.weighty = 0.0; addOKCancelButtons(2, 3); getContentPane ().add (topPanel); // pack makes the dialog too small // set the size of the dialog to half the screen width & 1/4 the screen height // or the preferred size, if larger Dimension prefSize = getPreferredSize(); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); setSize (Math.max (screenSize.width / 2, prefSize.width), Math.max (screenSize.height / 4, prefSize.height)); validate(); addComponentListener (new SizeConstrainer (getSize ())); } /** * @see org.openquark.util.ui.DialogBase#onOK() */ @Override protected boolean onOK () { return parseTemplate (); } /** * Method parseTemplate * * @return Returns true iff the formatted template is successfully parsed into a template and a list of bindings */ private boolean parseTemplate () { String formattedTemplate = templateTextArea.getText(); List<InputBinding> newArgumentBindings = new ArrayList<InputBinding> (); Pattern pattern = Pattern.compile ("\\{([^\\}]+)\\}"); Matcher matcher = pattern.matcher (formattedTemplate); StringBuilder stringBuilder = new StringBuilder (); int index = 0; int argIndex = 0; while (matcher.find ()) { if (matcher.start () > index) { stringBuilder.append(formattedTemplate.substring(index, matcher.start ())); } String argumentNameString = matcher.group(1); InputBinding binding = findBinding (argumentNameString); if (binding != null) { newArgumentBindings.add (binding); } else { JOptionPane.showMessageDialog(this, "The argument '" + argumentNameString + "' is not recognised.", "BAM Sample", JOptionPane.WARNING_MESSAGE); return false; } stringBuilder.append('{'); stringBuilder.append (Integer.toString(argIndex)); stringBuilder.append ('}'); ++argIndex; index = matcher.end(); } if (index < formattedTemplate.length()) { stringBuilder.append(formattedTemplate.substring(index)); } template = stringBuilder.toString(); argumentBindings = newArgumentBindings; return true; } /** * Method findBinding * * @param argumentNameString * @return Returns an InputBinding created from the given argument name */ private InputBinding findBinding (String argumentNameString) { return argumentNameToBindingMap.get(argumentNameString); } /** * Method getArgumentJList * * @return Returns the JList that shows the available properties and metrics */ private JList getArgumentJList () { if (argumentJList == null) { DefaultListModel model = new DefaultListModel (); argumentNameToBindingMap = new HashMap<String, InputBinding>(); //add all message properties for (final MessagePropertyDescription info : messagePropertyDescriptions) { model.addElement(new MessagePropertyItem (info)); argumentNameToBindingMap.put(info.name, new PropertyBinding (info)); } //add all metrics/properties combinations that produce printable outputs BasicCALServices calServices = MonitorApp.getInstance().getCalServices(); for (final MessagePropertyDescription propertyInfo : messagePropertyDescriptions) { TypeExpr propertyType = propertyInfo.getCalType(calServices); TypeExpr printableType = calServices.getTypeFromString(MonitorApp.TARGET_MODULE, "Cal.Samples.BusinessActivityMonitor.BAM.Printable a => a"); Set<GemEntity> gemEntities = new MetricGemFilter(propertyType, printableType ).getMatchingGems(); for (final GemEntity gemEntity : gemEntities) { MetricDescription metricDescription=new MetricDescription(gemEntity.getName(), propertyInfo ); model.addElement(new MetricItem (metricDescription)); argumentNameToBindingMap.put(metricDescription.getDescription(), new MetricBinding(metricDescription)); } } argumentJList = new JList (model); argumentJList.addMouseListener(new MouseAdapter () { @Override public void mouseClicked (MouseEvent e) { if (e.getClickCount() == 2) { onInsertArgument (); } } }); argumentJList.setSelectedIndex(0); } return argumentJList; } /** * Method getInsertArgumentButton * * @return Returns the JButton used to insert an argument */ private Component getInsertArgumentButton () { if (insertArgumentButton == null) { insertArgumentButton = new JButton (new AbstractAction (">>") { private static final long serialVersionUID = -3150734253300126088L; public void actionPerformed (ActionEvent e) { onInsertArgument (); } }); } return insertArgumentButton; } /** * Method onInsertArgument * * */ protected void onInsertArgument () { Object selectedValue = argumentJList.getSelectedValue(); int caretPosition = templateTextArea.getCaretPosition(); templateTextArea.insert('{' + selectedValue.toString() + '}', caretPosition); templateTextArea.requestFocus(); } /** * Method getTemplateTextArea * * @return Returns the JTextArea used to edit the template */ private JTextArea getTemplateTextArea () { if (templateTextArea == null) { templateTextArea = new JTextArea (makeFormattedTemplate ()); templateTextArea.setLineWrap(true); templateTextArea.setWrapStyleWord(true); } return templateTextArea; } /** * Method makeFormattedTemplate * * @return Returns the formatted template */ private String makeFormattedTemplate () { Pattern pattern = Pattern.compile ("\\{(\\d+)\\}"); Matcher matcher = pattern.matcher (template); StringBuilder stringBuilder = new StringBuilder (); int index = 0; while (matcher.find ()) { if (matcher.start () > index) { stringBuilder.append(template.substring(index, matcher.start ())); } String argIndexString = matcher.group(1); int argIndex = Integer.parseInt(argIndexString); if (argIndex < argumentBindings.size()) { stringBuilder.append ('{'); InputBinding binding = argumentBindings.get(argIndex); stringBuilder.append(binding.getPresentation()); stringBuilder.append ('}'); } index = matcher.end(); } if (index < template.length()) { stringBuilder.append(template.substring(index)); } return stringBuilder.toString(); } }