Parent: [r11] (diff)

Child: [r23] (diff)

Download this file

pluginSearch.java    468 lines (388 with data), 16.3 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
/*
* SPDXVersion: SPDX-1.1
* Creator: Person: Nuno Brito (nuno.brito@triplecheck.de)
* Creator: Organization: TripleCheck (contact@triplecheck.de)
* Created: 2013-11-08T00:00:00Z
* LicenseName: NOASSERTION
* FileName: pluginSearch.java
* FileType: SOURCE
* FileCopyrightText: <text> Copyright 2013 Nuno Brito, TripleCheck </text>
* FileComment: <text> This plugin takes care of the search operations made
* by the user on the standard User Interface.</text>
*/
package basic;
import definitions.Messages;
import definitions.definition;
import definitions.is;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import main.controller;
import script.Plugin;
import script.log;
import spdxlib.FileInfo;
import spdxlib.SPDXfile;
import ssdeep.SpamSumSignature;
import ssdeep.ssdeep;
import main.core;
import utils.html;
import www.RequestOrigin;
import www.Table;
import www.WebRequest;
/**
*
* @author Nuno Brito, 8th of November 2013 in Darmstadt, Germany.
* nuno.brito@triplecheck.de | http://nunobrito.eu
*/
public class pluginSearch extends Plugin{
// to add an HTML like break
int resultCounter = 0;
// what we will place on the search box
String output = "";
@Override
public void startup(){
log.hooks.addAction(Messages.SearchBoxPressedENTER,
thisFile, "doKeyPress");
log.hooks.addAction(Messages.SearchBoxPressedKey,
thisFile, "doKeyPress");
// whenever a search happens, trigger this method
log.hooks.addAction("Search: %1",
thisFile, "launchNewSearch");
// prepare a smart feature that we love!
prepareFileLauncher();
}
/**
* We use the search bar to launch our internal pages. Might seem hard
* to understand what is the fuzz but we love to type something like
* "server" and see it in front of us right away.
*/
private void prepareFileLauncher(){
// get all the java files that we are ready to launch if needed
ArrayList<File> files = utils.files.findFilesFiltered(core.getPluginsFolder(),
".java", 25);
// we need some filtering
HashMap list = new HashMap();
// go through all the files we found
for(File file : files){
String name = file.getName();
// avoid cases like .java.old
if(name.endsWith(".java")){
// remove the .java portion, transform to lower case
name = name.replace(".java", "").toLowerCase();
// put it on our list, if duplicate just overwrite we don't care
list.put(name, file);
}
}
// place the list available for the future
core.temp.put(definition.searchList, list);
}
/**
* Reacts to the case when users press the ENTER key
*/
void doKeyPress(){
String searchTerm = core.studio.getSearch().getText();
// no need to worry about empty searches or less than two characters
if(searchTerm.length() < 2){
return;
}
// do the search thing
doSearch(searchTerm);
}
/**
* The method that conducts the bulk of our search mechanism. You need to
* specify the textBox instead of using the one at the default UI window so
* that we use this feature in other places where needed in the future
*
* @param searchTerm The term that we want to look for
* @param textBox Where the results will be displayed
*/
private void doSearch(String searchTerm) {
// initial message to give some feedback
log.write(is.INFO, "Performing a search: %1", searchTerm);
// set our counter back to zero again
resultCounter = 0;
output = "";
// long timeStart = System.currentTimeMillis();
// check for internal commands like "help", or else do a normal search
if(internalCommand(searchTerm)==false){
// start by looking at the components
// String matchComponentName =
// searchListSPDX(core.components, searchTerm, "Library");
// look in products now
String matchProductName =
searchListSPDX(core.products, searchTerm, definition.nodeSoftware);
// compile all the results together
output = //matchComponentName
matchProductName;
}
if(resultCounter > 1){
// long timeFinish = System.currentTimeMillis();
// long timeElapsed = timeFinish - timeStart;
// add the grey text with a short summary
output =
html.div()
+ html.br
+ html.textGrey(resultCounter + " results found")
// + utils.time.timeNumberToHumanReadable(timeElapsed)
//+ html.br
//+ html.br
+ html._div
+ output;
}
// // do the final output, everything done
core.studio.editorPane(is.contentHTML, false, 0, output);
}
/**
* Allows to perform the list on a specific list of
* SPDX array files. This is intended to make the distinction
* between the components and products
* @param list
* @param searchTerm
* @param title
* @return
*/
public String searchListSPDX(ArrayList list, String searchTerm,
String title){
String result = "";
String keyword = searchTerm.toLowerCase();
// create the icons that might be displayed on the results
String iconPackage = html.getCommonFolderIcon("box.png");
String iconFile = html.getCommonFolderIcon("document-number.png");
for(Object object : list){
SPDXfile spdx = (SPDXfile) object;
String matchTitle = "";
// first search, find components we have with the same name
String spdxId = spdx.getId().toLowerCase();
if(spdxId.contains(keyword)){
matchTitle = "<i>(Title match)</i>";
resultCounter++;
}
// now look inside the files
ArrayList fileList = processFilters(spdx, searchTerm);
int fileCounter = fileList.size();
// do we have any files to report?
if(fileCounter > 0){
String fileText = "";
int[] size = new int[]{18, 300};
// create the file list
for(Object fileObject : fileList){
FileInfo file = (FileInfo) fileObject;
// do the details about this file
String fileDetails = "";
// add the file size on the details
if(file.tagFileSize != null){
String fileSize = file.tagFileSize.toString();
if(fileSize.contains("(")){
fileSize = fileSize.substring(0,
fileSize.indexOf("(")-1);
fileDetails = fileDetails + fileSize;
}
}
// add the LOC when available
if(file.tagFileLOC !=null){
fileDetails = fileDetails
+ ", "
+ file.tagFileLOC.toString() + " LOC";
}
if(fileDetails.length()>0){
fileDetails = " (" + fileDetails + ")";
}
// the internal hyperlink to read more details
String linkFileUID =
">> "
+ file.tagFileName.toString()
+ " >> "
+ "Files"
+ " >> "
+ spdx.getId()
+ " >> "
+ title
+ " ";
String filePath = "";
if(file.tagFilePath != null){
filePath = " "
+ html.textGrey(file.tagFilePath.toString());
}
String[] params = new String[]{iconFile,
html.linkNode(
file.tagFileName.toString(),
linkFileUID)
+ fileDetails
};
fileText = fileText.concat(
Table.alignedTable(params, size)
// iconFile
// + html.linkNode(
// file.tagFileName.toString(),
// linkFileUID)
+ "<code>" + filePath + "</code>"
+ html.br
+ html.br
);
// file.print();
}
// use correct grammar
String fileDesc = "files";
if(fileCounter == 1){
fileDesc = "file";
}
// the internal hyperlink to read more details
String linkPackageUID =
html.linkNode(spdx.getId(),
">> "
+ spdx.getId()
+ " >> "
+ title
+ " ");
// write out the text for the files
result = result.concat(
iconPackage
+ linkPackageUID
//+ spdx.getId()
+ " <i>("
+ fileCounter
+ " "
+fileDesc
+")</i> "
+ matchTitle
+ html.br
+ html.br
+ "<div style=\"margin-left: 10px;\">"
//+ "<ul>"
+ fileText
//+ "</ul>"
+ "</div>"
+ html.br
);
}
}
// add the title of our search
if(result.length() > 0){
result = html.div()
+ "<h2>"
+ title
+ "</h2>"
//+ html.br
+ result
+ html.br
+ html._div
;
}
return result;
}
/**
* We want to launch a new search and find files that match a given type
* of signature. We use this method to start the initial decision process
* about how the search expression should be treated. For example, if we can
* identify that the search is related to an MD5 signature then we launch
* the technique to find files with an MD5 signature.
*/
void launchNewSearch(){
// update the search box
core.studio.getSearch().setText(core.searchTerm);
core.studio.getSearch().setCaretPosition(0);
// do the hard work now
doSearch(core.searchTerm);
}
/**
* Do the most interesting part of the search
* @param spdx
* @return
*/
ArrayList processFilters(SPDXfile spdx, String originalKeyword){
String keyword = originalKeyword.toLowerCase();
ArrayList result = new ArrayList();
// look for names that match the keyword
if(keyword.startsWith("sha1:")){
// process the SHA1 term
String what = keyword.replace("sha1: ", "");
what = what.replace("sha1:", "");
for(Object fileObject : spdx.fileSection.files){
FileInfo file = (FileInfo) fileObject;
String test = file.tagFileChecksumSHA1.getValue().toLowerCase();
if(test.contains(what)){
result.add(file);
resultCounter++;
}
}
return result;
}
// look for names that match the keyword
if(keyword.startsWith("ssdeep:")){
// process the ssdeep term
String what = originalKeyword.replace("SSDEEP: ", "");
what = what.replace("SSDEEP:", "");
// lowercasetes
what = what.replace("ssdeep:", "");
what = what.replace("ssdeep: ", "");
for(Object fileObject : spdx.fileSection.files){
FileInfo file = (FileInfo) fileObject;
// SSDEEP might not be present on this data object
if(file.tagFileChecksumSSDEEP == null){
continue;
}
// get the SSDEEP signature from this file
String signature = file.tagFileChecksumSSDEEP.raw;
signature = signature.replace("FileChecksum: SSDEEP: ", "");
// comparing the two signatures
ssdeep test = new ssdeep();
int match = test.Compare(new SpamSumSignature(signature),
new SpamSumSignature(what));
// we have a threshold of 50% to match the other file
if(match > 50){
result.add(file);
}
}
return result;
}
// simply look for names that match the keyword
for(Object fileObject : spdx.fileSection.files){
FileInfo file = (FileInfo) fileObject;
String fileName = file.tagFileName.getValue().toLowerCase();
if(fileName.contains(keyword)){
result.add(file);
resultCounter++;
}
}
return result;
}
/**
* Check if this is an internal command or not, in case it is then we write
* the global variable "output" with the result from this query
* @param searchTerm
* @return
*/
private boolean internalCommand(String searchTerm) {
if(searchTerm.equalsIgnoreCase("help")){
File helpFile = new File(thisFolder, "help.html");
System.out.println(helpFile.getAbsoluteFile());
output = utils.files.readAsString(helpFile);
//System.out.println(output);
return true;
}
// check for internal pages we can run
HashMap list =
(HashMap) core.temp.get(definition.searchList);
// no need to continue if empty
if(list == null){
return false;
}
// files matching this search? let's process
if(list.containsKey(searchTerm)){
File file = (File) list.get(searchTerm);
System.err.println("Matched " + searchTerm);
// an action happened and needs a reply
WebRequest request = new WebRequest();
// signal that this request is coming from the user interface
request.requestOrigin = RequestOrigin.GUI;
request.BaseFolder = file.getParentFile();
request.scriptFile = file;
request.scriptMethod = is.methodDefault;
// submit the request to be executed
controller.process(request);
// all done, hope for the best.. :-)
return true;
}
return false;
}
}