br.ufrj.ppgi.greco.kettle.DataPropertyMappingStepDialog   A
last analyzed

Complexity

Total Complexity 40

Size/Duplication

Total Lines 382
Duplicated Lines 33.25 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 40
eloc 246
c 1
b 0
f 1
dl 127
loc 382
rs 9.2

21 Methods

Rating   Name   Duplication   Size   Complexity  
$ModifyListener$.modifyText(ModifyEvent) 2 2 ?
D buildContents(Control,ModifyListener) 0 107 12
A getFields() 0 2 1
$SelectionListener$.widgetDefaultSelected(SelectionEvent) 0 7 ?
C open() 108 108 8
A getDataTable() 0 7 1
A getRowFactoryWrite(DataTable) 0 6 1
A getRowFactoryRead(DataTable) 0 5 1
A getFields(int) 19 19 5
A addSelectionListenerToControls(SelectionAdapter) 0 7 1
$ShellAdapter$.shellClosed(ShellEvent) 2 2 ?
$KeyListener$.keyPressed(KeyEvent) 0 6 ?
$MouseAdapter$.mouseDoubleClick(MouseEvent) 0 4 ?
$Listener$.handleEvent(Event) 2 2 ?
A getData() 0 31 4
$SelectionListener$.widgetSelected(SelectionEvent) 0 2 ?
A ok() 0 30 4
$SelectionAdapter$.widgetDefaultSelected(SelectionEvent) 2 2 ?
$KeyListener$.keyReleased(KeyEvent) 0 1 ?
A DataPropertyMappingStepDialog(Shell,Object,TransMeta,String) 0 7 1
A cancel() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like br.ufrj.ppgi.greco.kettle.DataPropertyMappingStepDialog often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package br.ufrj.ppgi.greco.kettle;
2
3
import java.util.ArrayList;
4
import java.util.Iterator;
5
import java.util.List;
6
7
import org.eclipse.swt.SWT;
8
import org.eclipse.swt.custom.CTabFolder;
9
import org.eclipse.swt.custom.CTabItem;
10
import org.eclipse.swt.events.KeyEvent;
11
import org.eclipse.swt.events.KeyListener;
12
import org.eclipse.swt.events.ModifyEvent;
13
import org.eclipse.swt.events.ModifyListener;
14
import org.eclipse.swt.events.MouseAdapter;
15
import org.eclipse.swt.events.MouseEvent;
16
import org.eclipse.swt.events.SelectionAdapter;
17
import org.eclipse.swt.events.SelectionEvent;
18
import org.eclipse.swt.events.SelectionListener;
19
import org.eclipse.swt.events.ShellAdapter;
20
import org.eclipse.swt.events.ShellEvent;
21
import org.eclipse.swt.layout.FormAttachment;
22
import org.eclipse.swt.layout.FormData;
23
import org.eclipse.swt.layout.FormLayout;
24
import org.eclipse.swt.widgets.Button;
25
import org.eclipse.swt.widgets.Composite;
26
import org.eclipse.swt.widgets.Control;
27
import org.eclipse.swt.widgets.Display;
28
import org.eclipse.swt.widgets.Event;
29
import org.eclipse.swt.widgets.Group;
30
import org.eclipse.swt.widgets.Label;
31
import org.eclipse.swt.widgets.Listener;
32
import org.eclipse.swt.widgets.Shell;
33
import org.eclipse.swt.widgets.Text;
34
import org.pentaho.di.core.Const;
35
import org.pentaho.di.core.exception.KettleStepException;
36
import org.pentaho.di.core.row.RowMetaInterface;
37
import org.pentaho.di.core.row.ValueMetaInterface;
38
import org.pentaho.di.core.util.StringUtil;
39
import org.pentaho.di.i18n.BaseMessages;
40
import org.pentaho.di.trans.TransMeta;
41
import org.pentaho.di.trans.step.BaseStepMeta;
42
import org.pentaho.di.trans.step.StepDialogInterface;
43
import org.pentaho.di.ui.core.widget.ColumnInfo;
44
import org.pentaho.di.ui.core.widget.ComboVar;
45
import org.pentaho.di.ui.core.widget.TableView;
46
import org.pentaho.di.ui.core.widget.TextVar;
47
import org.pentaho.di.ui.trans.step.BaseStepDialog;
48
49
import br.ufrj.ppgi.greco.kettle.plugin.tools.datatable.DataTable;
50
import br.ufrj.ppgi.greco.kettle.plugin.tools.swthelper.SwtHelper;
51
52
public class DataPropertyMappingStepDialog extends BaseStepDialog implements StepDialogInterface {
53
54
	private static Class<?> PKG = DataPropertyMappingStepMeta.class;
55
	
56
	private DataPropertyMappingStepMeta input;
57
	private SwtHelper swthlp;
58
	private String dialogTitle;
59
60
	// Aba 'Mapeamento'
61
	private TextVar wRdfType;
62
	private ComboVar wSubjectFieldName;
63
	private TableView wMapTable;
64
	private org.eclipse.swt.widgets.List wRdfTypeList;
65
66
	// Aba 'Campos de saida'
67
	private Button wKeepInputFields;
68
	private TextVar wSubjectOutputFieldName;
69
	private TextVar wPredicateOutputFieldName;
70
	private TextVar wObjectOutputFieldName;
71
	private TextVar wDatatypeOutputFieldName;
72
	private TextVar wLangTagOutputFieldName;
73
74
	public DataPropertyMappingStepDialog(Shell parent, Object stepMeta, TransMeta transMeta, String stepname) {
75
		super(parent, (BaseStepMeta) stepMeta, transMeta, stepname);
76
77
		input = (DataPropertyMappingStepMeta) baseStepMeta;
78
		swthlp = new SwtHelper(transMeta, this.props);
79
80
		dialogTitle = BaseMessages.getString(PKG, "DataPropertyMappingStep.Title");
81
	}
82
83
	private Control buildContents(Control lastControl, ModifyListener defModListener) {
84
85
		CTabFolder wTabFolder = swthlp.appendTabFolder(shell, lastControl, 90);
86
87
		CTabItem item = new CTabItem(wTabFolder, SWT.NONE);
88
		item.setText(BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Mapping"));
89
		Composite cpt = swthlp.appendComposite(wTabFolder, lastControl);
90
91
		wSubjectFieldName = swthlp.appendComboVarRow(cpt, null, BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Mapping.Subject"), defModListener);
92
		wSubjectFieldName.setEditable(false);
93
		wSubjectFieldName.setItems(this.getFields(ValueMetaInterface.TYPE_STRING));
94
95
		Group wGroup = swthlp.appendGroup(cpt, wSubjectFieldName, BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Mapping.Rdftype"), 50);
96
		wRdfType = swthlp.appendTextVarWithButtonRow(wGroup, null, BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Mapping.NewRdftype"), defModListener, "+",
97
				new SelectionListener() {
98
					public void widgetSelected(SelectionEvent arg0) {
99
						widgetDefaultSelected(arg0);
100
					}
101
102
					public void widgetDefaultSelected(SelectionEvent arg0) {
103
						String textToAdd = wRdfType.getText().trim();
104
						if (!textToAdd.isEmpty()) {
105
							wRdfTypeList.add(textToAdd);
106
							wRdfType.setText("");
107
						}
108
						input.setChanged(true);
109
					}
110
				});
111
		wRdfType.setToolTipText(BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Mapping.Tooltip"));
112
113
		wRdfTypeList = swthlp.appendListRow(wGroup, wRdfType, BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Mapping.Rdftypelist"), new SelectionAdapter() {
114
		}, 90);
115
		wRdfTypeList.addKeyListener(new KeyListener() {
116
			public void keyPressed(KeyEvent e) {
117
				if (e.keyCode == SWT.DEL) {
118
					int index = wRdfTypeList.getSelectionIndex();
119
					if (index >= 0) {
120
						wRdfTypeList.remove(index);
121
						input.setChanged(true);
122
					}
123
				}
124
			}
125
126
			public void keyReleased(KeyEvent e) {
127
			}
128
		});
129
		wRdfTypeList.addMouseListener(new MouseAdapter() {
130
			@Override
131
			public void mouseDoubleClick(MouseEvent e) {
132
				if (wRdfTypeList.getSelectionIndex() >= 0)
133
					wRdfType.setText(wRdfTypeList.getSelection()[0]);
134
			}
135
		});
136
137
		Label wListLabel = swthlp.appendLabel(wGroup, wRdfTypeList,
138
				BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Mapping.Label"));
139
		wListLabel.setAlignment(SWT.RIGHT);
140
141
		ColumnInfo[] columns = new ColumnInfo[] {
142
				new ColumnInfo(BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Mapping.ColumnA"),
143
						ColumnInfo.COLUMN_TYPE_CCOMBO, this.getFields(ValueMetaInterface.TYPE_STRING)),
144
				new ColumnInfo(BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Mapping.ColumnB"), ColumnInfo.COLUMN_TYPE_CCOMBO, this.getFields(), true),
145
				new ColumnInfo(BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Mapping.ColumnC"), ColumnInfo.COLUMN_TYPE_CCOMBO,
146
						new String[] { "Tentar descobrir", "xsd:integer", "xsd:float", "xsd:double", "xsd:decimal",
147
								"xsd:date", "xsd:dateTime", "xsd:string" }),
148
				new ColumnInfo(BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Mapping.ColumnD"), ColumnInfo.COLUMN_TYPE_CCOMBO,
149
						new String[] { "en", "pt", "fr", "" }),
150
				new ColumnInfo(BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Mapping.ColumnE"), ColumnInfo.COLUMN_TYPE_CCOMBO, this.getFields(),
151
						true),
152
153
		};
154
		wMapTable = swthlp.appendTableView(cpt, wGroup, columns, defModListener, 98);
155
		item.setControl(cpt);
156
157
		item = new CTabItem(wTabFolder, SWT.NONE);
158
		item.setText(BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Output"));
159
		cpt = swthlp.appendComposite(wTabFolder, lastControl);
160
		wKeepInputFields = swthlp.appendCheckboxRow(cpt, null, BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Output.KeepInputFields"),
161
				new SelectionListener() {
162
163
					public void widgetDefaultSelected(SelectionEvent arg0) {
164
						widgetSelected(arg0);
165
					}
166
167
					public void widgetSelected(SelectionEvent e) {
168
						input.setChanged(true);
169
					}
170
				});
171
		wSubjectOutputFieldName = swthlp.appendTextVarRow(cpt, wKeepInputFields, BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Output.SubjectField"),
172
				defModListener);
173
		wPredicateOutputFieldName = swthlp.appendTextVarRow(cpt, wSubjectOutputFieldName, BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Output.PredicateField"),
174
				defModListener);
175
		wObjectOutputFieldName = swthlp.appendTextVarRow(cpt, wPredicateOutputFieldName, BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Output.ObjectField"),
176
				defModListener);
177
		wDatatypeOutputFieldName = swthlp.appendTextVarRow(cpt, wObjectOutputFieldName,
178
				BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Output.Rdftype"), defModListener);
179
		wLangTagOutputFieldName = swthlp.appendTextVarRow(cpt, wDatatypeOutputFieldName,
180
				BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Output.Rdflangtag"), defModListener);
181
		item.setControl(cpt);
182
183
		wSubjectOutputFieldName
184
				.setToolTipText(BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Output.Tooltipsubject"));
185
		wLangTagOutputFieldName.setToolTipText(BaseMessages.getString(PKG, "DataPropertyMappingStep.Tab.Output.Tooltiplangtag"));
186
187
		wTabFolder.setSelection(0);
188
189
		return wTabFolder;
190
	}
191
192
	private String[] getFields() {
193
		return getFields(-1);
194
	}
195
196 View Code Duplication
	private String[] getFields(int type) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
197
198
		List<String> result = new ArrayList<String>();
199
200
		try {
201
			RowMetaInterface inRowMeta = this.transMeta.getPrevStepFields(stepname);
202
203
			List<ValueMetaInterface> fields = inRowMeta.getValueMetaList();
204
205
			for (ValueMetaInterface field : fields) {
206
				if (field.getType() == type || type == -1)
207
					result.add(field.getName());
208
			}
209
210
		} catch (KettleStepException e) {
211
			e.printStackTrace();
212
		}
213
214
		return result.toArray(new String[result.size()]);
215
	}
216
217
	// Adiciona listeners para widgets tratarem Enter
218
	// The will close the window affirmatively when the user press Enter in one
219
	// of these text input fields
220
	private void addSelectionListenerToControls(SelectionAdapter lsDef) {
221
		wRdfType.addSelectionListener(lsDef);
222
		wSubjectOutputFieldName.addSelectionListener(lsDef);
223
		wPredicateOutputFieldName.addSelectionListener(lsDef);
224
		wObjectOutputFieldName.addSelectionListener(lsDef);
225
		wDatatypeOutputFieldName.addSelectionListener(lsDef);
226
		wLangTagOutputFieldName.addSelectionListener(lsDef);
227
	}
228
229 View Code Duplication
	public String open() {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
230
231
		Shell parent = getParent();
232
		Display display = parent.getDisplay();
233
234
		shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MIN | SWT.MAX);
235
		props.setLook(shell);
236
		setShellImage(shell, input);
237
238
		// ModifyListener padrao
239
		ModifyListener lsMod = new ModifyListener() {
240
241
			public void modifyText(ModifyEvent e) {
242
				input.setChanged();
243
			}
244
		};
245
246
		boolean changed = input.hasChanged();
247
248
		FormLayout formLayout = new FormLayout();
249
		formLayout.marginWidth = Const.FORM_MARGIN;
250
		formLayout.marginHeight = Const.FORM_MARGIN;
251
252
		shell.setLayout(formLayout);
253
254
		shell.setText(dialogTitle);
255
256
		int middle = props.getMiddlePct();
257
		int margin = Const.MARGIN;
258
259
		// Adiciona um label e um input text no topo do dialog shell
260
		wlStepname = new Label(shell, SWT.RIGHT);
261
		wlStepname.setText(BaseMessages.getString(PKG, "DataPropertyMappingStep.StepNameField.Label"));
262
		props.setLook(wlStepname);
263
264
		fdlStepname = new FormData();
265
		fdlStepname.left = new FormAttachment(0, 0);
266
		fdlStepname.right = new FormAttachment(middle, -margin);
267
		fdlStepname.top = new FormAttachment(0, margin);
268
		wlStepname.setLayoutData(fdlStepname);
269
270
		wStepname = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
271
		wStepname.setText(stepname);
272
		props.setLook(wStepname);
273
274
		wStepname.addModifyListener(lsMod);
275
		fdStepname = new FormData();
276
		fdStepname.left = new FormAttachment(middle, 0);
277
		fdStepname.top = new FormAttachment(0, margin);
278
		fdStepname.right = new FormAttachment(100, 0);
279
		wStepname.setLayoutData(fdStepname);
280
		Control lastControl = wStepname;
281
282
		lastControl = buildContents(lastControl, lsMod);
283
284
		// Bottom buttons
285
		wOK = new Button(shell, SWT.PUSH);
286
		wOK.setText(BaseMessages.getString(PKG, "DataPropertyMappingStep.Btn.OK"));
287
		wCancel = new Button(shell, SWT.PUSH);
288
		wCancel.setText(BaseMessages.getString(PKG, "DataPropertyMappingStep.Btn.Cancel"));
289
		setButtonPositions(new Button[] { wOK, wCancel }, margin, lastControl);
290
291
		// Add listeners
292
		lsCancel = new Listener() {
293
			public void handleEvent(Event e) {
294
				cancel();
295
			}
296
		};
297
		lsOK = new Listener() {
298
			public void handleEvent(Event e) {
299
				ok();
300
			}
301
		};
302
303
		wCancel.addListener(SWT.Selection, lsCancel);
304
		wOK.addListener(SWT.Selection, lsOK);
305
306
		// It closes the window affirmatively when the user press enter in one
307
		// of the text input fields
308
		lsDef = new SelectionAdapter() {
309
			public void widgetDefaultSelected(SelectionEvent e) {
310
				ok();
311
			}
312
		};
313
		wStepname.addSelectionListener(lsDef);
314
		addSelectionListenerToControls(lsDef);
315
316
		// Detect X or ALT-F4 or something that kills this window...
317
		shell.addShellListener(new ShellAdapter() {
318
			public void shellClosed(ShellEvent e) {
319
				cancel();
320
			}
321
		});
322
323
		// Populate the data of the controls
324
		getData();
325
326
		// Set the shell size, based upon previous time...
327
		setSize();
328
329
		input.setChanged(changed);
330
331
		shell.open();
332
		while (!shell.isDisposed()) {
333
			if (!display.readAndDispatch())
334
				display.sleep();
335
		}
336
		return stepname;
337
	}
338
339
	private void getData() {
340
		wStepname.selectAll();
341
342
		// Recupera dados do StepMeta e adiciona na GUI
343
		try {
344
			wRdfType.setText("");
345
346
			List<String> typesUri = input.getRdfTypeUris();
347
			Iterator<String> it = typesUri.iterator();
348
			while (it.hasNext()) {
349
				String rdfTypeUri = (String) it.next();
350
				wRdfTypeList.add(rdfTypeUri);
351
			}
352
353
			wSubjectFieldName.setText(Const.NVL(input.getSubjectUriFieldName(), ""));
354
355
			DataTable<String> table = input.getMapTable();
356
			DataTable<String>.RowFactory rf = getRowFactoryRead(table);
357
358
			for (int i = 0; i < table.size(); i++) {
359
				wMapTable.add(table.getRowRange(i, rf).getRow());
360
			}
361
			wMapTable.remove(0);
362
363
			wKeepInputFields.setSelection(input.isKeepInputFields());
364
			wSubjectOutputFieldName.setText(Const.NVL(input.getSubjectOutputFieldName(), ""));
365
			wPredicateOutputFieldName.setText(Const.NVL(input.getPredicateOutputFieldName(), ""));
366
			wObjectOutputFieldName.setText(Const.NVL(input.getObjectOutputFieldName(), ""));
367
			wDatatypeOutputFieldName.setText(Const.NVL(input.getDatatypeOutputFieldName(), ""));
368
			wLangTagOutputFieldName.setText(Const.NVL(input.getLangTagOutputFieldName(), ""));
369
		} catch (NullPointerException e) {
370
371
		}
372
	}
373
374
	protected void cancel() {
375
		stepname = null;
376
		input.setChanged(changed);
377
		dispose();
378
	}
379
380
	protected void ok() {
381
		if (StringUtil.isEmpty(wStepname.getText()))
382
			return;
383
384
		stepname = wStepname.getText();
385
386
		// Pega dados da GUI e colocar no StepMeta
387
		List<String> typesUri = new ArrayList<String>();
388
		for (int i = 0; i < wRdfTypeList.getItemCount(); i++) {
389
			typesUri.add(wRdfTypeList.getItem(i));
390
		}
391
		input.setRdfTypeUris(typesUri);
392
		input.setSubjectUriFieldName(wSubjectFieldName.getText());
393
394
		DataTable<String> table = getDataTable();
395
		DataTable<String>.RowFactory rf = getRowFactoryWrite(table);
396
		for (int i = 0; i < wMapTable.getItemCount(); i++) {
397
			table.add(rf.newRow(wMapTable.getItem(i)).getFullRow());
398
		}
399
		input.setMapTable(table);
400
401
		input.setKeepInputFields(wKeepInputFields.getSelection());
402
		input.setSubjectOutputFieldName(wSubjectOutputFieldName.getText());
403
		input.setPredicateOutputFieldName(wPredicateOutputFieldName.getText());
404
		input.setObjectOutputFieldName(wObjectOutputFieldName.getText());
405
		input.setDatatypeOutputFieldName(wDatatypeOutputFieldName.getText());
406
		input.setLangTagOutputFieldName(wLangTagOutputFieldName.getText());
407
408
		// Fecha janela
409
		dispose();
410
	}
411
412
	private DataTable<String> getDataTable() {
413
		return new DataTable<String>(DataPropertyMappingStepMeta.Field.MAP_TABLE.name(),
414
				DataPropertyMappingStepMeta.Field.MAP_TABLE_PREDICATE_URI.name(),
415
				DataPropertyMappingStepMeta.Field.MAP_TABLE_OBJECT_FIELD_NAME.name(),
416
				DataPropertyMappingStepMeta.Field.MAP_TABLE_TYPED_LITERAL.name(),
417
				DataPropertyMappingStepMeta.Field.MAP_TABLE_LANGUAGE_TAG.name(),
418
				DataPropertyMappingStepMeta.Field.MAP_TABLE_LANGTAG_FIELD_NAME.name());
419
	}
420
421
	private DataTable<String>.RowFactory getRowFactoryWrite(DataTable<String> table) {
422
		return table.newRowFactory(DataPropertyMappingStepMeta.Field.MAP_TABLE_PREDICATE_URI.name(),
423
				DataPropertyMappingStepMeta.Field.MAP_TABLE_OBJECT_FIELD_NAME.name(),
424
				DataPropertyMappingStepMeta.Field.MAP_TABLE_TYPED_LITERAL.name(),
425
				DataPropertyMappingStepMeta.Field.MAP_TABLE_LANGUAGE_TAG.name(),
426
				DataPropertyMappingStepMeta.Field.MAP_TABLE_LANGTAG_FIELD_NAME.name());
427
	}
428
429
	private DataTable<String>.RowFactory getRowFactoryRead(DataTable<String> table) {
430
		List<String> header = new ArrayList<String>();
431
		header.addAll(table.getHeader());
432
		header.remove(DataPropertyMappingStepMeta.Field.MAP_TABLE_PREDICATE_FIELD_NAME.name());
433
		return table.newRowFactory(header.toArray(new String[0]));
434
	}
435
436
}