From static code scanning engine PMD Source Learning-multithreaded task model and file filtering design

Source: Internet
Author: User

It has been about 4 months since I studied PMD and customized the rules in my work. In fact, PMD has many worthy of my learning source code, but because of time did not have to pen. Today's brief summary of PMD and file filtering design of the source code.

1  Public classMultithreadprocessorextendsAbstractpmdprocessor {2 3     PrivateExecutorservice executor;4     PrivateCompletionservice<report>Completionservice;5     Privatelist<future<report>> tasks =NewArraylist<>();6 7      PublicMultithreadprocessor (Finalpmdconfiguration Configuration) {8         Super(configuration);9 TenExecutor = Executors.newfixedthreadpool (Configuration.getthreads (),Newpmdthreadfactory ()); OneCompletionservice =NewExecutorcompletionservice<>(executor); A     } -  - @Override the     protected voidrunanalysis (pmdrunnable runnable) { -         //multi-threaded execution, dispatch analysis to worker threads - Tasks.add (Completionservice.submit (runnable)); -     } +  - @Override +     protected voidCollectreports (list<renderer>renderers) { A         //Collect result analysis, waiting for termination if needed at         Try { -              for(inti = 0; I < tasks.size (); i++) { -                 FinalReport report =Completionservice.take (). get (); -                 Super. Renderreports (renderers, report); -             } -}Catch(Interruptedexception IE) { in Thread.CurrentThread (). interrupt (); -}Catch(executionexception ee) { toThrowable t =ee.getcause (); +             if(tinstanceofruntimeexception) { -                 Throw(runtimeexception) t; the}Else if(tinstanceofError) { *                 Throw(Error) t; $}Else {Panax Notoginseng                 Throw NewIllegalStateException ("Pmdrunnable exception", T); -             } the}finally { + Executor.shutdownnow (); A         } the     } +}

This is the multithreadprocessor, multithreaded execution class.

The key class is that COMPLETIONSERVICE,PMD uses the Pmdrunnable class that implements the callable interface to encapsulate the specific operation of the thread, overriding it in the call method of this class. Today's core is not the code in call, but the core is the common notation for this type of multithreaded operation for task submissions. Which is the combination of completionservice.

We know that if the callable interface is implemented, the user wants results, and the result is the future object, and the report in the PMD code is the return of call, using the future to generic encapsulation.

Completionservice internally maintains a blockquene queue, passing a executor through executorcompletionservice<>(executor) , That is, a thread pool.

This uses the JDK's own executors.newfixedthreadpool to create a fixed-size thread pool, which is the upper limit.

If you use the callable interface to submit to the pool, returning to the future requires your own management, while the Completionservice can be managed perfectly and should be used every time.

Through completionservice.submit (runnable), submit the callable instance, get the future object, we store through a collection list, But actually our follow-up does not really have to traverse the use of each future.

Note that the submit is for the thread to start.

How do I get the results after the thread runs?

use Completionservice.take (). get (); Gets the result class object that the call method eventually returns. 
Completionservice.take is getting the future object, but this is already an asynchronous operation.
When a thread is started by a submit, the take operation obtains the result of the thread that runs out of the future instance, which is implemented by this service class internal code.
Get the future encapsulated object by Get report
At this point, a series of standard operation, very comfortable.
Next is the filter for the file:
Recently, exclude has been added to PMD. Found his Fileutil class wrote later to do exclude function of the comments ... The 6.x version of the result has not yet come true. Then I did it for half a day or so. (parameter passed in)

In fact, PMD file filtering is based on the filter implementation, but also related to FilenameFilter.
Core from JDK File.list (filenamefilter filter)
1  Public StaticList<datasource>collectfiles (String filelocations, FilenameFilter filenamefilter) {2List<datasource> datasources =NewArraylist<>();3          for(String fileLocation:fileLocations.split (",")) {4 Collect (datasources, filelocation, filenamefilter);5         }6         returndatasources;7     }8 9     Private StaticList<datasource> Collect (list<datasource>datasources, String filelocation,Ten FilenameFilter FilenameFilter) { OneFile File =NewFile (filelocation); A         if(!file.exists ()) { -             Throw NewRuntimeException ("File" + file.getname () + "doesn ' t exist"); -         } the         if(!file.isdirectory ()) { -             if(Filelocation.endswith (". zip") | | filelocation.endswith (". Jar"))) { - ZipFile ZipFile; -                 Try { +ZipFile =NewZipFile (filelocation); -enumeration<?extendsZipentry> e =zipfile.entries (); +                      while(E.hasmoreelements ()) { AZipEntry ZipEntry =e.nextelement (); at                         if(Filenamefilter.accept (NULL, Zipentry.getname ())) { -Datasources.add (NewZipdatasource (ZipFile, ZipEntry)); -                         } -                     } -}Catch(IOException ze) { -                     Throw NewRuntimeException ("Archive file" + file.getname () + "can ' t be opened"); in                 } -}Else { toDatasources.add (Newfiledatasource (file)); +             } -}Else { the             //Match files, or directories which is not excluded. *             //The excluded directories be some configurable option $filter<file> filter =NewOrfilter<>(Filters.tofilefilter (filenamefilter),Panax Notoginseng                     NewAndfilter<>(Filters.getdirectoryfilter (), Filters.tonormalizedfilefilter ( -Filters.buildregexfilterexcludeoverinclude (NULL, Collections.singletonlist ("SCCS"))))); theFilefinder Finder =NewFilefinder (); +list<file> files = Finder.findfilesfrom (File, Filters.tofilenamefilter (filter),true); A              for(File f:files) { theDatasources.add (NewFiledatasource (f)); +             } -         } $         returndatasources; $}

This is the core code of PMD to collect. DataSource is actually a class that the file encapsulates again.

Collectfiles This method is to pass in the source path, a directory, a file path.
then pass in a filter class FilenameFilter, in the PMD current implementation is directly passed in the language code language to do the suffix extension extension filtering filenamefilter,
The last is to pass in a collection, that is, to do the encapsulated box.
Because the path parameters are comma-delimited, the traversal is done first, and then the Collect method is called for each path.
Next is the core, collect passes in a filenamefilter, and then filters the file under this path.
in fact, it is also simple implementation.
and then go back, what if I want to add a filter directory function? It seems I can pass in the main code of a exclude filenamefilter, in fact it this collect return datasource, is not conducive to re-analysis.
In other words, this code does not really have the possibility of backwards compatibility.
since the author of Pmd, who wrote dead, I will make a slight change.
The essence of filter is actually orfilter and andfilter this kind, understanding is very simple, a orfilter to maintain a filter list, as long as there is a return true, then return True
The filter's list is maintained in the Andfilter, and all returns True to return true. I remember that Apache Commons also has a similar IO file filter class.
In the future if you want to do this function, you can also use the Apache package.
In fact, filter is also very simple, so much.

From static code scanning engine PMD Source Learning-multithreaded task model and file filtering design

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.