View Javadoc
1   /*******************************************************************************
2    * Copyhacked (H) 2012-2025.
3    * This program and the accompanying materials
4    * are made available under no term at all, use it like
5    * you want, but share and discuss it
6    * every time possible with every body.
7    * 
8    * Contributors:
9    *      ron190 at ymail dot com - initial implementation
10   ******************************************************************************/
11  package com.jsql.view.swing.manager;
12  
13  import com.jsql.util.I18nUtil;
14  import com.jsql.util.LogLevelUtil;
15  import com.jsql.view.swing.list.DnDList;
16  import com.jsql.view.swing.list.ItemList;
17  import com.jsql.view.swing.manager.util.JButtonStateful;
18  import com.jsql.view.swing.manager.util.StateButton;
19  import com.jsql.view.swing.text.JToolTipI18n;
20  import com.jsql.view.swing.util.I18nViewUtil;
21  import com.jsql.view.swing.util.UiUtil;
22  import org.apache.commons.lang3.StringUtils;
23  import org.apache.logging.log4j.LogManager;
24  import org.apache.logging.log4j.Logger;
25  
26  import javax.swing.*;
27  import java.awt.*;
28  import java.io.BufferedReader;
29  import java.io.IOException;
30  import java.io.InputStreamReader;
31  import java.nio.charset.StandardCharsets;
32  import java.util.ArrayList;
33  import java.util.List;
34  import java.util.Objects;
35  import java.util.concurrent.atomic.AtomicBoolean;
36  import java.util.concurrent.atomic.AtomicReference;
37  import java.util.stream.StreamSupport;
38  
39  /**
40   * Abstract manager containing a drag and drop list of item.
41   */
42  public abstract class AbstractManagerList extends JPanel {
43  
44      private static final Logger LOGGER = LogManager.getRootLogger();
45  
46      public static final String PRIVILEGE_TOOLTIP = "PRIVILEGE_TOOLTIP";
47      protected final transient List<ItemList> itemsList = new ArrayList<>();
48      protected final JPanel lastLine = new JPanel();
49  
50      /**
51       * Contains the paths of files.
52       */
53      protected DnDList listPaths;
54      protected final JScrollPane scrollListPaths;
55  
56      /**
57       * Starts the upload process.
58       */
59      protected JButtonStateful run;
60  
61      /**
62       * Display the FILE privilege of current user.
63       */
64      protected JLabel privilege;
65  
66      /**
67       * Text of the button that start the upload process.
68       * Used to get back the default text after a search (defaultText->"Stop"->defaultText).
69       */
70      protected String labelI18nRunButton;
71      protected String tooltipI18nRunButton;
72  
73      /**
74       * An animated bar displayed during processing.
75       */
76      protected final JProgressBar progressBar = new JProgressBar();
77      protected final Component horizontalGlue = Box.createHorizontalGlue();
78  
79      protected AbstractManagerList(String nameFile) {
80          this.setLayout(new BorderLayout());
81  
82          this.buildList(nameFile);
83          this.progressBar.setIndeterminate(true);
84          this.progressBar.setVisible(false);
85          this.progressBar.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
86          this.lastLine.setLayout(new BoxLayout(this.lastLine, BoxLayout.X_AXIS));
87  
88          this.scrollListPaths = new JScrollPane(this.listPaths);
89          this.add(this.scrollListPaths, BorderLayout.CENTER);
90      }
91  
92      public void buildRunButton(String labelI18n, String tooltipI18n) {
93          this.labelI18nRunButton = labelI18n;
94          this.tooltipI18nRunButton = tooltipI18n;
95          var tooltip = new AtomicReference<>(new JToolTipI18n(I18nUtil.valueByKey(this.tooltipI18nRunButton)));
96          this.run = new JButtonStateful(this.labelI18nRunButton) {
97              @Override
98              public JToolTip createToolTip() {
99                  return tooltip.get();
100             }
101         };
102         I18nViewUtil.addComponentForKey(this.labelI18nRunButton, this.run);
103         I18nViewUtil.addComponentForKey(this.tooltipI18nRunButton, tooltip.get());
104         this.run.setToolTipText(I18nUtil.valueByKey(this.tooltipI18nRunButton));
105     }
106 
107     public void buildList(String nameFile) {
108         try (
109             var inputStream = UiUtil.class.getClassLoader().getResourceAsStream(nameFile);
110             var inputStreamReader = new InputStreamReader(Objects.requireNonNull(inputStream), StandardCharsets.UTF_8);
111             var reader = new BufferedReader(inputStreamReader)
112         ) {
113             String line;
114             while ((line = reader.readLine()) != null) {
115                 this.itemsList.add(new ItemList(line));
116             }
117             this.listPaths = new DnDList(this.itemsList);
118         } catch (IOException e) {
119             LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
120         }
121     }
122 
123     public void buildPrivilege() {
124         var tooltip = new AtomicReference<>(new JToolTipI18n(I18nUtil.valueByKey(AbstractManagerList.PRIVILEGE_TOOLTIP)));
125         this.privilege = new JLabel(I18nUtil.valueByKey("PRIVILEGE_LABEL"), UiUtil.SQUARE.getIcon(), SwingConstants.LEFT) {
126             @Override
127             public JToolTip createToolTip() {
128                 return tooltip.get();
129             }
130         };
131         I18nViewUtil.addComponentForKey("PRIVILEGE_LABEL", this.privilege);
132         I18nViewUtil.addComponentForKey(AbstractManagerList.PRIVILEGE_TOOLTIP, tooltip.get());
133         this.privilege.setToolTipText(I18nUtil.valueByKey(AbstractManagerList.PRIVILEGE_TOOLTIP));
134 
135         this.lastLine.add(Box.createHorizontalStrut(5));
136         this.lastLine.add(this.privilege);
137         this.lastLine.add(this.horizontalGlue);
138         this.lastLine.add(this.progressBar);
139         this.lastLine.add(this.run);
140     }
141 
142     /**
143      * Add a new string to the list if it's not a duplicate.
144      * @param element The string to add to the list
145      */
146     public void addToList(String element) {
147         AtomicBoolean isFound = new AtomicBoolean(false);
148 
149         DefaultListModel<ItemList> listModel = (DefaultListModel<ItemList>) this.listPaths.getModel();
150         Iterable<ItemList> iterable = () -> listModel.elements().asIterator();
151         StreamSupport.stream(iterable.spliterator(), false)
152             .filter(itemList -> itemList.toString().equals(element))
153             .forEach(itemList -> isFound.set(true));
154 
155         if (!isFound.get()) {
156             listModel.add(0, new ItemList(element));
157         }
158     }
159     
160     public void highlight(String url, String tag) {
161         var itemLabel = String.format(" [%s]", tag);
162         DefaultListModel<ItemList> listModel = (DefaultListModel<ItemList>) this.listPaths.getModel();
163         for (var i = 0 ; i < listModel.getSize() ; i++) {
164             ItemList itemList = listModel.getElementAt(i);
165             if (url.contains(itemList.getOriginalString())) {
166                 itemList.setVulnerable(true);
167                 itemList.setInternalString(
168                     itemList.getInternalString().replace(itemLabel, StringUtils.EMPTY) + itemLabel
169                 );
170                 listModel.setElementAt(itemList, i);
171             }
172         }
173     }
174     
175     public void endProcess() {
176         SwingUtilities.invokeLater(() -> {  // required to prevent scan glitches
177             this.run.setText(I18nViewUtil.valueByKey(this.labelI18nRunButton));
178             this.setButtonEnable(true);
179             this.progressBar.setVisible(false);
180             this.horizontalGlue.setVisible(true);
181             this.run.setState(StateButton.STARTABLE);
182         });
183     }
184 
185     /**
186      * Enable or disable the button.
187      * @param isEnable The new state of the button
188      */
189     public void setButtonEnable(boolean isEnable) {
190         this.run.setEnabled(isEnable);
191     }
192 
193     /**
194      * Display another icon to the Privilege label.
195      * @param icon The new icon
196      */
197     public void changePrivilegeIcon(Icon icon) {
198         this.privilege.setIcon(icon);
199     }
200 }