2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.taxeditor
.preference
;
12 import java
.awt
.Toolkit
;
13 import java
.io
.BufferedReader
;
14 import java
.io
.IOException
;
15 import java
.io
.InputStreamReader
;
16 import java
.net
.HttpURLConnection
;
18 import java
.util
.ArrayList
;
20 import javax
.swing
.event
.DocumentEvent
;
22 import org
.apache
.commons
.lang
.StringUtils
;
23 import org
.eclipse
.equinox
.internal
.p2
.ui
.misc
.StringMatcher
;
24 import org
.eclipse
.jface
.fieldassist
.ComboContentAdapter
;
25 import org
.eclipse
.jface
.fieldassist
.ContentProposalAdapter
;
26 import org
.eclipse
.jface
.fieldassist
.IContentProposal
;
27 import org
.eclipse
.jface
.fieldassist
.IContentProposalProvider
;
28 import org
.eclipse
.jface
.resource
.JFaceResources
;
29 import org
.eclipse
.swt
.SWT
;
30 import org
.eclipse
.swt
.custom
.CLabel
;
31 import org
.eclipse
.swt
.events
.ModifyEvent
;
32 import org
.eclipse
.swt
.events
.ModifyListener
;
33 import org
.eclipse
.swt
.events
.MouseEvent
;
34 import org
.eclipse
.swt
.events
.MouseListener
;
35 import org
.eclipse
.swt
.graphics
.Rectangle
;
36 import org
.eclipse
.swt
.layout
.GridData
;
37 import org
.eclipse
.swt
.widgets
.Button
;
38 import org
.eclipse
.swt
.widgets
.Combo
;
39 import org
.eclipse
.swt
.widgets
.Composite
;
40 import org
.eclipse
.swt
.widgets
.Display
;
41 import org
.eclipse
.swt
.widgets
.Label
;
42 import org
.eclipse
.swt
.widgets
.List
;
43 import org
.eclipse
.swt
.widgets
.Text
;
44 import org
.json
.JSONArray
;
45 import org
.json
.JSONException
;
46 import org
.json
.JSONObject
;
48 import eu
.etaxonomy
.cdm
.model
.metadata
.CdmPreference
;
49 import eu
.etaxonomy
.cdm
.model
.metadata
.PreferencePredicate
;
50 import eu
.etaxonomy
.taxeditor
.l10n
.Messages
;
51 import eu
.etaxonomy
.taxeditor
.preference
.menu
.CdmPreferencePage
;
59 public class ListComponent
implements ModifyListener
63 private static final String addString
= Messages
.ListComponent_ADD_PROVIDER
;
64 private static final String removeString
= Messages
.ListComponent_REMOVE_PROVIDER
;
65 private static final String noProvider
= Messages
.ListComponent_NO_PROVIDER_AVAILABLE
;
66 private static final String serverSidePreference
= "Server Side Preference:";
67 private Button removeButton
;
68 private Combo providerURI
;
69 protected Label labelException
;
70 boolean isAdmin
= false;
71 CdmPreferencePage preferencePage
;
72 CdmPreference providerListPreference
;
77 public CdmPreference
getProviderListPreference() {
78 return providerListPreference
;
82 public void setProviderListPreference(CdmPreference providerListPreference
) {
83 this.providerListPreference
= providerListPreference
;
87 public ListComponent(Composite parent
, int style
, boolean isAdmin
, CdmPreferencePage parentPage
) {
88 this.isAdmin
= isAdmin
;
89 this.preferencePage
= parentPage
;
91 providerListPreference
= PreferencesUtil
.getPreferenceFromDB(PreferencePredicate
.BioCaseProvider
);
92 if (!isAdmin
&& providerListPreference
!= null && !providerListPreference
.isAllowOverride()){
93 Label editingNotAllowed
= new Label(parent
, style
);
94 editingNotAllowed
.setText(Messages
.AbcdImportProvider_description_not_available
);
97 final CLabel description
= new CLabel(parent
, SWT
.NULL
);
98 description
.setText(Messages
.AbcdImportProvider_description
);
99 list
= new List(parent
, SWT
.BORDER
| SWT
.V_SCROLL
);
100 GridData gridData
= new GridData(SWT
.FILL
, SWT
.CENTER
, true, true, 2, 3);
101 gridData
.grabExcessHorizontalSpace
= true;
102 list
.setLayoutData(gridData
);
104 Rectangle clientArea
= parent
.getShell().getClientArea ();
105 list
.setBounds (clientArea
.x
, clientArea
.y
, 50, 500);
108 providerList
= null; //$NON-NLS-1$
109 String allProviderStringDB
= "";
111 if (!isAdmin
&& ((providerListPreference
!= null && providerListPreference
.isAllowOverride()) || providerListPreference
== null)){
112 providerList
= PreferencesUtil
.getStringValue(PreferencePredicate
.BioCaseProvider
.getKey(), true);
115 if (providerListPreference
!= null){
116 providerList
= providerListPreference
.getValue();
120 //the string is structured like this: http://ww3.bgbm.org/biocase/pywrapper.cgi?dsa=DNA_Bank;http:...;
121 if (providerList
!= null){
122 String
[] providerArray
= providerList
.split(";"); //$NON-NLS-1$
123 for (String providerString
: providerArray
){
124 if (!StringUtils
.isBlank(providerString
)){
125 list
.add(providerString
);
131 if (list
.getItemCount() == 0){
132 list
.add(noProvider
);
134 list
.add(""); //$NON-NLS-1$
136 // list.setSelection(0);
137 GridData dataList
= new GridData();
138 dataList
.horizontalAlignment
= GridData
.FILL
;
139 dataList
.horizontalSpan
= 3;
142 // dataList.grabExcessVerticalSpace = true;
144 list
.setLayoutData(dataList
);
147 providerURI
= new Combo(parent
, SWT
.BORDER
);
150 String response
= null;
152 url
= new URL("https://www.biocase.org/whats_biocase/gbif_biocase.cgi");
154 HttpURLConnection conn
= (HttpURLConnection
) url
.openConnection();
155 conn
.setRequestProperty("Accept", "application/json");
156 // conn.setConnectTimeout(TIMEOUT*9);
157 // conn.setReadTimeout(TIMEOUT*9);
159 if (conn
.getResponseCode() != 200) {
160 throw new RuntimeException("Failed : HTTP error code : " + conn
.getResponseCode());
162 BufferedReader br
= new BufferedReader(new InputStreamReader((conn
.getInputStream())));
164 StringBuilder builder
= new StringBuilder();
166 while ((line
= br
.readLine()) != null) {
167 builder
.append(line
);
170 response
= builder
.toString();
171 } catch (IOException e
) {
172 // TODO Auto-generated catch block
176 JSONArray jsonResponseArray
;
178 jsonResponseArray
=new JSONArray(response
);
181 String service_url
= null;
182 JSONArray dataSets
= null;
183 items
= new String
[jsonResponseArray
.length()];
184 while (i
<jsonResponseArray
.length()){
185 JSONObject object
= jsonResponseArray
.getJSONObject(i
);
186 service_url
= (String
) object
.get("service_url");
187 dataSets
= (JSONArray
) object
.get("datasets");
188 if (service_url
!= null){
189 providerURI
.add(service_url
);
190 items
[i
] = service_url
;
195 } catch (JSONException e
) {
196 // TODO Auto-generated catch block
201 GridData dataProviderUri
= new GridData();
202 dataProviderUri
.horizontalAlignment
= GridData
.FILL
;
203 dataProviderUri
.horizontalSpan
= 3;
204 providerURI
.setLayoutData(dataProviderUri
);
205 // providerURI.setVisible(false);
207 ContentProposalAdapter adapter
= new ContentProposalAdapter(providerURI
, new ComboContentAdapter(), getProposalProvider(), null, null);
208 adapter
.setPropagateKeys(true);
209 adapter
.setProposalAcceptanceStyle(ContentProposalAdapter
.PROPOSAL_REPLACE
);
210 // String[] proposals = new String[providerURI.getItems().length];
212 // for (int i = 0; i < providerURI.getItems().length; i++) {
213 // proposals[i] = providerURI.getItem(i);
216 // ComboViewer comboViewer = new ComboViewer(parent, SWT.NONE);
217 // comboViewer.setContentProvider(new ArrayContentProvider());
218 // comboViewer.setLabelProvider(new LabelProvider(){
220 // public String getText(final Object element){
221 // if(element instanceof String){
222 // return (String) element;
224 // return element.toString();
227 // comboViewer.setInput(proposals);
228 // // additionally, configure the comboViewer arbitrary
229 // AutoCompleteField field = new AutoCompleteField(comboViewer.getCombo(), new ComboContentAdapter(), proposals);
234 //providerURI.addModifyListener(this);
235 labelException
= new Label(parent
, SWT
.NULL
);
236 labelException
.setText("");
239 labelException
.setLayoutData(dataProviderUri
);
241 Button addButton
= new Button(parent
, SWT
.NULL
);
242 AddListener addListener
= new AddListener(addButton
);
243 addButton
.setText(addString
);
244 addButton
.addMouseListener(addListener
);
246 removeButton
= new Button(parent
, SWT
.NULL
);
247 removeButton
.setText(removeString
);
248 removeButton
.addMouseListener(new RemoveListener());
255 IContentProposalProvider
getProposalProvider() {
256 return new IContentProposalProvider() {
258 public IContentProposal
[] getProposals(String contents
, int position
) {
259 //String[] items = getStringItems();
260 if (contents
.length() == 0 || items
.length
== 0) {
261 return new IContentProposal
[0];
263 StringMatcher matcher
= new StringMatcher("*" + contents
+ "*", true, false); //$NON-NLS-1$ //$NON-NLS-2$
264 ArrayList
<String
> matches
= new ArrayList
<String
>();
265 for (int i
= 0; i
< items
.length
; i
++) {
266 if (matcher
.match(items
[i
])) {
267 matches
.add(items
[i
]);
271 // We don't want to autoactivate if the only proposal exactly matches
272 // what is in the combo. This prevents the popup from
273 // opening when the user is merely scrolling through the combo values or
274 // has accepted a combo value.
275 if (matches
.size() == 1 && matches
.get(0).equals(providerURI
.getText())) {
276 return new IContentProposal
[0];
279 if (matches
.isEmpty()) {
280 return new IContentProposal
[0];
283 // Make the proposals
284 IContentProposal
[] proposals
= new IContentProposal
[matches
.size()];
285 for (int i
= 0; i
< matches
.size(); i
++) {
286 final String proposal
= matches
.get(i
);
287 proposals
[i
] = new IContentProposal() {
290 public String
getContent() {
295 public int getCursorPosition() {
296 return proposal
.length();
300 public String
getDescription() {
305 public String
getLabel() {
315 public boolean isAdmin() {
319 public void setAdmin(boolean isAdmin
) {
320 this.isAdmin
= isAdmin
;
323 class RemoveListener
implements MouseListener
{
325 public void mouseUp(MouseEvent e
) {
326 //This method can be called only if
327 //there's a valid selection
328 //so go ahead and remove whatever's selected.
329 int index
= list
.getSelectionIndex();
331 String item
= list
.getItem(index
);
332 if (item
.equals(serverSidePreference
)) {
338 int size
= list
.getItemCount();
340 if (size
== 0) { //Nothing's left, disable removing.
341 removeButton
.setEnabled(false);
343 } else { //Select an index.
345 //removed item in last position
349 list
.setSelection(index
-1);
350 preferencePage
.setApply(true);
353 }catch(IllegalArgumentException iae
){
354 //nothing was selected
363 public void mouseDoubleClick(MouseEvent e
) {
364 // TODO Auto-generated method stub
373 public void mouseDown(MouseEvent e
) {
374 // TODO Auto-generated method stub
379 //This listener is shared by the text field and the add button.
380 class AddListener
implements MouseListener
{
381 private boolean alreadyEnabled
= false;
382 private Button button
;
384 public AddListener(Button button
) {
385 this.button
= button
;
389 protected boolean alreadyInList(String name
) {
390 return list
.getData(name
) != null;
394 private void enableButton() {
395 if (!alreadyEnabled
) {
396 button
.setEnabled(true);
400 private boolean handleEmptyTextField(DocumentEvent e
) {
401 if (e
.getDocument().getLength() <= 0) {
402 button
.setEnabled(false);
403 alreadyEnabled
= false;
415 public void mouseDoubleClick(MouseEvent e
) {
416 // TODO Auto-generated method stub
424 public void mouseDown(MouseEvent e
) {
425 // TODO Auto-generated method stub
433 public void mouseUp(MouseEvent event
) {
434 String name
= providerURI
.getText();
436 //User didn't type in a unique name...
437 if (name
.equals("") || alreadyInList(name
) || !StringUtils
.isBlank(labelException
.getText())) { //$NON-NLS-1$
438 Toolkit
.getDefaultToolkit().beep();
439 //providerURI.selectAll();
443 int index
= list
.getSelectionIndex(); //get selected index
444 if (index
== -1) { //no selection, so insert at beginning
446 } else { //add after the selected item
449 if(list
.getItemCount() == 0){
451 }else if (list
.getItem(0).equals(noProvider
)){
452 list
.remove(noProvider
);
454 int itemCount
= list
.getItemCount();
457 list
.add(providerURI
.getText(), index
);
458 list
.setSelection(index
);
462 //Select the new item
464 providerURI
.setText(""); //$NON-NLS-1$
465 preferencePage
.setApply(true);
469 public String
createAllProviderString(){
470 String allProviderString
= null;
471 boolean first
= true;
472 for (String item
: list
.getItems()){
473 if (item
.equals(noProvider
) || item
.equals(serverSidePreference
)){
475 }else if (first
|| StringUtils
.isBlank(allProviderString
)){ //$NON-NLS-1$
476 allProviderString
= item
.trim();
479 allProviderString
+=";"+ item
.trim(); //$NON-NLS-1$
483 return allProviderString
;
489 public void modifyText(ModifyEvent e
) {
490 if(e
.widget
==providerURI
){
491 Text text
= (Text
) e
.widget
;
492 boolean hasControlCharacters
= false;
493 String textString
= text
.getText();
494 int stringLength
= textString
.length();
495 for (int i
= 0; i
< stringLength
; i
++) {
496 if (Character
.isISOControl(textString
.charAt(i
))) {
497 hasControlCharacters
= true;
502 //remove control character such as line breaks etc.
505 labelException
.setFont(JFaceResources
.getFontRegistry().getBold(JFaceResources
.DEFAULT_FONT
));
506 labelException
.setForeground(Display
.getCurrent().getSystemColor(SWT
.NULL
));
507 labelException
.setText("");
508 } catch (Exception exception
) {
509 labelException
.setFont(JFaceResources
.getFontRegistry().getBold(JFaceResources
.DEFAULT_FONT
));
510 labelException
.setForeground(Display
.getCurrent().getSystemColor(SWT
.COLOR_RED
));
511 labelException
.setText(Messages
.UriWithLabelElement_URL_NOT_SAVED
+exception
.getLocalizedMessage());
519 protected URL
getParsedText() throws Exception
{
520 String uriText
= providerURI
.getText();
521 if(!StringUtils
.isBlank(uriText
)){
522 return new URL(providerURI
.getText());