/** * Copyright 2009 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.safehaus.penrose.studio.expression.dialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.*; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.*; import org.eclipse.ui.forms.widgets.Hyperlink; import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.safehaus.penrose.studio.views.CodeAssist; import org.safehaus.penrose.studio.PenroseImage; import org.safehaus.penrose.mapping.Expression; import org.safehaus.penrose.directory.EntryAttributeConfig; import org.safehaus.penrose.directory.EntryFieldConfig; import org.safehaus.penrose.studio.PenroseStudio; import org.safehaus.penrose.studio.dialog.ErrorDialog; import org.apache.log4j.Logger; import java.util.ArrayList; import java.util.Collection; import java.io.*; /** * @author Endi S. Dewata */ public class ExpressionDialog extends Dialog { Logger log = Logger.getLogger(getClass()); public final static int CANCEL = 0; public final static int OK = 1; public final static int TEXT = 0; public final static int BINARY = 1; public final static int VARIABLE = 2; public final static int EXPRESSION = 3; Shell shell; Font font; Composite blankPanel; Composite currentPanel; int currentType; //Text nameText; Button binaryRadio; Text binaryText; Button textRadio; Text textText; Button variableRadio; Combo variableCombo; Button expressionRadio; Text scriptText; Combo foreachCombo; Text varText; private EntryAttributeConfig attributeConfig; private EntryFieldConfig fieldConfig; public Collection<String> variables = new ArrayList<String>(); private int action = CANCEL; public ExpressionDialog(Shell parent, int style) { super(parent, style); font = new Font(parent.getDisplay(), "Courier New", 8, SWT.NONE); shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE); shell.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent event) { font.dispose(); } }); createControl(shell); } public void open() { Point size = new Point(600, 400); shell.setSize(size); Point l = getParent().getLocation(); Point s = getParent().getSize(); shell.setLocation(l.x + (s.x - size.x)/2, l.y + (s.y - size.y)/2); shell.setText(getText()); shell.setImage(PenroseStudio.getImage(PenroseImage.LOGO)); shell.open(); Display display = getParent().getDisplay(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } } public void createControl(final Shell parent) { parent.setLayout(new GridLayout(1, false)); /* Composite names = new Composite(parent, SWT.NONE); names.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); names.setLayout(new GridLayout(2, false)); Label nameLabel = new Label(names, SWT.NONE); nameLabel.setText("Name:"); GridData gd = new GridData(); gd.widthHint = 80; nameLabel.setLayoutData(gd); nameText = new Text(names, SWT.BORDER); gd = new GridData(GridData.FILL_HORIZONTAL); nameText.setLayoutData(gd); */ Composite types = new Composite(parent, SWT.NONE); types.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); types.setLayout(new GridLayout(2, false)); Label typeLabel = new Label(types, SWT.NONE); typeLabel.setText("Type:"); GridData gd = new GridData(); gd.widthHint = 80; typeLabel.setLayoutData(gd); Composite typeButtons = new Composite(types, SWT.NONE); typeButtons.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); typeButtons.setLayout(new RowLayout()); textRadio = new Button(typeButtons, SWT.RADIO); textRadio.setText("text"); textRadio.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { setType(TEXT); } }); binaryRadio = new Button(typeButtons, SWT.RADIO); binaryRadio.setText("binary"); binaryRadio.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { setType(BINARY); } }); variableRadio = new Button(typeButtons, SWT.RADIO); variableRadio.setText("variable"); variableRadio.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { setType(VARIABLE); } }); expressionRadio = new Button(typeButtons, SWT.RADIO); expressionRadio.setText("expression"); expressionRadio.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { setType(EXPRESSION); } }); Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); blankPanel = new Composite(parent, SWT.NONE); blankPanel.setLayoutData(new GridData(GridData.FILL_BOTH)); blankPanel.setLayout(new FillLayout()); Composite controlButtons = createControlPanel(parent); gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalAlignment = GridData.END; controlButtons.setLayoutData(gd); //setType(TEXT); } public Composite createControlPanel(Composite parent) { Composite buttons = new Composite(parent, SWT.NONE); buttons.setLayout(new RowLayout()); Button saveButton = new Button(buttons, SWT.PUSH); saveButton.setText("Save"); saveButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { Object constant = null; String variable = null; Expression expression = null; if (TEXT == currentType) { constant = getConstant(); } else if (BINARY == currentType) { constant = getBinary(); } else if (VARIABLE == currentType) { variable = getVariable(); } else if (EXPRESSION == currentType) { expression = new Expression(); expression.setScript(getScript()); expression.setForeach(getForeach()); expression.setVar(getVar()); } if (attributeConfig != null) { //attributeMapping.setName(getName()); attributeConfig.setConstant(constant); attributeConfig.setVariable(variable); attributeConfig.setExpression(expression); } if (fieldConfig != null) { //fieldMapping.setName(getName()); fieldConfig.setConstant(constant); fieldConfig.setVariable(variable); fieldConfig.setExpression(expression); } action = OK; shell.close(); } }); Button cancelButton = new Button(buttons, SWT.PUSH); cancelButton.setText("Cancel"); cancelButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { shell.close(); } }); return buttons; } public Composite createTextPanel(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayout(new GridLayout(2, false)); Label label = new Label(composite, SWT.NONE); label.setText("Text:"); GridData gd = new GridData(); gd.widthHint = 80; label.setLayoutData(gd); textText = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); gd = new GridData(GridData.FILL_BOTH); gd.verticalSpan = 2; textText.setLayoutData(gd); if (attributeConfig != null) { Object value = attributeConfig.getConstant(); if (value != null && value instanceof String) { setConstant((String)value); } } if (fieldConfig != null) { Object value = fieldConfig.getConstant(); if (value != null && value instanceof String) { setConstant((String)value); } } textText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { } }); textText.setFocus(); return composite; } public Composite createBinaryPanel(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayout(new GridLayout(2, false)); Label label = new Label(composite, SWT.NONE); label.setText("Binary:"); GridData gd = new GridData(); gd.widthHint = 80; label.setLayoutData(gd); binaryText = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY); binaryText.setFont(font); gd = new GridData(GridData.FILL_BOTH); gd.verticalSpan = 2; binaryText.setLayoutData(gd); new Label(composite, SWT.NONE); new Label(composite, SWT.NONE); Composite actions = new Composite(composite, SWT.NONE); actions.setLayout(new RowLayout()); actions.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Hyperlink importData = new Hyperlink(actions, SWT.NONE); importData.setText("Import"); importData.setUnderlined(true); importData.addHyperlinkListener(new HyperlinkAdapter() { public void linkActivated(HyperlinkEvent event) { FileDialog dialog = new FileDialog(shell, SWT.OPEN); dialog.setText("Import Binary Data"); String filename = dialog.open(); if (filename == null) return; try { File file = new File(filename); byte bytes[] = new byte[(int)file.length()]; FileInputStream out = new FileInputStream(file); out.read(bytes); out.close(); setBinary(bytes); } catch (Exception e) { log.error(e.getMessage(), e); ErrorDialog.open(e); } } }); Hyperlink exportData = new Hyperlink(actions, SWT.NONE); exportData.setText("Export"); exportData.setUnderlined(true); exportData.addHyperlinkListener(new HyperlinkAdapter() { public void linkActivated(HyperlinkEvent event) { FileDialog dialog = new FileDialog(shell, SWT.SAVE); dialog.setText("Export Binary Data"); String filename = dialog.open(); if (filename == null) return; try { FileOutputStream out = new FileOutputStream(filename); out.write(getBinary()); out.close(); } catch (Exception e) { log.error(e.getMessage(), e); ErrorDialog.open(e); } } }); if (attributeConfig != null) { Object value = attributeConfig.getConstant(); if (value != null && value instanceof byte[]) { setBinary((byte[])value); } } if (fieldConfig != null) { Object value = fieldConfig.getConstant(); if (value != null && value instanceof byte[]) { setBinary((byte[])value); } } return composite; } public Composite createVariablePanel(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayout(new GridLayout(2, false)); Label label = new Label(composite, SWT.NONE); label.setText("Variable:"); GridData gd = new GridData(); gd.widthHint = 80; label.setLayoutData(gd); variableCombo = new Combo(composite, SWT.BORDER); variableCombo.add(""); for (String variable : variables) { variableCombo.add(variable); } variableCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); if (attributeConfig != null) { String variable = attributeConfig.getVariable(); if (variable != null) { setVariable(variable); } } if (fieldConfig != null) { String variable = fieldConfig.getVariable(); if (variable != null) { setVariable(variable); } } variableCombo.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { } }); variableCombo.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { } }); variableCombo.setFocus(); return composite; } public Composite createExpressionPanel(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayout(new GridLayout(2, false)); Label expressionLabel = new Label(composite, SWT.NONE); expressionLabel.setText("Expression:"); GridData gd = new GridData(); gd.widthHint = 80; expressionLabel.setLayoutData(gd); scriptText = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); gd = new GridData(GridData.FILL_BOTH); gd.verticalSpan = 2; scriptText.setLayoutData(gd); new Label(composite, SWT.NONE); Label foreachLabel = new Label(composite, SWT.NONE); foreachLabel.setText("Repeat for each:"); foreachLabel.setLayoutData(new GridData()); foreachCombo = new Combo(composite, SWT.BORDER | SWT.READ_ONLY); foreachCombo.add(""); for (String variable : variables) { foreachCombo.add(variable); } foreachCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Label varLabel = new Label(composite, SWT.NONE); varLabel.setText("Variable name:"); varLabel.setLayoutData(new GridData()); varText = new Text(composite, SWT.BORDER); varText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); if (attributeConfig != null) { Expression expression = attributeConfig.getExpression(); if (expression != null) { setForeach(expression.getForeach()); setVar(expression.getVar()); setScript(expression.getScript()); } } if (fieldConfig != null) { Expression expression = fieldConfig.getExpression(); if (expression != null) { setForeach(expression.getForeach()); setVar(expression.getVar()); setScript(expression.getScript()); } } scriptText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { } }); scriptText.addKeyListener(new KeyListener() { boolean ctrlPressed; public void keyPressed(KeyEvent e) { switch (e.keyCode) { case SWT.CTRL: ctrlPressed = true; break; case ' ': if (ctrlPressed) { e.doit = false; } } } public void keyReleased(KeyEvent e) { switch (e.keyCode) { case SWT.CTRL: ctrlPressed = false; break; } } }); scriptText.setFocus(); return composite; } public void setCurrentPanel(Composite panel) { if (currentPanel != null) currentPanel.dispose(); currentPanel = panel; blankPanel.layout(); } public void setType(int type) { currentType = type; boolean isText = type == TEXT; textRadio.setSelection(isText); if (isText) { setCurrentPanel(createTextPanel(blankPanel)); } boolean isBinary = type == BINARY; binaryRadio.setSelection(isBinary); if (isBinary) { setCurrentPanel(createBinaryPanel(blankPanel)); } boolean isVariable = type == VARIABLE; variableRadio.setSelection(isVariable); if (isVariable) { setCurrentPanel(createVariablePanel(blankPanel)); } boolean isExpression = type == EXPRESSION; expressionRadio.setSelection(isExpression); if (isExpression) { setCurrentPanel(createExpressionPanel(blankPanel)); } } void showHints() { CodeAssist codeAssist = new CodeAssist(getParent(), scriptText); codeAssist.open(); } public void addVariable(String variable) { variables.add(variable); } public void setScript(String script) { scriptText.setText(script == null ? "" : script); } public String getScript() { return "".equals(scriptText.getText()) ? null : scriptText.getText(); } public String getForeach() { return "".equals(foreachCombo.getText()) ? null : foreachCombo.getText(); } public void setForeach(String foreach) { foreachCombo.setText(foreach == null ? "" : foreach); } public int getAction() { return action; } public void setAction(int action) { this.action = action; } public EntryAttributeConfig getAttributeConfig() { return attributeConfig; } public void setConstant(String constant) { textText.setText(constant == null ? "" : constant); } public String getConstant() { return "".equals(textText.getText()) ? null : textText.getText(); } public void setBinary(byte[] bytes) { //log.debug("Writing "+bytes.length+" bytes."); StringBuilder sb = new StringBuilder(); int lines = bytes.length / 16 + 1; int pos = 0; for (int i=0; i<lines && pos < bytes.length; i++) { String index = Integer.toHexString(pos); for (int j=0; j<8-index.length(); j++) sb.append("0"); sb.append(index); sb.append(": "); StringBuilder text = new StringBuilder(); for (int j=0; j<16; j++) { if (pos < bytes.length) { int b = bytes[pos++] & 0xff; String hex = Integer.toHexString(b).toUpperCase(); if (hex.length() == 1) sb.append("0"); sb.append(hex); if (b >= '!' && b <= '~') { text.append((char)b); } else { text.append("."); } } else { sb.append(" "); } if (j % 2 == 1) sb.append(" "); } sb.append(text); sb.append("\n"); } binaryText.setText(sb.toString()); } public byte[] getBinary() { byte[] bytes = null; try { BufferedReader in = new BufferedReader(new StringReader(binaryText.getText())); Collection<Byte> c = new ArrayList<Byte>(); String line; while ((line = in.readLine()) != null) { String index = line.substring(0, 10); String values = line.substring(10, 50); String text = line.substring(50); for (int i=0; i<16; i++) { int pos = (i/2) * 5 + (i%2) * 2; String h = values.substring(pos, pos+2).trim(); if ("".equals(h)) break; byte b = Byte.parseByte(h, 16); c.add(b); //log.debug(" - "+h+" -> "+b); } } bytes = new byte[c.size()]; int pos = 0; for (Byte b : c) { bytes[pos++] = b; } } catch (Exception e) { log.error(e.getMessage(), e); ErrorDialog.open(e); } //log.debug("Reading "+bytes.length+" bytes."); return bytes; } public void setVariable(String variable) { variableCombo.setText(variable == null ? "" : variable); } public String getVariable() { return "".equals(variableCombo.getText()) ? null : variableCombo.getText(); } /* public void setName(String name) { nameText.setText(name == null ? "" : name); } public String getName() { return "".equals(nameText.getText()) ? null : nameText.getText(); } */ public void setAttributeConfig(EntryAttributeConfig attributeConfig) { this.attributeConfig = attributeConfig; //setName(attributeMapping.getName()); Object constant = attributeConfig.getConstant(); if (constant != null) { if (constant instanceof byte[]) { setType(BINARY); setBinary((byte[])constant); } else { setType(TEXT); setConstant((String)constant); } return; } String variable = attributeConfig.getVariable(); if (variable != null) { setType(VARIABLE); setVariable(variable); return; } Expression expression = attributeConfig.getExpression(); if (expression != null) { setType(EXPRESSION); setForeach(expression.getForeach()); setVar(expression.getVar()); setScript(expression.getScript()); return; } setType(TEXT); } public void setFieldConfig(EntryFieldConfig fieldConfig) { this.fieldConfig = fieldConfig; //setName(fieldMapping.getName()); Object constant = fieldConfig.getConstant(); if (constant != null) { if (constant instanceof byte[]) { setType(BINARY); setBinary((byte[])constant); } else { setType(TEXT); setConstant((String)constant); } return; } String variable = fieldConfig.getVariable(); if (variable != null) { setType(VARIABLE); setVariable(variable); return; } Expression expression = fieldConfig.getExpression(); if (expression != null) { setType(EXPRESSION); setForeach(expression.getForeach()); setVar(expression.getVar()); setScript(expression.getScript()); return; } setType(TEXT); } public EntryFieldConfig getFieldConfig() { return fieldConfig; } public interface NameChecker { public String checkName(String name); } public String getVar() { return "".equals(varText.getText()) ? null : varText.getText(); } public void setVar(String var) { varText.setText(var == null ? "" : var); } }