Full Code of vipshop/vjtools for AI

master 2f780edd504e cached
317 files
1022.4 KB
319.6k tokens
2264 symbols
1 requests
Download .txt
Showing preview only (1,122K chars total). Download the full file or copy to clipboard to get everything.
Repository: vipshop/vjtools
Branch: master
Commit: 2f780edd504e
Files: 317
Total size: 1022.4 KB

Directory structure:
gitextract_3z1lwxqk/

├── .gitignore
├── .travis.yml
├── LICENSE.txt
├── README.md
├── docs/
│   ├── .nojekyll
│   ├── README.md
│   ├── _coverpage.md
│   ├── _sidebar.md
│   ├── index.html
│   ├── other/
│   │   └── othertools.md
│   └── standard/
│       ├── README.md
│       ├── _sidebar.md
│       ├── ali.md
│       ├── chapter01.md
│       ├── chapter02.md
│       ├── chapter03.md
│       ├── chapter04.md
│       ├── chapter05.md
│       ├── chapter06.md
│       ├── chapter07.md
│       ├── chapter08.md
│       ├── chapter09.md
│       ├── chapter10.md
│       ├── chapter11.md
│       ├── chapter12.md
│       ├── merge.bat
│       └── merge.sh
├── pom.xml
├── standard/
│   ├── README.md
│   ├── formatter/
│   │   ├── README.md
│   │   ├── vjtools-code-conventions-eclipse.xml
│   │   └── vjtools-code-conventions-idea.xml
│   └── sonar-vj/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── com/
│               │       └── vip/
│               │           └── vjkit/
│               │               └── sonarvj/
│               │                   ├── SonarCheckRegistrar.java
│               │                   ├── SonarDefinition.java
│               │                   ├── SonarPlugin.java
│               │                   ├── SonarRulesList.java
│               │                   └── checks/
│               │                       ├── BadConstantNameCheck.java
│               │                       ├── CatchUsesExceptionWithContextCheck.java
│               │                       ├── HardcodedIpCheck.java
│               │                       ├── MissingCurlyBracesCheck.java
│               │                       ├── NoSonarCheck.java
│               │                       ├── OperatorPrecedenceCheck.java
│               │                       ├── UnusedMethodParameterCheck.java
│               │                       └── UnusedPrivateFieldCheck.java
│               └── resources/
│                   └── com/
│                       └── vip/
│                           └── java/
│                               └── rules/
│                                   ├── S1068_java.html
│                                   ├── S1068_java.json
│                                   ├── S115_java.html
│                                   ├── S115_java.json
│                                   ├── S1166_java.html
│                                   ├── S1166_java.json
│                                   ├── S1172_java.html
│                                   ├── S1172_java.json
│                                   ├── S121_java.html
│                                   ├── S121_java.json
│                                   ├── S1291_java.html
│                                   ├── S1291_java.json
│                                   ├── S1313_java.html
│                                   ├── S1313_java.json
│                                   ├── S864_java.html
│                                   └── S864_java.json
├── vjdump/
│   ├── README.md
│   ├── README_EN.md
│   └── vjdump.sh
├── vjkit/
│   ├── README.md
│   ├── docs/
│   │   ├── data_masking.md
│   │   └── direct_3rd.md
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── vip/
│       │   │           └── vjtools/
│       │   │               └── vjkit/
│       │   │                   ├── base/
│       │   │                   │   ├── BooleanUtil.java
│       │   │                   │   ├── EnumUtil.java
│       │   │                   │   ├── ExceptionUtil.java
│       │   │                   │   ├── MoreValidate.java
│       │   │                   │   ├── ObjectUtil.java
│       │   │                   │   ├── Platforms.java
│       │   │                   │   ├── PropertiesUtil.java
│       │   │                   │   ├── RuntimeUtil.java
│       │   │                   │   ├── SystemPropertiesUtil.java
│       │   │                   │   ├── ValueValidator.java
│       │   │                   │   ├── annotation/
│       │   │                   │   │   ├── NotNull.java
│       │   │                   │   │   ├── Nullable.java
│       │   │                   │   │   └── VisibleForTesting.java
│       │   │                   │   └── type/
│       │   │                   │       ├── CloneableException.java
│       │   │                   │       ├── CloneableRuntimeException.java
│       │   │                   │       ├── Pair.java
│       │   │                   │       ├── Triple.java
│       │   │                   │       └── UncheckedException.java
│       │   │                   ├── collection/
│       │   │                   │   ├── ArrayUtil.java
│       │   │                   │   ├── CollectionUtil.java
│       │   │                   │   ├── ListUtil.java
│       │   │                   │   ├── MapUtil.java
│       │   │                   │   ├── QueueUtil.java
│       │   │                   │   ├── SetUtil.java
│       │   │                   │   └── type/
│       │   │                   │       ├── ConcurrentHashSet.java
│       │   │                   │       ├── MoreLists.java
│       │   │                   │       ├── MoreMaps.java
│       │   │                   │       ├── MoreQueues.java
│       │   │                   │       ├── SortedArrayList.java
│       │   │                   │       └── primitive/
│       │   │                   │           ├── IntObjectHashMap.java
│       │   │                   │           ├── IntObjectMap.java
│       │   │                   │           ├── LongObjectHashMap.java
│       │   │                   │           └── LongObjectMap.java
│       │   │                   ├── concurrent/
│       │   │                   │   ├── Concurrents.java
│       │   │                   │   ├── ThreadDumpper.java
│       │   │                   │   ├── ThreadUtil.java
│       │   │                   │   ├── jsr166e/
│       │   │                   │   │   ├── LongAdder.java
│       │   │                   │   │   └── Striped64.java
│       │   │                   │   ├── limiter/
│       │   │                   │   │   ├── RateLimiterUtil.java
│       │   │                   │   │   ├── Sampler.java
│       │   │                   │   │   └── TimeIntervalLimiter.java
│       │   │                   │   ├── threadpool/
│       │   │                   │   │   ├── AbortPolicyWithReport.java
│       │   │                   │   │   ├── QueuableCachedThreadPool.java
│       │   │                   │   │   ├── ThreadPoolBuilder.java
│       │   │                   │   │   └── ThreadPoolUtil.java
│       │   │                   │   └── type/
│       │   │                   │       ├── BasicFuture.java
│       │   │                   │       └── ThreadLocalContext.java
│       │   │                   ├── datamasking/
│       │   │                   │   ├── DataMask.java
│       │   │                   │   ├── DataMaskJsonFilter.java
│       │   │                   │   ├── MaskMapping.java
│       │   │                   │   ├── MaskStrategy.java
│       │   │                   │   ├── Sensitive.java
│       │   │                   │   ├── SensitiveType.java
│       │   │                   │   └── strategy/
│       │   │                   │       ├── EmailMask.java
│       │   │                   │       ├── HashMask.java
│       │   │                   │       ├── NameMask.java
│       │   │                   │       └── PartMask.java
│       │   │                   ├── id/
│       │   │                   │   └── IdUtil.java
│       │   │                   ├── io/
│       │   │                   │   ├── FilePathUtil.java
│       │   │                   │   ├── FileTreeWalker.java
│       │   │                   │   ├── FileUtil.java
│       │   │                   │   ├── IOUtil.java
│       │   │                   │   ├── ResourceUtil.java
│       │   │                   │   ├── URLResourceUtil.java
│       │   │                   │   └── type/
│       │   │                   │       └── StringBuilderWriter.java
│       │   │                   ├── logging/
│       │   │                   │   └── PerformanceUtil.java
│       │   │                   ├── mapper/
│       │   │                   │   ├── BeanMapper.java
│       │   │                   │   ├── JsonMapper.java
│       │   │                   │   └── XmlMapper.java
│       │   │                   ├── net/
│       │   │                   │   ├── IPUtil.java
│       │   │                   │   └── NetUtil.java
│       │   │                   ├── number/
│       │   │                   │   ├── MathUtil.java
│       │   │                   │   ├── MoneyUtil.java
│       │   │                   │   ├── NumberUtil.java
│       │   │                   │   ├── RandomUtil.java
│       │   │                   │   ├── SizeUnit.java
│       │   │                   │   └── UnitConverter.java
│       │   │                   ├── reflect/
│       │   │                   │   ├── AnnotationUtil.java
│       │   │                   │   ├── ClassLoaderUtil.java
│       │   │                   │   ├── ClassUtil.java
│       │   │                   │   └── ReflectionUtil.java
│       │   │                   ├── security/
│       │   │                   │   └── CryptoUtil.java
│       │   │                   ├── text/
│       │   │                   │   ├── Charsets.java
│       │   │                   │   ├── CsvUtil.java
│       │   │                   │   ├── EncodeUtil.java
│       │   │                   │   ├── EscapeUtil.java
│       │   │                   │   ├── HashUtil.java
│       │   │                   │   ├── MoreStringUtil.java
│       │   │                   │   ├── StringBuilderHolder.java
│       │   │                   │   ├── TextValidator.java
│       │   │                   │   └── WildcardMatcher.java
│       │   │                   └── time/
│       │   │                       ├── CachingDateFormatter.java
│       │   │                       ├── ClockUtil.java
│       │   │                       ├── DateFormatUtil.java
│       │   │                       └── DateUtil.java
│       │   └── resources/
│       │       └── sys_data_mask.properties
│       └── test/
│           ├── java/
│           │   └── com/
│           │       └── vip/
│           │           └── vjtools/
│           │               ├── test/
│           │               │   ├── data/
│           │               │   │   └── RandomData.java
│           │               │   ├── log/
│           │               │   │   ├── LogbackListAppender.java
│           │               │   │   └── LogbackListAppenderTest.java
│           │               │   └── rule/
│           │               │       └── TestProgress.java
│           │               └── vjkit/
│           │                   ├── base/
│           │                   │   ├── BooleanUtilTest.java
│           │                   │   ├── EnumUtilTest.java
│           │                   │   ├── ExceptionUtilTest.java
│           │                   │   ├── MoreValidateTest.java
│           │                   │   ├── ObjectUtilTest.java
│           │                   │   ├── PairTest.java
│           │                   │   ├── PlatformsTest.java
│           │                   │   ├── PropertiesUtilTest.java
│           │                   │   ├── RuntimeUtilTest.java
│           │                   │   ├── SystemPropertiesUtilTest.java
│           │                   │   └── ValueValidatorTest.java
│           │                   ├── collection/
│           │                   │   ├── ArrayUtilTest.java
│           │                   │   ├── CollectionUtilTest.java
│           │                   │   ├── ListUtilTest.java
│           │                   │   ├── MapUtilTest.java
│           │                   │   ├── QueueUtilTest.java
│           │                   │   ├── SetUtilTest.java
│           │                   │   └── type/
│           │                   │       ├── ConcurrentHashSetTest.java
│           │                   │       └── SortedArrayListTest.java
│           │                   ├── concurrent/
│           │                   │   ├── ConcurrentsTest.java
│           │                   │   ├── ThreadDumpperTest.java
│           │                   │   ├── ThreadUtilTest.java
│           │                   │   ├── limiter/
│           │                   │   │   ├── RateLimiterUtilTest.java
│           │                   │   │   ├── SamplerTest.java
│           │                   │   │   └── TimeIntervalLimiterTest.java
│           │                   │   ├── threadpool/
│           │                   │   │   ├── AbortPolicyWithReportTest.java
│           │                   │   │   ├── QueuableCachedThreadPoolTest.java
│           │                   │   │   ├── ThreadPoolBuilderTest.java
│           │                   │   │   └── ThreadPoolUtilTest.java
│           │                   │   └── type/
│           │                   │       ├── BasicFutureTest.java
│           │                   │       └── ThreadLocalContextTest.java
│           │                   ├── datamasking/
│           │                   │   ├── DataMaskJsonFilterTest.java
│           │                   │   ├── DataMaskTest.java
│           │                   │   ├── MaskMappingTest.java
│           │                   │   ├── data/
│           │                   │   │   ├── TestChild.java
│           │                   │   │   ├── TestData.java
│           │                   │   │   ├── TestParent.java
│           │                   │   │   └── TestUserMapingData.java
│           │                   │   └── strategy/
│           │                   │       ├── EmailMaskTest.java
│           │                   │       ├── HashMaskTest.java
│           │                   │       ├── NameMaskTest.java
│           │                   │       └── PartMaskTest.java
│           │                   ├── id/
│           │                   │   └── IdUtilTest.java
│           │                   ├── io/
│           │                   │   ├── FilePathUtilTest.java
│           │                   │   ├── FileTreeWalkerTest.java
│           │                   │   ├── FileUtilTest.java
│           │                   │   ├── IOUtilTest.java
│           │                   │   ├── ResourceUtilTest.java
│           │                   │   └── URLResourceTest.java
│           │                   ├── logging/
│           │                   │   └── PerformanceUtilsTest.java
│           │                   ├── mapper/
│           │                   │   ├── BeanMapperTest.java
│           │                   │   ├── JsonMapperTest.java
│           │                   │   └── XmlMapperTest.java
│           │                   ├── net/
│           │                   │   ├── IPUtilTest.java
│           │                   │   └── NetUtilTest.java
│           │                   ├── number/
│           │                   │   ├── MathUtilTest.java
│           │                   │   ├── MoneyUtilTest.java
│           │                   │   ├── NumberUtilTest.java
│           │                   │   ├── RandomUtilTest.java
│           │                   │   └── UnitConverterTest.java
│           │                   ├── reflect/
│           │                   │   ├── ClassUtilTest.java
│           │                   │   ├── ClassloaderUtilTest.java
│           │                   │   └── ReflectionUtilTest.java
│           │                   ├── security/
│           │                   │   └── CryptoUtilTest.java
│           │                   ├── text/
│           │                   │   ├── CsvUtilTest.java
│           │                   │   ├── EncodeUtilTest.java
│           │                   │   ├── EscapeUtilTest.java
│           │                   │   ├── HashUtilTest.java
│           │                   │   ├── MoreStringUtilTest.java
│           │                   │   ├── StringBuilderHolderTest.java
│           │                   │   ├── TextValidatorTest.java
│           │                   │   └── WildcardMatcherTest.java
│           │                   └── time/
│           │                       ├── CachingDatFormatterTest.java
│           │                       ├── ClockUtilTest.java
│           │                       ├── DateFormatUtilTest.java
│           │                       └── DateUtilTest.java
│           └── resources/
│               ├── application.properties
│               ├── data_mask.properties
│               ├── logback-test.xml
│               └── test.txt
├── vjmap/
│   ├── README.md
│   ├── README_EN.md
│   ├── pom.xml
│   └── src/
│       └── main/
│           ├── assembly/
│           │   ├── distribution.xml
│           │   ├── vjmap.bat
│           │   └── vjmap.sh
│           └── java/
│               └── com/
│                   └── vip/
│                       └── vjtools/
│                           └── vjmap/
│                               ├── ClassStats.java
│                               ├── ResultPrinter.java
│                               ├── VJMap.java
│                               ├── oops/
│                               │   ├── GenAddressAccessor.java
│                               │   ├── HeapHistogramVisitor.java
│                               │   ├── HeapUtils.java
│                               │   ├── LoadedClassAccessor.java
│                               │   ├── OldgenAccessor.java
│                               │   └── SurvivorAccessor.java
│                               └── utils/
│                                   ├── FormatUtils.java
│                                   ├── ProgressNotifier.java
│                                   └── TimeController.java
├── vjmxcli/
│   ├── README.md
│   ├── pom.xml
│   └── src/
│       └── main/
│           ├── assembly/
│           │   ├── distribution.xml
│           │   ├── vjmxcli.bat
│           │   └── vjmxcli.sh
│           └── java/
│               └── com/
│                   └── vip/
│                       └── vjtools/
│                           └── jmx/
│                               ├── Client.java
│                               ├── ExtraCommand.java
│                               └── GCutilExpression.java
├── vjstar/
│   ├── README.md
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── vip/
│       │   │           └── vjstar/
│       │   │               ├── .gitkeep
│       │   │               ├── gc/
│       │   │               │   ├── CleanUpScheduler.java
│       │   │               │   └── ProactiveGcTask.java
│       │   │               └── window/
│       │   │                   ├── AtomicBitSet.java
│       │   │                   ├── RequestSlidingWindow.java
│       │   │                   └── TimeSlidingWindow.java
│       │   └── script/
│       │       ├── docker-cpus/
│       │       │   └── README.md
│       │       └── jvm-options/
│       │           └── jvm-options.sh
│       └── test/
│           └── java/
│               └── com/
│                   └── vip/
│                       └── vjstar/
│                           ├── .gitkeep
│                           ├── gc/
│                           │   ├── Enchanter.java
│                           │   └── ProactiveGcTaskDemo.java
│                           └── window/
│                               ├── RequestSlidingWindowTest.java
│                               └── TimeSlidingWindowTest.java
└── vjtop/
    ├── README.md
    ├── README_EN.md
    ├── pom.xml
    └── src/
        ├── main/
        │   ├── assembly/
        │   │   ├── distribution.xml
        │   │   ├── vjtop.bat
        │   │   └── vjtop.sh
        │   └── java/
        │       └── com/
        │           └── vip/
        │               └── vjtools/
        │                   └── vjtop/
        │                       ├── InteractiveTask.java
        │                       ├── ThreadPrinter.java
        │                       ├── TopThreadInfo.java
        │                       ├── VJTop.java
        │                       ├── VMDetailView.java
        │                       ├── VMInfo.java
        │                       ├── WarningRule.java
        │                       ├── data/
        │                       │   ├── PerfData.java
        │                       │   ├── ProcFileData.java
        │                       │   └── jmx/
        │                       │       ├── JmxBufferPoolManager.java
        │                       │       ├── JmxClient.java
        │                       │       ├── JmxGarbageCollectorManager.java
        │                       │       └── JmxMemoryPoolManager.java
        │                       └── util/
        │                           ├── Formats.java
        │                           ├── LongObjectHashMap.java
        │                           ├── LongObjectMap.java
        │                           ├── OptionAdvanceParser.java
        │                           ├── SelectPid.java
        │                           └── Utils.java
        └── test/
            └── java/
                └── com/
                    └── vip/
                        └── vjtools/
                            └── vjtop/
                                └── util/
                                    ├── FormatsTest.java
                                    └── UtilsTest.java

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Eclipse project files
.classpath
.project
.settings/

# Intellij project files
*.iml
.idea/

# Otherse
*.log
target/

vip-java-standard.md
release.sh
vjmap/vjmap/
vjtop/vjtop/
vjmxcli/vjmxcli


================================================
FILE: .travis.yml
================================================
language: java

jdk:
  - openjdk9

branches:
  only:
    - master

script: mvn clean package


================================================
FILE: LICENSE.txt
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [2006-2012] [www.springside.org.cn]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
![VJTools](/docs/images/logo.jpg) [![Build Status](https://travis-ci.org/vipshop/vjtools.svg?branch=master)](https://travis-ci.org/vipshop/vjtools) 


主力于Java的唯品会,关于Java的一些小家底。 

各位看官看着是好的,烦请“Star”。

[1.0.8版](https://github.com/vipshop/vjtools/releases/tag/v.1.0.8) - 2018.9.24

## Java Standard

| Project | Description |
| -------- | -------- |
| [standard](https://vipshop.github.io/vjtools/#/standard/) | 唯品会Java开发手册 |
| [code formatter](/standard/formatter) | IDE格式化模板 |
| [sonar rule](/standard/sonar-vj) | Sonar规则定制示例 |


## Java Core Library

| Project | Description |
| -------- | -------- |
| [vjkit](/vjkit) | 关于文本,集合,并发等基础功能的核心类库 |
| [vjstar](/vjstar) | 关于后端应用的性能、可用性的最佳实践 |


## Java Tools

| Project | Description | Manual |
| -------- | -------- | -------- |
| [vjtop](/vjtop)  | 观察JVM进程指标及其繁忙线程 | [Chinese](/vjtop/README.md)|
| [vjmap](/vjmap)  | JMAP的分代打印版 |[Chinese](/vjmap/README.md)|
| [vjdump](/vjdump)  | 线上紧急收集JVM数据脚本 | [Chinese](/vjdump/README.md), [English](/vjdump/README_EN.md)|
| [vjmxcli](/vjmxcli)  | JMX 查看工具 | [Chinese](/vjmxcli/README.md)|

视频:[《VJTools如何利用佛性技术玩转JVM》](http://kai.vkaijiang.com/product/course?courseID=120897)

文档:[《入门科普,围绕JVM的各种外挂技术》](https://mp.weixin.qq.com/s/cwU2rLOuwock048rKBz3ew)

其他直接使用的工具,见[常用工具](docs/other/othertools.md)


## Contributing

VJTools官方微信讨论群,请搜索微信号viptech128(唯技术),添加好友后加入。

所有报Bug、建议与咨询,请在[Issues](https://github.com/vipshop/vjtools/issues)发起;所有代码提交,请走[Pull Request](https://github.com/vipshop/vjtools/pulls)流程。

对于优秀的代码提交和建议,唯品会将不吝发挥电商本色,给予[vip.com](https://www.vip.com)购物卡的奖励 !!!


## Developers

唯品会团队: [江南白衣](http://calvin1978.blogcn.com), [郑德惠](https://github.com/zhengdehui), [黄云斌](https://github.com/huangyunbin), [梁耀曾](https://github.com/AJ-Liang), [林铭恺](https://github.com/acxlam), [李炫彬](https://github.com/lixuanbin) , [张晓玲](https://github.com/hjzhangxiaoling)

曾经一起战斗: [杨镌颖@阿里](https://github.com/yangjuanying), 陈维治@阿里


================================================
FILE: docs/.nojekyll
================================================


================================================
FILE: docs/README.md
================================================
All about java in vip.com

- Standard
- Core Libraries
- Tools

================================================
FILE: docs/_coverpage.md
================================================

![VJTools](images/logo2.png)

- Standard
- Core Libraries
- Tools

[GitHub Project](https://github.com/vipshop/vjtools)
[Java Coding Guidelines](standard/)


================================================
FILE: docs/_sidebar.md
================================================
- [GitHub Project](https://github.com/vipshop/vjtools)
- [Java Coding Guidelines](standard/)


================================================
FILE: docs/index.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>VJTools</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
    <meta name="keywords" content="java,coding standard,java开发规范">
    <meta name="description" content="vip.com‘ java coding standard and guidelines">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
</head>
<body>
<div id="app"></div>
<script>
    window.$docsify = {
        name: 'VJTools',
        auto2top: true,
        coverpage: true,
        executeScript: true,
        loadSidebar: true,
        loadNavbar: false,
        mergeNavbar: true,
        maxLevel: 4,
        subMaxLevel: 3,
        search: {
            noData: {
                '/standard/': '没有结果!',
                '/': 'No results!'
            },
            paths: 'auto',
            placeholder: {
                '/standard/': '搜索',
                '/': 'Search'
            }
        },
    }
</script>
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-java.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/search.js"></script>
<script type="text/javascript" src="//js.users.51.la/19520351.js"></script>
</body>
</html>


================================================
FILE: docs/other/othertools.md
================================================
# 1.问题排查

## BTrace 系

- [btrace](https://github.com/btraceio/btrace)
- [greys](https://github.com/oldmanpushcart/greys-anatomy) 交互式免脚本,比btrace更易用

[Java神器Btrace,从入门到熟练小工手册](https://mp.weixin.qq.com/s/4bZ6iSvpqPsjdvkSoFVhrg)

## 在线日志分析

- [easygc.io](http://www.gceasy.io/) gc日志分析
- [fastthread.io](http://fastthread.io/) thread dump分析

## HeapDump分析

- [Eclipse MAT](https://www.eclipse.org/mat/)

# 2.性能Profile

- [Java Mission Control](http://www.oracle.com/technetwork/java/javaseproducts/mission-control/index.html) JDK自带Profiler
- [async-profiler](https://github.com/jvm-profiling-tools/async-profiler) 火焰图生成工具

================================================
FILE: docs/standard/README.md
================================================
# 《唯品会Java开发手册》1.0.3版

## 1. 概述

[《阿里巴巴Java开发手册》](https://github.com/alibaba/p3c),是首个对外公布的企业级Java开发手册,对整个业界都有重要的意义。

我们结合唯品会的内部经验,参考《Clean Code》、《Effective Java》等重磅资料,增补了一些条目,也做了些精简。

感谢阿里授权我们定制和再发布。


## 2. 规范正文

1. [命名规约](standard/chapter01.md)
2. [格式规约](standard/chapter02.md)
3. [注释规约](standard/chapter03.md)
4. [方法设计](standard/chapter04.md)
5. [类设计](standard/chapter05.md)
6. [控制语句](standard/chapter06.md)
7. [基本类型](standard/chapter07.md)
8. [集合处理](standard/chapter08.md)
9. [并发处理](standard/chapter09.md)
10. [异常处理](standard/chapter10.md)
11. [日志规约](standard/chapter11.md)
12. [其他设计](standard/chapter12.md)


注意: 如需全文pdf版,请下载源码,在docs/standard/目录运行merge.sh生成。

## 3. 规范落地

规则落地主要依靠代码格式模版与[Sonar代码规则检查](https://www.sonarqube.org/)。

其中Sonar规则不如人意的地方,我们进行了定制。

* [Eclipse/Intellij 格式模板](https://github.com/vipshop/vjtools/tree/master/standard/formatter)
* [Sonar 规则修改示例](https://github.com/vipshop/vjtools/tree/master/standard/sonar-vj)

## 4. 参考资料

* [《Clean Code》](https://book.douban.com/subject/4199741/)
* [《Effective Java 2nd》](https://book.douban.com/subject/3360807/)
* [《SEI CERT Oracle Coding Standard for Java》(在线版)](https://www.securecoding.cert.org/confluence/display/java/SEI+CERT+Oracle+Coding+Standard+for+Java)
* [Sonar Java Rules](https://rules.sonarsource.com/java/)

## 5. 定制记录

* [《唯品会Java开发手册》-与阿里手册的比较文学I](http://calvin1978.blogcn.com/?p=1771)
* [阿里手册的增补与删减记录](standard/ali.md)


================================================
FILE: docs/standard/_sidebar.md
================================================
- [命名规约](standard/chapter01.md)
- [格式规约](standard/chapter02.md)
- [注释规约](standard/chapter03.md)
- [方法设计](standard/chapter04.md)
- [类设计](standard/chapter05.md)
- [控制语句](standard/chapter06.md)
- [基本类型](standard/chapter07.md)
- [集合处理](standard/chapter08.md)
- [并发处理](standard/chapter09.md)
- [异常处理](standard/chapter10.md)
- [日志规约](standard/chapter11.md)
- [其他设计](standard/chapter12.md)
- [定制记录](standard/ali.md)


================================================
FILE: docs/standard/ali.md
================================================
# 《阿里Java开发手册》定制纪录

只记录较大的改动,对更多条目内容的重新组织与扩写,则未一一冗述。

* [《唯品会Java开发手册》-与阿里手册的比较文学I](http://calvin1978.blogcn.com/?p=1771)


## (一) 命名规约

对应 [阿里规范《命名风格》一章](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/编程规约/命名风格.md)


| VIP 规范 | 阿里规范 | 修改|
| -------- | -------- |-------- |
| 13. 变量、参数重名覆盖|  |新增规则|
| 1. 禁止拼音缩写 | 2. 严禁使用拼音与英文混合的方式 |改写规则|
| 3. 禁用其他编程语言风格的前缀和后缀 | 1. 代码中的命名均不能以下划线或美元符号开始| 扩写规则,把其他语言的啰嗦都禁止掉|
| 4. 命名的好坏,在于其“模糊度”| 11. 为了达到代码自解释的目标 | 扩写规则,参考《Clean Code》的更多例子|
| 6. 常量命名全部大写| 5.常量名大写| 扩写规则|
| | 7. 类型与中括号紧挨相连来定义数组 | 删除规则,非命名风格,也不重要|
| | 13. 接口类中的方法和成员变量不要加任何修饰符号| 移动规则,非命名风格,移到类设计|
| | 16. 各层命名规约| 删除规则,各公司有自己的习惯|

----

## (二) 格式规约


对应 [阿里规范《代码格式》一章](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/编程规约/代码格式.md)

| VIP 规范 | 阿里规范 | 修改|
| -------- | -------- |-------- |
| 1. 项目组统一的代码格式模板| 规则1-8 | 用IDE模版代替逐条描述<br/>同时对Tab/空格不做硬性规定|
| 3. 用小括号来限定运算优先级| | 新增规则|
| 4. 类内方法定义的顺序| | 新增规则|
| 5. 通过空行进行逻辑分段| 11. 不同逻辑、不同语义| 改写规则|
| 6. 避免IDE格式化| | 新增规则|
| | 10.单个方法行数不超过80行| 删除规则,非格式规约,移动方法设计|
| | 11.没有必要增加若干空格来对齐| 删除规则,现在很少人这么做|

----

## (三) 注释规约

对应 [阿里规范《注释规约》一章](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/编程规约/注释规约.md)

| VIP 规范 | 阿里规范 | 修改|
| -------- | -------- |-------- |
| 2. 删除空注释,无意义注释| |增加规则|
| 7. JavaDoc中不要大量使用HTML标签和转义字符 | | 增加规则|
| 1. 注释的基本要求| 9. 对于注释的要求|扩写规则|
| 4.避免创建人的注释 | 3.所有的类都必须添加创建者| 冲突规则|
| | 2.所有的抽象方法必须用Javadoc注释| 删除规则,因为规则2不强制,并入规则1 |
| | 4.方法内部单行注释,使用//注释| 删除规则,区别不大不强求 |
| | 5. 所有的枚举类型字段必须要有注释|删除规则,因为规则2不强制|



----

## (四) 方法设计


* 规则 6,7,12,13 从[阿里规范《控制语句》一章](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/编程规约/控制语句.md) 移入
* 规则 9 从[阿里规范《异常处理》一章](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/异常日志/异常处理.md) 移入
* 规则1,2,3,4,5,8,10,11,14为新建规则

----

## (五) 类设计

对应 [阿里规范《OOP规范》一章](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/编程规约/OOP规范.md)

| VIP 规范 | 阿里规范 | 修改|
| -------- | -------- |-------- |
|2.减少类之间的依赖 | |增加规则|
|3.定义变量与方法参数时,尽量使用接口 | |增加规则|
|4.类的长度度量 | |增加规则|
|5.Builder模式 | |增加规则|
|8.静态方法不能被覆写 | |增加规则|
|9.静态方法的访问原则 | |扩写规则|
|10.内部类原则 | |增加规则|
|12-14.hashCode,equals,toString的规则 | |增加规则|
|16.总是移除无用属性、方法与参数 | |增加规则|
|18.【推荐】得墨忒耳法则 | |增加规则|
| | 3. 提倡同学们尽量不用可变参数编程|删除规则|
| | 9. 定义DO/DTO/VO等POJO类时,不要设定任何属性默认值|删除规则|
| | 10. 序列化类新增属性时,请不要修改serialVersionUID字段|删除规则|
| | 13. 使用索引访问用String的split方法时|删除规则|
| | 19. 慎用Object的clone方法来拷贝对象|删除规则|
| | 规则4,5 |移到《方法规约》|
| | 规则6 |移到《通用设计》|
| | 规则7,8,17 |移到《基础类型》|
| | 规则14,15|移到《格式规约》|

----

## (六) 控制语句

对应 [阿里规范《控制语句》一章](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/编程规约/控制语句.md)

| VIP 规范 | 阿里规范 | 修改|
| -------- | -------- |-------- |
|4.布尔表达式中的运算符个数不超过4个 | |扩写规则|
|5.善用三目运算符 | |增加规则|
|6.能造成短路概率较大的逻辑放前面 | |增加规则|
|10.能用while循环实现的代码,就不用do-while循环 | |增加规则|
| | 3. 在高并发场景中,避免使用 ”等于”作为条件|删除规则|
| | 8. 接口入参保护|删除规则|
| | 9. 下列情形,需要进行参数校验|移到《方法规约》|
| | 10. 下列情形,不需要进行参数校|移到《方法规约》|

----

## (七) 基本类型与字符串

* 规则1,3 从 阿里规范[《OOP规范》](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/编程规约/OOP规范.md)移入,并对2进行扩写
* 规则5 从 阿里规范[《常量定义》](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/编程规约/常量定义.md)移入并扩写
* 规则8 从 阿里规范[《其他》](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/异常日志/其他.md)移入
* 规则4,6,7为新建规则

----

## (八) 集合处理

对应 [阿里规范《集合处理》一章](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/编程规约/集合处理.md)

| VIP 规范 | 阿里规范 | 修改|
| -------- | -------- |-------- |
| 2. foreach语法遍历| |增加规则|
| 7. 长生命周期的集合| |增加规则|
| 8. 并发集合| |增加规则|
| 9. 泛型的通配符| |增加规则|
| 10. `List, List<?>` 与 `List<Object>`的选择| |增加规则|
| 11. EnumMap| |增加规则|
| | 2. ArrayList的subList结果|删除规则|
| | 6. 泛型通配符|删除规则|
| | 12.合理利用好集合的有序性|删除规则|
| | 13.利用Set元素唯一的特性|删除规则|
|12.Array 与 List互转的|使用集合转数组的方法,必须使用集合的toArray|某位老大的测试,new String[0]也不错|

----

## (九) 并发处理: 并发与多线程

对应 [阿里规范《并发处理》一章](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/编程规约/并发处理.md)

| VIP 规范 | 阿里规范 | 修改|
| -------- | -------- |-------- |
|1. 指定线程名 | |扩写规则|
|4. 正确停止线程 | |扩写规则|
|5. 编写可中断的Runnable| |增加规则|
|6. Runnable中必须捕获一切异常 |9.多线程并行处理定时任务 |扩写规则|
|7. 全局变量的线程安全 | |扩写规则|
|10. 选择分离锁, 分散锁甚至无锁的数据结构| |增加规则|
|13. volatile修饰符,AtomicXX系列的正确使用 | |扩写规则|
| |8.并发修改同一记录时,需要加锁 |删除规则|
| |10.使用CountDownLatch进行异步转同步操作 |删除规则|
| |14.HashMap在容量不够进行resize|移到《集合规约》一章|
|14. 延时初始化的正确写法 |12.双重检查锁 |冲突规则|

----

## (十) 异常处理

对应 [阿里规范《异常处理》一章](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/异常日志/异常处理.md)


| VIP 规范 | 阿里规范 | 修改|
| -------- | -------- |-------- |
|2.在特定场合,避免每次构造异常| |增加规则|
|5.异常抛出的原则| |增加规则|
|6.异常捕获的原则| |增加规则|
|7.异常处理的原则| |增加规则|
| |8.捕获异常与抛异常,必须是完全匹配 |删除规则|
| |12.对于公司外的开放接口必须使用“错误码” |删除规则|
| |13.DRY原则 |删除规则,为什么会出现在这章,太著名了|
| |9.返回值可以为null |移到《方法设计》一章|
| |10. 【推荐】防止NPE,是程序员的基本修养 |拆开到各章|
| |11.避免直接抛出RuntimeException |规则冲突|

----

## (十一) 日志规约

对应 [阿里规范《日志规约》一章](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/异常日志/日志规约.md)

| VIP 规范 | 阿里规范 | 修改|
| -------- | -------- |-------- |
|4.尽量使用异步日志| |增加规则|
|5.禁止使用System.out()| |增加规则|
|6.禁止配置日志框架打印日志打印时的类名,行号等信息| |增加规则|
| |2.日志文件推荐至少保存15天 |删除规则|
| |3.应用中的扩展日志命名方式 |删除规则|
| |6.异常信息应该包括两类信息 |移到《异常处理》|
|2.合理使用使用占位符 |4.对trace/debug/info级别的日志使用占位符 |还是要判断日志是否必然输出,<br>并强调条件判断与占位符之间的差别|

----

## (十二) 其他规约

保留 [阿里规范《常量定义》一章](dhttps://github.com/alibaba/p3c/blob/master/p3c-gitbook/编程规约/常量定义.md)的规则1

| VIP 规范 | 阿里规范 | 修改|
| -------- | -------- |-------- |
| | 规则2-4  | 删除规则|
| | 规则5. 如果变量值仅在一个固定范围内变化用enum类型来定义 | 移到《基本类型》|

保留 [阿里规范《其他》一章](https://github.com/alibaba/p3c/blob/master/p3c-gitbook/异常日志/其他.md)的规则7

| VIP 规范 | 阿里规范 | 修改|
| -------- | -------- |-------- |
| | 规则2-4,6-8 | 删除规则 |
| | 规则1. 在使用正则表达式时,利用好其预编译功 | 移到《基本类型》|

* 规则3,4,5,6,7均为新增规则


================================================
FILE: docs/standard/chapter01.md
================================================
# (一) 命名规约

**Rule 1. 【强制】禁止拼音缩写,避免阅读者费劲猜测;尽量不用拼音,除非中国式业务词汇没有通用易懂的英文对应。**

```text
禁止: DZ[打折] / getPFByName() [评分]

尽量避免:Dazhe / DaZhePrice

```

----

**Rule 2. 【强制】禁止使用非标准的英文缩写**

```text
反例: AbstractClass 缩写成 AbsClass;condition 缩写成 condi。
```

----

**Rule 3. 【强制】禁用其他编程语言风格的前缀和后缀**

在其它编程语言中使用的特殊前缀或后缀,如 `_name`、`name_`、`mName`、`i_name`,在 Java 中都禁止使用。

----

**Rule 4. 【推荐】命名的好坏,在于其“模糊度”**

1)如果上下文很清晰,局部变量可以使用 `list` 这种简略命名, 否则应该使用 `userList` 这种更清晰的命名。


2)禁止 `a1, a2, a3` 这种带编号的没诚意的命名方式。


3)方法的参数名叫 `bookList` ,方法里的局部变量名叫 `theBookList` 也是很没诚意。


4)如果一个应用里同时存在 `Account、AccountInfo、AccountData` 类,或者一个类里同时有 `getAccountInfo()、getAccountData()`, `save()、 store()` 的函数,阅读者将非常困惑。


5) `callerId` 与 `calleeId`, `mydearfriendswitha` 与 `mydearfriendswithb` 这种拼写极度接近,考验阅读者眼力的。

----

**Rule 5. 【推荐】包名全部小写。点分隔符之间尽量只有一个英语单词,即使有多个单词也不使用下划线或大小写分隔**

```text
正例: com.vip.javatool

反例: com.vip.java_tool, com.vip.javaTool
```

* [Sonar-120:Package names should comply with a naming convention](https://rules.sonarsource.com/java/RSPEC-120)

----

**Rule 6. 【强制】类名与接口名使用UpperCamelCase风格,遵从驼峰形式**

Tcp, Xml等缩写也遵循驼峰形式,可约定例外如:DTO/ VO等。

``` text
正例:UserId / XmlService / TcpUdpDeal / UserVO

反例:UserID / XMLService / TCPUDPDeal / UserVo
```

* [Sonar-101:Class names should comply with a naming convention](https://www.sonarsource.com/products/codeanalyzers/sonarjava/rules.html#RSPEC-101)
* [Sonar-114:Interface names should comply with a naming convention](https://www.sonarsource.com/products/codeanalyzers/sonarjava/rules.html#RSPEC-114)

----

**Rule 7. 【强制】方法名、参数名、成员变量、局部变量使用lowerCamelCase风格,遵从驼峰形式**

```text
正例: localValue / getHttpMessage();
```

* [Sonar-100:Method names should comply with a naming convention](https://www.sonarsource.com/products/codeanalyzers/sonarjava/rules.html#RSPEC-100)
* [Sonar-116:Field names should comply with a naming convention](https://www.sonarsource.com/products/codeanalyzers/sonarjava/rules.html#RSPEC-116)
* [Sonar-117:Local variable and method parameter names should comply with a naming convention](https://www.sonarsource.com/products/codeanalyzers/sonarjava/rules.html#RSPEC-117)

----

**Rule 8. 【强制】常量命名全大写,单词间用下划线隔开。力求语义表达完整清楚,不要嫌名字长**

```text
正例: MAX_STOCK_COUNT

反例: MAX_COUNT
```

例外:当一个static final字段不是一个真正常量,比如不是基本类型时,不需要使用大写命名。

```java
private static final Logger logger = Logger.getLogger(MyClass.class);
```

例外:枚举常量推荐全大写,但如果历史原因未遵循也是允许的,所以我们修改了Sonar的规则。

* [Sonar-115:Constant names should comply with a naming convention](https://www.sonarsource.com/products/codeanalyzers/sonarjava/rules.html#RSPEC-115)
* [Sonar-308:Static non-final field names should comply with a naming convention](https://www.sonarsource.com/products/codeanalyzers/sonarjava/rules.html#RSPEC-308)

----

**Rule 9. 【推荐】如果使用到了通用的设计模式,在类名中体现,有利于阅读者快速理解设计思想**

``` text
正例:OrderFactory, LoginProxy ,ResourceObserver
```

----

**Rule 10. 【推荐】枚举类名以Enum结尾; 抽象类使用Abstract或Base开头;异常类使用Exception结尾;测试类以它要测试的类名开始,以Test结尾**

```text
正例:DealStatusEnum, AbstractView,BaseView, TimeoutException,UserServiceTest
```

* [Sonar-2166:Classes named like "Exception" should extend "Exception" or a subclass](https://www.sonarsource.com/products/codeanalyzers/sonarjava/rules.html#RSPEC-2166)
* [Sonar-3577:Test classes should comply with a naming convention](https://www.sonarsource.com/products/codeanalyzers/sonarjava/rules.html#RSPEC-3577)


----

**Rule 11. 【推荐】实现类尽量用Impl的后缀与接口关联,除了形容能力的接口**

```text
正例:CacheServiceImpl 实现 CacheService接口。

正例: Foo 实现 Translatable接口。
```

----

**Rule 12. 【强制】POJO类中布尔类型的变量名,不要加is前缀,否则部分框架解析会引起序列化错误**

```text
反例:Boolean isSuccess的成员变量,它的GET方法也是isSuccess(),部分框架在反射解析的时候,“以为”对应的成员变量名称是success,导致出错。
```

----

**Rule 13. 【强制】避免成员变量,方法参数,局部变量的重名复写,引起混淆**

* 类的私有成员变量名,不与父类的成员变量重名

* 方法的参数名/局部变量名,不与类的成员变量重名 (getter/setter例外)

下面错误的地方,Java在编译时很坑人的都是合法的,但给阅读者带来极大的障碍。

```java
public class A {
  int foo;
}

public class B extends A {
  int foo; //WRONG
  int bar;

  public void hello(int bar) { //WRONG
    int foo = 0; //WRONG
  }

  public void setBar(int bar) { //OK
    this.bar = bar;
  }
}
```

* [Sonar-2387: Child class fields should not shadow parent class fields](https://www.sonarsource.com/products/codeanalyzers/sonarjava/rules.html#RSPEC-2387)
* [Sonar: Local variables should not shadow class fields](https://www.sonarsource.com/products/codeanalyzers/sonarjava/rules.html#RSPEC-1117)

----


================================================
FILE: docs/standard/chapter02.md
================================================
# (二) 格式规约

**Rule 1. 【强制】使用项目组统一的代码格式模板,基于IDE自动的格式化**

1)IDE的默认代码格式模板,能简化绝大部分关于格式规范(如空格,括号)的描述。

2)统一的模板,并在接手旧项目先进行一次全面格式化,可以避免, 不同开发者之间,因为格式不统一产生代码合并冲突,或者代码变更日志中因为格式不同引起的变更,掩盖了真正的逻辑变更。

3)设定项目组统一的行宽,建议120。

4)设定项目组统一的缩进方式(Tab或二空格,四空格均可),基于IDE自动转换。


* [VIP代码格式化模板](https://github.com/vipshop/vjtools/tree/master/standard/formatter)

----

**Rule 2. 【强制】IDE的text file encoding设置为UTF-8; IDE中文件的换行符使用Unix格式,不要使用Windows格式**

----

**Rule 3. 【推荐】 用小括号来限定运算优先级**

我们没有理由假设读者能记住整个Java运算符优先级表。除非作者和Reviewer都认为去掉小括号也不会使代码被误解,甚至更易于阅读。

```java
if ((a == b) && (c == d))
```

* [Sonar-1068:Limited dependence should be placed on operator precedence rules in expressions](https://www.sonarsource.com/products/codeanalyzers/sonarjava/rules.html#RSPEC-1068),我们修改了三目运算符 `foo!=null?foo:""` 不需要加括号。

----

**Rule 4. 【推荐】类内方法定义的顺序,不要“总是在类的最后添加新方法”**

一个类就是一篇文章,想象一个阅读者的存在,合理安排方法的布局。

1)顺序依次是:构造函数 > (公有方法>保护方法>私有方法)  > getter/setter方法。

如果公有方法可以分成几组,私有方法也紧跟公有方法的分组。


2)当一个类有多个构造方法,或者多个同名的重载方法,这些方法应该放置在一起。其中参数较多的方法在后面。

```java
public Foo(int a) {...}
public Foo(int a, String b) {...}

public void foo(int a) {...}
public void foo(int a, String b) {...}
```


3)作为调用者的方法,尽量放在被调用的方法前面。

```java
public void foo() {
	bar();
}

public void bar() {...}
```

----

**Rule 5. 【推荐】通过空行进行逻辑分段**

一段代码也是一段文章,需要合理的分段而不是一口气读到尾。

不同组的变量之间,不同业务逻辑的代码行之间,插入一个空行,起逻辑分段的作用。

而联系紧密的变量之间、语句之间,则尽量不要插入空行。

```java
int width;
int height;

String name;
```

----

**Rule 6.【推荐】避免IDE格式化**

对于一些特殊场景(如使用大量的字符串拼接成一段文字,或者想把大量的枚举值排成一列),为了避免IDE自动格式化,土办法是把注释符号//加在每一行的末尾,但这有视觉的干扰,可以使用@formatter:off和@formatter:on来包装这段代码,让IDE跳过它。

``` java
// @formatter:off
...
// @formatter:on
```
----


================================================
FILE: docs/standard/chapter03.md
================================================
# (三) 注释规约

**Rule 1.【推荐】基本的注释要求**

完全没有注释的大段代码对于阅读者形同天书,注释是给自己看的,即使隔很长时间,也能清晰理解当时的思路;注释也是给继任者看的,使其能够快速接替自己的工作。

代码将被大量后续维护,注释如果对阅读者有帮助,不要吝啬在注释上花费的时间。(但也综合参见规则2,3)

第一、能够准确反应设计思想和代码逻辑;第二、能够描述业务含义,使别的程序员能够迅速了解到代码背后的信息。

除了特别清晰的类,都尽量编写类级别注释,说明类的目的和使用方法。

除了特别清晰的方法,对外提供的公有方法,抽象类的方法,同样尽量清晰的描述:期待的输入,对应的输出,错误的处理和返回码,以及可能抛出的异常。

----

**Rule 2. 【推荐】通过更清晰的代码来避免注释**

在编写注释前,考虑是否可以通过更好的命名,更清晰的代码结构,更好的函数和变量的抽取,让代码不言自明,此时不需要额外的注释。

----

**Rule 3. 【推荐】删除空注释,无意义注释**

《Clean Code》建议,如果没有想说的,不要留着IDE自动生成的,空的@param,@return,@throws 标记,让代码更简洁。

反例:方法名为put,加上两个有意义的变量名elephant和fridge,已经说明了这是在干什么,不需要任何额外的注释。

```java
/**
 * put elephant into fridge.
 *
 * @param elephant
 * @param fridge
 * @return
 */
public void put(Elephant elephant, Fridge fridge);
```
----

**Rule 4.【推荐】避免创建人,创建日期,及更新日志的注释**

代码后续还会有多人多次维护,而创建人可能会离职,让我们相信源码版本控制系统对更新记录能做得更好。

----

**Rule 5. 【强制】代码修改的同时,注释也要进行相应的修改。尤其是参数、返回值、异常、核心逻辑等的修改**

----

**Rule 6. 【强制】类、类的公有成员、方法的注释必须使用Javadoc规范,使用/\*\* xxx \*/格式,不得使用`//xxx`方式**

正确的JavaDoc格式可以在IDE中,查看调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。

----

**Rule 7. 【推荐】JavaDoc中不要为了HTML格式化而大量使用HTML标签和转义字符**

如果为了Html版JavaDoc的显示,大量使用`<p\>` `<pre\>`这样的html标签,以及`&lt` `&quot` 这样的html转义字符,严重影响了直接阅读代码时的直观性,而直接阅读代码的几率其实比看Html版的JavaDoc大得多。

另外IDE对JavaDoc的格式化也要求`<p>`之类的标签来换行,可以配置让IDE不对JavaDoc的格式化。

----

**Rule 8. 【推荐】注释不要为了英文而英文**

如果没有国际化要求,中文能表达得更清晰时还是用中文。

----

**Rule 9. 【推荐】TODO 标记,清晰说明代办事项和处理人**

“对那些临时的, 短期的解决方案, 或已经够好但仍不完美的代码使用 TODO 注释. ”

清晰描述待修改的事项,保证过几个月后仍然能够清楚要做什么修改。

如果近期会处理的事项,写明处理人。如果远期的,写明提出人。

通过 IDE 和 Sonar 的标记扫描,经常清理此类标记,线上故障经常来源于这些标记但未处理的代码。

正例:

```java
// TODO(who): to do what.
// TODO(who): when to do what.
// TODO(calvin): use xxx to replace yyy.
```

反例:

```java
// TODO: refactor it
```

不推荐使用 FIXME 标记。这样,在项目中搜索 TODO 就可以得到完整的 TODO list,而不需要搜索 TODO 和 FIXME。

* [Sonar: Track uses of "TODO" tags](https://rules.sonarsource.com/java/RSPEC-1135)

----

**Rule 10. 【推荐】合理处理注释掉的代码**

如果后续会恢复此段代码,在目标代码上方用`///`说明注释动机,而不是简单的注释掉代码。

如果很大概率不再使用,则直接删除(版本管理工具保存了历史代码)。

* [Sonar: Sections of code should not be "commented out"](https://rules.sonarsource.com/java/RSPEC-125)

----


================================================
FILE: docs/standard/chapter04.md
================================================
# (四) 方法设计

**Rule 1. 【推荐】方法的长度度量**

方法尽量不要超过100行,或其他团队共同商定的行数。

另外,方法长度超过8000个字节码时,将不会被JIT编译成二进制码。


* [Sonar-107: Methods should not have too many lines](https://rules.sonarsource.com/java/RSPEC-107),默认值改为100
* Facebook-Contrib:Performance - This method is too long to be compiled by the JIT

----

**Rule 2. 【推荐】方法的语句在同一个抽象层级上**

反例:一个方法里,前20行代码在进行很复杂的基本价格计算,然后调用一个折扣计算函数,再调用一个赠品计算函数。

此时可将前20行也封装成一个价格计算函数,使整个方法在同一抽象层级上。

----

**Rule 3. 【推荐】为了帮助阅读及方法内联,将小概率发生的异常处理及其他极小概率进入的代码路径,封装成独立的方法**

```java
if(seldomHappenCase) {
  hanldMethod();
}

try {
  ...
} catch(SeldomHappenException e) {
  handleException();
}
```

----

**Rule 4. 【推荐】尽量减少重复的代码,抽取方法**

超过5行以上重复的代码,都可以考虑抽取公用的方法。

----

**Rule 5. 【推荐】方法参数最好不超过3个,最多不超过7个**

1)如果多个参数同属于一个对象,直接传递对象。

例外: 你不希望依赖整个对象,传播了类之间的依赖性。


2)将多个参数合并为一个新创建的逻辑对象。

例外: 多个参数之间毫无逻辑关联。


3)将函数拆分成多个函数,让每个函数所需的参数减少。

* [Sonar-107: Methods should not have too many parameters](https://rules.sonarsource.com/java/RSPEC-107)

----

**Rule 6.【推荐】下列情形,需要进行参数校验**

1) 调用频次低的方法。

2) 执行时间开销很大的方法。此情形中,参数校验时间几乎可以忽略不计,但如果因为参数错误导致中间执行回退,或者错误,代价更大。

3) 需要极高稳定性和可用性的方法。

4) 对外提供的开放接口,不管是RPC/HTTP/公共类库的API接口。

如果使用Apache Validate 或 Guava Precondition进行校验,并附加错误提示信息时,注意不要每次校验都做一次字符串拼接。

```java
//WRONG
Validate.isTrue(length > 2, "length is "+keys.length+", less than 2", length);
//RIGHT
Validate.isTrue(length > 2, "length is %d, less than 2", length);
```

----

**Rule 7.【推荐】下列情形,不需要进行参数校验**

1) 极有可能被循环调用的方法。


2) 底层调用频度比较高的方法。毕竟是像纯净水过滤的最后一道,参数错误不太可能到底层才会暴露问题。

比如,一般DAO层与Service层都在同一个应用中,所以DAO层的参数校验,可以省略。


3) 被声明成private,或其他只会被自己代码所调用的方法,如果能够确定在调用方已经做过检查,或者肯定不会有问题则可省略。

即使忽略检查,也尽量在方法说明里注明参数的要求,比如vjkit中的@NotNull,@Nullable标识。

----

**Rule 8.【推荐】禁用assert做参数校验**

assert断言仅用于测试环境调试,无需在生产环境时进行的校验。因为它需要增加-ea启动参数才会被执行。而且校验失败会抛出一个AssertionError(属于Error,需要捕获Throwable)

因此在生产环境进行的校验,需要使用Apache Commons Lang的Validate或Guava的Precondition。

----

**Rule 9.【推荐】返回值可以为Null,可以考虑使用JDK8的Optional类**

不强制返回空集合,或者空对象。但需要添加注释充分说明什么情况下会返回null值。

本手册明确`防止NPE是调用者的责任`。即使被调用方法返回空集合或者空对象,对调用者来说,也并非高枕无忧,必须考虑到远程调用失败、序列化失败、运行时异常等场景返回null的情况。

JDK8的Optional类的使用这里不展开。

----

**Rule 10.【推荐】返回值可以为内部数组和集合**

如果觉得被外部修改的可能性不大,或没有影响时,不强制在返回前包裹成Immutable集合,或进行数组克隆。

----

**Rule 11.【推荐】不能使用有继承关系的参数类型来重载方法**

因为方法重载的参数类型是根据编译时表面类型匹配的,不根据运行时的实际类型匹配。

```java
class A {
  void hello(List list);
  void hello(ArrayList arrayList);
}

List arrayList = new ArrayList();

// 下句调用的是hello(List list),因为arrayList的定义类型是List
a.hello(arrayList);
```

----

**Rule 12.【强制】正被外部调用的接口,不允许修改方法签名,避免对接口的调用方产生影响**

只能新增新接口,并对已过时接口加@Deprecated注解,并清晰地说明新接口是什么。

----

**Rule 13.【推荐】不使用`@Deprecated`的类或方法**

接口提供方既然明确是过时接口并提供新接口,那么作为调用方来说,有义务去考证过时方法的新实现是什么。

比如java.net.URLDecoder 中的方法decode(String encodeStr) 这个方法已经过时,应该使用双参数decode(String source, String encode)。

----

**Rule 14.【推荐】不使用不稳定方法,如com.sun.\*包下的类,底层类库中internal包下的类**

`com.sun.*`,`sun.*`包下的类,或者底层类库中名称为internal的包下的类,都是不对外暴露的,可随时被改变的不稳定类。

* [Sonar-1191: Classes from "sun.*" packages should not be used](https://rules.sonarsource.com/java/RSPEC-1191)

----


================================================
FILE: docs/standard/chapter05.md
================================================
# (五) 类设计

**Rule 1. 【推荐】类成员与方法的可见性最小化**

任何类、方法、参数、变量,严控访问范围。过于宽泛的访问范围,不利于模块解耦。思考:如果是一个private的方法,想删除就删除,可是一个public的service方法,或者一个public的成员变量,删除一下,不得手心冒点汗吗?

例外:为了单元测试,有时也可能将访问范围扩大,此时需要加上JavaDoc说明或vjkit中的`@VisibleForTesting`注解。

----

**Rule 2.【推荐】 减少类之间的依赖**

比如如果A类只依赖B类的某个属性,在构造函数和方法参数中,只传入该属性。让阅读者知道,A类只依赖了B类的这个属性,而不依赖其他属性,也不会调用B类的任何方法。

```java
a.foo(b);     //WRONG

a.foo(b.bar); //RIGHT
```
----

**Rule 3.【推荐】 定义变量与方法参数时,尽量使用接口而不是具体类**

使用接口可以保持一定的灵活性,也能向读者更清晰的表达你的需求:变量和参数只是要求有一个Map,而不是特定要求一个HashMap。

例外:如果变量和参数要求某种特殊类型的特性,则需要清晰定义该参数类型,同样是为了向读者表达你的需求。

----

**Rule 4. 【推荐】类的长度度量**

类尽量不要超过300行,或其他团队共同商定的行数。

对过大的类进行分拆时,可考虑其内聚性,即类的属性与类的方法的关联程度,如果有些属性没有被大部分的方法使用,其内聚性是低的。

----

**Rule 5.【推荐】 构造函数如果有很多参数,且有多种参数组合时,建议使用Builder模式**

```java
Executor executor = new ThreadPoolBuilder().coreThread(10).queueLenth(100).build();
```

即使仍然使用构造函数,也建议使用chain constructor模式,逐层加入默认值传递调用,仅在参数最多的构造函数里实现构造逻辑。

```java
public A(){
  A(DEFAULT_TIMEOUT);
}

public A(int timeout) {
  ...
}
```

----

**Rule 6.【推荐】构造函数要简单,尤其是存在继承关系的时候**

可以将复杂逻辑,尤其是业务逻辑,抽取到独立函数,如init(),start(),让使用者显式调用。

```java
Foo foo = new Foo();
foo.init();
```

----

**Rule 7.【强制】所有的子类覆写方法,必须加`@Override`注解**

比如有时候子类的覆写方法的拼写有误,或方法签名有误,导致没能真正覆写,加`@Override`可以准确判断是否覆写成功。

而且,如果在父类中对方法签名进行了修改,子类会马上编译报错。

另外,也能提醒阅读者这是个覆写方法。

最后,建议在IDE的Save Action中配置自动添加`@Override`注解,如果无意间错误同名覆写了父类方法也能被发现。

* [Sonar-1161: "@Override" should be used on overriding and implementing methods](https://rules.sonarsource.com/java/RSPEC-1161)

----

**Rule 8.【强制】静态方法不能被子类覆写。**

因为它只会根据表面类型来决定调用的方法。

```java
Base base = new Children();

// 下句实际调用的是父类的静态方法,虽然对象实例是子类的。
base.staticMethod();
```

----

**Rule 9.静态方法访问的原则**

**9.1【推荐】避免通过一个类的对象引用访问此类的静态变量或静态方法,直接用类名来访问即可**

目的是向读者更清晰传达调用的是静态方法。可在IDE的Save Action中配置自动转换。

```java
int i = objectA.staticMethod(); // WRONG

int i = ClassA.staticMethod(); // RIGHT
```

* [Sonar-2209: "static" members should be accessed statically](https://rules.sonarsource.com/java/RSPEC-2209)
* [Sonar-2440: Classes with only "static" methods should not be instantiated](https://rules.sonarsource.com/java/RSPEC-2440)


**9.2 【推荐】除测试用例,不要static import 静态方法**

静态导入后忽略掉的类名,给阅读者造成障碍。

例外:测试环境中的assert语句,大家都太熟悉了。

* [Sonar-3030: Classes should not have too many "static" imports](https://rules.sonarsource.com/java/RSPEC-3030) 但IDEA经常自动转换static import,所以暂不作为规则。


**9.3【推荐】尽量避免在非静态方法中修改静态成员变量的值**

```java
// WRONG
public void foo() {
  ClassA.staticFiled = 1;
}
```

* [Sonar-2696: Instance methods should not write to "static" fields](https://rules.sonarsource.com/java/RSPEC-2696)
* [Sonar-3010: Static fields should not be updated in constructors](https://rules.sonarsource.com/java/RSPEC-3010)


----

**Rule 10.【推荐】 内部类的定义原则**

当一个类与另一个类关联非常紧密,处于从属的关系,特别是只有该类会访问它时,可定义成私有内部类以提高封装性。

另外,内部类也常用作回调函数类,在JDK8下建议写成Lambda。

内部类分匿名内部类,内部类,静态内部类三种。

1) 匿名内部类 与 内部类,按需使用:

在性能上没有区别;当内部类会被多个地方调用,或匿名内部类的长度太长,已影响对调用它的方法的阅读时,定义有名字的内部类。


2) 静态内部类 与 内部类,优先使用静态内部类:

1. 非静态内部类持有外部类的引用,能访问外类的实例方法与属性。构造时多传入一个引用对性能没有太大影响,更关键的是向阅读者传递自己的意图,内部类会否访问外部类。
2. 非静态内部类里不能定义static的属性与方法。

* [Sonar-2694: Inner classes which do not reference their owning classes should be "static"](https://rules.sonarsource.com/java/RSPEC-2694)
* [Sonar-1604: Anonymous inner classes containing only one method should become lambdas](https://rules.sonarsource.com/java/RSPEC-1604)

----

**Rule 11.【推荐】使用getter/setter方法,还是直接public成员变量的原则。**

除非因为特殊原因方法内联失败,否则使用getter方法与直接访问成员变量的性能是一样的。

使用getter/setter,好处是可以进一步的处理:

1. 通过隐藏setter方法使得成员变量只读

2. 增加简单的校验逻辑

3. 增加简单的值处理,值类型转换等

建议通过IDE生成getter/setter。

但getter/seter中不应有复杂的业务处理,建议另外封装函数,并且不要以getXX/setXX命名。


如果是内部类,以及无逻辑的POJO/VO类,使用getter/setter除了让一些纯OO论者感觉舒服,没有任何的好处,建议直接使用public成员变量。

例外:有些序列化框架只能从getter/setter反射,不能直接反射public成员变量。

----

**Rule 12.【强制】POJO类必须覆写toString方法。**

便于记录日志,排查问题时调用POJO的toString方法打印其属性值。否则默认的Object.toString()只打印`类名@数字`的无效信息。

----

**Rule 13. hashCode和equals方法的处理,遵循如下规则:**


**13.1【强制】只要重写equals,就必须重写hashCode。 而且选取相同的属性进行运算。**


**13.2【推荐】只选取真正能决定对象是否一致的属性,而不是所有属性,可以改善性能。**


**13.3【推荐】对不可变对象,可以缓存hashCode值改善性能(比如String就是例子)。**


**13.4【强制】类的属性增加时,及时重新生成toString,hashCode和equals方法。**


* [Sonar-1206: "equals(Object obj)" and "hashCode()" should be overridden in pairs](https://rules.sonarsource.com/java/RSPEC-1206)

----

**Rule 14.【强制】使用 IDE 生成 toString、hashCode 和 equals 方法。**

使用 IDE 生成而不是手写,能保证 toString 有统一的格式,equals 和 hashCode 则避免不正确的 null 值处理。

子类生成 toString 时,还需要勾选父类的属性。

----

**Rule 15. 【强制】Object的equals方法容易抛空指针异常,应使用常量或确定非空的对象来调用equals**

推荐使用java.util.Objects#equals(JDK7引入的工具类)

```java
"test".equals(object);  //RIGHT

Objects.equals(object, "test"); //RIGHT
```

* [Sonar-1132: Strings literals should be placed on the left side when checking for equality](https://rules.sonarsource.com/java/RSPEC-1132)

----

**Rule 16.【强制】除了保持兼容性的情况,总是移除无用属性、方法与参数**

特别是private的属性、方法、内部类,private方法上的参数,一旦无用立刻移除。信任代码版本管理系统。

* [Sonar-3985: Unused "private" classes should be removed](https://rules.sonarsource.com/java/RSPEC-3985)
* [Sonar-1068: Unused "private" fields should be removed](https://rules.sonarsource.com/java/RSPEC-1068)
* [Sonar: Unused "private" methods should be removed](https://rules.sonarsource.com/java/RSPEC-1144)
* [Sonar-1481: Unused local variables should be removed](https://rules.sonarsource.com/java/RSPEC-1481)
* [Sonar-1172: Unused method parameters should be removed](https://rules.sonarsource.com/java/RSPEC-1172) Sonar-VJ版只对private方法的无用参数告警。


----

**Rule 17.【推荐】final关键字与性能无关,仅用于下列不可修改的场景**

1) 定义类及方法时,类不可继承,方法不可覆写;

2) 定义基本类型的函数参数和变量,不可重新赋值;

3) 定义对象型的函数参数和变量,仅表示变量所指向的对象不可修改,而对象自身的属性是可以修改的。

----

**Rule 18.【推荐】得墨忒耳法则,不要和陌生人说话**

以下调用,一是导致了对A对象的内部结构(B,C)的紧耦合,二是连串的调用很容易产生NPE,因此链式调用尽量不要过长。

```java
obj.getA().getB().getC().hello();
```

----


================================================
FILE: docs/standard/chapter06.md
================================================
# (六) 控制语句

**Rule 1. 【强制】if, else, for, do, while语句必须使用大括号,即使只有单条语句**

曾经试过合并代码时,因为没加括号,单条语句合并成两条语句后,仍然认为只有单条语句,另一条语句在循环外执行。

其他增加调试语句等情况也经常引起同样错误。

可在IDE的Save Action中配置自动添加。

```java
if (a == b) {
  ...
}
```

例外:一般由IDE生成的equals()函数

* [Sonar-121: Control structures should use curly braces](https://rules.sonarsource.com/java/RSPEC-121) Sonar-VJ版豁免了equals()函数

----

**Rule 2.【推荐】少用if-else方式,多用哨兵语句式以减少嵌套层次**

```java
if (condition) {
  ...
  return obj;
}

// 接着写else的业务逻辑代码;
```

* Facebook-Contrib: Style - Method buries logic to the right (indented) more than it needs to be

----

**Rule 3.【推荐】限定方法的嵌套层次**

所有if/else/for/while/try的嵌套,当层次过多时,将引起巨大的阅读障碍,因此一般推荐嵌套层次不超过4。

通过抽取方法,或哨兵语句(见Rule 2)来减少嵌套。

```java
public void applyDriverLicense() {
  if (isTooYoung()) {
    System.out.println("You are too young to apply driver license.");
    return;
  }

  if (isTooOld()) {
    System.out.println("You are too old to apply driver license.");
    return;
  }

  System.out.println("You've applied the driver license successfully.");
  return;
}
```

* [Sonar-134: Control flow statements "if", "for", "while", "switch" and "try" should not be nested too deeply](https://rules.sonarsource.com/java/RSPEC-134),增大为4

----

**Rule 4.【推荐】布尔表达式中的布尔运算符(&&,||)的个数不超过4个,将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性**


```java
//WRONG
if ((file.open(fileName, "w") != null) && (...) || (...)|| (...)) {
  ...
}

//RIGHT
boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
if (existed || (...)) {
  ...
}
```

* [Sonar-1067: Expressions should not be too complex](https://rules.sonarsource.com/java/RSPEC-1067),增大为4

----

**Rule 5.【推荐】简单逻辑,善用三目运算符,减少if-else语句的编写**

```java
s != null ? s : "";
```

----

**Rule 6.【推荐】减少使用取反的逻辑**

不使用取反的逻辑,有利于快速理解。且大部分情况,取反逻辑存在对应的正向逻辑写法。

```java
//WRONG
if (!(x >= 268) { ... }

//RIGHT
if (x < 268) { ... }
```

* [Sonar-1940: Boolean checks should not be inverted](https://rules.sonarsource.com/java/RSPEC-1940)

----

**Rule 7.【推荐】表达式中,能造成短路概率较大的逻辑尽量放前面,使得后面的判断可以免于执行**


```java
if (maybeTrue() || maybeFalse()) { ... }

if (maybeFalse() && maybeTrue()) { ... }
```

----


**Rule 8.【强制】switch的规则**

1)在一个switch块内,每个case要么通过break/return等来终止,要么注释说明程序将继续执行到哪一个case为止;

2)在一个switch块内,都必须包含一个default语句并且放在最后,即使它什么代码也没有。

```java
String animal = "tomcat";

switch (animal) {
case "cat":
  System.out.println("It's a cat.");
  break;
case "lion": // 执行到tiger
case "tiger":
  System.out.println("It's a beast.");
  break;
default:
  // 什么都不做,也要有default
  break;
}
```

* [Sonar: "switch" statements should end with "default" clauses](https://rules.sonarsource.com/java/RSPEC-131)

----

**Rule 9.【推荐】循环体中的语句要考量性能,操作尽量移至循环体外处理**

1)不必要的耗时较大的对象构造;

2)不必要的try-catch(除非出错时需要循环下去)。

----

**Rule 10.【推荐】能用while循环实现的代码,就不用do-while循环**

while语句能在循环开始的时候就看到循环条件,便于帮助理解循环内的代码;

do-while语句要在循环最后才看到循环条件,不利于代码维护,代码逻辑容易出错。

----


================================================
FILE: docs/standard/chapter07.md
================================================
# (七) 基本类型与字符串

**Rule 1. 原子数据类型(int等)与包装类型(Integer等)的使用原则**

**1.1 【推荐】需要序列化的POJO类属性使用包装数据类型**


**1.2 【推荐】RPC方法的返回值和参数使用包装数据类型**


**1.3 【推荐】局部变量尽量使用基本数据类型**


包装类型的坏处:

1)Integer 24字节,而原子类型 int 4字节。

2)包装类型每次赋值还需要额外创建对象,如Integer var = 200, 除非数值在缓存区间内(见Integer.IntegerCache与Long.LongCache)才会复用已缓存对象。默认缓存区间为-128到127,其中Integer的缓存区间还受启动参数的影响,如-XX:AutoBoxCacheMax=20000。

3)包装类型还有==比较的陷阱(见规则3)


包装类型的好处:

1)包装类型能表达 null 的语义。

比如数据库的查询结果可能是null,如果用基本数据类型有NPE风险。又比如显示成交总额涨跌情况,如果调用的RPC服务不成功时,应该返回null,显示成-%,而不是0%。

2)集合需要包装类型,除非使用数组,或者特殊的原子类型集合。

3)泛型需要包装类型,如`Result<Integer>`。

----

**Rule 2.原子数据类型与包装类型的转换原则**

**2.1【推荐】自动转换(AutoBoxing)有一定成本,调用者与被调用函数间尽量使用同一类型,减少默认转换**

```java
//WRONG, sum 类型为Long, i类型为long,每次相加都需要AutoBoxing。
Long sum=0L;

for( long i = 0; i < 10000; i++) {
  sum+=i;
}

//RIGHT, 准确使用API返回正确的类型
Integer i = Integer.valueOf(str);
int i = Integer.parseInt(str);
```

* [Sonar-2153: Boxing and unboxing should not be immediately reversed](https://rules.sonarsource.com/java/RSPEC-2153)


**2.2 【推荐】自动拆箱有可能产生NPE,要注意处理**

```java
//如果intObject为null,产生NPE
int i = intObject;
```

----

**Rule 3. 数值equals比较的原则**

**3.1【强制】 所有包装类对象之间值的比较,全部使用equals方法比较**

\==判断对象是否同一个。Integer var = ?在缓存区间的赋值(见规则1),会复用已有对象,因此这个区间内的Integer使用==进行判断可通过,但是区间之外的所有数据,则会在堆上新产生,不会通过。因此如果用\== 来比较数值,很可能在小的测试数据中通过,而到了生产环境才出问题。


**3.2【强制】 BigDecimal需要使用compareTo()**

因为BigDecimal的equals()还会比对精度,2.0与2.00不一致。

* Facebook-Contrib: Correctness - Method calls BigDecimal.equals()

**3.3【强制】 Atomic\* 系列,不能使用 equals 方法**

因为 Atomic\* 系列没有覆写 equals 方法。

```java
// RIGHT
if (counter1.get() == counter2.get()) {
    // ...
}
```

* [Sonar-2204: ".equals()" should not be used to test the values of "Atomic" classes](https://rules.sonarsource.com/java/RSPEC-2204)

**3.4【强制】 double 及 float 的比较,要特殊处理**

因为精度问题,浮点数间的 equals 非常不可靠,在 vjkit 的 NumberUtil 中有对应的封装函数。

```java
float f1 = 0.15f;
float f2 = 0.45f/3; // 实际等于0.14999999

// 反例
if (f1 == f2) {
    // ...
}

// 反例
if (Double.compare(f1, f2) == 0) {
    // ...
}

// 正例
// 绝对误差
static final float EPSILON = 0.00001f;
if (Math.abs(f1 - f2) < EPSILON) {
    // ...
}

// 正例
// 相对误差
static final float EPSILON = 0.001f;
if (Math.abs(f1 - f2) / (Math.abs(f1) + Math.abs(f2)) < EPSILON) {
    // ...
}
```

推荐使用“相对误差”的方式比较浮点数。

* [Sonar-1244: Floating point numbers should not be tested for equality](https://rules.sonarsource.com/java/RSPEC-1244)

----

**Rule 4. 数字类型的计算原则**

**4.1【强制】数字运算表达式,因为先进行等式右边的运算,再赋值给等式左边的变量,所以等式两边的类型要一致**

例子1: int与int相除后,哪怕被赋值给float或double,结果仍然是四舍五入取整的int。

需要强制将除数或被除数转换为float或double。

```java
double d = 24/7;  //结果是3.0
double d =  (double)24/7; //结果是正确的3.42857
```

例子2: int与int相乘,哪怕被赋值给long,仍然会溢出。

需要强制将乘数的一方转换为long。

```java
long l = Integer.MAX_VALUE * 2; // 结果是溢出的-2
long l = Integer.MAX_VALUE * 2L; //结果是正确的4294967294
```

另外,int的最大值约21亿,留意可能溢出的情况。

* [Sonar-2184: Math operands should be cast before assignment](https://rules.sonarsource.com/java/RSPEC-2184)


**4.2【强制】数字取模的结果不一定是正数,负数取模的结果仍然负数**

取模做数组下标时,如果不处理负数的情况,很容易ArrayIndexOutOfBoundException。

另外,Integer.MIN_VALUE取绝对值也仍然是负数。因此,vjkit的MathUtil对上述情况做了安全的封装。

```java
-4 % 3  = -1;
Math.abs(Integer.MIN_VALUE) = -2147483648;
```

* Findbugs: Style - Remainder of hashCode could be negative


**4.3【推荐】 double 或 float 计算时有不可避免的精度问题**

```java

float f = 0.45f/3;    //结果是0.14999999

double d1 = 0.45d/3;  //结果是正确的0.15

double d2 = 1.03d - 0.42d; //结果是0.6100000000000001

```

尽量用double而不用float,但如果是金融货币的计算,则必须使用如下选择:

选项1, 使用性能较差的BigDecimal。BigDecimal还能精确控制四舍五入或是其他取舍的方式。

选项2, 在预知小数精度的情况下,将浮点运算放大为整数计数,比如货币以"分"而不是以"元"计算。


* [Sonar-2164: Math should not be performed on floats](https://rules.sonarsource.com/java/RSPEC-2164)

----

**Rule 5. 【推荐】如果变量值仅有有限的可选值,用枚举类来定义常量**

尤其是变量还希望带有名称之外的延伸属性时,如下例:

```java
//WRONG
public String MONDAY = "MONDAY";
public int MONDAY_SEQ = 1;

//RIGHT
public enum SeasonEnum {
	SPRING(1), SUMMER(2), AUTUMN(3), WINTER(4);
	int seq;
	SeasonEnum(int seq) { this.seq = seq; }
}
```

业务代码中不要依赖ordinary()函数进行业务运算,而是自定义数字属性,以免枚举值的增减调序造成影响。 例外:永远不会有变化的枚举,比如上例的一年四季。

----

**Rule 6. 字符串拼接的原则**

**6.1 【推荐】 当字符串拼接不在一个命令行内写完,而是存在多次拼接时(比如循环),使用StringBuilder的append()**

```java
String s  = "hello" + str1 +  str2;  //Almost OK,除非初始长度有问题,见第3点.

String s  = "hello";  //WRONG
if (condition) {
  s += str1;
}

String str = "start";       //WRONG
for (int i = 0; i < 100; i++) {
  str = str + "hello";
}
```

反编译出的字节码文件显示,其实每条用`+`进行字符拼接的语句,都会new出一个StringBuilder对象,然后进行append操作,最后通过toString方法返回String对象。所以上面两个错误例子,会重复构造StringBuilder,重复toString()造成资源浪费。


* [Sonar-1643: Strings should not be concatenated using '+' in a loop](https://rules.sonarsource.com/java/RSPEC-1643)


**6.2 【强制】 字符串拼接对象时,不要显式调用对象的toString()**

如上,`+`实际是StringBuilder,本身会调用对象的toString(),且能很好的处理null的情况。

```java
//WRONG
str = "result:" + myObject.toString();  // myObject 为 null时,抛 NPE

//RIGHT
str = "result:" + myObject;  // myObject 为 null 时,输出 result:null
```


**6.3【强制】使用StringBuilder,而不是有所有方法都有同步修饰符的StringBuffer**

因为内联不成功,逃逸分析并不能抹除StringBuffer上的同步修饰符

* [Sonar-1149: Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used](https://rules.sonarsource.com/java/RSPEC-1149)


**6.4 【推荐】当拼接后字符串的长度远大于16时,指定StringBuilder的大概长度,避免容量不足时的成倍扩展**


**6.5 【推荐】如果字符串长度很大且频繁拼接,可考虑ThreadLocal重用StringBuilder对象**

参考BigDecimal的toString()实现,及vjkit中的StringBuilderHolder。

----

**Rule 7. 【推荐】字符操作时,优先使用字符参数,而不是字符串,能提升性能**

```java
//WRONG
str.indexOf("e");

//RIGHT
stringBuilder.append('a');
str.indexOf('e');
str.replace('m','z');
```

其他包括split等方法,在JDK String中未提供针对字符参数的方法,可考虑使用Apache Commons StringUtils 或Guava的Splitter。

* [Sonar-3027: String function use should be optimized for single characters](https://rules.sonarsource.com/java/RSPEC-3027)

----

**Rule 8. 【推荐】利用好正则表达式的预编译功能,可以有效加快正则匹配速度**

反例:
```java
//直接使用String的matches()方法
result = "abc".matches("[a-zA-z]");

//每次重新构造Pattern
Pattern pattern = Pattern.compile("[a-zA-z]");
result = pattern.matcher("abc").matches();
```

正例:
```java
//在某个地方预先编译Pattern,比如类的静态变量
private static Pattern pattern = Pattern.compile("[a-zA-z]");
...
//真正使用Pattern的地方
result = pattern.matcher("abc").matches();
```

----


================================================
FILE: docs/standard/chapter08.md
================================================
# (八) 集合处理

**Rule 1. 【推荐】底层数据结构是数组的集合,指定集合初始大小**

底层数据结构为数组的集合包括 ArrayList,HashMap,HashSet,ArrayDequeue等。

数组有大小限制,当超过容量时,需要进行复制式扩容,新申请一个是原来容量150% or 200%的数组,将原来的内容复制过去,同时浪费了内存与性能。HashMap/HashSet的扩容,还需要所有键值对重新落位,消耗更大。


默认构造函数使用默认的数组大小,比如ArrayList默认大小为10,HashMap为16。因此建议使用ArrayList(int initialCapacity)等构造函数,明确初始化大小。


HashMap/HashSet的初始值还要考虑加载因子:

为了降低哈希冲突的概率(Key的哈希值按数组大小取模后,如果落在同一个数组下标上,将组成一条需要遍历的Entry链),默认当HashMap中的键值对达到数组大小的75%时,即会触发扩容。因此,如果预估容量是100,即需要设定`100/0.75 +1=135`的数组大小。vjkit的MapUtil的Map创建函数封装了该计算。

如果希望加快Key查找的时间,还可以进一步降低加载因子,加大初始大小,以降低哈希冲突的概率。

----

**Rule 2. 【推荐】尽量使用新式的foreach语法遍历Collection与数组**

foreach是语法糖,遍历集合的实际字节码等价于基于Iterator的循环。

foreach代码一来代码简洁,二来有效避免了有多个循环或嵌套循环时,因为不小心的复制粘贴,用错了iterator或循环计数器(i,j)的情况。

----

**Rule 3. 【强制】不要在foreach循环里进行元素的remove/add操作,remove元素可使用Iterator方式**

```java
//WRONG
for (String str : list) {
  if (condition) {
    list.remove(str);
  }
}

//RIGHT
Iterator<String> it = list.iterator();
while (it.hasNext()) {
  String str = it.next();
  if (condition) {
    it.remove();
  }
}
```

* Facebook-Contrib: Correctness - Method modifies collection element while iterating
* Facebook-Contrib: Correctness - Method deletes collection element while iterating

----

**Rule 4. 【强制】使用entrySet遍历Map类集合Key/Value,而不是keySet	方式进行遍历**

keySet遍历的方式,增加了N次用key获取value的查询。

* [Sonar-2864:"entrySet()" should be iterated when both the key and value are needed](https://rules.sonarsource.com/java/RSPEC-2864)

----

**Rule 5. 【强制】当对象用于集合时,下列情况需要重新实现hashCode()和 equals()**

1) 以对象做为Map的KEY时;

2) 将对象存入Set时。

上述两种情况,都需要使用hashCode和equals比较对象,默认的实现会比较是否同一个对象(对象的引用相等)。

另外,对象放入集合后,会影响hashCode(),equals()结果的属性,将不允许修改。

* [Sonar-2141:Classes that don't define "hashCode()" should not be used in hashes](https://rules.sonarsource.com/java/RSPEC-2141)

----

**Rule 6. 【强制】高度注意各种Map类集合Key/Value能不能存储null值的情况**

| Map | Key | Value |
| -------- | -------- |-------- |
|HashMap|Nullable | Nullable|
|ConcurrentHashMap| NotNull| NotNull|
|TreeMap| NotNull| Nullable |

由于HashMap的干扰,很多人认为ConcurrentHashMap是可以置入null值。同理,Set中的value实际是Map中的key。

----

**Rule 7. 【强制】长生命周期的集合,里面内容需要及时清理,避免内存泄漏**

长生命周期集合包括下面情况,都要小心处理。

1) 静态属性定义;

2) 长生命周期对象的属性;

3) 保存在ThreadLocal中的集合。

如无法保证集合的大小是有限的,使用合适的缓存方案代替直接使用HashMap。

另外,如果使用WeakHashMap保存对象,当对象本身失效时,就不会因为它在集合中存在引用而阻止回收。但JDK的WeakHashMap并不支持并发版本,如果需要并发可使用Guava Cache的实现。

----

**Rule 8. 【强制】集合如果存在并发修改的场景,需要使用线程安全的版本**

1) 著名的反例,HashMap扩容时,遇到并发修改可能造成100%CPU占用。

推荐使用`java.util.concurrent(JUC)`工具包中的并发版集合,如ConcurrentHashMap等,优于使用Collections.synchronizedXXX()系列函数进行同步化封装(等价于在每个方法都加上synchronized关键字)。


例外:ArrayList所对应的CopyOnWriteArrayList,每次更新时都会复制整个数组,只适合于读多写很少的场景。如果频繁写入,可能退化为使用Collections.synchronizedList(list)。


2) 即使线程安全类仍然要注意函数的正确使用。

例如:即使用了 ConcurrentHashMap,但直接使用 get/put 方法,仍然可能会多线程间互相覆盖。

```java
//WRONG
E e = map.get(key);
if (e == null) {
  e = new E();
  map.put(key, e); //仍然能两条线程并发执行put,互相覆盖
}
return e;

//RIGHT
E e = map.get(key);
if (e == null) {
  e = new E();
  E previous = map.putIfAbsent(key, e);
  if(previous != null) {
    return previous;
  }
}
return e;
```
----

**Rule 9. 【推荐】正确使用集合泛型的通配符**

`List<String>`并不是`List<Object>`的子类,如果希望泛型的集合能向上向下兼容转型,而不仅仅适配唯一类,则需定义通配符,可以按需要extends 和 super的字面意义,也可以遵循`PECS(Producer Extends Consumer Super)`原则:

1) 如果集合要被读取,定义成`<? extends T>`

```java
Class Stack<E>{
  public void pushAll(Iterable<? extends E> src){
    for (E e: src)
      push(e);
  }
}

Stack<Number> stack = new Stack<Number>();
Iterable<Integer> integers = ...;
stack.pushAll(integers);
```


2) 如果集合要被写入,定义成`<? super T>`

```java
Class Stack<E>{
  public void popAll(Collection<? super E> dist){
     while(!isEmpty())
   	   dist.add(pop);
  }
}

Stack<Number> stack = new Stack<Number>();
Collection<Object> objects = ...;
stack.popAll(objects);
```
----

**Rule 10. 【推荐】`List`, `List<?>` 与 `List<Object>`的选择**

定义成`List`,会被IDE提示需要定义泛型。 如果实在无法确定泛型,就仓促定义成`List<?>`来蒙混过关的话,该list只能读,不能增改。定义成`List<Object>`呢,如规则9所述,`List<String>` 并不是`List<Object>`的子类,除非函数定义使用了通配符。

因此实在无法明确其泛型时,使用`List`也是可以的。

----

**Rule 11. 【推荐】如果Key只有有限的可选值,先将Key封装成Enum,并使用EnumMap**

EnumMap,以Enum为Key的Map,内部存储结构为`Object[enum.size]`,访问时以`value = Object[enum.ordinal()]`获取值,同时具备HashMap的清晰结构与数组的性能。

```java
public enum COLOR {
  RED, GREEN, BLUE, ORANGE;
}

EnumMap<COLOR, String> moodMap = new EnumMap<COLOR, String> (COLOR.class);
```

* [Sonar-1640: Maps with keys that are enum values should be replaced with EnumMap](https://rules.sonarsource.com/java/RSPEC-1640)

----

**Rule 12. 【推荐】Array 与 List互转的正确写法**

```java
// list -> array,构造数组时不需要设定大小
String[] array = (String[])list.toArray(); //WRONG;
String[] array = list.toArray(new String[0]); //RIGHT
String[] array = list.toArray(new String[list.size()]); //RIGHT,但list.size()可用0代替。


// array -> list
//非原始类型数组,且List不能再扩展
List list = Arrays.asList(array);

//非原始类型数组, 但希望List能再扩展
List list = new ArrayList(array.length);
Collections.addAll(list, array);

//原始类型数组,JDK8
List myList = Arrays.stream(intArray).boxed().collect(Collectors.toList());

//原始类型数组,JDK7则要自己写个循环来加入了
```
Arrays.asList(array),如果array是原始类型数组如int[],会把整个array当作List的一个元素,String[] 或 Foo[]则无此问题。
Collections.addAll()实际是循环加入元素,性能相对较低,同样会把int[]认作一个元素。

* Facebook-Contrib: Correctness - Impossible downcast of toArray() result
* Facebook-Contrib: Correctness - Method calls Array.asList on an array of primitive values

----


================================================
FILE: docs/standard/chapter09.md
================================================
# (九) 并发处理

**Rule 1. 【强制】创建线程或线程池时请指定有意义的线程名称,方便出错时回溯**

1)创建单条线程时直接指定线程名称

```java
Thread t = new Thread();
t.setName("cleanup-thread");
```

2) 线程池则使用guava或自行封装的ThreadFactory,指定命名规则。

```java
//guava 或自行封装的ThreadFactory
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat(threadNamePrefix + "-%d").build();

ThreadPoolExecutor executor = new ThreadPoolExecutor(..., threadFactory, ...);
```

----

**Rule 2. 【推荐】尽量使用线程池来创建线程**

除特殊情况,尽量不要自行创建线程,更好的保护线程资源。

```java
//WRONG
Thread thread = new Thread(...);
thread.start();
```

同理,定时器也不要使用Timer,而应该使用ScheduledExecutorService。

因为Timer只有单线程,不能并发的执行多个在其中定义的任务,而且如果其中一个任务抛出异常,整个Timer也会挂掉,而ScheduledExecutorService只有那个没捕获到异常的任务不再定时执行,其他任务不受影响。

----

**Rule 3. 【强制】线程池不允许使用 Executors去创建,避资源耗尽风险**

Executors返回的线程池对象的弊端 :

1)FixedThreadPool 和 SingleThreadPool:

允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。


2)CachedThreadPool 和 ScheduledThreadPool:

允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。


应通过 new ThreadPoolExecutor(xxx,xxx,xxx,xxx)这样的方式,更加明确线程池的运行规则,合理设置Queue及线程池的core size和max size,建议使用vjkit封装的ThreadPoolBuilder。

----

**Rule 4. 【强制】正确停止线程**

Thread.stop()不推荐使用,强行的退出太不安全,会导致逻辑不完整,操作不原子,已被定义成Deprecate方法。

停止单条线程,执行Thread.interrupt()。

停止线程池:

* ExecutorService.shutdown(): 不允许提交新任务,等待当前任务及队列中的任务全部执行完毕后退出;

* ExecutorService.shutdownNow(): 通过Thread.interrupt()试图停止所有正在执行的线程,并不再处理还在队列中等待的任务。

最优雅的退出方式是先执行shutdown(),再执行shutdownNow(),vjkit的`ThreadPoolUtil`进行了封装。

注意,Thread.interrupt()并不保证能中断正在运行的线程,需编写可中断退出的Runnable,见规则5。

----

**Rule 5. 【强制】编写可停止的Runnable**

执行Thread.interrupt()时,如果线程处于sleep(), wait(), join(), lock.lockInterruptibly()等blocking状态,会抛出InterruptedException,如果线程未处于上述状态,则将线程状态设为interrupted。

因此,如下的代码无法中断线程:

```java
public void run() {

  while (true) { //WRONG,无判断线程状态。
    sleep();
  }

  public void sleep() {
    try {
	  Thread.sleep(1000);
	} catch (InterruptedException e) {
	  logger.warn("Interrupted!", e); //WRONG,吃掉了异常,interrupt状态未再传递
	}
  }
}
```


**5.1 正确处理InterruptException**

因为InterruptException异常是个必须处理的Checked Exception,所以run()所调用的子函数很容易吃掉异常并简单的处理成打印日志,但这等于停止了中断的传递,外层函数将收不到中断请求,继续原有循环或进入下一个堵塞。

正确处理是调用`Thread.currentThread().interrupt();` 将中断往外传递。

```java
//RIGHT
public void myMethod() {
  try {
    ...
  } catch (InterruptedException e) {
    Thread.currentThread().interrupt();
  }
}
```

* [Sonar-2142: "InterruptedException" should not be ignored](https://rules.sonarsource.com/java/RSPEC-2142)



**5.2 主循环及进入阻塞状态前要判断线程状态**

```java
//RIGHT
public void run() {
  try {
    while (!Thread.isInterrupted()) {
      // do stuff
    }
  } catch (InterruptedException e) {
    logger.warn("Interrupted!", e);
  }
}
```

其他如Thread.sleep()的代码,在正式sleep前也会判断线程状态。

----

**Rule 6. 【强制】Runnable中必须捕获一切异常**

如果Runnable中没有捕获RuntimeException而向外抛出,会发生下列情况:

1) ScheduledExecutorService执行定时任务,任务会被中断,该任务将不再定时调度,但线程池里的线程还能用于其他任务。

2) ExecutorService执行任务,当前线程会中断,线程池需要创建新的线程来响应后续任务。

3) 如果没有在ThreadFactory设置自定义的UncaughtExceptionHanlder,则异常最终只打印在System.err,而不会打印在项目的日志中。


因此建议自写的Runnable都要保证捕获异常; 如果是第三方的Runnable,可以将其再包裹一层vjkit中的SafeRunnable。

```java
executor.execute(ThreadPoolUtil.safeRunner(runner));
```

----

**Rule 7. 【强制】全局的非线程安全的对象可考虑使用ThreadLocal存放**

全局变量包括单例对象,static成员变量。

著名的非线程安全类包括SimpleDateFormat,MD5/SHA1的Digest。

对这些类,需要每次使用时创建。

但如果创建有一定成本,可以使用ThreadLocal存放并重用。

ThreadLocal变量需要定义成static,并在每次使用前重置。

```java
private static final ThreadLocal<MessageDigest> SHA1_DIGEST = new ThreadLocal<MessageDigest>() {
  @Override
  protected MessageDigest initialValue() {
    try {
	  return MessageDigest.getInstance("SHA");
	} catch (NoSuchAlgorithmException e) {
	  throw new RuntimeException("...", e);
	}
  }
};

public void digest(byte[] input) {
  MessageDigest digest = SHA1_DIGEST.get();
  digest.reset();
  return digest.digest(input);
}
```

* [Sonar-2885: Non-thread-safe fields should not be static](https://rules.sonarsource.com/java/RSPEC-2885)
* Facebook-Contrib: Correctness - Field is an instance based ThreadLocal variable

----

**Rule 8. 【推荐】缩短锁**

1) 能锁区块,就不要锁整个方法体;

```java
//锁整个方法,等价于整个方法体内synchronized(this)
public synchronized boolean foo(){};

//锁区块方法,仅对需要保护的原子操作的连续代码块进行加锁。
public boolean foo() {
	synchronized(this) {
		...
		...
	}
	//other stuff
}
```

2)能用对象锁,就不要用类锁。

```java
//对象锁,只影响使用同一个对象加锁的线程
synchronized(this) {
	...
}

//类锁,使用类对象作为锁对象,影响所有线程。
synchronized(A.class) {
	...
}
```

----

**Rule 10. 【推荐】选择分离锁,分散锁甚至无锁的数据结构**

* 分离锁:

1) 读写分离锁ReentrantReadWriteLock,读读之间不加锁,仅在写读和写写之间加锁;

2) Array Base的queue一般是全局一把锁,而Linked Base的queue一般是队头队尾两把锁。



* 分散锁(又称分段锁):

1)如JDK7的ConcurrentHashMap,分散成16把锁;

2)对于经常写,少量读的计数器,推荐使用JDK8或vjkit封装的LongAdder对象性能更好(内部分散成多个counter,减少乐观锁的使用,取值时再相加所有counter)



* 无锁的数据结构:

1)完全无锁无等待的结构,如JDK8的ConcurrentHashMap;

2)基于CAS的无锁有等待的数据结构,如AtomicXXX系列。

----

**Rule 11. 【推荐】基于ThreadLocal来避免锁**

比如Random实例虽然是线程安全的,但其实它的seed的访问是有锁保护的。因此建议使用JDK7的ThreadLocalRandom,通过在每个线程里放一个seed来避免了加锁。

----

**Rule 12. 【推荐】规避死锁风险**

对多个资源多个对象的加锁顺序要一致。

如果无法确定完全避免死锁,可以使用带超时控制的tryLock语句加锁。

----

**Rule 13. 【推荐】volatile修饰符,AtomicXX系列的正确使用**

多线程共享的对象,在单一线程内的修改并不保证对所有线程可见。使用volatile定义变量可以解决(解决了可见性)。

但是如果多条线程并发进行基于当前值的修改,如并发的counter++,volatile则无能为力(解决不了原子性)。

此时可使用Atomic*系列:

```java
AtomicInteger count = new AtomicInteger();
count.addAndGet(2);
```

但如果需要原子地同时对多个AtomicXXX的Counter进行操作,则仍然需要使用synchronized将改动代码块加锁。

----

**Rule 14. 【推荐】延时初始化的正确写法**

通过双重检查锁(double-checked locking)实现延迟初始化存在隐患,需要将目标属性声明为volatile型,为了更高的性能,还要把volatile属性赋予给临时变量,写法复杂。

所以如果只是想简单的延迟初始化,可用下面的静态类的做法,利用JDK本身的class加载机制保证唯一初始化。

```java
private static class LazyObjectHolder {
  static final LazyObject instance = new LazyObject();
}

public void myMethod() {
  LazyObjectHolder.instance.doSomething();
}
```

* [Sonar-2168: Double-checked locking should not be used](https://rules.sonarsource.com/java/RSPEC-2168)

----


================================================
FILE: docs/standard/chapter10.md
================================================
# (十) 异常处理

**Rule 1. 【强制】创建异常的消耗大,只用在真正异常的场景**

构造异常时,需要获得整个调用栈,有一定消耗。

不要用来做流程控制,条件控制,因为异常的处理效率比条件判断低。

发生概率较高的条件,应该先进行检查规避,比如:IndexOutOfBoundsException,NullPointerException等,所以如果代码里捕获这些异常通常是个坏味道。

```java
//WRONG
try {
  return obj.method();
} catch (NullPointerException e) {
  return false;
}

//RIGHT
if (obj == null) {
  return false;
}
```

* [Sonar-1696: "NullPointerException" should not be caught](https://rules.sonarsource.com/java/RSPEC-1696)

----

**Rule 2. 【推荐】在特定场景,避免每次构造异常**

如上,异常的构造函数需要获得整个调用栈。

如果异常频繁发生,且不需要打印完整的调用栈时,可以考虑绕过异常的构造函数。

1) 如果异常的message不变,将异常定义为静态成员变量;

下例定义静态异常,并简单定义一层的StackTrace。`ExceptionUtil`见vjkit。

```java
private static RuntimeException TIMEOUT_EXCEPTION = ExceptionUtil.setStackTrace(new RuntimeException("Timeout"),
MyClass.class, "mymethod");

...

throw TIMEOUT_EXCEPTION;
```


2) 如果异常的message会变化,则对静态的异常实例进行clone()再修改message。

Exception默认不是Cloneable的,`CloneableException`见vjkit。

```java
private static CloneableException TIMEOUT_EXCEPTION = new CloneableException("Timeout") .setStackTrace(My.class,
 "hello");

...

throw TIMEOUT_EXCEPTION.clone("Timeout for 40ms");
```


3)自定义异常,也可以考虑重载fillStackTrace()为空函数,但相对没那么灵活,比如无法按场景指定一层的StackTrace。

----

**Rule 3. 【推荐】自定义异常,建议继承`RuntimeException`**

详见《Clean Code》,争论已经结束,不再推荐原本初衷很好的CheckedException。

因为CheckedException需要在抛出异常的地方,与捕获处理异常的地方之间,层层定义throws XXX来传递Exception,如果底层代码改动,将影响所有上层函数的签名,导致编译出错,对封装的破坏严重。对CheckedException的处理也给上层程序员带来了额外的负担。因此其他语言都没有CheckedException的设计。

----

**Rule 4. 【推荐】异常日志应包含排查问题的足够信息**

异常信息应包含排查问题时足够的上下文信息。

捕获异常并记录异常日志的地方,同样需要记录没有包含在异常信息中,而排查问题需要的信息,比如捕获处的上下文信息。

```java
//WRONG
new TimeoutException("timeout");
logger.error(e.getMessage(), e);


//RIGHT
new TimeoutException("timeout:" + eclapsedTime + ", configuration:" + configTime);
logger.error("user[" + userId + "] expired:" + e.getMessage(), e);
```

* Facebook-Contrib: Style - Method throws exception with static message string

----

**Rule 5. 异常抛出的原则**


**5.1 【推荐】尽量使用JDK标准异常,项目标准异常**

尽量使用JDK标准的Runtime异常如`IllegalArgumentException`,`IllegalStateException`,`UnsupportedOperationException`,项目定义的Exception如`ServiceException`。


**5.2 【推荐】根据调用者的需要来定义异常类,直接使用`RuntimeException`是允许的**

是否定义独立的异常类,关键是调用者会如何处理这个异常,如果没有需要特别的处理,直接抛出RuntimeException也是允许的。

----

**Rule 6. 异常捕获的原则**

**6.1 【推荐】按需要捕获异常,捕获`Exception`或`Throwable`是允许的**

如果无特殊处理逻辑,统一捕获Exception统一处理是允许的。

捕获Throwable是为了捕获Error类异常,包括其实无法处理的`OOM` `StackOverflow` `ThreadDeath`,以及类加载,反射时可能抛出的`NoSuchMethodError` `NoClassDefFoundError`等。


**6.2【推荐】多个异常的处理逻辑一致时,使用JDK7的语法避免重复代码**

```java
try {
  ...
} catch (AException | BException | CException ex) {
  handleException(ex);
}
```

* [Sonar-2147: Catches should be combined](https://rules.sonarsource.com/java/RSPEC-2147)

----

**Rule 7.异常处理的原则**

**7.1 【强制】捕获异常一定要处理;如果故意捕获并忽略异常,须要注释写明原因**

方便后面的阅读者知道,此处不是漏了处理。

```java
//WRONG
try {
} catch(Exception e) {
}

//RIGHT
try {
} catch(Exception ignoredExcetpion) {
	//continue the loop
}
```


**7.2 【强制】异常处理不能吞掉原异常,要么在日志打印,要么在重新抛出的异常里包含原异常**

```java
 //WRONG
throw new MyException("message");

//RIGHT 记录日志后抛出新异常,向上次调用者屏蔽底层异常
logger.error("message", ex);
throw new MyException("message");

//RIGHT 传递底层异常
throw new MyException("message", ex);
```

* [Sonar-1166: Exception handlers should preserve the original exceptions](https://rules.sonarsource.com/java/RSPEC-1166),其中默认包含了InterruptedException, NumberFormatException,NoSuchMethodException等若干例外


**7.3 【强制】如果不想处理异常,可以不进行捕获。但最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容**

----

**Rule 8. finally块的处理原则**

**8.1 【强制】必须对资源对象、流对象进行关闭,或使用语法try-with-resource**

关闭动作必需放在finally块,不能放在try块 或 catch块,这是经典的错误。

更加推荐直接使用JDK7的try-with-resource语法自动关闭Closeable的资源,无需在finally块处理,避免潜在问题。

```java
try (Writer writer = ...) {
  writer.append(content);
}
```


**8.2 【强制】如果处理过程中有抛出异常的可能,也要做try-catch,否则finally块中抛出的异常,将代替try块中抛出的异常**

```java
//WRONG
try {
  ...
  throw new TimeoutException();
} finally {
  file.close();//如果file.close()抛出IOException, 将代替TimeoutException
}

//RIGHT, 在finally块中try-catch
try {
  ...
  throw new TimeoutException();
} finally {
  IOUtil.closeQuietly(file); //该方法中对所有异常进行了捕获
}
```

* [Sonar-1163: Exceptions should not be thrown in finally blocks](https://rules.sonarsource.com/java/RSPEC-1163)


**8.3 【强制】不能在finally块中使用return,finally块中的return将代替try块中的return及throw Exception**

```java
//WRONG
try {
  ...
  return 1;
} finally {
  return 2; //实际return 2 而不是1
}

try {
  ...
  throw TimeoutException();
} finally {
  return 2; //实际return 2 而不是TimeoutException
}
```

* [Sonar-1143: Jump statements should not occur in "finally" blocks](https://rules.sonarsource.com/java/RSPEC-1143)

----


================================================
FILE: docs/standard/chapter11.md
================================================
# (十一) 日志规约

**Rule 1. 【强制】应用中不可直接使用日志库(Log4j、Logback)中的API,而应使用日志框架SLF4J中的API**

使用门面模式的日志框架,有利于维护各个类的日志处理方式统一。

```java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private static Logger logger = LoggerFactory.getLogger(Foo.class);
```

----

**Rule 2. 【推荐】对不确定会否输出的日志,采用占位符或条件判断**

```java
//WRONG
logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
```

如果日志级别是info,上述日志不会打印,但是会执行1)字符串拼接操作,2)如果symbol是对象,还会执行toString()方法,浪费了系统资源,最终日志却没有打印。

```java
//RIGHT
logger.debug("Processing trade with id: {} symbol : {} ", id, symbol);
```


但如果symbol.getMessage()本身是个消耗较大的动作,占位符在此时并没有帮助,须要改为条件判断方式来完全避免它的执行。

```java
//WRONG
logger.debug("Processing trade with id: {} symbol : {} ", id, symbol.getMessage());

//RIGHT
if (logger.isDebugEnabled()) {
  logger.debug("Processing trade with id: " + id + " symbol: " + symbol.getMessage());
}
```

----

**Rule 3. 【推荐】对确定输出,而且频繁输出的日志,采用直接拼装字符串的方式**

如果这是一条WARN,ERROR级别的日志,或者确定输出的INFO级别的业务日志,直接字符串拼接,比使用占位符替换,更加高效。

Slf4j的占位符并没有魔术,每次输出日志都要进行占位符的查找,字符串的切割与重新拼接。

```java
//RIGHT
logger.info("I am a business log with id: " + id + " symbol: " + symbol);

//RIGHT
logger.warn("Processing trade with id: " + id + " symbol: " + symbol);
```

----

**Rule 4. 【推荐】尽量使用异步日志**

低延时的应用,使用异步输出的形式(以AsyncAppender串接真正的Appender),可减少IO造成的停顿。

需要正确配置异步队列长度及队列满的行为,是丢弃还是等待可用,业务上允许丢弃的尽量选丢弃。

----

**Rule 5. 【强制】禁止使用性能很低的System.out()打印日志信息**

同理也禁止e.printStackTrace();

例外: 应用启动和关闭时,担心日志框架还未初始化或已关闭。

* [Sonar-106: Standard outputs should not be used directly to log anything](https://rules.sonarsource.com/java/RSPEC-106)
* [Sonar-1148: Throwable.printStackTrace(...) should not be called](https://rules.sonarsource.com/java/RSPEC-1148)

----

**Rule 6. 【强制】禁止配置日志框架输出日志打印处的类名,方法名及行号的信息**

日志框架在每次打印时,通过主动获得当前线程的StackTrace来获取上述信息的消耗非常大,尽量通过Logger名本身给出足够信息。

----

**Rule 7. 【推荐】谨慎地记录日志,避免大量输出无效日志,信息不全的日志**

大量地输出无效日志,不利于系统性能,也不利于快速定位错误点。

记录日志时请思考:这些日志真的有人看吗?看到这条日志你能做什么?能不能给问题排查带来好处?

----

**Rule 8. 【推荐】使用warn级别而不是error级别,记录外部输入参数错误的情况**

如非必要,请不在此场景打印error级别日志,避免频繁报警。

error级别只记录系统逻辑出错、异常或重要的错误信息。

----


================================================
FILE: docs/standard/chapter12.md
================================================
# (十二) 其他规约

**Rule 1. 【参考】尽量不要让魔法值(即未经定义的数字或字符串常量)直接出现在代码中**

```java
 //WRONG
 String key = "Id#taobao_"+tradeId;
 cache.put(key, value);
```
例外:-1,0,1,2,3 不认为是魔法数

* [Sonar-109: Magic numbers should not be used](https://rules.sonarsource.com/java/RSPEC-109) 但现实中所谓魔法数还是太多,该规则不能被真正执行。

----

**Rule 2. 【推荐】时间获取的原则**

1)获取当前毫秒数System.currentTimeMillis() 而不是new Date().getTime(),后者的消耗要大得多。


2)如果要获得更精确的,且不受NTP时间调整影响的流逝时间,使用System.nanoTime()获得机器从启动到现在流逝的纳秒数。


3)如果希望在测试用例中控制当前时间的值,则使用vjkit的Clock类封装,在测试和生产环境中使用不同的实现。

----

**Rule 3. 【推荐】变量声明尽量靠近使用的分支**

不要在一个代码块的开头把局部变量一次性都声明了(这是c语言的做法),而是在第一次需要使用它时才声明。

否则如果方法已经退出或进入其他分支,就白白初始化了变量。

```java
//WRONG
Foo foo = new Foo();

if(ok){
	return;
}

foo.bar();
```

----

**Rule 4. 【推荐】不要像C那样一行里做多件事情**

```java
 //WRONG
fooBar.fChar = barFoo.lchar = 'c';
argv++; argc--;
int level, size;
```

* [Sonar-1659: Multiple variables should not be declared on the same line](https://rules.sonarsource.com/java/RSPEC-1659)

----

**Rule 5. 【推荐】不要为了性能而使用JNI本地方法**

Java在JIT后并不比C代码慢,JNI方法因为要反复跨越JNI与Java的边界反而有额外的性能损耗。

因此JNI方法仅建议用于调用"JDK所没有包括的, 对特定操作系统的系统调用"

----

**Rule 6. 【推荐】正确使用反射,减少性能损耗**

获取Method/Field对象的性能消耗较大, 而如果对Method与Field对象进行缓存再反复调用,则并不会比直接调用类的方法与成员变量慢(前15次使用NativeAccessor,第15次后会生成GeneratedAccessorXXX,bytecode为直接调用实际方法)

```java
//用于对同一个方法多次调用
private Method method = ....

public void foo(){
  method.invoke(obj, args);
}

//用于仅会对同一个方法单次调用
ReflectionUtils.invoke(obj, methodName, args);
```

----

**Rule 7.【推荐】可降低优先级的常见代码检查规则**

1. 接口内容的定义中,去除所有modifier,如public等。 (多个public也没啥,反正大家都看惯了)

2. 工具类,定义private构造函数使其不能被实例化。(命名清晰的工具类,也没人会去实例化它,对静态方法通过类来访问也能避免实例化)

----


================================================
FILE: docs/standard/merge.bat
================================================
@echo off
type README.md > vip-java-standard.md
type chapter01.md >> vip-java-standard.md
type chapter02.md >> vip-java-standard.md
type chapter03.md >> vip-java-standard.md
type chapter04.md >> vip-java-standard.md
type chapter05.md >> vip-java-standard.md
type chapter06.md >> vip-java-standard.md
type chapter07.md >> vip-java-standard.md
type chapter08.md >> vip-java-standard.md
type chapter09.md >> vip-java-standard.md
type chapter10.md >> vip-java-standard.md
type chapter11.md >> vip-java-standard.md
type chapter12.md >> vip-java-standard.md
type ali.md >> vip-java-standard.md

echo vip-java-standard.md is ready to be converted to pdf by any tools you like.
echo press any key to exit.

pause > nul
exit


================================================
FILE: docs/standard/merge.sh
================================================
#!/bin/sh

cat README.md > vip-java-standard.md
cat chapter01.md >> vip-java-standard.md
cat chapter02.md >> vip-java-standard.md
cat chapter03.md >> vip-java-standard.md
cat chapter04.md >> vip-java-standard.md
cat chapter05.md >> vip-java-standard.md
cat chapter06.md >> vip-java-standard.md
cat chapter07.md >> vip-java-standard.md
cat chapter08.md >> vip-java-standard.md
cat chapter09.md >> vip-java-standard.md
cat chapter10.md >> vip-java-standard.md
cat chapter11.md >> vip-java-standard.md
cat chapter12.md >> vip-java-standard.md
cat ali.md >> vip-java-standard.md

echo vip-java-standard.md is ready to be converted to pdf by any tools you like.


================================================
FILE: pom.xml
================================================
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.sonatype.oss</groupId>
		<artifactId>oss-parent</artifactId>
		<version>7</version>
	</parent>

	<groupId>com.vip.vjtools</groupId>
	<artifactId>vjtools</artifactId>
	<version>1.0.9-SNAPSHOT</version>
	<name>vjtools</name>
	<packaging>pom</packaging>

	<description>VJTools - VIP's core libraries and tools</description>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>


	<distributionManagement>
		<snapshotRepository>
			<id>sonatype-nexus-snapshots</id>
			<url>https://oss.sonatype.org/content/repositories/snapshots</url>
		</snapshotRepository>
		<repository>
			<id>sonatype-nexus-releases</id>
			<url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
		</repository>
	</distributionManagement>

	<profiles>
		<profile>
			<id>jdk7</id>
			<activation>
				<jdk>1.7</jdk>
			</activation>
			<modules>
				<module>vjkit</module>
				<module>vjstar</module>
				<module>vjmap</module>
				<module>vjtop</module>
				<module>vjmxcli</module>
			</modules>
		</profile>

		<profile>
			<id>jdk8</id>
			<activation>
				<jdk>1.8</jdk>
			</activation>
			<modules>
				<module>vjkit</module>
				<module>vjstar</module>
				<module>vjmap</module>
				<module>vjtop</module>
				<module>vjmxcli</module>
				<module>standard/sonar-vj</module>
			</modules>
		</profile>

		<profile>
			<id>jdk9</id>
			<activation>
				<jdk>9</jdk>
			</activation>
			<modules>
				<module>vjkit</module>
				<module>vjstar</module>
			</modules>
		</profile>

		<profile>
			<id>release</id>
			<modules>
				<module>vjkit</module>
				<module>vjmap</module>
				<module>vjtop</module>
				<module>vjmxcli</module>
			</modules>
			<build>
				<plugins>
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-release-plugin</artifactId>
						<version>2.5.3</version>
						<configuration>
							<tagNameFormat>v.@{project.version}</tagNameFormat>
						 </configuration>
					</plugin>

					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-gpg-plugin</artifactId>
						<version>1.6</version>
						<executions>
							<execution>
								<id>sign-artifacts</id>
								<phase>verify</phase>
								<goals>
									<goal>sign</goal>
								</goals>
							</execution>
						</executions>
					</plugin>
				</plugins>
			</build>
		</profile>

	</profiles>

	<scm>
		<connection>scm:git:https://github.com/vipshop/vjtools.git</connection>
		<developerConnection>scm:git:https://github.com/vipshop/vjtools.git</developerConnection>
		<url>https://github.com/vipshop/vjtools</url>
	  <tag>v.1.0.2</tag>
  </scm>

	<url>https://github.com/vipshop/vjtools</url>

	<licenses>
		<license>
			<name>Apache License 2.0</name>
			<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
			<distribution>repo</distribution>
		</license>
	</licenses>

	<developers>
		<!--not noly me, write a name here just for sonatype requirement -->
		<developer>
			<id>calvin</id>
			<name>Calvin Xiao</name>
			<email>calvin.xiao at vipshop.com</email>
			<roles>
				<role>developer</role>
			</roles>
			<timezone>+8</timezone>
		</developer>
	</developers>
</project>


================================================
FILE: standard/README.md
================================================
# Java Standard

| Project | Description |
| -------- | -------- |
| [standard](https://vipshop.github.io/vjtools/#/standard/) | 唯品会Java开发手册 |
| [code formatter](formatter) | IDE格式化模板 |
| [sonar rule](sonar-vj) | Sonar规则定制示例 |

================================================
FILE: standard/formatter/README.md
================================================
# 公司通用代码格式化模板

定制原因详见[《唯品会Java开发手册》 第二章:格式规约](https://vipshop.github.io/vjtools/#/standard/chapter02),同时参考了一些Intellij IDEA默认模板的部分设置。

将下列profile下载并导入IDE即可,导入后Profile名称为`vipshop2.0`:

* [Eclipse Code Formatter Profile](https://raw.githubusercontent.com/vipshop/vjtools/master/standard/formatter/vjtools-code-conventions-eclipse.xml)
* [Intellij Code Formatter Profile](https://raw.githubusercontent.com/vipshop/vjtools/master/standard/formatter/vjtools-code-conventions-idea.xml)

因为Intellij导入Eclipse Profile存在问题,因此同时提供了两者的Profile。

## 1. 与 Eclipse 4.6 的`Eclipse [build-in]`模板的区别

* 不格式化JavaDoc
* 注释行宽从80改为120
* 打开format on/off标志
* 参考Intellij IDEA默认模板的修改(见后)


注意:Eclipse后来的build-in模板,代码行宽已经默认120。

## 2. 与IDEA默认模板的区别


本模板参考了Intellij IDEA默认模板中如下部分: 

* 简单的if语句,如果没有括号,则格式化成同一行。(勾选Control Statement->if else->Keep  simple 'if'  on one line)

```java
if (2 < 3) return;
```

当然,我们还是建议用括号,此处格式化成一行只是兜底的保护。

* 主动输入的空行,最多可保留两行 (Blank Lines->Existing blank lines -> Number of empty lines to preserve 从1 改为 2)

* switch 和 case 之间缩进(勾选Indentation-> Indent->Statements within switch body)

```java
switch (a) {
  case 0:
    doCase0();
    break;
  default:
    doDefault();    
}
```

* 数组构造时不要那么多空格(取消White Space->Arrays->Array Initializers->before opening brace,after opening brace,before closing brace)

```java
int[] a  = new int[]{1, 2, 3}; 
```

================================================
FILE: standard/formatter/vjtools-code-conventions-eclipse.xml
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="12">
<profile kind="CodeFormatterProfile" name="vjtools" version="12">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>


================================================
FILE: standard/formatter/vjtools-code-conventions-idea.xml
================================================
<code_scheme name="vjtools">
  <option name="AUTODETECT_INDENTS" value="false" />
  <option name="LINE_SEPARATOR" value="&#xA;" />
  <option name="ENABLE_JAVADOC_FORMATTING" value="false" />
  <option name="FORMATTER_TAGS_ENABLED" value="true" />
  <codeStyleSettings language="JAVA">
    <option name="KEEP_LINE_BREAKS" value="false" />
    <option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
    <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
    <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
    <option name="ALIGN_MULTILINE_RESOURCES" value="false" />
    <option name="CALL_PARAMETERS_WRAP" value="1" />
    <option name="METHOD_PARAMETERS_WRAP" value="1" />
    <option name="RESOURCE_LIST_WRAP" value="5" />
    <option name="EXTENDS_LIST_WRAP" value="1" />
    <option name="THROWS_LIST_WRAP" value="1" />
    <option name="EXTENDS_KEYWORD_WRAP" value="1" />
    <option name="THROWS_KEYWORD_WRAP" value="1" />
    <option name="METHOD_CALL_CHAIN_WRAP" value="1" />
    <option name="BINARY_OPERATION_WRAP" value="1" />
    <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
    <option name="TERNARY_OPERATION_WRAP" value="5" />
    <option name="KEEP_SIMPLE_BLOCKS_IN_ONE_LINE" value="true" />
    <option name="ARRAY_INITIALIZER_WRAP" value="1" />
    <indentOptions>
      <option name="USE_TAB_CHARACTER" value="true" />
    </indentOptions>
  </codeStyleSettings>
</code_scheme>

================================================
FILE: standard/sonar-vj/README.md
================================================
# Sonar VJ 规则

## 概述

我们使用[Sonar](https://www.sonarqube.org/)代码检查工具来辅助[《唯品会Java开发手册》](https://vipshop.github.io/vjtools/#/standard/)的落地。选择的原因是它同时提供了服务端的公共报表,及IDE端的Sonar Lint插件,而且对比PMD与FindBugs,规则也相对容易定制。

因为Sonar有些规则存在误报的情况,我们在力所能及的范围内对规则的实现进行了修改,以符合我们的规范。

## 实现方式

根据[Writing Custom Java Rules 101](https://docs.sonarqube.org/display/PLUG/Writing+Custom+Java+Rules+101),从[Sample Project](https://github.com/SonarSource/sonar-custom-rules-examples/tree/master/java-custom-rules)复制创建,对[Sonar Java](https://github.com/SonarSource/sonar-java/tree/master/java-checks/src/main/java/org/sonar/java/checks)规则进行修改。


## 使用方式

官方的Sonar Java Plugin在不断更新,以下修改未必对应其最新版,仅作为修改示例供大家参考(修改部分在代码中以//VJ 标注)。 

如果需要直接使用,编译后扔进sonar的lib目录,重启sonar后取消对原规则的检查,改为使用这些编号一样,带标题带VJ字样的规则即可。

## 修改规则列表

| 编号 | 等级 | 规则描述 | 修改 |
| -------- | -------- |-------- | -------- |
| 1068| Major | Unused "private" fields should be removed | 忽略由Lombok自动生成的getter/setter的类,私有变量不算无用变量 |
| 1172| Major | Unused method parameters should be removed | 只检查private方法是否有无用参数, 忽略其他公共方法 |
| 1166| Major | Exception handlers should preserve the original exceptions | 忽略异常变量名含ignore字样的检查,可以不进行处理,如catch(Exception ignore) |
| 121| Major | Control structures should use curly braces | if语句忽略一般由IDE生成的equals()方法,以及if(condition) return;的单行模式|
| 1068| Major |Limited dependence should be placed on operator precedence rules in expressions| 忽略三目运算符,不需要加括号来清晰优先级 |
| 115| Minor| Constant names should comply with a naming convention| 忽略对枚举成员的全大写检查 |
| 1312| Minor| IP addresses should not be hardcoded | 忽略对"127.0.0.1"的检查 |
| 1291| Info | Track uses of "NOSONAR" comments| 忽略行内含 Exception/Throwable, System.in/System.err的//NOSOANR 检查  |


================================================
FILE: standard/sonar-vj/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.vip</groupId>
	<artifactId>sonar-vj</artifactId>
	<version>1.0.9-SNAPSHOT</version>
	<packaging>sonar-plugin</packaging>

	<properties>
		<sonar.version>6.7.1</sonar.version>
		<java.plugin.version>5.0.1.12818</java.plugin.version>
		<sslr.version>1.21</sslr.version>
		<gson.version>2.6.2</gson.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>


	<dependencies>
		<dependency>
			<groupId>org.sonarsource.sonarqube</groupId>
			<artifactId>sonar-plugin-api</artifactId>
			<version>${sonar.version}</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>org.sonarsource.java</groupId>
			<artifactId>sonar-java-plugin</artifactId>
			<type>sonar-plugin</type>
			<version>${java.plugin.version}</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>org.sonarsource.java</groupId>
			<artifactId>java-frontend</artifactId>
			<version>${java.plugin.version}</version>
		</dependency>

		<dependency>
			<groupId>org.sonarsource.sslr-squid-bridge</groupId>
			<artifactId>sslr-squid-bridge</artifactId>
			<version>2.6.1</version>
			<exclusions>
				<exclusion>
					<groupId>org.codehaus.sonar.sslr</groupId>
					<artifactId>sslr-core</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.codehaus.sonar</groupId>
					<artifactId>sonar-plugin-api</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.codehaus.sonar.sslr</groupId>
					<artifactId>sslr-xpath</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>jcl-over-slf4j</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>${gson.version}</version>
		</dependency>

		<dependency>
			<groupId>org.sonarsource.sslr</groupId>
			<artifactId>sslr-testing-harness</artifactId>
			<version>${sslr.version}</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.6.2</version>
		</dependency>

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.assertj</groupId>
			<artifactId>assertj-core</artifactId>
			<version>3.6.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>0.9.30</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>

			<plugin>
				<groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
				<artifactId>sonar-packaging-maven-plugin</artifactId>
				<version>1.17</version>
				<extensions>true</extensions>
				<configuration>
					<pluginKey>vj-rules</pluginKey>
					<pluginName>VJ Rules</pluginName>
					<pluginClass>com.vip.vjkit.sonarvj.SonarPlugin</pluginClass>
					<pluginDescription>vip sonar java plugin</pluginDescription>
					<sonarLintSupported>true</sonarLintSupported>
					<sonarQubeMinVersion>6.7</sonarQubeMinVersion>
				</configuration>
			</plugin>


			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.7.0</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>


================================================
FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/SonarCheckRegistrar.java
================================================
package com.vip.vjkit.sonarvj;

import com.vip.vjkit.sonarvj.checks.*;
import org.sonar.plugins.java.api.CheckRegistrar;
import org.sonar.plugins.java.api.JavaCheck;

import java.util.Arrays;

public class SonarCheckRegistrar implements CheckRegistrar {

	@Override
	public void register(RegistrarContext registrarContext) {
		registrarContext.registerClassesForRepository(SonarDefinition.REPOSITORY_KEY, Arrays.asList(checkClasses()),
				Arrays.asList(testCheckClasses()));
	}

	public static Class<? extends JavaCheck>[] checkClasses() {
		return new Class[] { BadConstantNameCheck.class, OperatorPrecedenceCheck.class,
				UnusedMethodParameterCheck.class, UnusedPrivateFieldCheck.class, MissingCurlyBracesCheck.class,
				HardcodedIpCheck.class, NoSonarCheck.class, CatchUsesExceptionWithContextCheck.class };
	}

	public static Class<? extends JavaCheck>[] testCheckClasses() {
		return new Class[] {};
	}
}

================================================
FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/SonarDefinition.java
================================================

package com.vip.vjkit.sonarvj;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Iterables;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rules.RuleType;
import org.sonar.api.server.debt.DebtRemediationFunction;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader;
import org.sonar.api.utils.AnnotationUtils;
import org.sonar.check.Cardinality;
import org.sonar.squidbridge.annotations.RuleTemplate;

import javax.annotation.Nullable;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Locale;

/**
 * Declare rule metadata in server repository of rules.
 * That allows to list the rules in the page "Rules".
 */
public class SonarDefinition implements RulesDefinition {

    // don't change that because the path is hard coded in CheckVerifier
    private static final String RESOURCE_BASE_PATH = "/com/vip/java/rules";

    public static final String REPOSITORY_KEY = "v-squid";

    private final Gson gson = new Gson();

    @Override
    public void define(Context context) {
        NewRepository repository = context
                .createRepository(REPOSITORY_KEY, "java")
                .setName("VIPAnalyzer ");

        List<Class> checks = SonarRulesList.getChecks();
        new RulesDefinitionAnnotationLoader().load(repository, Iterables.toArray(checks, Class.class));

        for (Class ruleClass : checks) {
            newRule(ruleClass, repository);
        }
        repository.done();
    }

    @VisibleForTesting
    protected void newRule(Class<?> ruleClass, NewRepository repository) {

        org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getAnnotation(ruleClass, org.sonar.check.Rule.class);
        if (ruleAnnotation == null) {
            throw new IllegalArgumentException("No Rule annotation was found on " + ruleClass);
        }
        String ruleKey = ruleAnnotation.key();
        if (StringUtils.isEmpty(ruleKey)) {
            throw new IllegalArgumentException("No key is defined in Rule annotation of " + ruleClass);
        }
        NewRule rule = repository.rule(ruleKey);
        if (rule == null) {
            throw new IllegalStateException("No rule was created for " + ruleClass + " in " + repository.key());
        }
        ruleMetadata(ruleClass, rule);

        rule.setTemplate(AnnotationUtils.getAnnotation(ruleClass, RuleTemplate.class) != null);
        if (ruleAnnotation.cardinality() == Cardinality.MULTIPLE) {
            throw new IllegalArgumentException("Cardinality is not supported, use the RuleTemplate annotation instead for " + ruleClass);
        }
    }

    private String ruleMetadata(Class<?> ruleClass, NewRule rule) {
        String metadataKey = rule.key();
        org.sonar.java.RspecKey rspecKeyAnnotation = AnnotationUtils.getAnnotation(ruleClass, org.sonar.java.RspecKey.class);
        if (rspecKeyAnnotation != null) {
            metadataKey = rspecKeyAnnotation.value();
            rule.setInternalKey(metadataKey);
        }
        addHtmlDescription(rule, metadataKey);
        addMetadata(rule, metadataKey);
        return metadataKey;
    }

    private void addMetadata(NewRule rule, String metadataKey) {
        URL resource = SonarDefinition.class.getResource(RESOURCE_BASE_PATH + "/" + metadataKey + "_java.json");
        if (resource != null) {
            RuleMetatada metatada = gson.fromJson(readResource(resource), RuleMetatada.class);
            rule.setSeverity(metatada.defaultSeverity.toUpperCase(Locale.US));
            rule.setName(metatada.title);
            rule.addTags(metatada.tags);
            rule.setType(RuleType.valueOf(metatada.type));
            rule.setStatus(RuleStatus.valueOf(metatada.status.toUpperCase(Locale.US)));
            if (metatada.remediation != null) {
                rule.setDebtRemediationFunction(metatada.remediation.remediationFunction(rule.debtRemediationFunctions()));
                rule.setGapDescription(metatada.remediation.linearDesc);
            }
        }
    }

    private static void addHtmlDescription(NewRule rule, String metadataKey) {
        URL resource = SonarDefinition.class.getResource(RESOURCE_BASE_PATH + "/" + metadataKey + "_java.html");
        if (resource != null) {
            rule.setHtmlDescription(readResource(resource));
        }
    }

    private static String readResource(URL resource) {
        try {
            return Resources.toString(resource, StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new IllegalStateException("Failed to read: " + resource, e);
        }
    }

    private static class RuleMetatada {
        String title;
        String status;
        @Nullable
        Remediation remediation;

        String type;
        String[] tags;
        String defaultSeverity;
    }

    private static class Remediation {
        String func;
        String constantCost;
        String linearDesc;
        String linearOffset;
        String linearFactor;

        public DebtRemediationFunction remediationFunction(DebtRemediationFunctions drf) {
            if (func.startsWith("Constant")) {
                return drf.constantPerIssue(constantCost.replace("mn", "min"));
            }
            if ("Linear".equals(func)) {
                return drf.linear(linearFactor.replace("mn", "min"));
            }
            return drf.linearWithOffset(linearFactor.replace("mn", "min"), linearOffset.replace("mn", "min"));
        }
    }

}


================================================
FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/SonarPlugin.java
================================================
package com.vip.vjkit.sonarvj;

import org.sonar.api.Plugin;

/**
 * Created by cloud.huang on 18/1/5.
 */
public class SonarPlugin implements Plugin {
    @Override
    public void define(Context context) {
        context.addExtension(SonarDefinition.class);
        context.addExtension(SonarCheckRegistrar.class);
    }
}


================================================
FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/SonarRulesList.java
================================================
package com.vip.vjkit.sonarvj;

import com.google.common.collect.ImmutableList;
import com.vip.vjkit.sonarvj.checks.*;
import org.sonar.plugins.java.api.JavaCheck;

import java.util.List;

/**
 * Created by cloud.huang on 18/1/5.
 */
public class SonarRulesList {

    public static List<Class> getChecks() {
        return ImmutableList.<Class>builder().addAll(getJavaChecks()).addAll(getJavaTestChecks()).build();
    }

    public static List<Class<? extends JavaCheck>> getJavaChecks() {
        return ImmutableList.<Class<? extends JavaCheck>>builder()
                .add(BadConstantNameCheck.class)
                .add(OperatorPrecedenceCheck.class)
                .add(UnusedPrivateFieldCheck.class)
                .add(UnusedMethodParameterCheck.class)
                .add(MissingCurlyBracesCheck.class)
                .add(HardcodedIpCheck.class)
                .add(NoSonarCheck.class)
                .add(CatchUsesExceptionWithContextCheck.class)
                .build();
    }

    public static List<Class<? extends JavaCheck>> getJavaTestChecks() {
        return ImmutableList.<Class<? extends JavaCheck>>builder()
                .build();
    }

}


================================================
FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/BadConstantNameCheck.java
================================================
/*
 * SonarQube Java Copyright (C) 2012-2018 SonarSource SA mailto:info AT sonarsource DOT com
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
 * Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package com.vip.vjkit.sonarvj.checks;

import java.util.List;
import java.util.regex.Pattern;

import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.java.checks.serialization.SerializableContract;
import org.sonar.java.resolve.JavaType;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.JavaFileScannerContext;
import org.sonar.plugins.java.api.semantic.Type;
import org.sonar.plugins.java.api.tree.ClassTree;
import org.sonar.plugins.java.api.tree.Modifier;
import org.sonar.plugins.java.api.tree.ModifierKeywordTree;
import org.sonar.plugins.java.api.tree.Tree;
import org.sonar.plugins.java.api.tree.VariableTree;

import com.google.common.collect.ImmutableList;

/**
 * 不对枚举的命名进行检查
 * 
 * 另顺便修正了isConstantTyp一个BUG,加强了报错信息
 * 
 * https://github.com/SonarSource/sonar-java/blob/master/java-checks/src/main/java/org/sonar/java/checks/naming/BadConstantNameCheck.java
 * 
 * 0d54578 Jan 8, 2018
 */
@Rule(key = "S115")
public class BadConstantNameCheck extends IssuableSubscriptionVisitor {

	private static final String DEFAULT_FORMAT = "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$";
	@RuleProperty(key = "format", description = "Regular expression used to check the constant names against.", defaultValue = ""
			+ DEFAULT_FORMAT)
	public String format = DEFAULT_FORMAT;

	private Pattern pattern = null;

	@Override
	public List<Tree.Kind> nodesToVisit() {
		// VJ Replace
		return ImmutableList.of(Tree.Kind.CLASS, Tree.Kind.INTERFACE, Tree.Kind.ANNOTATION_TYPE);
		// return ImmutableList.of(Tree.Kind.CLASS, Tree.Kind.ENUM, Tree.Kind.INTERFACE, Tree.Kind.ANNOTATION_TYPE);
	}

	@Override
	public void scanFile(JavaFileScannerContext context) {
		if (pattern == null) {
			pattern = Pattern.compile(format, Pattern.DOTALL);
		}
		super.scanFile(context);
	}

	@Override
	public void visitNode(Tree tree) {
		ClassTree classTree = (ClassTree) tree;
		for (Tree member : classTree.members()) {
			if (member.is(Tree.Kind.VARIABLE) && hasSemantic()) {
				VariableTree variableTree = (VariableTree) member;
				Type symbolType = variableTree.type().symbolType();
				 if (isConstantType(symbolType) && (classTree.is(Tree.Kind.INTERFACE, Tree.Kind.ANNOTATION_TYPE) || isStaticFinal(variableTree))) {
			          checkName(variableTree);
			     }
			}
			// VJ Remove //
			// else if (member.is(Tree.Kind.ENUM_CONSTANT)) {
			// checkName((VariableTree) member);
			// }
		}
	}

	//VJ: 加上symbolType instanceof JavaType的判断,防止数组转换出错
	private static boolean isConstantType(Type symbolType) {
		return symbolType.isPrimitive() || symbolType.is("java.lang.String") ||  symbolType.is("java.lang.Byte") ||
				symbolType.is("java.lang.Character") ||
				symbolType.is("java.lang.Short") ||
				symbolType.is("java.lang.Integer") ||
				symbolType.is("java.lang.Long") ||
				symbolType.is("java.lang.Float") ||
				symbolType.is("java.lang.Double") ||
				symbolType.is("java.lang.Boolean");
	}

	private void checkName(VariableTree variableTree) {
		String name = variableTree.simpleName().name();
		if (!SerializableContract.SERIAL_VERSION_UID_FIELD.equals(name)
				&& !pattern.matcher(name).matches()) {
			//VJ 报错信息加上变量名
			reportIssue(variableTree.simpleName(),
					"Rename this constant name '" + name + "' to match the regular expression '" + format + "'.");
		}
	}

	private static boolean isStaticFinal(VariableTree variableTree) {
		boolean isStatic = false;
		boolean isFinal = false;
		for (ModifierKeywordTree modifierKeywordTree : variableTree.modifiers().modifiers()) {
			Modifier modifier = modifierKeywordTree.modifier();
			if (modifier == Modifier.STATIC) {
				isStatic = true;
			}
			if (modifier == Modifier.FINAL) {
				isFinal = true;
			}
		}
		return isStatic && isFinal;
	}

}


================================================
FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/CatchUsesExceptionWithContextCheck.java
================================================
package com.vip.vjkit.sonarvj.checks;

import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.java.checks.helpers.ExpressionsHelper;
import org.sonar.java.matcher.MethodMatcher;
import org.sonar.java.matcher.TypeCriteria;
import org.sonar.plugins.java.api.JavaFileScanner;
import org.sonar.plugins.java.api.JavaFileScannerContext;
import org.sonar.plugins.java.api.semantic.Symbol;
import org.sonar.plugins.java.api.tree.*;
import org.sonar.plugins.java.api.tree.Tree.Kind;

import java.util.*;

/**
 * catch异常的变量名包含ignore,忽略检查
 */
@Rule(key = "S1166")
public class CatchUsesExceptionWithContextCheck extends BaseTreeVisitor implements JavaFileScanner {

    private static final String EXCLUDED_EXCEPTION_TYPE = "java.lang.InterruptedException, " +
            "java.lang.NumberFormatException, " +
            "java.lang.NoSuchMethodException, " +
            "java.text.ParseException, " +
            "java.net.MalformedURLException, " +
            "java.time.format.DateTimeParseException";

    @RuleProperty(
            key = "exceptions",
            description = "List of exceptions which should not be checked",
            defaultValue = "" + EXCLUDED_EXCEPTION_TYPE)
    public String exceptionsCommaSeparated = EXCLUDED_EXCEPTION_TYPE;

    private JavaFileScannerContext context;
    private Deque<Collection<IdentifierTree>> validUsagesStack;
    private Iterable<String> exceptions;
    private List<String> exceptionIdentifiers;
    private Set<CatchTree> excludedCatchTrees = new HashSet<>();

    @Override
    public void scanFile(JavaFileScannerContext context) {
        this.context = context;
        validUsagesStack = new ArrayDeque<>();
        exceptions = Splitter.on(",").trimResults().split(exceptionsCommaSeparated);
        exceptionIdentifiers = Lists.newArrayList();
        for (String exception : exceptions) {
            exceptionIdentifiers.add(exception.substring(exception.lastIndexOf('.') + 1));
        }
        if (context.getSemanticModel() != null) {
            scan(context.getTree());
        }
        excludedCatchTrees.clear();
    }

    @Override
    public void visitTryStatement(TryStatementTree tree) {
        if (containsEnumValueOf(tree.block())) {
            tree.catches().stream()
                    .filter(c -> c.parameter().symbol().type().is("java.lang.IllegalArgumentException"))
                    .findAny()
                    .ifPresent(excludedCatchTrees::add);
        }
        super.visitTryStatement(tree);
    }

    private static boolean containsEnumValueOf(Tree tree) {
        EnumValueOfVisitor visitor = new EnumValueOfVisitor();
        tree.accept(visitor);
        return visitor.hasEnumValueOf;
    }

    private static class EnumValueOfVisitor extends BaseTreeVisitor {
        private static final MethodMatcher ENUM_VALUE_OF = MethodMatcher.create()
                .typeDefinition(TypeCriteria.subtypeOf("java.lang.Enum"))
                .name("valueOf")
                .withAnyParameters();
        private boolean hasEnumValueOf = false;

        @Override
        public void visitMethodInvocation(MethodInvocationTree tree) {
            if (ENUM_VALUE_OF.matches(tree)) {
                hasEnumValueOf = true;
            }
            super.visitMethodInvocation(tree);
        }

        @Override
        public void visitClass(ClassTree tree) {
            // skip anonymous classes
        }

        @Override
        public void visitLambdaExpression(LambdaExpressionTree lambdaExpressionTree) {
            // skip lambdas
        }
    }

    @Override
    public void visitCatch(CatchTree tree) {
        if (!isExcludedType(tree.parameter().type()) && !excludedCatchTrees.contains(tree)) {
            Symbol exception = tree.parameter().symbol();
            //catch异常的变量名包含ignore,忽略检查
            if (StringUtils.containsIgnoreCase(exception.name(), "ignore")) {
                return;
            }
            validUsagesStack.addFirst(Lists.newArrayList(exception.usages()));
            super.visitCatch(tree);
            Collection<IdentifierTree> usages = validUsagesStack.pop();
            if (usages.isEmpty()) {
                context.reportIssue(this, tree.parameter(), "Either log or rethrow this exception.");
            }
        }
    }

    @Override
    public void visitMemberSelectExpression(MemberSelectExpressionTree tree) {
        IdentifierTree identifier = null;
        ExpressionTree expression = tree.expression();
        if (expression.is(Kind.IDENTIFIER)) {
            identifier = (IdentifierTree) expression;
        } else if (expression.is(Kind.PARENTHESIZED_EXPRESSION) && ((ParenthesizedTree) expression).expression().is(Kind.IDENTIFIER)) {
            identifier = (IdentifierTree) ((ParenthesizedTree) expression).expression();
        }
        if (!validUsagesStack.isEmpty() && identifier != null) {
            Iterator<Collection<IdentifierTree>> iterator = validUsagesStack.iterator();
            while (iterator.hasNext()) {
                iterator.next().remove(identifier);
            }
        }
        super.visitMemberSelectExpression(tree);

    }

    private boolean isExcludedType(Tree tree) {
        return isUnqualifiedExcludedType(tree) ||
                isQualifiedExcludedType(tree);
    }

    private boolean isUnqualifiedExcludedType(Tree tree) {
        return tree.is(Kind.IDENTIFIER) &&
                exceptionIdentifiers.contains(((IdentifierTree) tree).name());
    }

    private boolean isQualifiedExcludedType(Tree tree) {
        if (!tree.is(Kind.MEMBER_SELECT)) {
            return false;
        }
        return Iterables.contains(exceptions, concatenate((MemberSelectExpressionTree) tree));
    }
    
    public static String concatenate(ExpressionTree tree) {
        if(tree == null) {
          return "";
        }
        Deque<String> pieces = new LinkedList<>();
        ExpressionTree expr = tree;
        while (expr.is(Tree.Kind.MEMBER_SELECT)) {
          MemberSelectExpressionTree mse = (MemberSelectExpressionTree) expr;
          pieces.push(mse.identifier().name());
          pieces.push(".");
          expr = mse.expression();
        }
        if (expr.is(Tree.Kind.IDENTIFIER)) {
          IdentifierTree idt = (IdentifierTree) expr;
          pieces.push(idt.name());
        }

        StringBuilder sb = new StringBuilder();
        for (String piece: pieces) {
          sb.append(piece);
        }
        return sb.toString();
      }

}


================================================
FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/HardcodedIpCheck.java
================================================
package com.vip.vjkit.sonarvj.checks;

import com.google.common.base.Splitter;

import org.sonar.check.Rule;
import org.sonar.java.model.LiteralUtils;
import org.sonar.plugins.java.api.JavaFileScanner;
import org.sonar.plugins.java.api.JavaFileScannerContext;
import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
import org.sonar.plugins.java.api.tree.LiteralTree;
import org.sonar.plugins.java.api.tree.Tree;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 忽略127.0.0.1
 * 
 * https://github.com/SonarSource/sonar-java/blob/master/java-checks/src/main/java/org/sonar/java/checks/HardcodedIpCheck.java
 * 
 * 0d54578  Jan 8, 2018
 */
@Rule(key = "S1313")
public class HardcodedIpCheck extends BaseTreeVisitor implements JavaFileScanner {

	private static final Matcher IP = Pattern
			.compile("([^\\d.]*\\/)?(?<ip>(?:\\d{1,3}\\.){3}\\d{1,3}(?!\\d|\\.))(\\/.*)?").matcher("");

	private JavaFileScannerContext context;

	@Override
	public void scanFile(final JavaFileScannerContext context) {
		this.context = context;
		scan(context.getTree());
	}

	@Override
	public void visitLiteral(LiteralTree tree) {
		if (tree.is(Tree.Kind.STRING_LITERAL)) {
			String value = LiteralUtils.trimQuotes(tree.value());
			IP.reset(value);
			if (IP.matches()) {
				String ip = IP.group("ip");

				// VJ:ADD 忽略127.0.0.1
				if ("127.0.0.1".equals(ip)) {
					return;
				}
				// VJ:END
				if (areAllBelow256(Splitter.on('.').split(ip))) {
					context.reportIssue(this, tree, "Make this IP \"" + ip + "\" address configurable.");
				}
			}
		}
	}

	private static boolean areAllBelow256(Iterable<String> numbersAsStrings) {
		for (String numberAsString : numbersAsStrings) {
			if (Integer.valueOf(numberAsString) > 255) {
				return false;
			}
		}
		return true;
	}

}


================================================
FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/MissingCurlyBracesCheck.java
================================================
package com.vip.vjkit.sonarvj.checks;

import com.google.common.collect.ImmutableList;
import org.sonar.check.Rule;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;

import java.util.List;

/**
 * 1. equals 方法忽略if的检查 2. if(conditon) return true; 忽略在同一行的模式
 * 
 * https://github.com/SonarSource/sonar-java/blob/master/java-checks/src/main/java/org/sonar/java/checks/MissingCurlyBracesCheck.java
 * 
 * 0d54578 Jan 8, 2018
 */
@Rule(key = "S121")
public class MissingCurlyBracesCheck extends IssuableSubscriptionVisitor {

	@Override
	public List<Tree.Kind> nodesToVisit() {
		return ImmutableList.of(Tree.Kind.IF_STATEMENT, Tree.Kind.FOR_EACH_STATEMENT, Tree.Kind.FOR_STATEMENT,
				Tree.Kind.WHILE_STATEMENT, Tree.Kind.DO_STATEMENT);
	}

	@Override
	public void visitNode(Tree tree) {
		switch (tree.kind()) {
		case WHILE_STATEMENT:
			WhileStatementTree whileStatementTree = (WhileStatementTree) tree;
			checkStatement(whileStatementTree.whileKeyword(), whileStatementTree.statement());
			break;
		case DO_STATEMENT:
			DoWhileStatementTree doWhileStatementTree = (DoWhileStatementTree) tree;
			checkStatement(doWhileStatementTree.doKeyword(), doWhileStatementTree.statement());
			break;
		case FOR_STATEMENT:
			ForStatementTree forStatementTree = (ForStatementTree) tree;
			checkStatement(forStatementTree.forKeyword(), forStatementTree.statement());
			break;
		case FOR_EACH_STATEMENT:
			ForEachStatement forEachStatement = (ForEachStatement) tree;
			checkStatement(forEachStatement.forKeyword(), forEachStatement.statement());
			break;
		case IF_STATEMENT:
			checkIfStatement((IfStatementTree) tree);
			break;
		default:
			break;
		}
	}

	private void checkIfStatement(IfStatementTree ifStmt) {
		// equals 方法忽略if的检查, 如果if 与处理函数在同一行忽略。
		if (isInEqualsMethod(ifStmt)) {
			return;
		}

		if (!isSameLine(ifStmt)) {
			checkStatement(ifStmt.ifKeyword(), ifStmt.thenStatement());
		}

		StatementTree elseStmt = ifStmt.elseStatement();
		if (elseStmt != null && !elseStmt.is(Tree.Kind.IF_STATEMENT)) {
			checkStatement(ifStmt.elseKeyword(), elseStmt);
		}
	}

	private boolean isSameLine(IfStatementTree ifStmt) {
		StatementTree thenStmt = ifStmt.thenStatement();
		if (thenStmt.is(Tree.Kind.BLOCK)) {
			return false;
		}

		return ifStmt.firstToken().line() == thenStmt.firstToken().line();
	}

	private boolean isInEqualsMethod(IfStatementTree ifStmt) {
		Tree tree = ifStmt.parent();
		while (tree != null && !(tree instanceof MethodTree)) {
			tree = tree.parent();
		}

		if (tree == null) {
			return false;
		}

		MethodTree methodTree = (MethodTree) tree;
		if (methodTree.simpleName().toString().equals("equals")) {
			return true;
		}
		return false;
	}

	private void checkStatement(SyntaxToken reportToken, StatementTree statement) {
		if (!statement.is(Tree.Kind.BLOCK)) {
			reportIssue(reportToken, "Missing curly brace.");
		}
	}
}


================================================
FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/NoSonarCheck.java
================================================
/*
 * SonarQube Java Copyright (C) 2012-2018 SonarSource SA mailto:info AT sonarsource DOT com
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
 * Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package com.vip.vjkit.sonarvj.checks;

import java.util.Collections;
import java.util.List;

import org.sonar.check.Rule;
import org.sonar.java.RspecKey;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.JavaFileScannerContext;
import org.sonar.plugins.java.api.tree.Tree;

/**
 * 忽略在system.out, e.printStacktrace, catch exception 后设置的NONSAR
 * 
 * 基于TooLongLineCheck完全重写
 */
@Rule(key = "NoSonar")
@RspecKey("S1291")
public class NoSonarCheck extends IssuableSubscriptionVisitor {
	private static final String PATTERN = "NOSONAR";
	private static final String[] IGNORE_PATTERNS = new String[] { "Exception", "Throwable", "System.out", "System.err",
			"printStackTrace" };
	private static final String MESSAGE = "//NOSONAR found: ";

	@Override
	public List<Tree.Kind> nodesToVisit() {
		return Collections.emptyList();
	}

	@Override
	public void scanFile(JavaFileScannerContext context) {
		super.context = context;
		super.scanFile(context);
		visitFile();
	}

	private void visitFile() {
		List<String> lines = context.getFileLines();
		for (int i = 0; i < lines.size(); i++) {
			String line = lines.get(i);
			if (line.contains(PATTERN) && !ignoredLine(line)) {
				addIssue(i + 1, MESSAGE + line);
			}
		}
	}

	private boolean ignoredLine(String line) {
		for (String ignorePattern : IGNORE_PATTERNS) {
			if (line.contains(ignorePattern)) {
				return true;
			}
		}
		return false;
	}
}


================================================
FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/OperatorPrecedenceCheck.java
================================================
/*
 * SonarQube Java
 * Copyright (C) 2012-2017 SonarSource SA
 * mailto:info AT sonarsource DOT com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package com.vip.vjkit.sonarvj.checks;

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Table;
import org.apache.commons.lang.BooleanUtils;
import org.sonar.check.Rule;
import org.sonar.plugins.java.api.JavaFileScanner;
import org.sonar.plugins.java.api.JavaFileScannerContext;
import org.sonar.plugins.java.api.tree.*;

import java.util.*;

/**
 * 三目运算符中的表达式可以不要括号
 * 
 * https://github.com/SonarSource/sonar-java/blob/master/java-checks/src/main/java/org/sonar/java/checks/OperatorPrecedenceCheck.java
 * 
 * 0d54578  Jan 8, 2018
 */
@Rule(key = "S864")
public class OperatorPrecedenceCheck extends BaseTreeVisitor implements JavaFileScanner {

    private static final Table<Tree.Kind, Tree.Kind, Boolean> OPERATORS_RELATION_TABLE;

    private static final Set<Tree.Kind> ARITHMETIC_OPERATORS = EnumSet.of(
            Tree.Kind.MINUS,
            Tree.Kind.REMAINDER,
            Tree.Kind.MULTIPLY,
            Tree.Kind.PLUS
    );

    private static final Set<Tree.Kind> EQUALITY_RELATIONAL_OPERATORS = EnumSet.of(
            Tree.Kind.EQUAL_TO,
            Tree.Kind.GREATER_THAN,
            Tree.Kind.GREATER_THAN_OR_EQUAL_TO,
            Tree.Kind.LESS_THAN,
            Tree.Kind.LESS_THAN_OR_EQUAL_TO,
            Tree.Kind.NOT_EQUAL_TO
    );

    private static final Set<Tree.Kind> SHIFT_OPERATORS = EnumSet.of(
            Tree.Kind.LEFT_SHIFT,
            Tree.Kind.RIGHT_SHIFT,
            Tree.Kind.UNSIGNED_RIGHT_SHIFT
    );

    private static final Tree.Kind[] CONDITIONAL_EXCLUSIONS = new Tree.Kind[]{
            Tree.Kind.METHOD_INVOCATION, Tree.Kind.IDENTIFIER, Tree.Kind.MEMBER_SELECT,
            Tree.Kind.PARENTHESIZED_EXPRESSION, Tree.Kind.TYPE_CAST, Tree.Kind.NEW_CLASS,
            Tree.Kind.ARRAY_ACCESS_EXPRESSION, Tree.Kind.NEW_ARRAY
    };

    static {
        OPERATORS_RELATION_TABLE = HashBasedTable.create();
        put(ARITHMETIC_OPERATORS, Iterables.concat(SHIFT_OPERATORS, EnumSet.of(Tree.Kind.AND, Tree.Kind.XOR, Tree.Kind.OR)));
        put(SHIFT_OPERATORS, Iterables.concat(ARITHMETIC_OPERATORS, EnumSet.of(Tree.Kind.AND, Tree.Kind.XOR, Tree.Kind.OR)));
        put(EnumSet.of(Tree.Kind.AND), Iterables.concat(ARITHMETIC_OPERATORS, SHIFT_OPERATORS, EnumSet.of(Tree.Kind.XOR, Tree.Kind.OR)));
        put(EnumSet.of(Tree.Kind.XOR), Iterables.concat(ARITHMETIC_OPERATORS, SHIFT_OPERATORS, EnumSet.of(Tree.Kind.AND, Tree.Kind.OR)));
        put(EnumSet.of(Tree.Kind.OR), Iterables.concat(ARITHMETIC_OPERATORS, SHIFT_OPERATORS, EnumSet.of(Tree.Kind.AND, Tree.Kind.XOR)));
        put(EnumSet.of(Tree.Kind.CONDITIONAL_AND), EnumSet.of(Tree.Kind.CONDITIONAL_OR));
        put(EnumSet.of(Tree.Kind.CONDITIONAL_OR), EnumSet.of(Tree.Kind.CONDITIONAL_AND));
    }

    private JavaFileScannerContext context;
    private Deque<Tree.Kind> stack = new LinkedList<>();
    private Set<Integer> reportedLines = new HashSet<>();

    private static void put(Iterable<Tree.Kind> firstSet, Iterable<Tree.Kind> secondSet) {
        for (Tree.Kind first : firstSet) {
            for (Tree.Kind second : secondSet) {
                OPERATORS_RELATION_TABLE.put(first, second, true);
            }
        }
    }

    @Override
    public void scanFile(JavaFileScannerContext context) {
        this.context = context;
        reportedLines.clear();
        scan(context.getTree());
        reportedLines.clear();
    }

    @Override
    public void visitAnnotation(AnnotationTree tree) {
        stack.push(null);
        for (ExpressionTree argument : tree.arguments()) {
            if (argument.is(Tree.Kind.ASSIGNMENT)) {
                scan(((AssignmentExpressionTree) argument).expression());
            } else {
                scan(argument);
            }
        }
        stack.pop();
    }

    @Override
    public void visitArrayAccessExpression(ArrayAccessExpressionTree tree) {
        scan(tree.expression());
        stack.push(null);
        scan(tree.dimension());
        stack.pop();
    }

    @Override
    public void visitBinaryExpression(BinaryExpressionTree tree) {
        Tree.Kind peek = stack.peek();
        Tree.Kind kind = tree.kind();
        if (requiresParenthesis(peek, kind)) {
            raiseIssue(tree.operatorToken().line(), tree);
        }
        stack.push(kind);
        super.visitBinaryExpression(tree);
        stack.pop();
    }

    private static boolean requiresParenthesis(Tree.Kind kind1, Tree.Kind kind2) {
        return BooleanUtils.isTrue(OPERATORS_RELATION_TABLE.get(kind1, kind2));
    }

    @Override
    public void visitIfStatement(IfStatementTree tree) {
        super.visitIfStatement(tree);
        ExpressionTree condition = tree.condition();
        if (condition.is(Tree.Kind.ASSIGNMENT) && EQUALITY_RELATIONAL_OPERATORS.contains(((AssignmentExpressionTree) condition).expression().kind())) {
            raiseIssue(((AssignmentExpressionTree) condition).operatorToken().line(), tree);
        }
    }

    @Override
    public void visitMethodInvocation(MethodInvocationTree tree) {
        scan(tree.methodSelect());
        scan(tree.typeArguments());
        for (ExpressionTree argument : tree.arguments()) {
            stack.push(null);
            scan(argument);
            stack.pop();
        }
    }

    @Override
    public void visitNewArray(NewArrayTree tree) {
        stack.push(null);
        super.visitNewArray(tree);
        stack.pop();
    }

    @Override
    public void visitNewClass(NewClassTree tree) {
        stack.push(null);
        super.visitNewClass(tree);
        stack.pop();
    }

    @Override
    public void visitParenthesized(ParenthesizedTree tree) {
        stack.push(null);
        super.visitParenthesized(tree);
        stack.pop();
    }

    @Override
    public void visitConditionalExpression(ConditionalExpressionTree tree) {
        checkConditionalOperand(tree.trueExpression());
        checkConditionalOperand(tree.falseExpression());
        super.visitConditionalExpression(tree);
    }

    private void checkConditionalOperand(ExpressionTree tree) {
        if (!(tree.is(CONDITIONAL_EXCLUSIONS) || tree instanceof LiteralTree || tree instanceof UnaryExpressionTree)) {
            //VJ ADD 三目运算符中的表达式可以不要括号
            if (tree.parent() != null && tree.parent().kind().equals(Tree.Kind.CONDITIONAL_EXPRESSION)) {
                return;
            }
            //VJ END
            raiseIssue(tree.firstToken().line(), tree);
        }
    }

    private void raiseIssue(int line, Tree tree) {
        if (reportedLines.add(line)) {
            context.reportIssue(this, tree, "Add parentheses to make the operator precedence explicit.");
        }
    }

}


================================================
FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/UnusedMethodParameterCheck.java
================================================
/*
 * SonarQube Java
 * Copyright (C) 2012-2018 SonarSource SA
 * mailto:info AT sonarsource DOT com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package com.vip.vjkit.sonarvj.checks;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.sonar.check.Rule;
import org.sonar.java.model.ModifiersUtils;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.JavaFileScannerContext;
import org.sonar.plugins.java.api.semantic.Symbol;
import org.sonar.plugins.java.api.semantic.Type;
import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
import org.sonar.plugins.java.api.tree.ExpressionTree;
import org.sonar.plugins.java.api.tree.IdentifierTree;
import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree;
import org.sonar.plugins.java.api.tree.MethodInvocationTree;
import org.sonar.plugins.java.api.tree.MethodTree;
import org.sonar.plugins.java.api.tree.Modifier;
import org.sonar.plugins.java.api.tree.Tree;
import org.sonar.plugins.java.api.tree.VariableTree;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

/**
 * 只判读private方法里的无用参数
 * 
 * https://github.com/SonarSource/sonar-java/blob/master/java-checks/src/main/java/org/sonar/java/checks/unused/UnusedMethodParameterCheck.java
 * 
 * 2c86dbb Jan 12, 2018
 */
@Rule(key = "S1172")
public class UnusedMethodParameterCheck extends IssuableSubscriptionVisitor {
	private static final String AUTHORIZED_ANNOTATION = "javax.enterprise.event.Observes";
	private static final String STRUTS_ACTION_SUPERCLASS = "org.apache.struts.action.Action";
	private static final Collection<String> EXCLUDED_STRUTS_ACTION_PARAMETER_TYPES = ImmutableList.of(
			"org.apache.struts.action.ActionMapping", "org.apache.struts.action.ActionForm",
			"javax.servlet.http.HttpServletRequest", "javax.servlet.http.HttpServletResponse");

	@Override
	public List<Tree.Kind> nodesToVisit() {
		return ImmutableList.of(Tree.Kind.METHOD, Tree.Kind.CONSTRUCTOR);
	}

	@Override
	public void visitNode(Tree tree) {
		if (!hasSemantic()) {
			return;
		}
		MethodTree methodTree = (MethodTree) tree;
		if (methodTree.block() == null || !isIncluded(methodTree)) {
			return;
		}
		List<IdentifierTree> unused = Lists.newArrayList();
		for (VariableTree var : methodTree.parameters()) {
			Symbol symbol = var.symbol();
			if (symbol.usages().isEmpty() && !symbol.metadata().isAnnotatedWith(AUTHORIZED_ANNOTATION)
					&& !isStrutsActionParameter(var)) {
				unused.add(var.simpleName());
			}
		}
		Set<String> unresolvedIdentifierNames = unresolvedIdentifierNames(methodTree.block());
		// kill the noise regarding unresolved identifiers, and remove the one with matching names from the list of
		// unused
		unused = unused.stream().filter(id -> !unresolvedIdentifierNames.contains(id.name()))
				.collect(Collectors.toList());
		if (!unused.isEmpty()) {
			reportUnusedParameters(unused);
		}
	}

	private void reportUnusedParameters(List<IdentifierTree> unused) {
		List<JavaFileScannerContext.Location> locations = new ArrayList<>();
		for (IdentifierTree identifier : unused) {
			locations.add(new JavaFileScannerContext.Location(
					"Remove this unused method parameter " + identifier.name() + "\".", identifier));
		}
		IdentifierTree firstUnused = unused.get(0);
		String msg;
		if (unused.size() > 1) {
			msg = "Remove these unused method parameters.";
		} else {
			msg = "Remove this unused method parameter \"" + firstUnused.name() + "\".";
		}
		reportIssue(firstUnused, msg, locations, null);
	}

	// VJ: 改为只判读private方法里的无用参数,替代原isExclude
	// 大量删除原来exclude里的复杂判断
	private static boolean isIncluded(MethodTree tree) {
		return isPrivateMethod(tree);
	}

	private static boolean isStrutsActionParameter(VariableTree variableTree) {
		Type superClass = variableTree.symbol().enclosingClass().superClass();
		return superClass != null && superClass.isSubtypeOf(STRUTS_ACTION_SUPERCLASS)
				&& EXCLUDED_STRUTS_ACTION_PARAMETER_TYPES.contains(variableTree.symbol().type().fullyQualifiedName());
	}

	private static boolean isPrivateMethod(MethodTree methodTree) {
		return ModifiersUtils.hasModifier(methodTree.modifiers(), Modifier.PRIVATE);
	}

	private static Set<String> unresolvedIdentifierNames(Tree tree) {
		UnresolvedIdentifierVisitor visitor = new UnresolvedIdentifierVisitor();
		tree.accept(visitor);
		return visitor.unresolvedIdentifierNames;
	}

	private static class UnresolvedIdentifierVisitor extends BaseTreeVisitor {

		private Set<String> unresolvedIdentifierNames = new HashSet<>();

		@Override
		public void visitMemberSelectExpression(MemberSelectExpressionTree tree) {
			// skip annotations and identifier, a method parameter will only be used in expression side (before the dot)
			scan(tree.expression());
		}

		@Override
		public void visitMethodInvocation(MethodInvocationTree tree) {
			ExpressionTree methodSelect = tree.methodSelect();
			if (!methodSelect.is(Tree.Kind.IDENTIFIER)) {
				// not interested in simple method invocations, we are targeting usage of method parameters
				scan(methodSelect);
			}
			scan(tree.typeArguments());
			scan(tree.arguments());
		}

		@Override
		public void visitIdentifier(IdentifierTree tree) {
			if (tree.symbol().isUnknown()) {
				unresolvedIdentifierNames.add(tree.name());
			}
			super.visitIdentifier(tree);
		}
	}
}


================================================
FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/UnusedPrivateFieldCheck.java
================================================
/*
 * SonarQube Java Copyright (C) 2012-2018 SonarSource SA mailto:info AT sonarsource DOT com
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
 * Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

package com.vip.vjkit.sonarvj.checks;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.sonar.check.Rule;
import org.sonar.java.model.ExpressionUtils;
import org.sonar.java.model.ModifiersUtils;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.JavaFileScannerContext;
import org.sonar.plugins.java.api.semantic.Symbol;
import org.sonar.plugins.java.api.tree.AssignmentExpressionTree;
import org.sonar.plugins.java.api.tree.ClassTree;
import org.sonar.plugins.java.api.tree.ExpressionStatementTree;
import org.sonar.plugins.java.api.tree.ExpressionTree;
import org.sonar.plugins.java.api.tree.IdentifierTree;
import org.sonar.plugins.java.api.tree.ImportTree;
import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree;
import org.sonar.plugins.java.api.tree.MethodInvocationTree;
import org.sonar.plugins.java.api.tree.MethodReferenceTree;
import org.sonar.plugins.java.api.tree.MethodTree;
import org.sonar.plugins.java.api.tree.Modifier;
import org.sonar.plugins.java.api.tree.Tree;
import org.sonar.plugins.java.api.tree.Tree.Kind;
import org.sonar.plugins.java.api.tree.VariableTree;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;

/**
 * 不检查lombok自动生成getter/setter的类
 * 
 * https://github.com/SonarSource/sonar-java/blob/master/java-checks/src/main/java/org/sonar/java/checks/unused/UnusedPrivateFieldCheck.java
 * 0d54578 Jan 8, 2018
 */
@Rule(key = "S1068")
public class UnusedPrivateFieldCheck extends IssuableSubscriptionVisitor {

	private static final Tree.Kind[] ASSIGNMENT_KINDS = { Tree.Kind.ASSIGNMENT, Tree.Kind.MULTIPLY_ASSIGNMENT,
			Tree.Kind.DIVIDE_ASSIGNMENT, Tree.Kind.REMAINDER_ASSIGNMENT, Tree.Kind.PLUS_ASSIGNMENT,
			Tree.Kind.MINUS_ASSIGNMENT, Tree.Kind.LEFT_SHIFT_ASSIGNMENT, Tree.Kind.RIGHT_SHIFT_ASSIGNMENT,
			Tree.Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT, Tree.Kind.AND_ASSIGNMENT, Tree.Kind.XOR_ASSIGNMENT,
			Tree.Kind.OR_ASSIGNMENT };

	private List<ClassTree> classes = Lists.newArrayList();
	private ListMultimap<Symbol, IdentifierTree> assignments = ArrayListMultimap.create();
	private Set<String> unknownIdentifiers = new HashSet<>();
	private boolean hasNativeMethod = false;
	private boolean lombokClass = false;

	@Override
	public List<Kind> nodesToVisit() {
		return ImmutableList.of(Tree.Kind.IMPORT, Tree.Kind.CLASS, Tree.Kind.METHOD, Tree.Kind.EXPRESSION_STATEMENT,
				Tree.Kind.IDENTIFIER);
	}

	@Override
	public void scanFile(JavaFileScannerContext context) {
		super.scanFile(context);
		if (!hasNativeMethod && !lombokClass) {
			classes.forEach(this::checkClassFields);
		}
		classes.clear();
		assignments.clear();
		unknownIdentifiers.clear();
		hasNativeMethod = false;
		lombokClass = false;
	}

	@Override
	public void visitNode(Tree tree) {
		if (!hasSemantic()) {
			return;
		}
		switch (tree.kind()) {
		case METHOD:
			checkIfNativeMethod((MethodTree) tree);
			break;
		case CLASS:
			classes.add((ClassTree) tree);
			break;
		case IMPORT:// VJ
			checkIfLombokClass((ImportTree) tree);
			break;
		case EXPRESSION_STATEMENT:
			collectAssignment(((ExpressionStatementTree) tree).expression());
			break;
		case IDENTIFIER:
			collectUnknownIdentifier((IdentifierTree) tree);
			break;
		default:
			throw new IllegalStateException("Unexpected subscribed tree.");
		}
	}

	// VJ
	private void checkIfLombokClass(ImportTree tree) {
		String importStr = fullQualifiedName(tree.qualifiedIdentifier());
		if (importStr.contains("lombok")) {
			lombokClass = true;
		}
	}

	// from WildcardImportsShouldNotBeUsedCheck
	private static String fullQualifiedName(Tree tree) {
		if (tree.is(Tree.Kind.IDENTIFIER)) {
			return ((IdentifierTree) tree).name();
		} else if (tree.is(Tree.Kind.MEMBER_SELECT)) {
			MemberSelectExpressionTree m = (MemberSelectExpressionTree) tree;
			return fullQualifiedName(m.expression()) + "." + m.identifier().name();
		}
		throw new UnsupportedOperationException(String.format("Kind/Class '%s' not supported", tree.getClass()));
	}

	private void collectUnknownIdentifier(IdentifierTree identifier) {
		if (identifier.symbol().isUnknown() && !isMethodIdentifier(identifier)) {
			unknownIdentifiers.add(identifier.name());
		}
	}

	private static boolean isMethodIdentifier(IdentifierTree identifier) {
		Tree parent = identifier.parent();
		while (parent != null && !parent.is(Tree.Kind.METHOD_INVOCATION, Tree.Kind.METHOD_REFERENCE)) {
			parent = parent.parent();
		}
		if (parent == null) {
			return false;
		}
		if (parent.is(Tree.Kind.METHOD_INVOCATION)) {
			return identifier.equals(methodName((MethodInvocationTree) parent));
		} else {
			return identifier.equals(((MethodReferenceTree) parent).method());
		}
	}

	//VJ: copy from MethodsHelper
	public static IdentifierTree methodName(MethodInvocationTree mit) {
	    IdentifierTree id;
	    if (mit.methodSelect().is(Tree.Kind.IDENTIFIER)) {
	      id = (IdentifierTree) mit.methodSelect();
	    } else {
	      id = ((MemberSelectExpressionTree) mit.methodSelect()).identifier();
	    }
	    return id;
	  }
	
	private void checkIfNativeMethod(MethodTree method) {
		if (ModifiersUtils.hasModifier(method.modifiers(), Modifier.NATIVE)) {
			hasNativeMethod = true;
		}
	}

	private void checkClassFields(ClassTree classTree) {
		classTree.members().stream().filter(member -> member.is(Tree.Kind.VARIABLE)).map(VariableTree.class::cast)
				.forEach(this::checkIfUnused);
	}

	public void checkIfUnused(VariableTree tree) {
		if (hasNoAnnotation(tree)) {
			Symbol symbol = tree.symbol();
			String name = symbol.name();
			if (symbol.isPrivate() && onlyUsedInVariableAssignment(symbol) && !"serialVersionUID".equals(name)
					&& !unknownIdentifiers.contains(name)) {
				reportIssue(tree.simpleName(), "Remove this unused \"" + name + "\" private field.");
			}
		}
	}

	private boolean onlyUsedInVariableAssignment(Symbol symbol) {
		return symbol.usages().size() == assignments.get(symbol).size();
	}

	private static boolean hasNoAnnotation(VariableTree tree) {
		return tree.modifiers().annotations().isEmpty();
	}

	private void collectAssignment(ExpressionTree expressionTree) {
		if (expressionTree.is(ASSIGNMENT_KINDS)) {
			addAssignment(((AssignmentExpressionTree) expressionTree).variable());
		}
	}

	private void addAssignment(ExpressionTree tree) {
		ExpressionTree variable = ExpressionUtils.skipParentheses(tree);
		if (variable.is(Tree.Kind.IDENTIFIER)) {
			addAssignment((IdentifierTree) variable);
		} else if (variable.is(Tree.Kind.MEMBER_SELECT)) {
			addAssignment(((MemberSelectExpressionTree) variable).identifier());
		}
	}

	private void addAssignment(IdentifierTree identifier) {
		Symbol reference = identifier.symbol();
		if (!reference.isUnknown()) {
			assignments.put(reference, identifier);
		}
	}

}


================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S1068_java.html
================================================
<h2>VJ update: 使用lobmok的类不告警</h2>
<p>If a <code>private</code> field is declared but not used in the program, it can be considered dead code and should therefore be removed. This will
improve maintainability because developers will not wonder what the variable is used for.</p>
<p>Note that this rule does not take reflection into account, which means that issues will be raised on <code>private</code> fields that are only
accessed using the reflection API.</p>
<h2>Noncompliant Code Example</h2>
<pre>
public class MyClass {
  private int foo = 42;

  public int compute(int a) {
    return a * 42;
  }

}
</pre>
<h2>Compliant Solution</h2>
<pre>
public class MyClass {
  public int compute(int a) {
    return a * 42;
  }
}
</pre>
<h2>Exceptions</h2>
<p>The Java serialization runtime associates with each serializable class a version number, called <code>serialVersionUID</code>, which is used during
deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to
serialization.</p>
<p>A serializable class can declare its own <code>serialVersionUID</code> explicitly by declaring a field named <code>serialVersionUID</code> that
must be static, final, and of type long. By definition those <code>serialVersionUID</code> fields should not be reported by this rule:</p>
<pre>
public class MyClass implements java.io.Serializable {
  private static final long serialVersionUID = 42L;
}
</pre>
<p>Moreover, this rule doesn't raise any issue on annotated fields.</p>

================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S1068_java.json
================================================
{
  "title": "VJ: Unused \"private\" fields should be removed",
  "type": "CODE_SMELL",
  "status": "ready",
  "remediation": {
    "func": "Constant\/Issue",
    "constantCost": "5min"
  },
  "tags": [
    "cert",
    "unused"
  ],
  "defaultSeverity": "Major",
  "ruleSpecification": "RSPEC-1068",
  "sqKey": "S1068"
}

================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S115_java.html
================================================
<h2>VJ update: 枚举可以是小写</h2>
<p>Shared coding conventions allow teams to collaborate efficiently. This rule checks that all constant names match a provided regular expression.</p>
<h2>Noncompliant Code Example</h2>
<p>With the default regular expression <code>^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$</code>:</p>
<pre>
public class MyClass {
  public static final int first = 1;
}

</pre>
<h2>Compliant Solution</h2>
<pre>
public class MyClass {
  public static final int FIRST = 1;
}

</pre>



================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S115_java.json
================================================
{
  "title": "VJ: Constant names should comply with a naming convention",
  "type": "CODE_SMELL",
  "status": "ready",
  "remediation": {
    "func": "Constant\/Issue",
    "constantCost": "2min"
  },
  "tags": [
    "convention"
  ],
  "defaultSeverity": "Minor"
}


================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S1166_java.html
================================================
<h2>VJ update: catch异常的变量名包含ignore,忽略检查</h2>
<p>When handling a caught exception, the original exception's message and stack trace should be logged or passed forward.</p>
<h2>Noncompliant Code Example</h2>
<pre>
try {
  /* ... */
} catch (Exception e) {   // Noncompliant - exception is lost
  LOGGER.info("context");
}

try {
  /* ... */
} catch (Exception e) {  // Noncompliant - exception is lost (only message is preserved)
  LOGGER.info(e.getMessage());
}

try {
  /* ... */
} catch (Exception e) {  // Noncompliant - original exception is lost
  throw new RuntimeException("context");
}
</pre>
<h2>Compliant Solution</h2>
<pre>
try {
  /* ... */
} catch (Exception e) {
  LOGGER.info(e);  // exception is logged
}

try {
  /* ... */
} catch (Exception e) {
  throw new RuntimeException(e);   // exception stack trace is propagated
}

try {
  /* ... */
} catch (RuntimeException e) {
  doSomething();
  throw e;  // original exception passed forward
} catch (Exception e) {
  throw new RuntimeException(e);  // Conversion into unchecked exception is also allowed
}
</pre>
<h2>Exceptions</h2>
<p><code>InterruptedException</code>, <code>NumberFormatException</code>, <code>DateTimeParseException</code>, <code>ParseException</code> and
<code>MalformedURLException</code> exceptions are arguably used to indicate nonexceptional outcomes. Similarly, handling
<code>NoSuchMethodException</code> is often required when dealing with the Java reflection API.</p>
<p>Because they are part of Java, developers have no choice but to deal with them. This rule does not verify that those particular exceptions are
correctly handled.</p>
<pre>
int myInteger;
try {
  myInteger = Integer.parseInt(myString);
} catch (NumberFormatException e) {
  // It is perfectly acceptable to not handle "e" here
  myInteger = 0;
}
</pre>
<h2>See</h2>
<ul>
  <li> <a href="https://www.securecoding.cert.org/confluence/x/6gEqAQ">CERT, ERR00-J.</a> - Do not suppress or ignore checked exceptions </li>
  <li> OWASP Top 10 2017 Category A10 - Insufficient Logging &amp; Monitoring </li>
</ul>



================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S1166_java.json
================================================
{
  "title": "VJ:Exception handlers should preserve the original exceptions",
  "type": "CODE_SMELL",
  "status": "ready",
  "remediation": {
    "func": "Constant\/Issue",
    "constantCost": "10min"
  },
  "tags": [
    "error-handling",
    "owasp-a10",
    "cert",
    "suspicious"
  ],
  "standards": [
    "CERT"
  ],
  "defaultSeverity": "Major",
  "ruleSpecification": "RSPEC-1166",
  "sqKey": "S1166"
}


================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S1172_java.html
================================================
<h2>VJ update:只判断private函数</h2>

<p>Unused parameters for private method misleading. Whatever the values passed to such parameters, the behavior will be the same.</p>

<h2>Noncompliant Code Example</h2>
<pre>
private void doSomething(int a, int b) {     // "b" is unused
  compute(a);
}
</pre>
<h2>Compliant Solution</h2>
<pre>
private void doSomething(int a) {
  compute(a);
}
</pre>

<h2>Exceptions</h2>
<p>The rule will not raise issues for protected or public methods </p>

<h2>See</h2>
<ul>
  <li> MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions. </li>
  <li> MISRA C:2012, 2.7 - There should be no unused parameters in functions </li>
  <li> <a href="https://www.securecoding.cert.org/confluence/x/NYA5">CERT, MSC12-C.</a> - Detect and remove code that has no effect or is never
  executed </li>
  <li> <a href="https://www.securecoding.cert.org/confluence/x/SIIyAQ">CERT, MSC12-CPP.</a> - Detect and remove code that has no effect </li>
</ul>

================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S1172_java.json
================================================
{
  "title": "VJ: Unused private method parameters should be removed",
  "type": "CODE_SMELL",
  "status": "ready",
  "remediation": {
    "func": "Constant\/Issue",
    "constantCost": "5min"
  },
  "tags": [
    "misra",
    "cert",
    "unused"
  ],
  "defaultSeverity": "Major",
  "ruleSpecification": "RSPEC-1172",
  "sqKey": "S1172"
}

================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S121_java.html
================================================
<h2>VJ update: IDE自动生成的方法如equals忽略</h2>
<p>While not technically incorrect, the omission of curly braces can be misleading, and may lead to the introduction of errors during maintenance.</p>
<h2>Noncompliant Code Example</h2>
<pre>
if (condition)  // Noncompliant
  executeSomething();
</pre>
<h2>Compliant Solution</h2>
<pre>
if (condition) {
  executeSomething();
}
</pre>
<h2>See</h2>
<ul>
  <li> MISRA C:2004, 14.8 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement </li>
  <li> MISRA C:2004, 14.9 - An if (expression) construct shall be followed by a compound statement. The else keyword shall be followed by either a
  compound statement, or another if statement </li>
  <li> MISRA C++:2008, 6-3-1 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement </li>
  <li> MISRA C++:2008, 6-4-1 - An if (condition) construct shall be followed by a compound statement. The else keyword shall be followed by either a
  compound statement, or another if statement </li>
  <li> MISRA C:2012, 15.6 - The body of an iteration-statement or a selection-statement shall be a compound-statement </li>
  <li> <a href="https://www.securecoding.cert.org/confluence/x/1QGMAg">CERT, EXP19-C.</a> - Use braces for the body of an if, for, or while statement
  </li>
  <li> <a href="https://www.securecoding.cert.org/confluence/x/3wHEAw">CERT, EXP52-J.</a> - Use braces for the body of an if, for, or while statement
  </li>
</ul>



================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S121_java.json
================================================
{
  "title": "VJ: Control structures should use curly braces",
  "type": "CODE_SMELL",
  "status": "ready",
  "remediation": {
    "func": "Constant\/Issue",
    "constantCost": "2min"
  },
  "tags": [
    "misra",
    "cert",
    "pitfall"
  ],
  "standards": [
    "CERT"
  ],
  "defaultSeverity": "Major",
  "ruleSpecification": "RSPEC-121",
  "sqKey": "S121"
}


================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S1291_java.html
================================================
<h2>VJ update: 忽略在异常捕获语句和System.out后的NOSONAR</h2>
<p>Any issue to quality rule can be deactivated with the <code>NOSONAR</code> marker. This marker is pretty useful to exclude false-positive results
but it can also be used abusively to hide real quality flaws.</p>
<p>This rule raises an issue when <code>NOSONAR</code> is used.</p>

================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S1291_java.json
================================================
{
  "title": "VJ: Track uses of \"NOSONAR\" comments",
  "type": "CODE_SMELL",
  "status": "ready",
  "remediation": {
    "func": "Constant\/Issue",
    "constantCost": "1min"
  },
  "tags": [
    "bad-practice"
  ],
  "defaultSeverity": "Info",
  "ruleSpecification": "RSPEC-1291",
  "sqKey": "S1291"
}

================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S1313_java.html
================================================
<h2>VJ update: 忽略"127.0.0.1"</h2>
<p>Hardcoding an IP address into source code is a bad idea for several reasons:</p>
<ul>
  <li> a recompile is required if the address changes </li>
  <li> it forces the same address to be used in every environment (dev, sys, qa, prod) </li>
  <li> it places the responsibility of setting the value to use in production on the shoulders of the developer </li>
  <li> it allows attackers to decompile the code and thereby discover a potentially sensitive address </li>
</ul>
<h2>Noncompliant Code Example</h2>
<pre>
String ip = "200.112.44.55";
Socket socket = new Socket(ip, 6667);
</pre>
<h2>Compliant Solution</h2>
<pre>
String ip = System.getProperty("myapplication.ip");
Socket socket = new Socket(ip, 6667);
</pre>
<h2>See</h2>
<ul>
  <li> <a href="https://www.securecoding.cert.org/confluence/x/qQCHAQ">CERT, MSC03-J.</a> - Never hard code sensitive information </li>
</ul>

================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S1313_java.json
================================================
{
  "title": "VJ: IP addresses should not be hardcoded",
  "type": "VULNERABILITY",
  "status": "ready",
  "remediation": {
    "func": "Constant\/Issue",
    "constantCost": "30min"
  },
  "tags": [
    "cert"
  ],
  "standards": [
    "CERT"
  ],
  "defaultSeverity": "Minor",
  "ruleSpecification": "RSPEC-1313",
  "sqKey": "S1313"
}

================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S864_java.html
================================================
<h2>VJ update: 三目运算符中的简单表达式可以不要括号</h2>
<p>The rules of operator precedence are complicated and can lead to errors. For this reason, parentheses should be used for clarification in complex
statements. However, this does not mean that parentheses should be gratuitously added around every operation. </p>
<p>This rule raises issues when <code>&amp;&amp;</code> and <code>||</code> are used in combination, when assignment and equality or relational
operators are used in together in a condition, and for other operator combinations according to the following table:</p>
<table>
  <tbody>
    <tr>
      <td> </td>
      <td><code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, <code>%</code></td>
      <td><code>&lt;&lt;</code>, <code>&gt;&gt;</code>, <code>&gt;&gt;&gt;</code></td>
      <td><code>&amp;</code></td>
      <td><code>^</code></td>
      <td> <code>|</code> </td>
    </tr>
    <tr>
      <td><code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, <code>%</code></td>
      <td> </td>
      <td>x</td>
      <td>x</td>
      <td>x</td>
      <td>x</td>
    </tr>
    <tr>
      <td><code>&lt;&lt;</code>, <code>&gt;&gt;</code>, <code>&gt;&gt;&gt;</code></td>
      <td>x</td>
      <td> </td>
      <td>x</td>
      <td>x</td>
      <td>x</td>
    </tr>
    <tr>
      <td><code>&amp;</code></td>
      <td>x</td>
      <td>x</td>
      <td> </td>
      <td>x</td>
      <td>x</td>
    </tr>
    <tr>
      <td><code>^</code></td>
      <td>x</td>
      <td>x</td>
      <td>x</td>
      <td> </td>
      <td>x</td>
    </tr>
    <tr>
      <td> <code>|</code> </td>
      <td>x</td>
      <td>x</td>
      <td>x</td>
      <td>x</td>
      <td> </td>
    </tr>
  </tbody>
</table>
<h2>Noncompliant Code Example</h2>
<pre>
x = a + b - c;
x = a + 1 &lt;&lt; b;  // Noncompliant

if ( a &gt; b || c &lt; d || a == d) {...}
if ( a &gt; b &amp;&amp; c &lt; d || a == b) {...}  // Noncompliant
if (a = f(b,c) == 1) { ... } // Noncompliant; == evaluated first
</pre>
<h2>Compliant Solution</h2>
<pre>
x = a + b - c;
x = (a + 1) &lt;&lt; b;

if ( a &gt; b || c &lt; d || a == d) {...}
if ( (a &gt; b &amp;&amp; c &lt; d) || a == b) {...}
if ( (a = f(b,c)) == 1) { ... }
</pre>
<h2>See</h2>
<ul>
  <li> MISRA C:2004, 12.1 - Limited dependence should be placed on C's operator precedence rules in expressions </li>
  <li> MISRA C:2004, 12.2 - The value of an expression shall be the same under any order of evaluation that the standard permits. </li>
  <li> MISRA C:2004, 12.5 - The operands of a logical &amp;&amp; or || shall be primary-expressions. </li>
  <li> MISRA C++:2008, 5-0-1 - The value of an expression shall be the same under any order of evaluation that the standard permits. </li>
  <li> MISRA C++:2008, 5-0-2 - Limited dependence should be placed on C++ operator precedence rules in expressions </li>
  <li> MISRA C++:2008, 5-2-1 - Each operand of a logical &amp;&amp; or || shall be a postfix-expression. </li>
  <li> MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit </li>
  <li> <a href="https://www.securecoding.cert.org/confluence/x/_wI">CERT, EXP00-C.</a> - Use parentheses for precedence of operation </li>
  <li> <a href="https://www.securecoding.cert.org/confluence/x/VoAyAQ">CERT, EXP00-CPP.</a> - Use parentheses for precedence of operation </li>
  <li> <a href="https://www.securecoding.cert.org/confluence/x/9wHEAw">CERT, EXP53-J.</a> - Use parentheses for precedence of operation </li>
  <li> <a href="http://cwe.mitre.org/data/definitions/783.html">MITRE, CWE-783</a> - Operator Precedence Logic Error </li>
</ul>



================================================
FILE: standard/sonar-vj/src/main/resources/com/vip/java/rules/S864_java.json
================================================
{
  "title": "VJ: Limited dependence should be placed on operator precedence rules in expressions",
  "type": "CODE_SMELL",
  "status": "ready",
  "remediation": {
    "func": "Constant\/Issue",
    "constantCost": "2min"
  },
  "tags": [
    "cwe",
    "misra",
    "cert"
  ],
  "standards": [
    "CWE",
    "CERT"
  ],
  "defaultSeverity": "Major",
  "ruleSpecification": "RSPEC-864",
  "sqKey": "S864"
}


================================================
FILE: vjdump/README.md
================================================
# 1. 概述

VJDump是线上JVM数据紧急收集脚本。 

它可以在紧急场景下(比如马上要对进程进行重启),一键收集jstack、jmap以及GC日志等相关信息,并以zip包保存(默认在目录`/tmp/vjtools/vjdump`下),保证在紧急情况下仍能收集足够的问题排查信息,减轻运维团队的工作量,以及与开发团队的沟通成本。

收集数据包括:
* thread dump数据:`jstack -l $PID`
* vjtop JVM概况及繁忙线程:`vjtop.sh -n 1 $PID` (需要将vjtop.sh 加入用户的PATH变量中)
* jmap histo 堆对象统计数据:`jmap -histo $PID` & `jmap -histo:live $PID`
* GC日志(如果JVM有设定GC日志输出)
* heap dump数据(需指定--liveheap开启):`jmap -dump:live,format=b,file=${DUMP_FILE} $PID`

# 2. 下载

[vjdump.sh](https://raw.githubusercontent.com/vipshop/vjtools/master/vjdump/vjdump.sh)

# 3. 快速入门

以目标JVM相同用户或root用户运行脚本:

```shell

# 对指定的进程PID进行急诊
vjdump.sh $pid


# 额外收集heap dump信息(jmap -dump:live的信息)
vjdump.sh --liveheap $pid

```


在收集过程中,某些命令如`jmap -histo:live $PID` 会造成JVM停顿,因此仅用于紧急情况或已摘流量的情况。为了避免连续停顿,在每条会造成停顿的收集指令之间,默认插入了1秒的执行间隔。


================================================
FILE: vjdump/README_EN.md
================================================
# VJDump
VJDump comes as a handy script for collecting diagnostic data for JVM during urgent failures to
**allow for complete analysis later**.

# 1.Introduction
When major system failures occur for reasons not yet known, rebooting may be the only option to ease user complaints.
There is so little time that even an experienced system admin might forget to pick up all he needs for offline analysis. 

VJDump script is written to make us eaiser, which just packs outputs from T
jstack, jmap, gc logs into the form of a single zip file under `/tmp/vjtools/vjdump`.

**[Important]**: Commands like jstack and jmap DO cause stop-of-the-world of the target app. Make sure the target app 
is isolated from user access before you run this full check in production.

Items to be collected by VJDump are:
* thread dump via `jstack -l $PID`
* vjtop JVM overview and busy threads snapshot via  `vjtop.sh -n 1 -d 3 $PID` (enabled when you have our vjtop installed and 
have the folder of vjtop.sh appended to the PATH environment variable)
* jmap histo object statistics via`jmap -histo $PID` & `jmap -histo:live $PID`
* GC logs if available
* heap dump (which can be optionally switched on via --liveheap):`jmap -dump:live,format=b,file=${DUMP_FILE} $PID`

# 2. Download
[vjdump.sh](https://raw.githubusercontent.com/vipshop/vjtools/master/vjdump/vjdump.sh)

# 3. Getting Started
Use the following commands under **the same user who started the target process** and collect results in `/tmp/vjtools/vjdump`.

```shell

# collect dignostics for target $pid
vjdump.sh $pid


# include heap dump also via jmap -dump:live, might take longer
vjdump.sh --liveheap $pid

```


================================================
FILE: vjdump/vjdump.sh
================================================
#!/bin/bash

USAGE()
{
  echo "usage: $0 [--liveheap][-nz|--nozip][-i|--interval] <pid>"
}

if [ $# -lt 1 ]; then
  USAGE
  exit -1
fi

BASEDIR=/tmp/vjtools
LOGDIR=${BASEDIR}/vjdump
SLEEP_TIME=1
CLOSE_COMPRESS=0
NEED_HEAP_DUMP=0
PID="$1"

while true; do
  case "$1" in
    -i|--interval) SLEEP_TIME="$2"; PID="$3"; shift 1;;
    -nz|--nozip) CLOSE_COMPRESS=1; PID="$2"; shift;;
    --liveheap) NEED_HEAP_DUMP=1; PID="$2"; shift;;
    *) break;;
  esac
done

CMD="$1"
shift

START()
{
  if [[ x"$PID" == x ]]; then
     echo -e "The pid is empty, please enter pid".
     exit -1
  else 
     echo -e "The pid is ${PID}"
  fi

  # try to find $JAVA_HOME if not set
  if [ -z "$JAVA_HOME" ] ; then
      JAVA_HOME=`readlink -f \`which java 2>/dev/null\` 2>/dev/null | \
      sed 's/\jre\/bin\/java//' | sed 's/\/bin\/java//'`
  fi

  if [ ! -f "$JAVA_HOME/bin/jstack" ] ; then
      echo -e "\033[31m\$JAVA_HOME not found. please export JAVA_HOME manually.\033[0m"
      exit -1
  fi


  # clean all history logs
  rm -rf ${LOGDIR}/*.log ${LOGDIR}/*jmap_dump_live-*.bin
  mkdir -p ${LOGDIR}
    
  DATE=$(date "+%Y%m%d%H%M%S")
  
  echo -e "\033[34m$(date '+%Y-%m-%d %H:%M:%S') vjdump begin. command interval is ${SLEEP_TIME}s.\033[0m"
  
  # jstack
  echo -e "$(date '+%Y-%m-%d %H:%M:%S') Begin to process jstack."
  JSTACK_LOG=${LOGDIR}/jstack-${PID}-${DATE}.log
  ${JAVA_HOME}/bin/jstack -l $PID > ${JSTACK_LOG}
  if [[ $? != 0 ]]; then
    echo -e "\033[31mprocess jstack error.\033[0m"
  fi
  echo -e "$(date '+%Y-%m-%d %H:%M:%S') Finish to process jstack."
  sleep ${SLEEP_TIME}
  
  # vjtop
  VJTOP_SCRIPT=vjtop.sh
  which $VJTOP_SCRIPT 2>/dev/null
  if [[ $? == 0 ]]; then
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') Begin to process vjtop."
    echo -e "It will take 3 seconds, please wait."
    VJTOP_LOG=${LOGDIR}/vjtop-${PID}-${DATE}.log
    $VJTOP_SCRIPT -n 3 -d 1 $PID > ${VJTOP_LOG}
    if [[ $? != 0 ]]; then
      echo -e "\033[31mprocess vjtop error.\033[0m"
    fi
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') Finish to process vjtop."
  else
    # no vjtop, use other replacement
    # jinfo -flags $PID
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') Begin to process jinfo -flags."
    JINFO_FLAGS_LOG=${LOGDIR}/jinfo-flags-${PID}-${DATE}.log
    ${JAVA_HOME}/bin/jinfo -flags $PID 1>${JINFO_FLAGS_LOG} 2>&1
    if [[ $? != 0 ]]; then
      echo -e "\033[31mprocess jinfo -flags error.\033[0m"
    fi
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') Finish to process jinfo -flags."
  
    #jmap -heap
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') Begin to process jmap -heap."
    JMAP_HEAP_LOG=${LOGDIR}/jmap_heap-${PID}-${DATE}.log
    ${JAVA_HOME}/bin/jmap -heap $PID > ${JMAP_HEAP_LOG}
    if [[ $? != 0 ]]; then
      echo -e "\033[31mprocess jmap -heap error.\033[0m"
    fi
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') Finish to process jmap -heap."
  fi
  
  # jmap -histo
  echo -e "$(date '+%Y-%m-%d %H:%M:%S') Begin to process jmap -histo."
  JMAP_HISTO_LOG=${LOGDIR}/jmap_histo-${PID}-${DATE}.log
  ${JAVA_HOME}/bin/jmap -histo $PID > ${JMAP_HISTO_LOG}
  if [[ $? != 0 ]]; then
    echo -e "\033[31mprocess jmap -histo error.\033[0m"
  fi
  echo -e "$(date '+%Y-%m-%d %H:%M:%S') Finish to process jmap -histo."
  sleep ${SLEEP_TIME}
  
  # jmap -histo:live
  echo -e "$(date '+%Y-%m-%d %H:%M:%S') Begin to process jmap -histo:live."
  JMAP_HISTO_LIVE_LOG=${LOGDIR}/jmap_histo_live-${PID}-${DATE}.log
  ${JAVA_HOME}/bin/jmap -histo:live $PID > ${JMAP_HISTO_LIVE_LOG}
  if [[ $? != 0 ]]; then
    echo -e "\033[31mprocess jmap -histo:live error.\033[0m"
  fi
  echo -e "$(date '+%Y-%m-%d %H:%M:%S') Finish to process jmap -histo:live."
  sleep ${SLEEP_TIME}
  
  # jmap -dump:live
  if [[ $NEED_HEAP_DUMP == 1 ]]; then
    JMAP_DUMP_FILE=${LOGDIR}/jmap_dump_live-${PID}-${DATE}.bin
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') Begin to process jmap -dump:live."
    ${JAVA_HOME}/bin/jmap -dump:live,format=b,file=${JMAP_DUMP_FILE} $PID
    if [[ $? != 0 ]]; then
      echo -e "\033[31mprocess jmap -dump:live error.\033[0m"
    fi
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') Finish to process jmap -dump:live."
     
    sleep ${SLEEP_TIME}
  fi
  

  # gc log
  echo -e "$(date '+%Y-%m-%d %H:%M:%S') Begin to process gc log."
  GCLOG=$(strings /proc/${PID}/cmdline |grep '\-Xloggc' |cut -d : -f 2)
  if [[ x"$GCLOG" == x ]]; then
    echo -e "No GC log existing."
  else
    # "\cp" means unalias cp, it can cover files without prompting
    \cp -rf $GCLOG ${LOGDIR}/
    if [[ $? != 0 ]]; then
      echo -e "copy gc log error."
    fi
  fi
  echo -e "$(date '+%Y-%m-%d %H:%M:%S') Finish to process gc log."

  # packaging
  if [[ $CLOSE_COMPRESS == 1 ]]; then
    echo -e "The zip option is closed, no zip package will be generated."
  else
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') Begin to zip all files."
    # zip files without heap dump 
    if [ -x "$(command -v zip)" ]; then
        COMPRESS_FILE=${BASEDIR}/vjdump-${PID}-${DATE}.zip
        zip -j ${COMPRESS_FILE} ${LOGDIR}/*.log
    else
        COMPRESS_FILE=${BASEDIR}/vjdump-${PID}-${DATE}.tar.gz
        (cd ${LOGDIR} && tar -zcvf ${COMPRESS_FILE} *.log)
    fi

    if [[ $? != 0 ]]; then
      echo -e "\033[31mzip files error.\033[0m"
    else
      echo -e "zip files success, the zip file is \033[34m${ZIP_FILE}\033[0m"
    fi
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') Finish to zip all files."
    
    if [[ $NEED_HEAP_DUMP == 1 ]]; then
      # compress all files
      echo -e "$(date '+%Y-%m-%d %H:%M:%S') Begin to zip files which include dump file."

      if [ -x "$(command -v zip)" ]; then
        COMPRESS_FILE_WITH_HEAP_DUMP=${BASEDIR}/vjdump-with-heap-${PID}-${DATE}.zip
        zip -j ${COMPRESS_FILE_WITH_HEAP_DUMP} ${LOGDIR}/*.log ${JMAP_DUMP_FILE}
      else
        COMPRESS_FILE_WITH_HEAP_DUMP=${BASEDIR}/vjdump-with-heap-${PID}-${DATE}.tar.gz
        (cd ${LOGDIR} && tar -zcvf ${COMPRESS_FILE_WITH_HEAP_DUMP} *.log *.bin)
      fi

      if [[ $? != 0 ]]; then
        echo -e "\033[31mzip files which include dump file error.\033[0m"
      else
        echo -e "zip files which include dump file success, the zip path is \033[34m${ZIP_FILE_WITH_HEAP_DUMP}\033[0m"
      fi
      echo -e "$(date '+%Y-%m-%d %H:%M:%S') Finish to zip files which include dump file."
    fi
  fi
  echo -e "\033[34m$(date '+%Y-%m-%d %H:%M:%S') vjdump finish. \033[0m"
}

case "$CMD" in
  help) USAGE;;
  *) START;;
esac


================================================
FILE: vjkit/README.md
================================================
# 1. Overview

唯品会Java开发基础类库,综合各门各派众多开源类库的精华而成, 让开发人员避免底层代码的重复开发,默认就拥有最佳实践,尤其在性能的方面。


综合众多开源类库的精华而成, 让开发人员避免底层代码的重复开发,默认就拥有最佳实践,尤其在性能的方面。

针对“基础,文本,数字,日期,文件,集合,并发,反射,日志脱敏”这些开发人员的日常,VJKit做了两件事情:

一是对[Guava](https://github.com/google/guava) 与[Common Lang](https://github.com/apache/commons-lang)中最常用的API的提炼归类,避免了大家直面茫茫多的API(但有些工具类如Guava Cache还是建议直接使用,详见[直用三方工具类](docs/direct_3rd.md) )

二是对各门各派的精华的借鉴移植:比如一些大项目的附送基础库: [Netty](https://github.com/netty/netty/),[ElasticSearch](https://github.com/elastic/elasticsearch), 一些专业的基础库 : [Jodd](https://github.com/oblac/jodd/), [commons-io](https://github.com/apache/commons-io), [commons-collections](https://github.com/apache/commons-collections); 一些大厂的基础库:[Facebook JCommon](https://github.com/facebook/jcommon),[twitter commons](https://github.com/twitter/commons)


具体使用文档请在IDE中阅读JavaDoc,以及对应的单元测试写法。

* [日志脱敏](docs/data_masking.md)


# 2. Usage

Maven : 
```
<dependency>
	<groupId>com.vip.vjtools</groupId>
	<artifactId>vjkit</artifactId>
	<version>1.0.8</version>
</dependency>
```

Download: [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.vip.vjtools/vjkit/badge.svg)](http://search.maven.org/#search|gav|1|g:"com.vip.vjtools"%20AND%20a:"vjkit")


# 3. Dependency

要求JDK 7.0及以上版本。

| Project | Version | Optional|
|--- | --- | --- |
|[Guava](https://github.com/google/guava) | 20.0 ||
|[Apache Common Lang](https://github.com/apache/commons-lang) | 3.7 ||
|[Slf4j](https://www.slf4j.org) | 1.7.25 ||
|[Dozer](http://dozermapper.github.io/) | 5.5.1 |Optional for BeanMapper,[选型](https://github.com/vipshop/vjtools/blob/master/vjkit/src/main/java/com/vip/vjtools/vjkit/reflect/BeanMapper.java#L11) |

如果使用Optional的依赖,请参考pom文件在业务项目自行引入

# 4. Sonar Status

[https://sonarcloud.io/dashboard?id=com.vip.vjtools:vjkit](https://sonarcloud.io/dashboard?id=com.vip.vjtools:vjkit)

(sonarcloud use "Sonar Way")





================================================
FILE: vjkit/docs/data_masking.md
================================================
# 1.简介
vjmask是唯品会的日志脱敏组件,在业务中广泛使用。基于性能和通用性考虑,采用了现在的方案。让使用方用最少的配置和代码,就可以轻松实现敏感信息过滤。

# 2.使用
## 2.1 依赖

```
<dependency>
    <groupId>com.vip.vjtools</groupId>
    <artifactId>vjkit</artifactId>
    <version>${version}</version>
</dependency>
```

## 2.2 最佳实践
脱敏组件支持对单个字符串进行脱敏,也支持toJSON和toString的序列化脱敏

```
import com.vip.vjtools.vjkit.datamasking.DataMask;

// 单个字符串,按中文姓名规则脱敏
logger.info("some sensitive info:{}",DataMask.mask(name,SensitiveType.Name));
//单个字符串,按默认方式脱敏,结果为 "t***";
logger.info("some sensitive info:{}",DataMask.mask("test")); 
 
//对象json序列化脱敏
logger.info("some sensitive object:{}",DataMask.toJSONString(obj));
//对象toString序列化脱敏
logger.info("some sensitive object:{}",DataMask.toString(obj));
```

对类的序列化脱敏,先要对相关敏感字段标记 @Sensitive,支持字符串类型的字段,包括String、String[]和Collection<String>. 嵌套类的敏感字段也是可以识别的。

```
public class User{
  @Sensitive(type = SensitiveType.Phone)  type参考2.3
  private String phone;
}
```

## 2.3 脱敏规则
我们已经定义实现了常用的脱敏类型,可以直接使用

敏感信息 | 脱敏要求 | 样例 | SensitiveType
---|---|---|---
中文姓名 | 三个字及以下,只显示最后一个字;三个字以上,显示最后两个字 | *明,****小明 | Name
手机号/固定电话 | 只显示前三后三 | 138*****111 | Phone
身份证号 | 显示前五个和后二个字符 | 44010************58 | IDCard
银行卡号 | 显示前四个和后二个字符 | 6228************89 | BankCard
地址 | 保留前9个字符 | 广东省广州市荔湾区****** | Address
电子邮箱 | 只显示前一后一及@和后面的内容 | a***b@abc.com | Email
验证码 | 只显示前一后一 | a**b | Captcha
护照/军官号 | 只显示前二后二 | EI****64 | Passport
账号 | 只显示前一后一 | a****b | Account
密码 | 不显示任意字符 | ********* | Password
散列 | sha1(source+salt) ,可以通过DataMask.setSalt设置salt,用于希望在日志系统中精确找回这条日志的场景,可以再自己hash获得hash值 | 6b76e070c5b5d1b889295506faa8b98e97da7e87 | Hash


# 3.详细介绍
## 3.1 Annotation标注
要使用序列化脱敏,先要对敏感字段标注@Sensitive,注意,只对字符串相关的类型字段会生效。

```
//根据类型来标注
@Sensitive(type = SensitiveType.Name)
private String name;
 
//也可以自定义掩码规则
@Sensitive(keepChars = 2) //首尾保留2个字符串,如果keepChars = {1,3} 表示头部保留1个字符,尾部保留3个字符
private String[] phone;
 
// 散列的方式
@Sensitive(type = SensitiveType.Hash)
private String hash;
 
//默认的方式,只保留第一个字符串
@Sensitive
private List<String> account;
```

## 3.2 映射配置
如果你不想对一个个类字段标注@Sensitive,也可以在resource 目录下新建一个data_mask。properties,添加敏感字段映射

```
#SensitiveType=字段名称
Name=nickName
```
那么nickName字段即使没有标注@Sensitive ,在序列化的时候,也会自动脱敏,按照Sent
Download .txt
gitextract_3z1lwxqk/

├── .gitignore
├── .travis.yml
├── LICENSE.txt
├── README.md
├── docs/
│   ├── .nojekyll
│   ├── README.md
│   ├── _coverpage.md
│   ├── _sidebar.md
│   ├── index.html
│   ├── other/
│   │   └── othertools.md
│   └── standard/
│       ├── README.md
│       ├── _sidebar.md
│       ├── ali.md
│       ├── chapter01.md
│       ├── chapter02.md
│       ├── chapter03.md
│       ├── chapter04.md
│       ├── chapter05.md
│       ├── chapter06.md
│       ├── chapter07.md
│       ├── chapter08.md
│       ├── chapter09.md
│       ├── chapter10.md
│       ├── chapter11.md
│       ├── chapter12.md
│       ├── merge.bat
│       └── merge.sh
├── pom.xml
├── standard/
│   ├── README.md
│   ├── formatter/
│   │   ├── README.md
│   │   ├── vjtools-code-conventions-eclipse.xml
│   │   └── vjtools-code-conventions-idea.xml
│   └── sonar-vj/
│       ├── README.md
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── com/
│               │       └── vip/
│               │           └── vjkit/
│               │               └── sonarvj/
│               │                   ├── SonarCheckRegistrar.java
│               │                   ├── SonarDefinition.java
│               │                   ├── SonarPlugin.java
│               │                   ├── SonarRulesList.java
│               │                   └── checks/
│               │                       ├── BadConstantNameCheck.java
│               │                       ├── CatchUsesExceptionWithContextCheck.java
│               │                       ├── HardcodedIpCheck.java
│               │                       ├── MissingCurlyBracesCheck.java
│               │                       ├── NoSonarCheck.java
│               │                       ├── OperatorPrecedenceCheck.java
│               │                       ├── UnusedMethodParameterCheck.java
│               │                       └── UnusedPrivateFieldCheck.java
│               └── resources/
│                   └── com/
│                       └── vip/
│                           └── java/
│                               └── rules/
│                                   ├── S1068_java.html
│                                   ├── S1068_java.json
│                                   ├── S115_java.html
│                                   ├── S115_java.json
│                                   ├── S1166_java.html
│                                   ├── S1166_java.json
│                                   ├── S1172_java.html
│                                   ├── S1172_java.json
│                                   ├── S121_java.html
│                                   ├── S121_java.json
│                                   ├── S1291_java.html
│                                   ├── S1291_java.json
│                                   ├── S1313_java.html
│                                   ├── S1313_java.json
│                                   ├── S864_java.html
│                                   └── S864_java.json
├── vjdump/
│   ├── README.md
│   ├── README_EN.md
│   └── vjdump.sh
├── vjkit/
│   ├── README.md
│   ├── docs/
│   │   ├── data_masking.md
│   │   └── direct_3rd.md
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── vip/
│       │   │           └── vjtools/
│       │   │               └── vjkit/
│       │   │                   ├── base/
│       │   │                   │   ├── BooleanUtil.java
│       │   │                   │   ├── EnumUtil.java
│       │   │                   │   ├── ExceptionUtil.java
│       │   │                   │   ├── MoreValidate.java
│       │   │                   │   ├── ObjectUtil.java
│       │   │                   │   ├── Platforms.java
│       │   │                   │   ├── PropertiesUtil.java
│       │   │                   │   ├── RuntimeUtil.java
│       │   │                   │   ├── SystemPropertiesUtil.java
│       │   │                   │   ├── ValueValidator.java
│       │   │                   │   ├── annotation/
│       │   │                   │   │   ├── NotNull.java
│       │   │                   │   │   ├── Nullable.java
│       │   │                   │   │   └── VisibleForTesting.java
│       │   │                   │   └── type/
│       │   │                   │       ├── CloneableException.java
│       │   │                   │       ├── CloneableRuntimeException.java
│       │   │                   │       ├── Pair.java
│       │   │                   │       ├── Triple.java
│       │   │                   │       └── UncheckedException.java
│       │   │                   ├── collection/
│       │   │                   │   ├── ArrayUtil.java
│       │   │                   │   ├── CollectionUtil.java
│       │   │                   │   ├── ListUtil.java
│       │   │                   │   ├── MapUtil.java
│       │   │                   │   ├── QueueUtil.java
│       │   │                   │   ├── SetUtil.java
│       │   │                   │   └── type/
│       │   │                   │       ├── ConcurrentHashSet.java
│       │   │                   │       ├── MoreLists.java
│       │   │                   │       ├── MoreMaps.java
│       │   │                   │       ├── MoreQueues.java
│       │   │                   │       ├── SortedArrayList.java
│       │   │                   │       └── primitive/
│       │   │                   │           ├── IntObjectHashMap.java
│       │   │                   │           ├── IntObjectMap.java
│       │   │                   │           ├── LongObjectHashMap.java
│       │   │                   │           └── LongObjectMap.java
│       │   │                   ├── concurrent/
│       │   │                   │   ├── Concurrents.java
│       │   │                   │   ├── ThreadDumpper.java
│       │   │                   │   ├── ThreadUtil.java
│       │   │                   │   ├── jsr166e/
│       │   │                   │   │   ├── LongAdder.java
│       │   │                   │   │   └── Striped64.java
│       │   │                   │   ├── limiter/
│       │   │                   │   │   ├── RateLimiterUtil.java
│       │   │                   │   │   ├── Sampler.java
│       │   │                   │   │   └── TimeIntervalLimiter.java
│       │   │                   │   ├── threadpool/
│       │   │                   │   │   ├── AbortPolicyWithReport.java
│       │   │                   │   │   ├── QueuableCachedThreadPool.java
│       │   │                   │   │   ├── ThreadPoolBuilder.java
│       │   │                   │   │   └── ThreadPoolUtil.java
│       │   │                   │   └── type/
│       │   │                   │       ├── BasicFuture.java
│       │   │                   │       └── ThreadLocalContext.java
│       │   │                   ├── datamasking/
│       │   │                   │   ├── DataMask.java
│       │   │                   │   ├── DataMaskJsonFilter.java
│       │   │                   │   ├── MaskMapping.java
│       │   │                   │   ├── MaskStrategy.java
│       │   │                   │   ├── Sensitive.java
│       │   │                   │   ├── SensitiveType.java
│       │   │                   │   └── strategy/
│       │   │                   │       ├── EmailMask.java
│       │   │                   │       ├── HashMask.java
│       │   │                   │       ├── NameMask.java
│       │   │                   │       └── PartMask.java
│       │   │                   ├── id/
│       │   │                   │   └── IdUtil.java
│       │   │                   ├── io/
│       │   │                   │   ├── FilePathUtil.java
│       │   │                   │   ├── FileTreeWalker.java
│       │   │                   │   ├── FileUtil.java
│       │   │                   │   ├── IOUtil.java
│       │   │                   │   ├── ResourceUtil.java
│       │   │                   │   ├── URLResourceUtil.java
│       │   │                   │   └── type/
│       │   │                   │       └── StringBuilderWriter.java
│       │   │                   ├── logging/
│       │   │                   │   └── PerformanceUtil.java
│       │   │                   ├── mapper/
│       │   │                   │   ├── BeanMapper.java
│       │   │                   │   ├── JsonMapper.java
│       │   │                   │   └── XmlMapper.java
│       │   │                   ├── net/
│       │   │                   │   ├── IPUtil.java
│       │   │                   │   └── NetUtil.java
│       │   │                   ├── number/
│       │   │                   │   ├── MathUtil.java
│       │   │                   │   ├── MoneyUtil.java
│       │   │                   │   ├── NumberUtil.java
│       │   │                   │   ├── RandomUtil.java
│       │   │                   │   ├── SizeUnit.java
│       │   │                   │   └── UnitConverter.java
│       │   │                   ├── reflect/
│       │   │                   │   ├── AnnotationUtil.java
│       │   │                   │   ├── ClassLoaderUtil.java
│       │   │                   │   ├── ClassUtil.java
│       │   │                   │   └── ReflectionUtil.java
│       │   │                   ├── security/
│       │   │                   │   └── CryptoUtil.java
│       │   │                   ├── text/
│       │   │                   │   ├── Charsets.java
│       │   │                   │   ├── CsvUtil.java
│       │   │                   │   ├── EncodeUtil.java
│       │   │                   │   ├── EscapeUtil.java
│       │   │                   │   ├── HashUtil.java
│       │   │                   │   ├── MoreStringUtil.java
│       │   │                   │   ├── StringBuilderHolder.java
│       │   │                   │   ├── TextValidator.java
│       │   │                   │   └── WildcardMatcher.java
│       │   │                   └── time/
│       │   │                       ├── CachingDateFormatter.java
│       │   │                       ├── ClockUtil.java
│       │   │                       ├── DateFormatUtil.java
│       │   │                       └── DateUtil.java
│       │   └── resources/
│       │       └── sys_data_mask.properties
│       └── test/
│           ├── java/
│           │   └── com/
│           │       └── vip/
│           │           └── vjtools/
│           │               ├── test/
│           │               │   ├── data/
│           │               │   │   └── RandomData.java
│           │               │   ├── log/
│           │               │   │   ├── LogbackListAppender.java
│           │               │   │   └── LogbackListAppenderTest.java
│           │               │   └── rule/
│           │               │       └── TestProgress.java
│           │               └── vjkit/
│           │                   ├── base/
│           │                   │   ├── BooleanUtilTest.java
│           │                   │   ├── EnumUtilTest.java
│           │                   │   ├── ExceptionUtilTest.java
│           │                   │   ├── MoreValidateTest.java
│           │                   │   ├── ObjectUtilTest.java
│           │                   │   ├── PairTest.java
│           │                   │   ├── PlatformsTest.java
│           │                   │   ├── PropertiesUtilTest.java
│           │                   │   ├── RuntimeUtilTest.java
│           │                   │   ├── SystemPropertiesUtilTest.java
│           │                   │   └── ValueValidatorTest.java
│           │                   ├── collection/
│           │                   │   ├── ArrayUtilTest.java
│           │                   │   ├── CollectionUtilTest.java
│           │                   │   ├── ListUtilTest.java
│           │                   │   ├── MapUtilTest.java
│           │                   │   ├── QueueUtilTest.java
│           │                   │   ├── SetUtilTest.java
│           │                   │   └── type/
│           │                   │       ├── ConcurrentHashSetTest.java
│           │                   │       └── SortedArrayListTest.java
│           │                   ├── concurrent/
│           │                   │   ├── ConcurrentsTest.java
│           │                   │   ├── ThreadDumpperTest.java
│           │                   │   ├── ThreadUtilTest.java
│           │                   │   ├── limiter/
│           │                   │   │   ├── RateLimiterUtilTest.java
│           │                   │   │   ├── SamplerTest.java
│           │                   │   │   └── TimeIntervalLimiterTest.java
│           │                   │   ├── threadpool/
│           │                   │   │   ├── AbortPolicyWithReportTest.java
│           │                   │   │   ├── QueuableCachedThreadPoolTest.java
│           │                   │   │   ├── ThreadPoolBuilderTest.java
│           │                   │   │   └── ThreadPoolUtilTest.java
│           │                   │   └── type/
│           │                   │       ├── BasicFutureTest.java
│           │                   │       └── ThreadLocalContextTest.java
│           │                   ├── datamasking/
│           │                   │   ├── DataMaskJsonFilterTest.java
│           │                   │   ├── DataMaskTest.java
│           │                   │   ├── MaskMappingTest.java
│           │                   │   ├── data/
│           │                   │   │   ├── TestChild.java
│           │                   │   │   ├── TestData.java
│           │                   │   │   ├── TestParent.java
│           │                   │   │   └── TestUserMapingData.java
│           │                   │   └── strategy/
│           │                   │       ├── EmailMaskTest.java
│           │                   │       ├── HashMaskTest.java
│           │                   │       ├── NameMaskTest.java
│           │                   │       └── PartMaskTest.java
│           │                   ├── id/
│           │                   │   └── IdUtilTest.java
│           │                   ├── io/
│           │                   │   ├── FilePathUtilTest.java
│           │                   │   ├── FileTreeWalkerTest.java
│           │                   │   ├── FileUtilTest.java
│           │                   │   ├── IOUtilTest.java
│           │                   │   ├── ResourceUtilTest.java
│           │                   │   └── URLResourceTest.java
│           │                   ├── logging/
│           │                   │   └── PerformanceUtilsTest.java
│           │                   ├── mapper/
│           │                   │   ├── BeanMapperTest.java
│           │                   │   ├── JsonMapperTest.java
│           │                   │   └── XmlMapperTest.java
│           │                   ├── net/
│           │                   │   ├── IPUtilTest.java
│           │                   │   └── NetUtilTest.java
│           │                   ├── number/
│           │                   │   ├── MathUtilTest.java
│           │                   │   ├── MoneyUtilTest.java
│           │                   │   ├── NumberUtilTest.java
│           │                   │   ├── RandomUtilTest.java
│           │                   │   └── UnitConverterTest.java
│           │                   ├── reflect/
│           │                   │   ├── ClassUtilTest.java
│           │                   │   ├── ClassloaderUtilTest.java
│           │                   │   └── ReflectionUtilTest.java
│           │                   ├── security/
│           │                   │   └── CryptoUtilTest.java
│           │                   ├── text/
│           │                   │   ├── CsvUtilTest.java
│           │                   │   ├── EncodeUtilTest.java
│           │                   │   ├── EscapeUtilTest.java
│           │                   │   ├── HashUtilTest.java
│           │                   │   ├── MoreStringUtilTest.java
│           │                   │   ├── StringBuilderHolderTest.java
│           │                   │   ├── TextValidatorTest.java
│           │                   │   └── WildcardMatcherTest.java
│           │                   └── time/
│           │                       ├── CachingDatFormatterTest.java
│           │                       ├── ClockUtilTest.java
│           │                       ├── DateFormatUtilTest.java
│           │                       └── DateUtilTest.java
│           └── resources/
│               ├── application.properties
│               ├── data_mask.properties
│               ├── logback-test.xml
│               └── test.txt
├── vjmap/
│   ├── README.md
│   ├── README_EN.md
│   ├── pom.xml
│   └── src/
│       └── main/
│           ├── assembly/
│           │   ├── distribution.xml
│           │   ├── vjmap.bat
│           │   └── vjmap.sh
│           └── java/
│               └── com/
│                   └── vip/
│                       └── vjtools/
│                           └── vjmap/
│                               ├── ClassStats.java
│                               ├── ResultPrinter.java
│                               ├── VJMap.java
│                               ├── oops/
│                               │   ├── GenAddressAccessor.java
│                               │   ├── HeapHistogramVisitor.java
│                               │   ├── HeapUtils.java
│                               │   ├── LoadedClassAccessor.java
│                               │   ├── OldgenAccessor.java
│                               │   └── SurvivorAccessor.java
│                               └── utils/
│                                   ├── FormatUtils.java
│                                   ├── ProgressNotifier.java
│                                   └── TimeController.java
├── vjmxcli/
│   ├── README.md
│   ├── pom.xml
│   └── src/
│       └── main/
│           ├── assembly/
│           │   ├── distribution.xml
│           │   ├── vjmxcli.bat
│           │   └── vjmxcli.sh
│           └── java/
│               └── com/
│                   └── vip/
│                       └── vjtools/
│                           └── jmx/
│                               ├── Client.java
│                               ├── ExtraCommand.java
│                               └── GCutilExpression.java
├── vjstar/
│   ├── README.md
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── vip/
│       │   │           └── vjstar/
│       │   │               ├── .gitkeep
│       │   │               ├── gc/
│       │   │               │   ├── CleanUpScheduler.java
│       │   │               │   └── ProactiveGcTask.java
│       │   │               └── window/
│       │   │                   ├── AtomicBitSet.java
│       │   │                   ├── RequestSlidingWindow.java
│       │   │                   └── TimeSlidingWindow.java
│       │   └── script/
│       │       ├── docker-cpus/
│       │       │   └── README.md
│       │       └── jvm-options/
│       │           └── jvm-options.sh
│       └── test/
│           └── java/
│               └── com/
│                   └── vip/
│                       └── vjstar/
│                           ├── .gitkeep
│                           ├── gc/
│                           │   ├── Enchanter.java
│                           │   └── ProactiveGcTaskDemo.java
│                           └── window/
│                               ├── RequestSlidingWindowTest.java
│                               └── TimeSlidingWindowTest.java
└── vjtop/
    ├── README.md
    ├── README_EN.md
    ├── pom.xml
    └── src/
        ├── main/
        │   ├── assembly/
        │   │   ├── distribution.xml
        │   │   ├── vjtop.bat
        │   │   └── vjtop.sh
        │   └── java/
        │       └── com/
        │           └── vip/
        │               └── vjtools/
        │                   └── vjtop/
        │                       ├── InteractiveTask.java
        │                       ├── ThreadPrinter.java
        │                       ├── TopThreadInfo.java
        │                       ├── VJTop.java
        │                       ├── VMDetailView.java
        │                       ├── VMInfo.java
        │                       ├── WarningRule.java
        │                       ├── data/
        │                       │   ├── PerfData.java
        │                       │   ├── ProcFileData.java
        │                       │   └── jmx/
        │                       │       ├── JmxBufferPoolManager.java
        │                       │       ├── JmxClient.java
        │                       │       ├── JmxGarbageCollectorManager.java
        │                       │       └── JmxMemoryPoolManager.java
        │                       └── util/
        │                           ├── Formats.java
        │                           ├── LongObjectHashMap.java
        │                           ├── LongObjectMap.java
        │                           ├── OptionAdvanceParser.java
        │                           ├── SelectPid.java
        │                           └── Utils.java
        └── test/
            └── java/
                └── com/
                    └── vip/
                        └── vjtools/
                            └── vjtop/
                                └── util/
                                    ├── FormatsTest.java
                                    └── UtilsTest.java
Download .txt
SYMBOL INDEX (2264 symbols across 228 files)

FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/SonarCheckRegistrar.java
  class SonarCheckRegistrar (line 9) | public class SonarCheckRegistrar implements CheckRegistrar {
    method register (line 11) | @Override
    method checkClasses (line 17) | public static Class<? extends JavaCheck>[] checkClasses() {
    method testCheckClasses (line 23) | public static Class<? extends JavaCheck>[] testCheckClasses() {

FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/SonarDefinition.java
  class SonarDefinition (line 29) | public class SonarDefinition implements RulesDefinition {
    method define (line 38) | @Override
    method newRule (line 53) | @VisibleForTesting
    method ruleMetadata (line 76) | private String ruleMetadata(Class<?> ruleClass, NewRule rule) {
    method addMetadata (line 88) | private void addMetadata(NewRule rule, String metadataKey) {
    method addHtmlDescription (line 104) | private static void addHtmlDescription(NewRule rule, String metadataKe...
    method readResource (line 111) | private static String readResource(URL resource) {
    class RuleMetatada (line 119) | private static class RuleMetatada {
    class Remediation (line 130) | private static class Remediation {
      method remediationFunction (line 137) | public DebtRemediationFunction remediationFunction(DebtRemediationFu...

FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/SonarPlugin.java
  class SonarPlugin (line 8) | public class SonarPlugin implements Plugin {
    method define (line 9) | @Override

FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/SonarRulesList.java
  class SonarRulesList (line 12) | public class SonarRulesList {
    method getChecks (line 14) | public static List<Class> getChecks() {
    method getJavaChecks (line 18) | public static List<Class<? extends JavaCheck>> getJavaChecks() {
    method getJavaTestChecks (line 31) | public static List<Class<? extends JavaCheck>> getJavaTestChecks() {

FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/BadConstantNameCheck.java
  class BadConstantNameCheck (line 44) | @Rule(key = "S115")
    method nodesToVisit (line 54) | @Override
    method scanFile (line 61) | @Override
    method visitNode (line 69) | @Override
    method isConstantType (line 88) | private static boolean isConstantType(Type symbolType) {
    method checkName (line 99) | private void checkName(VariableTree variableTree) {
    method isStaticFinal (line 109) | private static boolean isStaticFinal(VariableTree variableTree) {

FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/CatchUsesExceptionWithContextCheck.java
  class CatchUsesExceptionWithContextCheck (line 23) | @Rule(key = "S1166")
    method scanFile (line 45) | @Override
    method visitTryStatement (line 60) | @Override
    method containsEnumValueOf (line 71) | private static boolean containsEnumValueOf(Tree tree) {
    class EnumValueOfVisitor (line 77) | private static class EnumValueOfVisitor extends BaseTreeVisitor {
      method visitMethodInvocation (line 84) | @Override
      method visitClass (line 92) | @Override
      method visitLambdaExpression (line 97) | @Override
    method visitCatch (line 103) | @Override
    method visitMemberSelectExpression (line 120) | @Override
    method isExcludedType (line 139) | private boolean isExcludedType(Tree tree) {
    method isUnqualifiedExcludedType (line 144) | private boolean isUnqualifiedExcludedType(Tree tree) {
    method isQualifiedExcludedType (line 149) | private boolean isQualifiedExcludedType(Tree tree) {
    method concatenate (line 156) | public static String concatenate(ExpressionTree tree) {

FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/HardcodedIpCheck.java
  class HardcodedIpCheck (line 22) | @Rule(key = "S1313")
    method scanFile (line 30) | @Override
    method visitLiteral (line 36) | @Override
    method areAllBelow256 (line 56) | private static boolean areAllBelow256(Iterable<String> numbersAsString...

FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/MissingCurlyBracesCheck.java
  class MissingCurlyBracesCheck (line 17) | @Rule(key = "S121")
    method nodesToVisit (line 20) | @Override
    method visitNode (line 26) | @Override
    method checkIfStatement (line 53) | private void checkIfStatement(IfStatementTree ifStmt) {
    method isSameLine (line 69) | private boolean isSameLine(IfStatementTree ifStmt) {
    method isInEqualsMethod (line 78) | private boolean isInEqualsMethod(IfStatementTree ifStmt) {
    method checkStatement (line 95) | private void checkStatement(SyntaxToken reportToken, StatementTree sta...

FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/NoSonarCheck.java
  class NoSonarCheck (line 31) | @Rule(key = "NoSonar")
    method nodesToVisit (line 39) | @Override
    method scanFile (line 44) | @Override
    method visitFile (line 51) | private void visitFile() {
    method ignoredLine (line 61) | private boolean ignoredLine(String line) {

FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/OperatorPrecedenceCheck.java
  class OperatorPrecedenceCheck (line 40) | @Rule(key = "S864")
    method put (line 88) | private static void put(Iterable<Tree.Kind> firstSet, Iterable<Tree.Ki...
    method scanFile (line 96) | @Override
    method visitAnnotation (line 104) | @Override
    method visitArrayAccessExpression (line 117) | @Override
    method visitBinaryExpression (line 125) | @Override
    method requiresParenthesis (line 137) | private static boolean requiresParenthesis(Tree.Kind kind1, Tree.Kind ...
    method visitIfStatement (line 141) | @Override
    method visitMethodInvocation (line 150) | @Override
    method visitNewArray (line 161) | @Override
    method visitNewClass (line 168) | @Override
    method visitParenthesized (line 175) | @Override
    method visitConditionalExpression (line 182) | @Override
    method checkConditionalOperand (line 189) | private void checkConditionalOperand(ExpressionTree tree) {
    method raiseIssue (line 200) | private void raiseIssue(int line, Tree tree) {

FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/UnusedMethodParameterCheck.java
  class UnusedMethodParameterCheck (line 56) | @Rule(key = "S1172")
    method nodesToVisit (line 64) | @Override
    method visitNode (line 69) | @Override
    method reportUnusedParameters (line 96) | private void reportUnusedParameters(List<IdentifierTree> unused) {
    method isIncluded (line 114) | private static boolean isIncluded(MethodTree tree) {
    method isStrutsActionParameter (line 118) | private static boolean isStrutsActionParameter(VariableTree variableTr...
    method isPrivateMethod (line 124) | private static boolean isPrivateMethod(MethodTree methodTree) {
    method unresolvedIdentifierNames (line 128) | private static Set<String> unresolvedIdentifierNames(Tree tree) {
    class UnresolvedIdentifierVisitor (line 134) | private static class UnresolvedIdentifierVisitor extends BaseTreeVisit...
      method visitMemberSelectExpression (line 138) | @Override
      method visitMethodInvocation (line 144) | @Override
      method visitIdentifier (line 155) | @Override

FILE: standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/UnusedPrivateFieldCheck.java
  class UnusedPrivateFieldCheck (line 54) | @Rule(key = "S1068")
    method nodesToVisit (line 69) | @Override
    method scanFile (line 75) | @Override
    method visitNode (line 88) | @Override
    method checkIfLombokClass (line 115) | private void checkIfLombokClass(ImportTree tree) {
    method fullQualifiedName (line 123) | private static String fullQualifiedName(Tree tree) {
    method collectUnknownIdentifier (line 133) | private void collectUnknownIdentifier(IdentifierTree identifier) {
    method isMethodIdentifier (line 139) | private static boolean isMethodIdentifier(IdentifierTree identifier) {
    method methodName (line 155) | public static IdentifierTree methodName(MethodInvocationTree mit) {
    method checkIfNativeMethod (line 165) | private void checkIfNativeMethod(MethodTree method) {
    method checkClassFields (line 171) | private void checkClassFields(ClassTree classTree) {
    method checkIfUnused (line 176) | public void checkIfUnused(VariableTree tree) {
    method onlyUsedInVariableAssignment (line 187) | private boolean onlyUsedInVariableAssignment(Symbol symbol) {
    method hasNoAnnotation (line 191) | private static boolean hasNoAnnotation(VariableTree tree) {
    method collectAssignment (line 195) | private void collectAssignment(ExpressionTree expressionTree) {
    method addAssignment (line 201) | private void addAssignment(ExpressionTree tree) {
    method addAssignment (line 210) | private void addAssignment(IdentifierTree identifier) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/BooleanUtil.java
  class BooleanUtil (line 12) | public class BooleanUtil {
    method toBoolean (line 17) | public static boolean toBoolean(String str) {
    method toBooleanObject (line 24) | public static Boolean toBooleanObject(String str) {
    method toBooleanObject (line 31) | public static Boolean toBooleanObject(String str, Boolean defaultValue) {
    method parseGeneralString (line 38) | public static Boolean parseGeneralString(String str) {
    method parseGeneralString (line 45) | public static Boolean parseGeneralString(String str, Boolean defaultVa...
    method negate (line 52) | public static boolean negate(final boolean bool) {
    method negate (line 59) | public static Boolean negate(final Boolean bool) {
    method and (line 66) | public static boolean and(final boolean... array) {
    method or (line 73) | public static boolean or(final boolean... array) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/EnumUtil.java
  class EnumUtil (line 16) | public class EnumUtil {
    method generateBits (line 21) | public static <E extends Enum<E>> long generateBits(final Class<E> enu...
    method generateBits (line 28) | public static <E extends Enum<E>> long generateBits(final Class<E> enu...
    method processBits (line 35) | public static <E extends Enum<E>> EnumSet<E> processBits(final Class<E...
    method toString (line 42) | public static String toString(Enum e) {
    method fromString (line 49) | public static <T extends Enum<T>> T fromString(Class<T> enumClass, Str...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/ExceptionUtil.java
  class ExceptionUtil (line 29) | public class ExceptionUtil {
    method unchecked (line 52) | public static RuntimeException unchecked(@Nullable Throwable t) {
    method unwrap (line 70) | public static Throwable unwrap(@Nullable Throwable t) {
    method unwrapAndUnchecked (line 83) | public static RuntimeException unwrapAndUnchecked(@Nullable Throwable ...
    method stackTraceText (line 94) | public static String stackTraceText(@NotNull Throwable t) {
    method toStringWithShortName (line 107) | public static String toStringWithShortName(@Nullable Throwable t) {
    method toStringWithRootCause (line 114) | public static String toStringWithRootCause(@Nullable Throwable t) {
    method getRootCause (line 140) | public static Throwable getRootCause(@NotNull Throwable t) {
    method findCause (line 149) | public static <T extends Throwable> T findCause(@NotNull Throwable thr...
    method isCausedBy (line 162) | @SuppressWarnings("unchecked")
    method setStackTrace (line 191) | public static <T extends Throwable> T setStackTrace(@NotNull T throwab...
    method clearStackTrace (line 204) | public static <T extends Throwable> T clearStackTrace(@NotNull T throw...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/MoreValidate.java
  class MoreValidate (line 13) | public class MoreValidate extends org.apache.commons.lang3.Validate {
    method positive (line 18) | public static int positive(@Nullable String role, int x) {
    method positive (line 28) | public static Integer positive(@Nullable String role, Integer x) {
    method positive (line 38) | public static long positive(@Nullable String role, long x) {
    method positive (line 48) | public static Long positive(@Nullable String role, Long x) {
    method positive (line 58) | public static double positive(@Nullable String role, double x) {
    method nonNegative (line 68) | public static int nonNegative(@Nullable String role, int x) {
    method nonNegative (line 78) | public static Integer nonNegative(@Nullable String role, Integer x) {
    method nonNegative (line 88) | public static long nonNegative(@Nullable String role, long x) {
    method nonNegative (line 98) | public static Long nonNegative(@Nullable String role, Long x) {
    method nonNegative (line 108) | public static double nonNegative(@Nullable String role, double x) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/ObjectUtil.java
  class ObjectUtil (line 13) | public class ObjectUtil {
    method equals (line 20) | public static boolean equals(@Nullable Object a, @Nullable Object b) {
    method hashCode (line 27) | public static int hashCode(Object... objects) {
    method toPrettyString (line 34) | public static String toPrettyString(Object value) {
    method primitiveArrayToString (line 58) | private static String primitiveArrayToString(Object value, Class compo...
    method objectArrayToString (line 84) | private static String objectArrayToString(Object value) {
    method collectionToString (line 99) | private static String collectionToString(Object value) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/Platforms.java
  class Platforms (line 10) | public class Platforms {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/PropertiesUtil.java
  class PropertiesUtil (line 23) | public class PropertiesUtil {
    method getBoolean (line 29) | public static Boolean getBoolean(Properties p, String name, Boolean de...
    method getInt (line 33) | public static Integer getInt(Properties p, String name, Integer defaul...
    method getLong (line 37) | public static Long getLong(Properties p, String name, Long defaultValu...
    method getDouble (line 41) | public static Double getDouble(Properties p, String name, Double defau...
    method getString (line 45) | public static String getString(Properties p, String name, String defau...
    method loadFromFile (line 55) | public static Properties loadFromFile(String generalPath) {
    method loadFromString (line 68) | public static Properties loadFromString(String content) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/RuntimeUtil.java
  class RuntimeUtil (line 18) | public class RuntimeUtil {
    method getPid (line 29) | public static int getPid() {
    method getUpTime (line 48) | public static long getUpTime() {
    method getVmArguments (line 55) | public static String getVmArguments() {
    method getCores (line 64) | public static int getCores() {
    method addShutdownHook (line 71) | public static void addShutdownHook(Runnable runnable) {
    method getCallerClass (line 82) | public static String getCallerClass() {
    method getCallerMethod (line 97) | public static String getCallerMethod() {
    method getCurrentClass (line 112) | public static String getCurrentClass() {
    method getCurrentMethod (line 127) | public static String getCurrentMethod() {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/SystemPropertiesUtil.java
  class SystemPropertiesUtil (line 19) | public class SystemPropertiesUtil {
    method getBoolean (line 24) | public static Boolean getBoolean(String name) {
    method getBoolean (line 32) | public static Boolean getBoolean(String name, Boolean defaultValue) {
    method getString (line 40) | public static String getString(String name) {
    method getString (line 47) | public static String getString(String name, String defaultValue) {
    method getInteger (line 54) | public static Integer getInteger(String name) {
    method getInteger (line 61) | public static Integer getInteger(String name, Integer defaultValue) {
    method getLong (line 68) | public static Long getLong(String name) {
    method getLong (line 75) | public static Long getLong(String name, Long defaultValue) {
    method getDouble (line 82) | public static Double getDouble(String propertyName) {
    method getDouble (line 89) | public static Double getDouble(String propertyName, Double defaultValu...
    method getString (line 99) | public static String getString(String propertyName, String envName, St...
    method getInteger (line 113) | public static Integer getInteger(String propertyName, String envName, ...
    method getLong (line 127) | public static Long getLong(String propertyName, String envName, Long d...
    method getDouble (line 141) | public static Double getDouble(String propertyName, String envName, Do...
    method getBoolean (line 155) | public static Boolean getBoolean(String propertyName, String envName, ...
    method checkEnvName (line 169) | private static void checkEnvName(String envName) {
    method registerSystemPropertiesListener (line 182) | public static synchronized void registerSystemPropertiesListener(Prope...
    class ListenableProperties (line 201) | public static class ListenableProperties extends Properties {
      method ListenableProperties (line 207) | public ListenableProperties(Properties properties) {
      method register (line 211) | public void register(PropertiesListener listener) {
      method setProperty (line 215) | @Override
    class PropertiesListener (line 230) | public abstract static class PropertiesListener {
      method PropertiesListener (line 235) | public PropertiesListener(String propertyName) {
      method onChange (line 239) | public abstract void onChange(String propertyName, String value);

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/ValueValidator.java
  class ValueValidator (line 16) | public class ValueValidator {
    method checkAndGet (line 30) | public static <T> T checkAndGet(T value, T defaultValue, Validator<T> ...
    type Validator (line 41) | public interface Validator<T> {
      method validate (line 45) | boolean validate(T value);
      method validate (line 51) | @Override
      method validate (line 61) | @Override
      method validate (line 71) | @Override

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/type/CloneableException.java
  class CloneableException (line 14) | public class CloneableException extends Exception implements Cloneable {
    method CloneableException (line 20) | public CloneableException() {
    method CloneableException (line 24) | public CloneableException(String message) {
    method CloneableException (line 29) | public CloneableException(String message, Throwable cause) {
    method clone (line 34) | @Override
    method getMessage (line 43) | @Override
    method setStackTrace (line 51) | public CloneableException setStackTrace(Class<?> throwClazz, String th...
    method clone (line 59) | public CloneableException clone(String message) {
    method setMessage (line 68) | public CloneableException setMessage(String message) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/type/CloneableRuntimeException.java
  class CloneableRuntimeException (line 10) | public class CloneableRuntimeException extends RuntimeException implemen...
    method CloneableRuntimeException (line 16) | public CloneableRuntimeException() {
    method CloneableRuntimeException (line 20) | public CloneableRuntimeException(String message) {
    method CloneableRuntimeException (line 25) | public CloneableRuntimeException(String message, Throwable cause) {
    method clone (line 30) | @Override
    method getMessage (line 39) | @Override
    method setStackTrace (line 47) | public CloneableRuntimeException setStackTrace(Class<?> throwClazz, St...
    method clone (line 55) | public CloneableRuntimeException clone(String message) {
    method setMessage (line 64) | public CloneableRuntimeException setMessage(String message) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/type/Pair.java
  class Pair (line 10) | public class Pair<L, R> {
    method Pair (line 20) | public Pair(@Nullable L left, @Nullable R right) {
    method getLeft (line 25) | @Nullable
    method getRight (line 30) | @Nullable
    method hashCode (line 35) | @Override
    method equals (line 43) | @Override
    method toString (line 69) | @Override
    method of (line 77) | public static <L, R> Pair<L, R> of(@Nullable L left, @Nullable R right) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/type/Triple.java
  class Triple (line 10) | public class Triple<L, M, R> {
    method Triple (line 22) | public Triple(@Nullable L left, @Nullable M middle, @Nullable R right) {
    method getLeft (line 28) | @Nullable
    method getMiddle (line 33) | @Nullable
    method getRight (line 38) | @Nullable
    method hashCode (line 43) | @Override
    method equals (line 52) | @Override
    method toString (line 85) | @Override
    method of (line 93) | public static <L, M, R> Triple<L, M, R> of(@Nullable L left, @Nullable...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/base/type/UncheckedException.java
  class UncheckedException (line 8) | public class UncheckedException extends RuntimeException {
    method UncheckedException (line 12) | public UncheckedException(Throwable wrapped) {
    method getMessage (line 16) | @Override

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/ArrayUtil.java
  class ArrayUtil (line 28) | public class ArrayUtil {
    method newArray (line 35) | @SuppressWarnings("unchecked")
    method toArray (line 47) | @SuppressWarnings("unchecked")
    method swap (line 55) | private static void swap(Object[] arr, int i, int j) {
    method shuffle (line 64) | public static <T> T[] shuffle(T[] array) {
    method shuffle (line 76) | public static <T> T[] shuffle(T[] array, Random random) {
    method concat (line 88) | public static <T> T[] concat(@Nullable T element, T[] array) {
    method concat (line 95) | public static <T> T[] concat(T[] array, @Nullable T element) {
    method asList (line 107) | public static <T> List<T> asList(T... a) {
    method intAsList (line 120) | public static List<Integer> intAsList(int... backingArray) {
    method longAsList (line 132) | public static List<Long> longAsList(long... backingArray) {
    method doubleAsList (line 144) | public static List<Double> doubleAsList(double... backingArray) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/CollectionUtil.java
  class CollectionUtil (line 28) | public class CollectionUtil {
    method isEmpty (line 33) | public static boolean isEmpty(Collection<?> collection) {
    method isNotEmpty (line 40) | public static boolean isNotEmpty(Collection<?> collection) {
    method getFirst (line 47) | public static <T> T getFirst(Collection<T> collection) {
    method getLast (line 60) | public static <T> T getLast(Collection<T> collection) {
    method elementsEqual (line 77) | public static boolean elementsEqual(Iterable<?> iterable1, Iterable<?>...
    method min (line 85) | public static <T extends Object & Comparable<? super T>> T min(Collect...
    method min (line 92) | public static <T> T min(Collection<? extends T> coll, Comparator<? sup...
    method max (line 99) | public static <T extends Object & Comparable<? super T>> T max(Collect...
    method max (line 106) | public static <T> T max(Collection<? extends T> coll, Comparator<? sup...
    method minAndMax (line 115) | public static <T extends Object & Comparable<? super T>> Pair<T, T> mi...
    method minAndMax (line 136) | public static <T> Pair<T, T> minAndMax(Collection<? extends T> coll, C...
    method topN (line 157) | public static <T extends Comparable<?>> List<T> topN(Iterable<T> coll,...
    method topN (line 164) | public static <T> List<T> topN(Iterable<T> coll, int n, Comparator<? s...
    method bottomN (line 171) | public static <T extends Comparable<?>> List<T> bottomN(Iterable<T> co...
    method bottomN (line 178) | public static <T> List<T> bottomN(Iterable<T> coll, int n, Comparator<...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/ListUtil.java
  class ListUtil (line 27) | @SuppressWarnings("unchecked")
    method isEmpty (line 33) | public static boolean isEmpty(List<?> list) {
    method isNotEmpty (line 40) | public static boolean isNotEmpty(List<?> list) {
    method getFirst (line 47) | public static <T> T getFirst(List<T> list) {
    method getLast (line 57) | public static <T> T getLast(List<T> list) {
    method newArrayList (line 71) | @Deprecated
    method newArrayList (line 81) | public static <T> ArrayList<T> newArrayList(T... elements) {
    method newArrayList (line 90) | public static <T> ArrayList<T> newArrayList(Iterable<T> elements) {
    method newArrayListWithCapacity (line 99) | public static <T> ArrayList<T> newArrayListWithCapacity(int initSize) {
    method newLinkedList (line 108) | @Deprecated
    method newLinkedList (line 118) | public static <T> LinkedList<T> newLinkedList(Iterable<? extends T> el...
    method newCopyOnWriteArrayList (line 127) | @Deprecated
    method newCopyOnWriteArrayList (line 135) | public static <T> CopyOnWriteArrayList<T> newCopyOnWriteArrayList(T......
    method emptyList (line 148) | public static final <T> List<T> emptyList() {
    method emptyListIfNull (line 159) | public static <T> List<T> emptyListIfNull(final List<T> list) {
    method singletonList (line 170) | public static <T> List<T> singletonList(T o) {
    method unmodifiableList (line 181) | public static <T> List<T> unmodifiableList(List<? extends T> list) {
    method synchronizedList (line 190) | public static <T> List<T> synchronizedList(List<T> list) {
    method sort (line 201) | public static <T extends Comparable<? super T>> void sort(List<T> list) {
    method sortReverse (line 210) | public static <T extends Comparable<? super T>> void sortReverse(List<...
    method sort (line 219) | public static <T> void sort(List<T> list, Comparator<? super T> c) {
    method sortReverse (line 228) | public static <T> void sortReverse(List<T> list, Comparator<? super T>...
    method binarySearch (line 241) | public static <T> int binarySearch(List<? extends Comparable<? super T...
    method binarySearch (line 254) | public static <T> int binarySearch(List<? extends T> sortedList, T key...
    method shuffle (line 263) | public static void shuffle(List<?> list) {
    method shuffle (line 272) | public static void shuffle(List<?> list, Random rnd) {
    method reverse (line 281) | public static <T> List<T> reverse(final List<T> list) {
    method partition (line 289) | public static <T> List<List<T>> partition(List<T> list, int size) {
    method notNullList (line 298) | public static <T> void notNullList(List<T> list) {
    method uniqueNotNullList (line 313) | public static <T> void uniqueNotNullList(List<T> list) {
    method union (line 344) | public static <E> List<E> union(final List<? extends E> list1, final L...
    method intersection (line 358) | public static <T> List<T> intersection(final List<? extends T> list1, ...
    method difference (line 383) | public static <T> List<T> difference(final List<? extends T> list1, fi...
    method disjoint (line 399) | public static <T> List<T> disjoint(final List<? extends T> list1, fina...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/MapUtil.java
  class MapUtil (line 40) | @SuppressWarnings("unchecked")
    method isEmpty (line 48) | public static boolean isEmpty(final Map<?, ?> map) {
    method isNotEmpty (line 55) | public static boolean isNotEmpty(final Map<?, ?> map) {
    method putIfAbsentReturnLast (line 64) | public static <K, V> V putIfAbsentReturnLast(@NotNull final Concurrent...
    method createIfAbsentReturnLast (line 77) | public static <K, V> V createIfAbsentReturnLast(@NotNull final Concurr...
    type ValueCreator (line 91) | public interface ValueCreator<T> {
      method get (line 95) | T get();
    method newHashMap (line 107) | @Deprecated
    method newHashMapWithCapacity (line 121) | public static <K, V> HashMap<K, V> newHashMapWithCapacity(int expected...
    method newHashMap (line 131) | public static <K, V> HashMap<K, V> newHashMap(final K key, final V val...
    method newHashMap (line 142) | public static <K, V> HashMap<K, V> newHashMap(@NotNull final K[] keys,...
    method newHashMap (line 160) | public static <K, V> HashMap<K, V> newHashMap(@NotNull final List<K> k...
    method newSortedMap (line 180) | @SuppressWarnings("rawtypes")
    method newSortedMap (line 190) | public static <C, K extends C, V> TreeMap<K, V> newSortedMap(@Nullable...
    method newEnumMap (line 197) | public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(@NotNull...
    method newConcurrentHashMap (line 204) | public static <K, V> ConcurrentHashMap<K, V> newConcurrentHashMap() {
    method newConcurrentSortedMap (line 211) | public static <K, V> ConcurrentSkipListMap<K, V> newConcurrentSortedMa...
    method emptyMap (line 224) | public static <K, V> Map<K, V> emptyMap() {
    method emptyMapIfNull (line 235) | public static <K, V> Map<K, V> emptyMapIfNull(final Map<K, V> map) {
    method singletonMap (line 246) | public static <K, V> Map<K, V> singletonMap(final K key, final V value) {
    method unmodifiableMap (line 257) | public static <K, V> Map<K, V> unmodifiableMap(final Map<? extends K, ...
    method unmodifiableSortedMap (line 266) | public static <K, V> SortedMap<K, V> unmodifiableSortedMap(final Sorte...
    method difference (line 278) | public static <K, V> MapDifference<K, V> difference(Map<? extends K, ?...
    method sortByValue (line 289) | public static <K, V extends Comparable> Map<K, V> sortByValue(Map<K, V...
    method sortByValue (line 297) | public static <K, V> Map<K, V> sortByValue(Map<K, V> map, final Compar...
    method sortByValueInternal (line 301) | private static <K, V> Map<K, V> sortByValueInternal(Map<K, V> map, Com...
    method topNByValue (line 318) | public static <K, V extends Comparable> Map<K, V> topNByValue(Map<K, V...
    method topNByValue (line 326) | public static <K, V> Map<K, V> topNByValue(Map<K, V> map, final Compar...
    method topNByValueInternal (line 330) | private static <K, V> Map<K, V> topNByValueInternal(Map<K, V> map, int...
    class ComparableEntryValueComparator (line 344) | private static final class ComparableEntryValueComparator<K, V extends...
      method compare (line 346) | @Override
    class EntryValueComparator (line 352) | private static final class EntryValueComparator<K, V> implements Compa...
      method EntryValueComparator (line 355) | private EntryValueComparator(Comparator<? super V> comparator2) {
      method compare (line 359) | @Override

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/QueueUtil.java
  class QueueUtil (line 16) | public class QueueUtil {
    method newArrayDeque (line 23) | public static <E> ArrayDeque<E> newArrayDeque(int initSize) {
    method newLinkedDeque (line 30) | public static <E> LinkedList<E> newLinkedDeque() {
    method newConcurrentNonBlockingQueue (line 37) | public static <E> ConcurrentLinkedQueue<E> newConcurrentNonBlockingQue...
    method newConcurrentNonBlockingDeque (line 44) | public static <E> Deque<E> newConcurrentNonBlockingDeque() {
    method newBlockingUnlimitQueue (line 53) | public static <E> LinkedBlockingQueue<E> newBlockingUnlimitQueue() {
    method newBlockingUnlimitDeque (line 62) | public static <E> LinkedBlockingDeque<E> newBlockingUnlimitDeque() {
    method newArrayBlockingQueue (line 69) | public static <E> ArrayBlockingQueue<E> newArrayBlockingQueue(int capa...
    method newLinkedBlockingQueue (line 76) | public static <E> LinkedBlockingQueue<E> newLinkedBlockingQueue(int ca...
    method newBlockingDeque (line 83) | public static <E> LinkedBlockingDeque<E> newBlockingDeque(int capacity) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/SetUtil.java
  class SetUtil (line 21) | public class SetUtil {
    method newHashSet (line 28) | public static <T> HashSet<T> newHashSet() {
    method newHashSet (line 37) | @SuppressWarnings("unchecked")
    method newHashSet (line 47) | public static <T> HashSet<T> newHashSet(Iterable<? extends T> elements) {
    method newHashSetWithCapacity (line 56) | public static <T> HashSet<T> newHashSetWithCapacity(int expectedSize) {
    method newSortedSet (line 65) | @SuppressWarnings("rawtypes")
    method newSortedSet (line 75) | public static <T> TreeSet<T> newSortedSet(@Nullable Comparator<? super...
    method newConcurrentHashSet (line 82) | public static <T> ConcurrentHashSet<T> newConcurrentHashSet() {
    method emptySet (line 95) | public static <T> Set<T> emptySet() {
    method emptySetIfNull (line 106) | public static <T> Set<T> emptySetIfNull(final Set<T> set) {
    method singletonSet (line 117) | public static <T> Set<T> singletonSet(T o) {
    method unmodifiableSet (line 128) | public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
    method newSetFromMap (line 137) | public static <T> Set<T> newSetFromMap(Map<T, Boolean> map) {
    method unionView (line 147) | public static <E> Set<E> unionView(final Set<? extends E> set1, final ...
    method intersectionView (line 156) | public static <E> Set<E> intersectionView(final Set<E> set1, final Set...
    method differenceView (line 165) | public static <E> Set<E> differenceView(final Set<E> set1, final Set<?...
    method disjointView (line 174) | public static <E> Set<E> disjointView(final Set<? extends E> set1, fin...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/ConcurrentHashSet.java
  class ConcurrentHashSet (line 17) | public class ConcurrentHashSet<E> extends AbstractSet<E> implements Set<...
    method ConcurrentHashSet (line 25) | public ConcurrentHashSet() {
    method clear (line 30) | public void clear() {
    method size (line 34) | public int size() {
    method isEmpty (line 38) | public boolean isEmpty() {
    method contains (line 42) | public boolean contains(Object o) {
    method remove (line 46) | public boolean remove(Object o) {
    method add (line 50) | public boolean add(E e) {
    method iterator (line 54) | public Iterator<E> iterator() {
    method toArray (line 58) | public Object[] toArray() {
    method toArray (line 62) | public <T> T[] toArray(T[] a) {
    method toString (line 66) | @Override
    method hashCode (line 71) | public int hashCode() {
    method equals (line 75) | public boolean equals(Object o) {
    method containsAll (line 79) | public boolean containsAll(Collection<?> c) {
    method removeAll (line 83) | public boolean removeAll(Collection<?> c) {
    method retainAll (line 87) | public boolean retainAll(Collection<?> c) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/MoreLists.java
  class MoreLists (line 8) | public class MoreLists {
    method createSortedArrayList (line 15) | @SuppressWarnings("rawtypes")
    method createSortedArrayList (line 25) | public static <T> SortedArrayList<T> createSortedArrayList(Comparator<...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/MoreMaps.java
  class MoreMaps (line 22) | public class MoreMaps {
    method createWeakKeyConcurrentMap (line 29) | public static <K, V> ConcurrentMap<K, V> createWeakKeyConcurrentMap(in...
    method createWeakValueConcurrentMap (line 38) | public static <K, V> ConcurrentMap<K, V> createWeakValueConcurrentMap(...
    method createPrimitiveIntKeyMap (line 49) | public static <V> IntObjectHashMap<V> createPrimitiveIntKeyMap(int ini...
    method createPrimitiveLongKeyMap (line 59) | public static <V> LongObjectHashMap<V> createPrimitiveLongKeyMap(int i...
    method createMutableIntValueMap (line 69) | public static <K> HashMap<K, MutableInt> createMutableIntValueMap(int ...
    method createMutableLongValueMap (line 79) | public static <K> HashMap<K, MutableLong> createMutableLongValueMap(in...
    method createConcurrentCounterMap (line 86) | public static <E> AtomicLongMap<E> createConcurrentCounterMap() {
    method createListMultiValueMap (line 100) | public static <K, V> ArrayListMultimap<K, V> createListMultiValueMap(i...
    method createSortedSetMultiValueMap (line 111) | public static <K, V extends Comparable> SortedSetMultimap<K, V> create...
    method createSortedSetMultiValueMap (line 122) | public static <K, V> SortedSetMultimap<K, V> createSortedSetMultiValue...
    method createRangeMap (line 129) | @SuppressWarnings("rawtypes")

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/MoreQueues.java
  class MoreQueues (line 13) | public class MoreQueues {
    method createStack (line 24) | public static <E> Queue<E> createStack(int initSize) {
    method createConcurrentStack (line 35) | public static <E> Queue<E> createConcurrentStack() {
    method createLRUQueue (line 46) | public static <E> EvictingQueue<E> createLRUQueue(int maxSize) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/SortedArrayList.java
  class SortedArrayList (line 45) | public final class SortedArrayList<E> extends ArrayList<E> {
    method SortedArrayList (line 54) | public SortedArrayList(Comparator<? super E> c) {
    method SortedArrayList (line 62) | public SortedArrayList() {
    method SortedArrayList (line 70) | public SortedArrayList(Collection<? extends E> c) {
    method getComparator (line 78) | public Comparator getComparator() {
    method add (line 92) | @Override
    method addAll (line 105) | @Override
    method findInsertionPoint (line 121) | public int findInsertionPoint(E o) {
    method add (line 130) | @Override
    method set (line 139) | @Override
    method addAll (line 148) | @Override
    method compare (line 161) | @SuppressWarnings({ "unchecked" })
    method findInsertionPoint (line 173) | protected int findInsertionPoint(E o, int originalLow, int originalHig...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/primitive/IntObjectHashMap.java
  class IntObjectHashMap (line 39) | public class IntObjectHashMap<V> implements IntObjectMap<V> {
    method iterator (line 67) | @Override
    method IntObjectHashMap (line 73) | public IntObjectHashMap() {
    method IntObjectHashMap (line 77) | public IntObjectHashMap(int initialCapacity) {
    method IntObjectHashMap (line 81) | public IntObjectHashMap(int initialCapacity, float loadFactor) {
    method toExternal (line 104) | private static <T> T toExternal(T value) {
    method toInternal (line 109) | @SuppressWarnings("unchecked")
    method get (line 114) | @Override
    method put (line 120) | @Override
    method putAll (line 148) | @Override
    method remove (line 169) | @Override
    method size (line 181) | @Override
    method isEmpty (line 186) | @Override
    method clear (line 191) | @Override
    method containsKey (line 198) | @Override
    method containsValue (line 203) | @Override
    method entries (line 216) | @Override
    method values (line 221) | @Override
    method hashCode (line 253) | @Override
    method equals (line 272) | @Override
    method containsKey (line 302) | @Override
    method get (line 307) | @Override
    method put (line 312) | @Override
    method remove (line 317) | @Override
    method keySet (line 322) | @Override
    method entrySet (line 327) | @Override
    method objectToKey (line 332) | private int objectToKey(Object key) {
    method indexOf (line 342) | private int indexOf(int key) {
    method hashIndex (line 365) | private int hashIndex(int key) {
    method hashCode (line 373) | private static int hashCode(int key) {
    method probeNext (line 380) | private int probeNext(int index) {
    method growSize (line 388) | private void growSize() {
    method removeAt (line 408) | private boolean removeAt(final int index) {
    method calcMaxSize (line 441) | private int calcMaxSize(int capacity) {
    method rehash (line 452) | private void rehash(int newCapacity) {
    method toString (line 487) | @Override
    method keyToString (line 512) | protected String keyToString(int key) {
    class EntrySet (line 519) | private final class EntrySet extends AbstractSet<Entry<Integer, V>> {
      method iterator (line 520) | @Override
      method size (line 525) | @Override
    class KeySet (line 534) | private final class KeySet extends AbstractSet<Integer> {
      method size (line 535) | @Override
      method contains (line 540) | @Override
      method remove (line 545) | @Override
      method retainAll (line 550) | @Override
      method clear (line 563) | @Override
      method iterator (line 568) | @Override
    class PrimitiveIterator (line 594) | private final class PrimitiveIterator implements Iterator<PrimitiveEnt...
      method scanNext (line 599) | private void scanNext() {
      method hasNext (line 604) | @Override
      method next (line 612) | @Override
      method remove (line 626) | @Override
      method key (line 643) | @Override
      method value (line 648) | @Override
      method setValue (line 653) | @Override
    class MapIterator (line 662) | private final class MapIterator implements Iterator<Entry<Integer, V>> {
      method hasNext (line 665) | @Override
      method next (line 670) | @Override
      method remove (line 681) | @Override
    class MapEntry (line 690) | final class MapEntry implements Entry<Integer, V> {
      method MapEntry (line 693) | MapEntry(int entryIndex) {
      method getKey (line 697) | @Override
      method getValue (line 703) | @Override
      method setValue (line 709) | @Override
      method verifyExists (line 717) | private void verifyExists() {
    method safeFindNextPositivePowerOfTwo (line 724) | public static int safeFindNextPositivePowerOfTwo(final int value) {
    method findNextPositivePowerOfTwo (line 728) | public static int findNextPositivePowerOfTwo(final int value) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/primitive/IntObjectMap.java
  type IntObjectMap (line 22) | public interface IntObjectMap<V> extends Map<Integer, V> {
    type PrimitiveEntry (line 29) | interface PrimitiveEntry<V> {
      method key (line 33) | int key();
      method value (line 38) | V value();
      method setValue (line 43) | void setValue(V value);
    method get (line 52) | V get(int key);
    method put (line 61) | V put(int key, V value);
    method remove (line 69) | V remove(int key);
    method entries (line 76) | Iterable<PrimitiveEntry<V>> entries();
    method containsKey (line 81) | boolean containsKey(int key);

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/primitive/LongObjectHashMap.java
  class LongObjectHashMap (line 36) | public class LongObjectHashMap<V> implements LongObjectMap<V> {
    method iterator (line 64) | @Override
    method LongObjectHashMap (line 70) | public LongObjectHashMap() {
    method LongObjectHashMap (line 74) | public LongObjectHashMap(int initialCapacity) {
    method LongObjectHashMap (line 78) | public LongObjectHashMap(int initialCapacity, float loadFactor) {
    method toExternal (line 101) | private static <T> T toExternal(T value) {
    method toInternal (line 106) | @SuppressWarnings("unchecked")
    method get (line 111) | @Override
    method put (line 117) | @Override
    method putAll (line 145) | @Override
    method remove (line 166) | @Override
    method size (line 178) | @Override
    method isEmpty (line 183) | @Override
    method clear (line 188) | @Override
    method containsKey (line 195) | @Override
    method containsValue (line 200) | @Override
    method entries (line 213) | @Override
    method values (line 218) | @Override
    method hashCode (line 250) | @Override
    method equals (line 269) | @Override
    method containsKey (line 299) | @Override
    method get (line 304) | @Override
    method put (line 309) | @Override
    method remove (line 314) | @Override
    method keySet (line 319) | @Override
    method entrySet (line 324) | @Override
    method objectToKey (line 329) | private long objectToKey(Object key) {
    method indexOf (line 339) | private int indexOf(long key) {
    method hashIndex (line 362) | private int hashIndex(long key) {
    method hashCode (line 370) | private static int hashCode(long key) {
    method probeNext (line 377) | private int probeNext(int index) {
    method growSize (line 385) | private void growSize() {
    method removeAt (line 405) | private boolean removeAt(final int index) {
    method calcMaxSize (line 438) | private int calcMaxSize(int capacity) {
    method rehash (line 449) | private void rehash(int newCapacity) {
    method toString (line 484) | @Override
    method keyToString (line 509) | protected String keyToString(long key) {
    class EntrySet (line 516) | private final class EntrySet extends AbstractSet<Entry<Long, V>> {
      method iterator (line 517) | @Override
      method size (line 522) | @Override
    class KeySet (line 531) | private final class KeySet extends AbstractSet<Long> {
      method size (line 532) | @Override
      method contains (line 537) | @Override
      method remove (line 542) | @Override
      method retainAll (line 547) | @Override
      method clear (line 560) | @Override
      method iterator (line 565) | @Override
    class PrimitiveIterator (line 591) | private final class PrimitiveIterator implements Iterator<PrimitiveEnt...
      method scanNext (line 596) | private void scanNext() {
      method hasNext (line 601) | @Override
      method next (line 609) | @Override
      method remove (line 623) | @Override
      method key (line 640) | @Override
      method value (line 645) | @Override
      method setValue (line 650) | @Override
    class MapIterator (line 659) | private final class MapIterator implements Iterator<Entry<Long, V>> {
      method hasNext (line 662) | @Override
      method next (line 667) | @Override
      method remove (line 678) | @Override
    class MapEntry (line 687) | final class MapEntry implements Entry<Long, V> {
      method MapEntry (line 690) | MapEntry(int entryIndex) {
      method getKey (line 694) | @Override
      method getValue (line 700) | @Override
      method setValue (line 706) | @Override
      method verifyExists (line 714) | private void verifyExists() {
    method safeFindNextPositivePowerOfTwo (line 721) | public static int safeFindNextPositivePowerOfTwo(final int value) {
    method findNextPositivePowerOfTwo (line 725) | public static int findNextPositivePowerOfTwo(final int value) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/primitive/LongObjectMap.java
  type LongObjectMap (line 22) | public interface LongObjectMap<V> extends Map<Long, V> {
    type PrimitiveEntry (line 29) | interface PrimitiveEntry<V> {
      method key (line 33) | long key();
      method value (line 38) | V value();
      method setValue (line 43) | void setValue(V value);
    method get (line 52) | V get(long key);
    method put (line 61) | V put(long key, V value);
    method remove (line 69) | V remove(long key);
    method entries (line 76) | Iterable<PrimitiveEntry<V>> entries();
    method containsKey (line 81) | boolean containsKey(long key);

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/Concurrents.java
  class Concurrents (line 17) | public class Concurrents {
    method longAdder (line 24) | public static LongAdder longAdder() {
    method countDownLatch (line 31) | public static CountDownLatch countDownLatch(int count) {
    method cyclicBarrier (line 38) | public static CyclicBarrier cyclicBarrier(int count) {
    method nonFairSemaphore (line 45) | public static Semaphore nonFairSemaphore(int permits) {
    method fairSemaphore (line 52) | public static Semaphore fairSemaphore(int permits) {
    method rateLimiter (line 62) | public static RateLimiter rateLimiter(int permitsPerSecond) {
    method rateLimiter (line 72) | public static RateLimiter rateLimiter(int permitsPerSecond, int maxBur...
    method sampler (line 82) | public static Sampler sampler(double selectPercent) {
    method timeIntervalLimiter (line 91) | public static TimeIntervalLimiter timeIntervalLimiter(long interval, T...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/ThreadDumpper.java
  class ThreadDumpper (line 19) | public class ThreadDumpper {
    method ThreadDumpper (line 31) | public ThreadDumpper() {
    method ThreadDumpper (line 35) | public ThreadDumpper(long leastIntervalMills, int maxStackLevel) {
    method tryThreadDump (line 43) | public void tryThreadDump() {
    method tryThreadDump (line 52) | public void tryThreadDump(String reasonMsg) {
    method threadDump (line 61) | public void threadDump(String reasonMsg) {
    method dumpThreadInfo (line 79) | private String dumpThreadInfo(Thread thread, StackTraceElement[] stack...
    method setLeastInterval (line 99) | public void setLeastInterval(int leastIntervalSeconds) {
    method setMaxStackLevel (line 106) | public void setMaxStackLevel(int maxStackLevel) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/ThreadUtil.java
  class ThreadUtil (line 12) | public class ThreadUtil {
    method sleep (line 17) | public static void sleep(long durationMillis) {
    method sleep (line 28) | public static void sleep(long duration, TimeUnit unit) {
    method handleInterruptedException (line 39) | public static void handleInterruptedException() {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/jsr166e/LongAdder.java
  class LongAdder (line 45) | public class LongAdder extends Striped64 implements Serializable {
    method fn (line 51) | final long fn(long v, long x) {
    method LongAdder (line 58) | public LongAdder() {
    method add (line 67) | public void add(long x) {
    method increment (line 84) | public void increment() {
    method decrement (line 91) | public void decrement() {
    method sum (line 104) | public long sum() {
    method reset (line 124) | public void reset() {
    method sumThenReset (line 138) | public long sumThenReset() {
    method toString (line 159) | public String toString() {
    method longValue (line 168) | public long longValue() {
    method intValue (line 176) | public int intValue() {
    method floatValue (line 184) | public float floatValue() {
    method doubleValue (line 192) | public double doubleValue() {
    method writeObject (line 196) | private void writeObject(ObjectOutputStream s) throws IOException {
    method readObject (line 201) | private void readObject(ObjectInputStream s) throws IOException, Class...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/jsr166e/Striped64.java
  class Striped64 (line 19) | public abstract class Striped64 extends Number {
    class Cell (line 68) | static final class Cell {
      method Cell (line 73) | Cell(long x) {
      method cas (line 77) | final boolean cas(long cmp, long val) {
    method Striped64 (line 131) | Striped64() {
    method casBase (line 137) | final boolean casBase(long cmp, long val) {
    method casBusy (line 144) | final boolean casBusy() {
    method fn (line 157) | abstract long fn(long currentValue, long newValue);
    method retryUpdate (line 170) | final void retryUpdate(long x, int[] hc, boolean wasUncontended) {
    method internalReset (line 252) | final void internalReset(long initialValue) {
    method getUnsafe (line 286) | private static sun.misc.Unsafe getUnsafe() {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/limiter/RateLimiterUtil.java
  class RateLimiterUtil (line 9) | public class RateLimiterUtil {
    method create (line 17) | public static RateLimiter create(double permitsPerSecond, double maxBu...
    method create (line 29) | public static RateLimiter create(double permitsPerSecond, double maxBu...
    method setField (line 54) | private static boolean setField(Object targetObject, String fieldName,...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/limiter/Sampler.java
  class Sampler (line 15) | public class Sampler {
    method Sampler (line 22) | protected Sampler() {
    method Sampler (line 28) | protected Sampler(double selectPercent) {
    method create (line 38) | public static Sampler create(Double selectPercent) {
    method select (line 51) | public boolean select() {
    class AlwaysSampler (line 58) | protected static class AlwaysSampler extends Sampler {
      method select (line 59) | @Override
    class NeverSampler (line 68) | protected static class NeverSampler extends Sampler {
      method select (line 69) | @Override

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/limiter/TimeIntervalLimiter.java
  class TimeIntervalLimiter (line 6) | public class TimeIntervalLimiter {
    method TimeIntervalLimiter (line 12) | public TimeIntervalLimiter(long interval, TimeUnit timeUnit) {
    method tryAcquire (line 16) | public boolean tryAcquire() {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/threadpool/AbortPolicyWithReport.java
  class AbortPolicyWithReport (line 15) | public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy {
    method AbortPolicyWithReport (line 23) | public AbortPolicyWithReport(String threadName) {
    method rejectedExecution (line 27) | @Override

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/threadpool/QueuableCachedThreadPool.java
  class QueuableCachedThreadPool (line 23) | public final class QueuableCachedThreadPool extends java.util.concurrent...
    method QueuableCachedThreadPool (line 32) | public QueuableCachedThreadPool(int corePoolSize, int maximumPoolSize,...
    method afterExecute (line 39) | @Override
    method getSubmittedCount (line 44) | public int getSubmittedCount() {
    method execute (line 51) | @Override
    method execute (line 68) | public void execute(Runnable command, long timeout, TimeUnit unit) {
    class ControllableQueue (line 91) | protected static class ControllableQueue extends LinkedBlockingQueue<R...
      method ControllableQueue (line 96) | public ControllableQueue(int capacity) {
      method setParent (line 100) | public void setParent(QueuableCachedThreadPool tp) {
      method force (line 104) | public boolean force(Runnable o) {
      method force (line 111) | public boolean force(Runnable o, long timeout, TimeUnit unit) throws...
      method offer (line 118) | @Override

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/threadpool/ThreadPoolBuilder.java
  class ThreadPoolBuilder (line 34) | public class ThreadPoolBuilder {
    method fixedPool (line 41) | public static FixedThreadPoolBuilder fixedPool() {
    method cachedPool (line 48) | public static CachedThreadPoolBuilder cachedPool() {
    method scheduledPool (line 55) | public static ScheduledThreadPoolBuilder scheduledPool() {
    method queuableCachedPool (line 62) | public static QueuableCachedThreadPoolBuilder queuableCachedPool() {
    class FixedThreadPoolBuilder (line 82) | public static class FixedThreadPoolBuilder {
      method setPoolSize (line 96) | public FixedThreadPoolBuilder setPoolSize(int poolSize) {
      method setQueueSize (line 107) | public FixedThreadPoolBuilder setQueueSize(int queueSize) {
      method setThreadFactory (line 115) | public FixedThreadPoolBuilder setThreadFactory(ThreadFactory threadF...
      method setThreadNamePrefix (line 123) | public FixedThreadPoolBuilder setThreadNamePrefix(String threadNameP...
      method setDaemon (line 133) | public FixedThreadPoolBuilder setDaemon(Boolean daemon) {
      method setRejectHandler (line 138) | public FixedThreadPoolBuilder setRejectHandler(RejectedExecutionHand...
      method build (line 143) | public ThreadPoolExecutor build() {
    class CachedThreadPoolBuilder (line 179) | public static class CachedThreadPoolBuilder {
      method setMinSize (line 191) | public CachedThreadPoolBuilder setMinSize(int minSize) {
      method setMaxSize (line 199) | public CachedThreadPoolBuilder setMaxSize(int maxSize) {
      method setKeepAliveSecs (line 207) | public CachedThreadPoolBuilder setKeepAliveSecs(int keepAliveSecs) {
      method setThreadFactory (line 215) | public CachedThreadPoolBuilder setThreadFactory(ThreadFactory thread...
      method setThreadNamePrefix (line 223) | public CachedThreadPoolBuilder setThreadNamePrefix(String threadName...
      method setDaemon (line 233) | public CachedThreadPoolBuilder setDaemon(Boolean daemon) {
      method setRejectHandler (line 238) | public CachedThreadPoolBuilder setRejectHandler(RejectedExecutionHan...
      method build (line 243) | public ThreadPoolExecutor build() {
    class ScheduledThreadPoolBuilder (line 259) | public static class ScheduledThreadPoolBuilder {
      method setPoolSize (line 268) | public ScheduledThreadPoolBuilder setPoolSize(int poolSize) {
      method setThreadFactory (line 276) | public ScheduledThreadPoolBuilder setThreadFactory(ThreadFactory thr...
      method setThreadNamePrefix (line 281) | public ScheduledThreadPoolBuilder setThreadNamePrefix(String threadN...
      method build (line 286) | public ScheduledThreadPoolExecutor build() {
    class QueuableCachedThreadPoolBuilder (line 297) | public static class QueuableCachedThreadPoolBuilder {
      method setMinSize (line 310) | public QueuableCachedThreadPoolBuilder setMinSize(int minSize) {
      method setMaxSize (line 315) | public QueuableCachedThreadPoolBuilder setMaxSize(int maxSize) {
      method setQueueSize (line 323) | public QueuableCachedThreadPoolBuilder setQueueSize(int queueSize) {
      method setKeepAliveSecs (line 328) | public QueuableCachedThreadPoolBuilder setKeepAliveSecs(int keepAliv...
      method setThreadFactory (line 336) | public QueuableCachedThreadPoolBuilder setThreadFactory(ThreadFactor...
      method setThreadNamePrefix (line 344) | public QueuableCachedThreadPoolBuilder setThreadNamePrefix(String th...
      method setDaemon (line 354) | public QueuableCachedThreadPoolBuilder setDaemon(Boolean daemon) {
      method setRejectHandler (line 359) | public QueuableCachedThreadPoolBuilder setRejectHandler(RejectedExec...
      method build (line 364) | public QueuableCachedThreadPool build() {
    method createThreadFactory (line 380) | private static ThreadFactory createThreadFactory(ThreadFactory threadF...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/threadpool/ThreadPoolUtil.java
  class ThreadPoolUtil (line 28) | public class ThreadPoolUtil {
    method gracefulShutdown (line 46) | public static boolean gracefulShutdown(@Nullable ExecutorService threa...
    method gracefulShutdown (line 54) | public static boolean gracefulShutdown(@Nullable ExecutorService threa...
    method buildThreadFactory (line 66) | public static ThreadFactory buildThreadFactory(@NotNull String threadN...
    method buildThreadFactory (line 75) | public static ThreadFactory buildThreadFactory(@NotNull String threadN...
    method safeRunnable (line 84) | public static Runnable safeRunnable(@NotNull Runnable runnable) {
    class SafeRunnable (line 91) | private static class SafeRunnable implements Runnable {
      method SafeRunnable (line 97) | public SafeRunnable(Runnable runnable) {
      method run (line 102) | @Override

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/type/BasicFuture.java
  class BasicFuture (line 36) | public abstract class BasicFuture<T> implements Future<T> {
    method isCancelled (line 43) | @Override
    method isDone (line 48) | @Override
    method get (line 53) | @Override
    method get (line 61) | @Override
    method getResult (line 87) | private T getResult() throws ExecutionException {
    method completed (line 98) | public boolean completed(final T result) {
    method failed (line 112) | public boolean failed(final Exception exception) {
    method cancel (line 127) | @Override
    method onCompleted (line 143) | protected abstract void onCompleted(T result);
    method onFailed (line 145) | protected abstract void onFailed(Exception ex);
    method onCancelled (line 147) | protected abstract void onCancelled();

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/type/ThreadLocalContext.java
  class ThreadLocalContext (line 24) | public class ThreadLocalContext {
    method initialValue (line 27) | @Override
    method put (line 37) | public static void put(String key, Object value) {
    method get (line 44) | @SuppressWarnings("unchecked")
    method reset (line 52) | public static void reset() {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/DataMask.java
  class DataMask (line 9) | public class DataMask {
    method setHashSalt (line 16) | public static void setHashSalt(String salt){
    method mask (line 25) | public static String mask(String source) {
    method mask (line 39) | public static String mask(String source, SensitiveType type) {
    method mask (line 54) | public static String mask(String source,MaskStrategy strategy,int...pa...
    method toJSONString (line 67) | public static String toJSONString(Object object) {
    method toString (line 84) | public static String toString(Object object) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/DataMaskJsonFilter.java
  class DataMaskJsonFilter (line 15) | public class DataMaskJsonFilter implements ContextValueFilter {
    method process (line 16) | @Override
    method isStringCollection (line 82) | private boolean isStringCollection(Field field){
    method mask (line 99) | private String mask(String value, Sensitive sensitive, SensitiveType t...
    method getSensitiveType (line 114) | private SensitiveType getSensitiveType(Field field, Sensitive sensitiv...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/MaskMapping.java
  class MaskMapping (line 17) | public class MaskMapping {
    method init (line 34) | private static void init() {
    method loadPropertyFromFile (line 42) | private static void loadPropertyFromFile(String resourcePath) {
    method getMaskTypeMapping (line 103) | public static SensitiveType getMaskTypeMapping(String fieldName) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/MaskStrategy.java
  type MaskStrategy (line 6) | public interface MaskStrategy {
    method mask (line 8) | String mask(String source, int[] params);

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/SensitiveType.java
  type SensitiveType (line 11) | public enum SensitiveType {
    method SensitiveType (line 33) | SensitiveType(MaskStrategy strategy, int... params) {
    method getStrategy (line 38) | public MaskStrategy getStrategy() {
    method getParams (line 43) | public int[] getParams() {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/strategy/EmailMask.java
  class EmailMask (line 10) | public class EmailMask extends PartMask implements MaskStrategy {
    method mask (line 12) | @Override

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/strategy/HashMask.java
  class HashMask (line 11) | public class HashMask implements MaskStrategy {
    method mask (line 16) | @Override
    method setSalt (line 27) | public static void setSalt(String salt){
    method getSalt (line 35) | public static String getSalt() {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/strategy/NameMask.java
  class NameMask (line 11) | public class NameMask extends PartMask implements MaskStrategy {
    method mask (line 13) | @Override

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/strategy/PartMask.java
  class PartMask (line 12) | public class PartMask implements MaskStrategy {
    method getMaskCodeByNum (line 26) | private static String getMaskCodeByNum(int num) {
    method mask (line 38) | @Override

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/id/IdUtil.java
  class IdUtil (line 6) | public class IdUtil {
    method fastUUID (line 10) | public static UUID fastUUID() {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/io/FilePathUtil.java
  class FilePathUtil (line 14) | public class FilePathUtil {
    method normalizePath (line 19) | public static String normalizePath(String path) {
    method simplifyPath (line 32) | public static String simplifyPath(String path) {
    method concat (line 39) | public static String concat(String baseName, String... appendName) {
    method getParentPath (line 63) | public static String getParentPath(String path) {
    method getJarPath (line 85) | public static String getJarPath(Class<?> clazz) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/io/FileTreeWalker.java
  class FileTreeWalker (line 12) | public class FileTreeWalker {
    method listAll (line 19) | public static List<File> listAll(File rootDir) {
    method listFile (line 26) | public static List<File> listFile(File rootDir) {
    method listFileWithExtension (line 33) | public static List<File> listFileWithExtension(final File rootDir, fin...
    method listFileWithWildcardFileName (line 42) | public static List<File> listFileWithWildcardFileName(final File rootD...
    method listFileWithRegexFileName (line 52) | public static List<File> listFileWithRegexFileName(final File rootDir,...
    method listFileWithAntPath (line 62) | public static List<File> listFileWithAntPath(final File rootDir, final...
    method fileTreeTraverser (line 74) | public static TreeTraverser<File> fileTreeTraverser() {
    class RegexFileNameFilter (line 81) | public static final class RegexFileNameFilter implements Predicate<Fil...
      method RegexFileNameFilter (line 84) | private RegexFileNameFilter(String pattern) {
      method apply (line 88) | @Override
    class WildcardFileNameFilter (line 99) | public static final class WildcardFileNameFilter implements Predicate<...
      method WildcardFileNameFilter (line 102) | private WildcardFileNameFilter(String pattern) {
      method apply (line 106) | @Override
    class FileExtensionFilter (line 115) | public static final class FileExtensionFilter implements Predicate<Fil...
      method FileExtensionFilter (line 118) | private FileExtensionFilter(String extension) {
      method apply (line 122) | @Override
    class AntPathFilter (line 133) | public static final class AntPathFilter implements Predicate<File> {
      method AntPathFilter (line 136) | private AntPathFilter(String pattern) {
      method apply (line 140) | @Override

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/io/FileUtil.java
  class FileUtil (line 36) | public class FileUtil {
    method visitFile (line 41) | @Override
    method postVisitDirectory (line 47) | @Override
    method toByteArray (line 61) | public static byte[] toByteArray(final File file) throws IOException {
    method toString (line 68) | public static String toString(final File file) throws IOException {
    method toLines (line 77) | public static List<String> toLines(final File file) throws IOException {
    method write (line 84) | public static void write(final CharSequence data, final File file) thr...
    method append (line 96) | public static void append(final CharSequence data, final File file) th...
    method asInputStream (line 111) | public static InputStream asInputStream(String fileName) throws IOExce...
    method asInputStream (line 120) | public static InputStream asInputStream(File file) throws IOException {
    method asInputStream (line 130) | public static InputStream asInputStream(Path path) throws IOException {
    method asOutputStream (line 140) | public static OutputStream asOutputStream(String fileName) throws IOEx...
    method asOutputStream (line 149) | public static OutputStream asOutputStream(File file) throws IOException {
    method asOutputStream (line 159) | public static OutputStream asOutputStream(Path path) throws IOException {
    method asBufferedReader (line 169) | public static BufferedReader asBufferedReader(String fileName) throws ...
    method asBufferedReader (line 174) | public static BufferedReader asBufferedReader(Path path) throws IOExce...
    method asBufferedWriter (line 184) | public static BufferedWriter asBufferedWriter(String fileName) throws ...
    method asBufferedWriter (line 194) | public static BufferedWriter asBufferedWriter(Path path) throws IOExce...
    method copy (line 207) | public static void copy(@NotNull File from, @NotNull File to) throws I...
    method copy (line 220) | public static void copy(@NotNull Path from, @NotNull Path to) throws I...
    method copyFile (line 237) | public static void copyFile(@NotNull File from, @NotNull File to) thro...
    method copyFile (line 249) | public static void copyFile(@NotNull Path from, @NotNull Path to) thro...
    method copyDir (line 259) | public static void copyDir(@NotNull File from, @NotNull File to) throw...
    method copyDir (line 269) | public static void copyDir(@NotNull Path from, @NotNull Path to) throw...
    method moveFile (line 286) | public static void moveFile(@NotNull File from, @NotNull File to) thro...
    method moveFile (line 298) | public static void moveFile(@NotNull Path from, @NotNull Path to) thro...
    method moveDir (line 309) | public static void moveDir(@NotNull File from, @NotNull File to) throw...
    method touch (line 332) | public static void touch(String filePath) throws IOException {
    method touch (line 341) | public static void touch(File file) throws IOException {
    method deleteFile (line 350) | public static void deleteFile(@Nullable File file) throws IOException {
    method deleteFile (line 360) | public static void deleteFile(@Nullable Path path) throws IOException {
    method deleteDir (line 371) | public static void deleteDir(Path dir) throws IOException {
    method deleteDir (line 381) | public static void deleteDir(File dir) throws IOException {
    method isDirExists (line 389) | public static boolean isDirExists(String dirPath) {
    method isDirExists (line 396) | public static boolean isDirExists(Path dirPath) {
    method isDirExists (line 403) | public static boolean isDirExists(File dir) {
    method makesureDirExists (line 413) | public static void makesureDirExists(String dirPath) throws IOException {
    method makesureDirExists (line 420) | public static void makesureDirExists(File file) throws IOException {
    method makesureDirExists (line 431) | public static void makesureDirExists(Path dirPath) throws IOException {
    method makesureParentDirExists (line 440) | public static void makesureParentDirExists(File file) throws IOExcepti...
    method isFileExists (line 451) | public static boolean isFileExists(String fileName) {
    method isFileExists (line 464) | public static boolean isFileExists(File file) {
    method isFileExists (line 477) | public static boolean isFileExists(Path path) {
    method createTempDir (line 489) | public static Path createTempDir() throws IOException {
    method createTempFile (line 498) | public static Path createTempFile() throws IOException {
    method createTempFile (line 507) | public static Path createTempFile(String prefix, String suffix) throws...
    method getPath (line 511) | private static Path getPath(String filePath) {
    method getFileName (line 518) | public static String getFileName(@NotNull String fullName) {
    method getFileExtension (line 529) | public static String getFileExtension(File file) {
    method getFileExtension (line 538) | public static String getFileExtension(String fullName) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/io/IOUtil.java
  class IOUtil (line 40) | public class IOUtil {
    method closeQuietly (line 49) | public static void closeQuietly(Closeable closeable) {
    method toString (line 63) | public static String toString(InputStream input) throws IOException {
    method toString (line 73) | public static String toString(Reader input) throws IOException {
    method toLines (line 80) | public static List<String> toLines(final InputStream input) throws IOE...
    method toLines (line 89) | public static List<String> toLines(final Reader input) throws IOExcept...
    method readLine (line 96) | public static String readLine(final InputStream input) throws IOExcept...
    method readLine (line 103) | public static String readLine(final Reader reader) throws IOException {
    method write (line 110) | public static void write(final String data, final OutputStream output)...
    method write (line 119) | public static void write(final String data, final Writer output) throw...
    method toInputStream (line 128) | public static InputStream toInputStream(String input) {
    method toInputStreamReader (line 135) | public static Reader toInputStreamReader(String input) {
    method copy (line 144) | public static long copy(final Reader input, final Writer output) throw...
    method copy (line 153) | public static long copy(final InputStream input, final OutputStream ou...
    method toBufferedReader (line 157) | public static BufferedReader toBufferedReader(final Reader reader) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/io/ResourceUtil.java
  class ResourceUtil (line 37) | public class ResourceUtil {
    method asUrl (line 43) | public static URL asUrl(String resourceName) {
    method asUrl (line 50) | public static URL asUrl(Class<?> contextClass, String resourceName) {
    method asStream (line 57) | public static InputStream asStream(String resourceName) throws IOExcep...
    method asStream (line 64) | public static InputStream asStream(Class<?> contextClass, String resou...
    method toString (line 73) | public static String toString(String resourceName) throws IOException {
    method toString (line 80) | public static String toString(Class<?> contextClass, String resourceNa...
    method toLines (line 87) | public static List<String> toLines(String resourceName) throws IOExcep...
    method toLines (line 94) | public static List<String> toLines(Class<?> contextClass, String resou...
    method getResourcesQuietly (line 100) | public static List<URL> getResourcesQuietly(String resourceName) {
    method getResourcesQuietly (line 104) | public static List<URL> getResourcesQuietly(String resourceName, Class...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/io/URLResourceUtil.java
  class URLResourceUtil (line 22) | public class URLResourceUtil {
    method asFile (line 33) | public static File asFile(String generalPath) throws IOException {
    method asStream (line 50) | public static InputStream asStream(String generalPath) throws IOExcept...
    method getFileByURL (line 65) | private static File getFileByURL(URL fileUrl) throws FileNotFoundExcep...
    method toURI (line 79) | public static URI toURI(String location) throws URISyntaxException {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/io/type/StringBuilderWriter.java
  class StringBuilderWriter (line 31) | public class StringBuilderWriter extends Writer implements Serializable {
    method StringBuilderWriter (line 39) | public StringBuilderWriter() {
    method StringBuilderWriter (line 48) | public StringBuilderWriter(final int capacity) {
    method StringBuilderWriter (line 61) | public StringBuilderWriter(final StringBuilder builder) {
    method append (line 71) | @Override
    method append (line 83) | @Override
    method append (line 97) | @Override
    method close (line 106) | @Override
    method flush (line 114) | @Override
    method write (line 124) | @Override
    method write (line 138) | @Override
    method getBuilder (line 150) | public StringBuilder getBuilder() {
    method toString (line 159) | @Override

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/logging/PerformanceUtil.java
  class PerformanceUtil (line 11) | public class PerformanceUtil {
    method PerformanceUtil (line 12) | private PerformanceUtil() {
    method initialValue (line 17) | @Override
    method initialValue (line 25) | @Override
    method start (line 34) | public static void start() {
    method duration (line 41) | public static long duration() {
    method end (line 48) | public static long end() {
    method start (line 57) | public static void start(String key) {
    method duration (line 64) | public static long duration(String key) {
    method end (line 71) | public static long end(String key) {
    method removeAll (line 80) | public static void removeAll() {
    method slowLog (line 92) | public static void slowLog(Logger logger, long duration, long threshol...
    method slowLog (line 104) | public static void slowLog(Logger logger, String key, long duration, l...
    method slowLog (line 117) | public static void slowLog(Logger logger, long duration, long threshol...
    method slowLog (line 130) | public static void slowLog(Logger logger, String key, long duration, l...
    method endWithSlowLog (line 142) | public static void endWithSlowLog(Logger logger, long threshold) {
    method endWithSlowLog (line 152) | public static void endWithSlowLog(Logger logger, String key, long thre...
    method endWithSlowLog (line 162) | public static void endWithSlowLog(Logger logger, long threshold, Strin...
    method endWithSlowLog (line 173) | public static void endWithSlowLog(Logger logger, String key, long thre...
    method getTimer (line 177) | private static Timer getTimer(String key) {
    class Timer (line 188) | static class Timer {
      method start (line 191) | public void start() {
      method duration (line 195) | public long duration() {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/mapper/BeanMapper.java
  class BeanMapper (line 28) | public class BeanMapper {
    method map (line 35) | public static <S, D> D map(S source, Class<D> destinationClass) {
    method mapList (line 42) | public static <S, D> List<D> mapList(Iterable<S> sourceList, Class<D> ...
    method mapArray (line 55) | public static <S, D> D[] mapArray(final S[] sourceArray, final Class<D...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/mapper/JsonMapper.java
  class JsonMapper (line 31) | public class JsonMapper {
    method JsonMapper (line 39) | public JsonMapper() {
    method JsonMapper (line 43) | public JsonMapper(Include include) {
    method nonNullMapper (line 56) | public static JsonMapper nonNullMapper() {
    method nonEmptyMapper (line 65) | public static JsonMapper nonEmptyMapper() {
    method defaultMapper (line 72) | public static JsonMapper defaultMapper() {
    method toJson (line 79) | public String toJson(Object object) {
    method fromJson (line 98) | public <T> T fromJson(@Nullable String jsonString, Class<T> clazz) {
    method fromJson (line 116) | public <T> T fromJson(@Nullable String jsonString, JavaType javaType) {
    method buildCollectionType (line 132) | public JavaType buildCollectionType(Class<? extends Collection> collec...
    method buildMapType (line 139) | public JavaType buildMapType(Class<? extends Map> mapClass, Class<?> k...
    method update (line 146) | public void update(String jsonString, Object object) {
    method toJsonP (line 159) | public String toJsonP(String functionName, Object object) {
    method enableEnumUseToString (line 166) | public void enableEnumUseToString() {
    method getMapper (line 174) | public ObjectMapper getMapper() {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/mapper/XmlMapper.java
  class XmlMapper (line 32) | public class XmlMapper {
    method toXml (line 39) | public static String toXml(Object root) {
    method toXml (line 47) | public static String toXml(Object root, String encoding) {
    method toXml (line 55) | public static String toXml(Object root, Class clazz, String encoding) {
    method toXml (line 68) | public static String toXml(Collection<?> root, String rootName, Class ...
    method toXml (line 75) | public static String toXml(Collection<?> root, String rootName, Class ...
    method fromXml (line 95) | public static <T> T fromXml(String xml, Class<T> clazz) {
    method createMarshaller (line 108) | public static Marshaller createMarshaller(Class clazz, String encoding) {
    method createUnmarshaller (line 130) | public static Unmarshaller createUnmarshaller(Class clazz) {
    method getJaxbContext (line 139) | protected static JAXBContext getJaxbContext(Class clazz) {
    class CollectionWrapper (line 157) | public static class CollectionWrapper {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/net/IPUtil.java
  class IPUtil (line 21) | public class IPUtil {
    method toInt (line 30) | public static int toInt(InetAddress address) {
    method toIpString (line 41) | public static String toIpString(InetAddress address) {
    method fromInt (line 48) | public static Inet4Address fromInt(int address) {
    method fromIpString (line 59) | public static InetAddress fromIpString(String address) {
    method fromIpv4String (line 70) | public static Inet4Address fromIpv4String(String address) {
    method intToIpv4String (line 86) | public static String intToIpv4String(int i) {
    method ipv4StringToInt (line 94) | public static int ipv4StringToInt(String ipv4Str) {
    method ip4StringToBytes (line 106) | private static byte[] ip4StringToBytes(String ipv4Str) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/net/NetUtil.java
  class NetUtil (line 30) | @Beta
    method getLocalAddress (line 44) | public static InetAddress getLocalAddress() {
    method getLocalHost (line 51) | public static String getLocalHost() {
    method getHostName (line 58) | public static String getHostName() {
    class LocalAddressHoler (line 65) | private static class LocalAddressHoler {
    class LocalAddress (line 69) | private static class LocalAddress {
      method LocalAddress (line 75) | public LocalAddress() {
      method initLocalAddress (line 84) | private void initLocalAddress() {
      method findLocalAddressViaNetworkInterface (line 112) | private static InetAddress findLocalAddressViaNetworkInterface() {
      method findAvailableInetAddress (line 169) | private static InetAddress findAvailableInetAddress(NetworkInterface...
    method isPortAvailable (line 185) | public static boolean isPortAvailable(int port) {
    method findRandomAvailablePort (line 199) | public static int findRandomAvailablePort() {
    method findRandomAvailablePort (line 208) | public static int findRandomAvailablePort(int minPort, int maxPort) {
    method findAvailablePortFrom (line 230) | public static int findAvailablePortFrom(int minPort) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/number/MathUtil.java
  class MathUtil (line 15) | public class MathUtil {
    method nextPowerOfTwo (line 24) | public static int nextPowerOfTwo(int value) {
    method nextPowerOfTwo (line 33) | public static long nextPowerOfTwo(long value) {
    method previousPowerOfTwo (line 42) | public static int previousPowerOfTwo(int value) {
    method previousPowerOfTwo (line 51) | public static long previousPowerOfTwo(long value) {
    method isPowerOfTwo (line 60) | public static boolean isPowerOfTwo(int value) {
    method isPowerOfTwo (line 69) | public static boolean isPowerOfTwo(long value) {
    method modByPowerOfTwo (line 78) | public static int modByPowerOfTwo(int value, int mod) {
    method mod (line 89) | public static int mod(int x, int m) {
    method mod (line 98) | public static long mod(long x, long m) {
    method mod (line 105) | public static int mod(long x, int m) {
    method divide (line 114) | public static int divide(int p, int q, RoundingMode mode) {
    method divide (line 123) | public static long divide(long p, long q, RoundingMode mode) {
    method pow (line 132) | public static int pow(int b, int k) {
    method pow (line 141) | public static long pow(long b, int k) {
    method sqrt (line 148) | public static int sqrt(int x, RoundingMode mode) {
    method sqrt (line 155) | public static long sqrt(long x, RoundingMode mode) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/number/MoneyUtil.java
  class MoneyUtil (line 18) | public class MoneyUtil {
    method createThreadLocalNumberformat (line 25) | private static ThreadLocal<DecimalFormat> createThreadLocalNumberforma...
    method fen2yuan (line 43) | public static BigDecimal fen2yuan(BigDecimal num) {
    method fen2yuan (line 50) | public static BigDecimal fen2yuan(long num) {
    method fen2yuan (line 57) | public static BigDecimal fen2yuan(String num) {
    method yuan2fen (line 67) | public static BigDecimal yuan2fen(String y) {
    method yuan2fen (line 74) | public static BigDecimal yuan2fen(double y) {
    method yuan2fen (line 81) | public static BigDecimal yuan2fen(BigDecimal y) {
    method format (line 93) | public static String format(BigDecimal number) {
    method format (line 100) | public static String format(double number) {
    method prettyFormat (line 107) | public static String prettyFormat(BigDecimal number) {
    method prettyFormat (line 114) | public static String prettyFormat(double number) {
    method format (line 121) | public static String format(BigDecimal number, String pattern) {
    method format (line 128) | public static String format(double number, String pattern) {
    method parseString (line 145) | public static BigDecimal parseString(String numberStr) throws ParseExc...
    method parsePrettyString (line 152) | public static BigDecimal parsePrettyString(String numberStr) throws Pa...
    method parseString (line 159) | public static BigDecimal parseString(String numberStr, String pattern)...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/number/NumberUtil.java
  class NumberUtil (line 22) | public class NumberUtil {
    method equalsWithin (line 29) | public static boolean equalsWithin(double d1, double d2) {
    method equalsWithin (line 36) | public static boolean equalsWithin(double d1, double d2, double epsilo...
    method toBytes (line 42) | public static byte[] toBytes(int value) {
    method toBytes (line 46) | public static byte[] toBytes(long value) {
    method toBytes (line 53) | public static byte[] toBytes(double val) {
    method toInt (line 57) | public static int toInt(byte[] bytes) {
    method toLong (line 61) | public static long toLong(byte[] bytes) {
    method toDouble (line 68) | public static double toDouble(byte[] bytes) {
    method isNumber (line 76) | public static boolean isNumber(@Nullable String str) {
    method isHexNumber (line 83) | public static boolean isHexNumber(@Nullable String value) {
    method toInt (line 99) | public static int toInt(@NotNull String str) {
    method toInt (line 108) | public static int toInt(@Nullable String str, int defaultValue) {
    method toLong (line 117) | public static long toLong(@NotNull String str) {
    method toLong (line 126) | public static long toLong(@Nullable String str, long defaultValue) {
    method toDouble (line 135) | public static double toDouble(@NotNull String str) {
    method toDouble (line 148) | public static double toDouble(@Nullable String str, double defaultValu...
    method toIntObject (line 158) | public static Integer toIntObject(@NotNull String str) {
    method toIntObject (line 167) | public static Integer toIntObject(@Nullable String str, Integer defaul...
    method toLongObject (line 183) | public static Long toLongObject(@NotNull String str) {
    method toLongObject (line 192) | public static Long toLongObject(@Nullable String str, Long defaultValu...
    method toDoubleObject (line 208) | public static Double toDoubleObject(@NotNull String str) {
    method toDoubleObject (line 221) | public static Double toDoubleObject(@Nullable String str, Double defau...
    method hexToIntObject (line 239) | public static Integer hexToIntObject(@NotNull String str) {
    method hexToIntObject (line 250) | public static Integer hexToIntObject(@Nullable String str, Integer def...
    method hexToLongObject (line 266) | public static Long hexToLongObject(@NotNull String str) {
    method hexToLongObject (line 277) | public static Long hexToLongObject(@Nullable String str, Long defaultV...
    method toString (line 291) | public static String toString(int i) {
    method toString (line 295) | public static String toString(@NotNull Integer i) {
    method toString (line 299) | public static String toString(long l) {
    method toString (line 303) | public static String toString(@NotNull Long l) {
    method toString (line 307) | public static String toString(double d) {
    method toString (line 311) | public static String toString(@NotNull Double d) {
    method to2DigitString (line 318) | public static String to2DigitString(double d) {
    method toInt32 (line 327) | public static int toInt32(long x) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/number/RandomUtil.java
  class RandomUtil (line 25) | public class RandomUtil {
    method threadLocalRandom (line 31) | public static Random threadLocalRandom() {
    method secureRandom (line 43) | public static SecureRandom secureRandom() {
    method nextInt (line 55) | public static int nextInt() {
    method nextInt (line 62) | public static int nextInt(Random random) {
    method nextInt (line 76) | public static int nextInt(int max) {
    method nextInt (line 83) | public static int nextInt(Random random, int max) {
    method nextInt (line 92) | public static int nextInt(int min, int max) {
    method nextInt (line 105) | public static int nextInt(Random random, int min, int max) {
    method nextLong (line 120) | public static long nextLong() {
    method nextLong (line 127) | public static long nextLong(Random random) {
    method nextLong (line 140) | public static long nextLong(long max) {
    method nextLong (line 147) | public static long nextLong(Random random, long max) {
    method nextLong (line 156) | public static long nextLong(long min, long max) {
    method nextLong (line 169) | public static long nextLong(Random random, long min, long max) {
    method nextDouble (line 184) | public static double nextDouble() {
    method nextDouble (line 191) | public static double nextDouble(Random random) {
    method nextDouble (line 200) | public static double nextDouble(double max) {
    method nextDouble (line 207) | public static double nextDouble(Random random, double max) {
    method nextDouble (line 214) | public static double nextDouble(final double min, final double max) {
    method nextDouble (line 221) | public static double nextDouble(Random random, final double min, final...
    method randomStringFixLength (line 236) | public static String randomStringFixLength(int length) {
    method randomStringFixLength (line 243) | public static String randomStringFixLength(Random random, int length) {
    method randomStringRandomLength (line 250) | public static String randomStringRandomLength(int minLength, int maxLe...
    method randomStringRandomLength (line 257) | public static String randomStringRandomLength(Random random, int minLe...
    method randomLetterFixLength (line 264) | public static String randomLetterFixLength(int length) {
    method randomLetterFixLength (line 271) | public static String randomLetterFixLength(Random random, int length) {
    method randomLetterRandomLength (line 278) | public static String randomLetterRandomLength(int minLength, int maxLe...
    method randomLetterRandomLength (line 285) | public static String randomLetterRandomLength(Random random, int minLe...
    method randomAsciiFixLength (line 292) | public static String randomAsciiFixLength(int length) {
    method randomAsciiFixLength (line 299) | public static String randomAsciiFixLength(Random random, int length) {
    method randomAsciiRandomLength (line 306) | public static String randomAsciiRandomLength(int minLength, int maxLen...
    method randomAsciiRandomLength (line 314) | public static String randomAsciiRandomLength(Random random, int minLen...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/number/SizeUnit.java
  type SizeUnit (line 10) | public enum SizeUnit {
    method toBytes (line 32) | public double toBytes(final long input) {
    method toKiloBytes (line 59) | public double toKiloBytes(final long input) {
    method toMegaBytes (line 86) | public double toMegaBytes(final long input) {
    method toGigaBytes (line 113) | public double toGigaBytes(final long input) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/number/UnitConverter.java
  class UnitConverter (line 24) | public class UnitConverter {
    method toDurationMillis (line 45) | public static long toDurationMillis(String duration) {
    method toBytes (line 86) | public static long toBytes(String size) {
    method toSizeUnit (line 123) | public static String toSizeUnit(Long bytes, int scale) {
    method toTimeUnit (line 151) | public static String toTimeUnit(long millis, int scale) {
    method toTimeWithMinorUnit (line 177) | public static String toTimeWithMinorUnit(long millis) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/reflect/AnnotationUtil.java
  class AnnotationUtil (line 21) | public class AnnotationUtil {
    method getAllAnnotations (line 28) | public static Set<Annotation> getAllAnnotations(final Class<?> cls) {
    method getSuperAnnotations (line 48) | private static <A extends Annotation> void getSuperAnnotations(Class<A...
    method getAnnotatedPublicFields (line 65) | public static <T extends Annotation> Set<Field> getAnnotatedPublicFiel...
    method getAnnotatedFields (line 91) | public static <T extends Annotation> Set<Field> getAnnotatedFields(Cla...
    method getAnnotatedPublicMethods (line 114) | public static <T extends Annotation> Set<Method> getAnnotatedPublicMet...
    method searchOnInterfaces (line 136) | private static <T extends Annotation> boolean searchOnInterfaces(Metho...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/reflect/ClassLoaderUtil.java
  class ClassLoaderUtil (line 3) | public class ClassLoaderUtil {
    method getDefaultClassLoader (line 14) | public static ClassLoader getDefaultClassLoader() {
    method isPresent (line 39) | public static boolean isPresent(String className, ClassLoader classLoa...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/reflect/ClassUtil.java
  class ClassUtil (line 19) | public class ClassUtil {
    method getShortClassName (line 31) | public static String getShortClassName(final Class<?> cls) {
    method getShortClassName (line 40) | public static String getShortClassName(final String className) {
    method getPackageName (line 47) | public static String getPackageName(final Class<?> cls) {
    method getPackageName (line 54) | public static String getPackageName(final String className) {
    method getAllSuperclasses (line 62) | public static List<Class<?>> getAllSuperclasses(final Class<?> cls) {
    method getAllInterfaces (line 69) | public static List<Class<?>> getAllInterfaces(final Class<?> cls) {
    method isSubClassOrInterfaceOf (line 83) | public static boolean isSubClassOrInterfaceOf(Class subclass, Class su...
    method unwrapCglib (line 90) | public static Class<?> unwrapCglib(Object instance) {
    method getClassGenericType (line 114) | public static <T> Class<T> getClassGenericType(final Class clazz) {
    method getClassGenericType (line 131) | public static Class getClassGenericType(final Class clazz, final int i...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/reflect/ReflectionUtil.java
  class ReflectionUtil (line 32) | @SuppressWarnings("unchecked")
    method getSetterMethod (line 43) | public static Method getSetterMethod(Class<?> clazz, String propertyNa...
    method getGetterMethod (line 51) | public static Method getGetterMethod(Class<?> clazz, String propertyNa...
    method getMethod (line 75) | public static Method getMethod(final Class<?> clazz, final String meth...
    method getAccessibleMethodByName (line 94) | public static Method getAccessibleMethodByName(final Class clazz, fina...
    method getField (line 118) | public static Field getField(final Class clazz, final String fieldName) {
    method invokeGetter (line 139) | public static <T> T invokeGetter(Object obj, String propertyName) {
    method invokeSetter (line 153) | public static void invokeSetter(Object obj, String propertyName, Objec...
    method getFieldValue (line 167) | public static <T> T getFieldValue(final Object obj, final String field...
    method getFieldValue (line 180) | public static <T> T getFieldValue(final Object obj, final Field field) {
    method setFieldValue (line 193) | public static void setFieldValue(final Object obj, final String fieldN...
    method setField (line 206) | public static void setField(final Object obj, Field field, final Objec...
    method getProperty (line 219) | public static <T> T getProperty(Object obj, String propertyName) {
    method setProperty (line 233) | public static void setProperty(Object obj, String propertyName, final ...
    method invokeMethod (line 250) | public static <T> T invokeMethod(Object obj, String methodName, Object...
    method invokeMethod (line 263) | public static <T> T invokeMethod(final Object obj, final String method...
    method invokeMethodByName (line 280) | public static <T> T invokeMethodByName(final Object obj, final String ...
    method invokeMethod (line 292) | public static <T> T invokeMethod(final Object obj, Method method, Obje...
    method invokeConstructor (line 305) | public static <T> T invokeConstructor(final Class<T> cls, Object... ar...
    method makeAccessible (line 318) | public static void makeAccessible(Method method) {
    method makeAccessible (line 328) | public static void makeAccessible(Field field) {
    method convertReflectionExceptionToUnchecked (line 339) | public static RuntimeException convertReflectionExceptionToUnchecked(E...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/security/CryptoUtil.java
  class CryptoUtil (line 23) | public class CryptoUtil {
    method hmacSha1 (line 42) | public static byte[] hmacSha1(byte[] input, byte[] key) {
    method isMacValid (line 60) | public static boolean isMacValid(byte[] expected, byte[] input, byte[]...
    method generateHmacSha1Key (line 68) | public static byte[] generateHmacSha1Key() {
    method aesEncrypt (line 86) | public static byte[] aesEncrypt(byte[] input, byte[] key) {
    method aesEncrypt (line 97) | public static byte[] aesEncrypt(byte[] input, byte[] key, byte[] iv) {
    method aesDecrypt (line 107) | public static String aesDecrypt(byte[] input, byte[] key) {
    method aesDecrypt (line 119) | public static String aesDecrypt(byte[] input, byte[] key, byte[] iv) {
    method aes (line 131) | private static byte[] aes(byte[] input, byte[] key, int mode) {
    method aes (line 150) | private static byte[] aes(byte[] input, byte[] key, byte[] iv, int mod...
    method generateAesKey (line 165) | public static byte[] generateAesKey() {
    method generateAesKey (line 172) | public static byte[] generateAesKey(int keysize) {
    method generateIV (line 186) | public static byte[] generateIV() {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/text/Charsets.java
  class Charsets (line 14) | public class Charsets {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/text/CsvUtil.java
  class CsvUtil (line 40) | public class CsvUtil {
    method toCsvString (line 52) | public static String toCsvString(Object... elements) {
    method fromCsvString (line 97) | public static String[] fromCsvString(String line) {
    method addField (line 133) | private static void addField(List<String> row, String line, int startI...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/text/EncodeUtil.java
  class EncodeUtil (line 8) | public class EncodeUtil {
    method encodeHex (line 13) | public static String encodeHex(byte[] input) {
    method decodeHex (line 22) | public static byte[] decodeHex(CharSequence input) {
    method encodeBase64 (line 29) | public static String encodeBase64(byte[] input) {
    method decodeBase64 (line 38) | public static byte[] decodeBase64(CharSequence input) {
    method encodeBase64UrlSafe (line 45) | public static String encodeBase64UrlSafe(byte[] input) {
    method decodeBase64UrlSafe (line 54) | public static byte[] decodeBase64UrlSafe(CharSequence input) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/text/EscapeUtil.java
  class EscapeUtil (line 18) | public class EscapeUtil {
    method urlEncode (line 25) | public static String urlEncode(String part) {
    method urlDecode (line 37) | public static String urlDecode(String part) {
    method escapeXml (line 51) | public static String escapeXml(String xml) {
    method unescapeXml (line 60) | public static String unescapeXml(String xml) {
    method escapeHtml (line 69) | public static String escapeHtml(String html) {
    method unescapeHtml (line 78) | public static String unescapeHtml(String html) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/text/HashUtil.java
  class HashUtil (line 31) | public class HashUtil {
    method createThreadLocalMessageDigest (line 41) | private static ThreadLocal<MessageDigest> createThreadLocalMessageDige...
    method sha1 (line 59) | public static byte[] sha1(@NotNull byte[] input) {
    method sha1 (line 66) | public static byte[] sha1(@NotNull String input) {
    method sha1 (line 73) | public static byte[] sha1(@NotNull byte[] input, @Nullable byte[] salt) {
    method sha1 (line 80) | public static byte[] sha1(@NotNull String input, @Nullable byte[] salt) {
    method sha1 (line 89) | public static byte[] sha1(@NotNull byte[] input, @Nullable byte[] salt...
    method sha1 (line 98) | public static byte[] sha1(@NotNull String input, @Nullable byte[] salt...
    method get (line 102) | private static MessageDigest get(ThreadLocal<MessageDigest> messageDig...
    method digest (line 111) | private static byte[] digest(@NotNull byte[] input, MessageDigest dige...
    method generateSalt (line 134) | public static byte[] generateSalt(int numBytes) {
    method sha1File (line 145) | public static byte[] sha1File(InputStream input) throws IOException {
    method md5File (line 152) | public static byte[] md5File(InputStream input) throws IOException {
    method digestFile (line 156) | private static byte[] digestFile(InputStream input, MessageDigest mess...
    method crc32AsInt (line 176) | public static int crc32AsInt(@NotNull String input) {
    method crc32AsInt (line 185) | public static int crc32AsInt(@NotNull byte[] input) {
    method crc32AsLong (line 197) | public static long crc32AsLong(@NotNull String input) {
    method crc32AsLong (line 206) | public static long crc32AsLong(@NotNull byte[] input) {
    method murmur32AsInt (line 216) | public static int murmur32AsInt(@NotNull byte[] input) {
    method murmur32AsInt (line 223) | public static int murmur32AsInt(@NotNull String input) {
    method murmur128AsLong (line 230) | public static long murmur128AsLong(@NotNull byte[] input) {
    method murmur128AsLong (line 237) | public static long murmur128AsLong(@NotNull String input) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/text/MoreStringUtil.java
  class MoreStringUtil (line 25) | public class MoreStringUtil {
    method split (line 36) | public static List<String> split(@Nullable final String str, final cha...
    method split (line 55) | public static List<String> split(@Nullable final String str, final cha...
    method charsSplitter (line 96) | public static Splitter charsSplitter(final String separatorChars) {
    method replaceFirst (line 104) | public static String replaceFirst(@Nullable String s, char sub, char w...
    method replaceLast (line 120) | public static String replaceLast(@Nullable String s, char sub, char wi...
    method startWith (line 139) | public static boolean startWith(@Nullable CharSequence s, char c) {
    method endWith (line 151) | public static boolean endWith(@Nullable CharSequence s, char c) {
    method removeEnd (line 161) | public static String removeEnd(final String s, final char c) {
    method utf8EncodedLength (line 174) | public static int utf8EncodedLength(@Nullable CharSequence sequence) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/text/StringBuilderHolder.java
  class StringBuilderHolder (line 14) | public class StringBuilderHolder {
    method initialValue (line 18) | @Override
    method initialValue (line 26) | @Override
    method StringBuilderHolder (line 41) | public StringBuilderHolder(int initSize) {
    method getGlobal (line 52) | public static StringBuilder getGlobal() {
    method get (line 63) | public StringBuilder get() {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/text/TextValidator.java
  class TextValidator (line 17) | public class TextValidator {
    method isMobileSimple (line 92) | public static boolean isMobileSimple(@Nullable CharSequence input) {
    method isMobileExact (line 99) | public static boolean isMobileExact(@Nullable CharSequence input) {
    method isTel (line 106) | public static boolean isTel(@Nullable CharSequence input) {
    method isIdCard (line 113) | public static boolean isIdCard(@Nullable CharSequence input) {
    method isEmail (line 120) | public static boolean isEmail(@Nullable CharSequence input) {
    method isUrl (line 127) | public static boolean isUrl(@Nullable CharSequence input) {
    method isDate (line 134) | public static boolean isDate(@Nullable CharSequence input) {
    method isIp (line 141) | public static boolean isIp(@Nullable CharSequence input) {
    method isMatch (line 145) | public static boolean isMatch(Pattern pattern, CharSequence input) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/text/WildcardMatcher.java
  class WildcardMatcher (line 46) | public class WildcardMatcher {
    method match (line 55) | public static boolean match(CharSequence string, CharSequence pattern) {
    method match (line 62) | private static boolean match(CharSequence string, CharSequence pattern...
    method matchOne (line 144) | public static int matchOne(String src, String... patterns) {
    method matchPathOne (line 162) | public static int matchPathOne(String platformDependentPath, String......
    method matchPath (line 176) | public static boolean matchPath(String path, String pattern) {
    method matchTokens (line 185) | protected static boolean matchTokens(String[] tokens, String[] pattern...

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/time/CachingDateFormatter.java
  class CachingDateFormatter (line 18) | public class CachingDateFormatter {
    method CachingDateFormatter (line 23) | public CachingDateFormatter(String pattern) {
    method CachingDateFormatter (line 27) | public CachingDateFormatter(FastDateFormat fastDateFormat) {
    method format (line 35) | public String format(final long timestampMillis) {
    class CachedTime (line 51) | static final class CachedTime {
      method CachedTime (line 55) | public CachedTime(final long timestamp, String formatted) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/time/ClockUtil.java
  class ClockUtil (line 10) | public class ClockUtil {
    method elapsedTime (line 17) | public static long elapsedTime(long beginTime) {
    method useDummyClock (line 24) | public static synchronized DummyClock useDummyClock() {
    method useDummyClock (line 32) | public static synchronized DummyClock useDummyClock(long timeStampMill...
    method useDummyClock (line 40) | public static synchronized DummyClock useDummyClock(Date date) {
    method useDefaultClock (line 48) | public static synchronized void useDefaultClock() {
    method currentDate (line 55) | public static Date currentDate() {
    method currentTimeMillis (line 62) | public static long currentTimeMillis() {
    method nanoTime (line 69) | public static long nanoTime() {
    type Clock (line 73) | public interface Clock {
      method currentDate (line 78) | Date currentDate();
      method currentTimeMillis (line 83) | long currentTimeMillis();
      method nanoTime (line 88) | long nanoTime();
    class DefaultClock (line 94) | public static class DefaultClock implements Clock {
      method currentDate (line 96) | @Override
      method currentTimeMillis (line 101) | @Override
      method nanoTime (line 106) | @Override
    class DummyClock (line 115) | public static class DummyClock implements Clock {
      method DummyClock (line 120) | public DummyClock() {
      method DummyClock (line 124) | public DummyClock(Date date) {
      method DummyClock (line 128) | public DummyClock(long time) {
      method currentDate (line 133) | @Override
      method currentTimeMillis (line 138) | @Override
      method nanoTime (line 146) | @Override
      method updateNow (line 154) | public void updateNow(Date newDate) {
      method updateNow (line 161) | public void updateNow(long newTime) {
      method increaseTime (line 168) | public void increaseTime(int millis) {
      method decreaseTime (line 175) | public void decreaseTime(int millis) {
      method setNanoTime (line 182) | public void setNanoTime(long nanoTime) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/time/DateFormatUtil.java
  class DateFormatUtil (line 26) | public class DateFormatUtil {
    method parseDate (line 55) | public static Date parseDate(@NotNull String pattern, @NotNull String ...
    method formatDate (line 66) | public static String formatDate(@NotNull String pattern, @NotNull Date...
    method formatDate (line 77) | public static String formatDate(@NotNull String pattern, long date) {
    method formatDuration (line 89) | public static String formatDuration(@NotNull Date startDate, @NotNull ...
    method formatDuration (line 100) | public static String formatDuration(long durationMillis) {
    method formatDurationOnSecond (line 111) | public static String formatDurationOnSecond(@NotNull Date startDate, @...
    method formatDurationOnSecond (line 122) | public static String formatDurationOnSecond(long durationMillis) {
    method formatFriendlyTimeSpanByNow (line 132) | public static String formatFriendlyTimeSpanByNow(@NotNull Date date) {
    method formatFriendlyTimeSpanByNow (line 141) | public static String formatFriendlyTimeSpanByNow(long timeStampMillis) {

FILE: vjkit/src/main/java/com/vip/vjtools/vjkit/time/DateUtil.java
  class DateUtil (line 16) | public class DateUtil {
    method isSameDay (line 31) | public static boolean isSameDay(@NotNull final Date date1, @NotNull fi...
    method isSameTime (line 38) | public static boolean isSameTime(@NotNull final Date date1, @NotNull f...
    method isBetween (line 46) | public static boolean isBetween(@NotNull final Date date, @NotNull fin...
    method addMonths (line 58) | public static Date addMonths(@NotNull final Date date, int amount) {
    method subMonths (line 65) | public static Date subMonths(@NotNull final Date date, int amount) {
    method addWeeks (line 72) | public static Date addWeeks(@NotNull final Date date, int amount) {
    method subWeeks (line 79) | public static Date subWeeks(@NotNull final Date date, int amount) {
    method addDays (line 86) | public static Date addDays(@NotNull final Date date, final int amount) {
    method subDays (line 93) | public static Date subDays(@NotNull final Date date, int amount) {
    method addHours (line 100) | public static Date addHours(@NotNull final Date date, int amount) {
    method subHours (line 107) | public static Date subHours(@NotNull final Date date, int amount) {
    method addMinutes (line 114) | public static Date addMinutes(@NotNull final Date date, int amount) {
    method subMinutes (line 121) | public static Date subMinutes(@NotNull final Date date, int amount) {
    method addSeconds (line 128) | public static Date addSeconds(@NotNull final Date date, int amount) {
    method subSeconds (line 135) | public static Date subSeconds(@NotNull final Date date, int amount) {
    method setYears (line 144) | public static Date setYears(@NotNull final Date date, int amount) {
    method setMonths (line 151) | public static Date setMonths(@NotNull final Date date, int amount) {
    method setDays (line 161) | public static Date setDays(@NotNull final Date date, int amount) {
    method setHours (line 168) | public static Date setHours(@NotNull final Date date, int amount) {
    method setMinutes (line 175) | public static Date setMinutes(@NotNull final Date date, int amount) {
    method setSeconds (line 182) | public static Date setSeconds(@NotNull final Date date, int amount) {
    method setMilliseconds (line 189) | public static Date setMilliseconds(@NotNull final Date date, int amoun...
    method getDayOfWeek (line 197) | public static int getDayOfWeek(@NotNull final Date date) {
    method getDayOfYear (line 205) | public static int getDayOfYear(@NotNull final Date date) {
    method getWeekOfMonth (line 214) | public static int getWeekOfMonth(@NotNull final Date date) {
    method getWeekOfYear (line 223) | public static int getWeekOfYear(@NotNull final Date date) {
    method get (line 227) | private static int get(final Date date, int field) {
    method getWithMondayFirst (line 235) | private static int getWithMondayFirst(final Date date, int field) {
    method beginOfYear (line 248) | public static Date beginOfYear(@NotNull final Date date) {
    method endOfYear (line 255) | public static Date endOfYear(@NotNull final Date date) {
    method nextYear (line 262) | public static Date nextYear(@NotNull final Date date) {
    method beginOfMonth (line 269) | public static Date beginOfMonth(@NotNull final Date date) {
    method endOfMonth (line 276) | public static Date endOfMonth(@NotNull final Date date) {
    method nextMonth (line 283) | public static Date nextMonth(@NotNull final Date date) {
    method beginOfWeek (line 290) | public static Date beginOfWeek(@NotNull final Date date) {
    method endOfWeek (line 297) | public static Date endOfWeek(@NotNull final Date date) {
    method nextWeek (line 304) | public static Date nextWeek(@NotNull final Date date) {
    method beginOfDate (line 311) | public static Date beginOfDate(@NotNull final Date date) {
    method endOfDate (line 318) | public static Date endOfDate(@NotNull final Date date) {
    method nextDate (line 325) | public static Date nextDate(@NotNull final Date date) {
    method beginOfHour (line 332) | public static Date beginOfHour(@NotNull final Date date) {
    method endOfHour (line 339) | public static Date endOfHour(@NotNull final Date date) {
    method nextHour (line 346) | public static Date nextHour(@NotNull final Date date) {
    method beginOfMinute (line 353) | public static Date beginOfMinute(@NotNull final Date date) {
    method endOfMinute (line 360) | public static Date endOfMinute(@NotNull final Date date) {
    method nextMinute (line 367) | public static Date nextMinute(@NotNull final Date date) {
    method isLeapYear (line 375) | public static boolean isLeapYear(@NotNull final Date date) {
    method isLeapYear (line 384) | public static boolean isLeapYear(int y) {
    method getMonthLength (line 399) | public static int getMonthLength(@NotNull final Date date) {
    method getMonthLength (line 408) | public static int getMonthLength(int year, int month) {

FILE: vjkit/src/test/java/com/vip/vjtools/test/data/RandomData.java
  class RandomData (line 10) | public class RandomData {
    method randomId (line 17) | public static long randomId() {
    method randomName (line 24) | public static String randomName(String prefix) {
    method randomOne (line 31) | public static <T> T randomOne(List<T> list) {
    method randomSome (line 39) | public static <T> List<T> randomSome(List<T> list, int n) {
    method randomSome (line 47) | public static <T> List<T> randomSome(List<T> list) {

FILE: vjkit/src/test/java/com/vip/vjtools/test/log/LogbackListAppender.java
  class LogbackListAppender (line 19) | public class LogbackListAppender extends UnsynchronizedAppenderBase<ILog...
    method LogbackListAppender (line 23) | public LogbackListAppender() {
    method create (line 27) | public static LogbackListAppender create(Class<?> loggerClass) {
    method create (line 33) | public static LogbackListAppender create(String loggerName) {
    method append (line 39) | @Override
    method getFirstLog (line 47) | public ILoggingEvent getFirstLog() {
    method getFirstMessage (line 57) | public String getFirstMessage() {
    method getLastLog (line 67) | public ILoggingEvent getLastLog() {
    method getLastMessage (line 77) | public String getLastMessage() {
    method getAllLogs (line 87) | public List<ILoggingEvent> getAllLogs() {
    method getLogsCount (line 94) | public int getLogsCount() {
    method isEmpty (line 101) | public boolean isEmpty() {
    method clearLogs (line 108) | public void clearLogs() {
    method addToLogger (line 115) | public void addToLogger(String loggerName) {
    method addToLogger (line 123) | public void addToLogger(Class<?> loggerClass) {
    method addToRootLogger (line 131) | public void addToRootLogger() {
    method removeFromLogger (line 139) | public void removeFromLogger(String loggerName) {
    method removeFromLogger (line 147) | public void removeFromLogger(Class<?> loggerClass) {
    method removeFromRootLogger (line 155) | public void removeFromRootLogger() {

FILE: vjkit/src/test/java/com/vip/vjtools/test/log/LogbackListAppenderTest.java
  class LogbackListAppenderTest (line 9) | public class LogbackListAppenderTest {
    method normal (line 11) | @Test
    method addAndRemoveAppender (line 46) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/test/rule/TestProgress.java
  class TestProgress (line 11) | public class TestProgress extends TestWatcher {
    method starting (line 13) | @Override
    method finished (line 19) | @Override

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/base/BooleanUtilTest.java
  class BooleanUtilTest (line 7) | public class BooleanUtilTest {
    method test (line 9) | @Test
    method logic (line 25) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/base/EnumUtilTest.java
  class EnumUtilTest (line 9) | public class EnumUtilTest {
    type Options (line 11) | public enum Options {
    method testBits (line 15) | @Test
    method testString (line 30) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/base/ExceptionUtilTest.java
  class ExceptionUtilTest (line 15) | public class ExceptionUtilTest {
    method unchecked (line 26) | @Test
    method unwrap (line 57) | @Test
    method getStackTraceAsString (line 77) | @Test
    method cause (line 86) | @Test
    method getRootCause (line 103) | @Test
    method buildMessage (line 114) | @Test
    method clearStackTrace (line 129) | @Test
    method staticException (line 138) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/base/MoreValidateTest.java
  class MoreValidateTest (line 8) | public class MoreValidateTest {
    method test (line 10) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/base/ObjectUtilTest.java
  class ObjectUtilTest (line 9) | public class ObjectUtilTest {
    method hashCodeTest (line 11) | @Test
    method toPrettyString (line 16) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/base/PairTest.java
  class PairTest (line 10) | public class PairTest {
    method pairTest (line 12) | @Test
    method tripleTest (line 27) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/base/PlatformsTest.java
  class PlatformsTest (line 7) | public class PlatformsTest {
    method PlatformTest (line 9) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/base/PropertiesUtilTest.java
  class PropertiesUtilTest (line 9) | public class PropertiesUtilTest {
    method loadProperties (line 11) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/base/RuntimeUtilTest.java
  class RuntimeUtilTest (line 7) | public class RuntimeUtilTest {
    method testRuntime (line 8) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/base/SystemPropertiesUtilTest.java
  class SystemPropertiesUtilTest (line 11) | public class SystemPropertiesUtilTest {
    method systemProperty (line 13) | @Test
    method stringSystemProperty (line 87) | @Test
    method intSystemProperty (line 116) | @Test
    method longSystemProperty (line 135) | @Test
    method doubleSystemProperty (line 154) | @Test
    method booleanSystemProperty (line 173) | @Test
    method listenableProperties (line 192) | @Test
    class TestPropertiesListener (line 204) | public static class TestPropertiesListener extends PropertiesListener {
      method TestPropertiesListener (line 206) | public TestPropertiesListener(String propertyName) {
      method onChange (line 212) | @Override

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/base/ValueValidatorTest.java
  class ValueValidatorTest (line 9) | public class ValueValidatorTest {
    method testValidator (line 10) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/collection/ArrayUtilTest.java
  class ArrayUtilTest (line 14) | public class ArrayUtilTest {
    method shuffle (line 16) | @Test
    method asList (line 30) | @Test
    method contact (line 53) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/collection/CollectionUtilTest.java
  class CollectionUtilTest (line 12) | public class CollectionUtilTest {
    method test (line 14) | @Test
    method minAndMax (line 55) | @Test
    method listCompare (line 71) | @Test
    method topNAndBottomN (line 88) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/collection/ListUtilTest.java
  class ListUtilTest (line 12) | public class ListUtilTest {
    method guavaBuildList (line 13) | @Test
    method jdkBuild (line 33) | @Test
    method general (line 74) | @Test
    method sortAndSearch (line 99) | @Test
    method collectionCalc (line 134) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/collection/MapUtilTest.java
  class MapUtilTest (line 20) | public class MapUtilTest {
    method buildMap (line 22) | @Test
    method generalMethod (line 33) | @Test
    method guavaBuildMap (line 70) | @Test
    method jdkBuildMap (line 95) | @Test
    method weakMap (line 126) | @Test
    method initExpireAllMap (line 166) | private void initExpireAllMap(ConcurrentMap<MyBean, MyBean> weakKeyMap) {
    method initExpireKeyMap (line 174) | private void initExpireKeyMap(ConcurrentMap<MyBean, MyBean> weakKeyMap...
    method initExpireValueMap (line 181) | private void initExpireValueMap(ConcurrentMap<MyBean, MyBean> weakKeyM...
    method initWeakValue (line 188) | private void initWeakValue(ConcurrentMap<MyBean, MyBean> weakKeyMap) {
    class MyBean (line 195) | public static class MyBean {
      method MyBean (line 198) | public MyBean(String name) {
      method hashCode (line 202) | @Override
      method equals (line 210) | @Override
    type EnumA (line 224) | public enum EnumA {
    method sortAndTop (line 228) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/collection/QueueUtilTest.java
  class QueueUtilTest (line 18) | public class QueueUtilTest {
    method guavaBuildSet (line 20) | @Test
    method stack (line 36) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/collection/SetUtilTest.java
  class SetUtilTest (line 14) | public class SetUtilTest {
    method guavaBuildSet (line 16) | @Test
    method jdkBuildSet (line 36) | @Test
    method collectionCaculate (line 76) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/collection/type/ConcurrentHashSetTest.java
  class ConcurrentHashSetTest (line 9) | public class ConcurrentHashSetTest {
    method concurrentHashSet (line 11) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/collection/type/SortedArrayListTest.java
  class SortedArrayListTest (line 10) | public class SortedArrayListTest {
    method sortedArrayList (line 12) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/ConcurrentsTest.java
  class ConcurrentsTest (line 9) | public class ConcurrentsTest {
    method longAdder (line 11) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/ThreadDumpperTest.java
  class ThreadDumpperTest (line 14) | public class ThreadDumpperTest {
    class LongRunTask (line 16) | public static class LongRunTask implements Runnable {
      method LongRunTask (line 20) | public LongRunTask(CountDownLatch countDownLatch) {
      method run (line 24) | @Override
    method test (line 31) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/ThreadUtilTest.java
  class ThreadUtilTest (line 10) | public class ThreadUtilTest {
    method testCaller (line 11) | @Test
    method hello (line 21) | private void hello() {
    class MyClass (line 30) | public static class MyClass {
      method hello (line 31) | public void hello() {

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/limiter/RateLimiterUtilTest.java
  class RateLimiterUtilTest (line 11) | public class RateLimiterUtilTest {
    method testCreate (line 12) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/limiter/SamplerTest.java
  class SamplerTest (line 11) | public class SamplerTest {
    method test (line 13) | @Test
    method always (line 39) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/limiter/TimeIntervalLimiterTest.java
  class TimeIntervalLimiterTest (line 12) | public class TimeIntervalLimiterTest {
    method testTryAcquire (line 14) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/threadpool/AbortPolicyWithReportTest.java
  class AbortPolicyWithReportTest (line 9) | public class AbortPolicyWithReportTest {
    method jStackDumpTest (line 11) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/threadpool/QueuableCachedThreadPoolTest.java
  class QueuableCachedThreadPoolTest (line 12) | public class QueuableCachedThreadPoolTest {
    class LongRunTask (line 14) | public static class LongRunTask implements Runnable {
      method run (line 15) | @Override
    method test (line 21) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/threadpool/ThreadPoolBuilderTest.java
  class ThreadPoolBuilderTest (line 16) | public class ThreadPoolBuilderTest {
    method fixPool (line 18) | @Test
    method cachedPool (line 67) | @Test
    method scheduledPool (line 95) | @Test
    method quequablePool (line 118) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/threadpool/ThreadPoolUtilTest.java
  class ThreadPoolUtilTest (line 20) | public class ThreadPoolUtilTest {
    method buildThreadFactory (line 21) | @Test
    method gracefulShutdown (line 44) | @Test
    method wrapException (line 94) | @Test
    class ExceptionTask (line 119) | static class ExceptionTask implements Runnable {
      method run (line 122) | @Override
    class Task (line 130) | static class Task implements Runnable {
      method Task (line 137) | Task(Logger logger, int sleepTime, int runTime) {
      method run (line 143) | @Override

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/type/BasicFutureTest.java
  class BasicFutureTest (line 15) | public class BasicFutureTest {
    class MyFuture (line 17) | public static class MyFuture<T> extends BasicFuture<T> {
      method onCompleted (line 19) | @Override
      method onFailed (line 24) | @Override
      method onCancelled (line 29) | @Override
    class Tasks (line 35) | private static class Tasks {
      method success (line 37) | public static void success(MyFuture<String> future) {
      method fail (line 41) | public static void fail(MyFuture<String> future) {
      method cancel (line 45) | public static void cancel(MyFuture<String> future) {
    method test (line 50) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/type/ThreadLocalContextTest.java
  class ThreadLocalContextTest (line 13) | public class ThreadLocalContextTest {
    method test (line 15) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/datamasking/DataMaskJsonFilterTest.java
  class DataMaskJsonFilterTest (line 18) | public class DataMaskJsonFilterTest {
    method testProcess (line 20) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/datamasking/DataMaskTest.java
  class DataMaskTest (line 25) | public class DataMaskTest {
    method testMaskByType (line 27) | @Test
    method testMask (line 43) | @Test
    method testSha1Mask (line 48) | @Test
    method testToJson (line 59) | @Test
    method testToString (line 79) | @Test
    method testMapping (line 99) | @Test
    method testInherit (line 116) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/datamasking/MaskMappingTest.java
  class MaskMappingTest (line 11) | public class MaskMappingTest {
    method test (line 13) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/datamasking/data/TestChild.java
  class TestChild (line 14) | public class TestChild {
    method getStr (line 25) | public String getStr() {
    method setStr (line 29) | public void setStr(String str) {
    method getArr (line 33) | public String[] getArr() {
    method setArr (line 37) | public void setArr(String[] arr) {
    method getList (line 41) | public List<String> getList() {
    method setList (line 45) | public void setList(List<String> list) {
    method getSet (line 49) | public Set<String> getSet() {
    method setSet (line 53) | public void setSet(Set<String> set) {
    method toString (line 57) | @Override

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/datamasking/data/TestData.java
  class TestData (line 10) | public class TestData {
    method getName (line 27) | public String getName() {
    method setName (line 31) | public void setName(String name) {
    method getPhone (line 35) | public String getPhone() {
    method setPhone (line 39) | public void setPhone(String phone) {
    method getAccount (line 43) | public String getAccount() {
    method setAccount (line 47) | public void setAccount(String account) {
    method getHash (line 51) | public String getHash() {
    method setHash (line 55) | public void setHash(String hash) {
    method getTest (line 59) | public String getTest() {
    method setTest (line 63) | public void setTest(String test) {
    method toString (line 67) | @Override

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/datamasking/data/TestParent.java
  class TestParent (line 9) | public class TestParent {
    method getChild (line 17) | public TestChild getChild() {
    method setChild (line 21) | public void setChild(TestChild child) {
    method getChildren (line 25) | public List<TestChild> getChildren() {
    method setChildren (line 29) | public void setChildren(List<TestChild> children) {
    method getOther (line 33) | public TestParent getOther() {
    method setOther (line 37) | public void setOther(TestParent other) {
    method toString (line 41) | @Override

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/datamasking/data/TestUserMapingData.java
  class TestUserMapingData (line 13) | public class TestUserMapingData {
    method getTel (line 33) | public String getTel() {
    method setTel (line 37) | public void setTel(String tel) {
    method getNickName (line 41) | public String getNickName() {
    method setNickName (line 45) | public void setNickName(String nickName) {
    method getTest (line 50) | public String getTest() {
    method setTest (line 54) | public void setTest(String test) {
    method getStrArr (line 59) | public String[] getStrArr() {
    method setStrArr (line 63) | public void setStrArr(String[] strArr) {
    method getStrList (line 67) | public List<String> getStrList() {
    method setStrList (line 71) | public void setStrList(List<String> strList) {
    method getSet (line 76) | public Set<String> getSet() {
    method setSet (line 80) | public void setSet(Set<String> set) {
    method getSetInt (line 84) | public Set<Integer> getSetInt() {
    method setSetInt (line 88) | public void setSetInt(Set<Integer> setInt) {
    method toString (line 92) | @Override

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/datamasking/strategy/EmailMaskTest.java
  class EmailMaskTest (line 11) | public class EmailMaskTest {
    method testMask (line 13) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/datamasking/strategy/HashMaskTest.java
  class HashMaskTest (line 13) | public class HashMaskTest {
    method testMask (line 15) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/datamasking/strategy/NameMaskTest.java
  class NameMaskTest (line 11) | public class NameMaskTest {
    method testMask (line 13) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/datamasking/strategy/PartMaskTest.java
  class PartMaskTest (line 11) | public class PartMaskTest {
    method testMask (line 13) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/id/IdUtilTest.java
  class IdUtilTest (line 7) | public class IdUtilTest {
    method normal (line 9) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/io/FilePathUtilTest.java
  class FilePathUtilTest (line 10) | public class FilePathUtilTest {
    method pathName (line 14) | @Test
    method getJarPath (line 33) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/io/FileTreeWalkerTest.java
  class FileTreeWalkerTest (line 13) | public class FileTreeWalkerTest {
    method listFile (line 15) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/io/FileUtilTest.java
  class FileUtilTest (line 21) | public class FileUtilTest {
    method readWrite (line 23) | @Test
    method opFiles (line 42) | @Test
    method opDir (line 66) | @Test
    method fileExist (line 89) | @Test
    method getName (line 106) | @Test
    method testAsInputStream (line 118) | @Test
    method testAsOututStream (line 135) | @Test
    method testAsBufferedReader (line 152) | @Test
    method testAsBufferedWriter (line 166) | @Test
    method testCopy (line 178) | @Test
    method testMakesureDirExists (line 202) | @Test
    method testIsFileExists (line 222) | @Test
    method testGetFileExtension (line 236) | @Test
    method testIsDirExists (line 244) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/io/IOUtilTest.java
  class IOUtilTest (line 14) | public class IOUtilTest {
    method read (line 16) | @Test
    method write (line 22) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/io/ResourceUtilTest.java
  class ResourceUtilTest (line 12) | public class ResourceUtilTest {
    method test (line 14) | @Test
    method resourceNameTest (line 36) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/io/URLResourceTest.java
  class URLResourceTest (line 11) | public class URLResourceTest {
    method resource (line 13) | @Test
    method file (line 38) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/logging/PerformanceUtilsTest.java
  class PerformanceUtilsTest (line 8) | public class PerformanceUtilsTest {
    method test (line 12) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/mapper/BeanMapperTest.java
  class BeanMapperTest (line 12) | public class BeanMapperTest {
    method copySingleObject (line 14) | @Test
    method copyListObject (line 27) | @Test
    method copyArrayObject (line 45) | @Test
    method copy2Map (line 62) | @Test
    class Student (line 74) | public static class Student {
      method Student (line 80) | public Student() {
      method Student (line 84) | public Student(String name, int age, Teacher teacher, List<String> c...
      method getCourse (line 91) | public List<String> getCourse() {
      method setCourse (line 95) | public void setCourse(List<String> course) {
      method getAge (line 99) | public int getAge() {
      method setAge (line 103) | public void setAge(int age) {
      method getTeacher (line 107) | public Teacher getTeacher() {
      method setTeacher (line 111) | public void setTeacher(Teacher teacher) {
      method getName (line 115) | public String getName() {
      method setName (line 119) | public void setName(String name) {
    class Teacher (line 126) | public static class Teacher {
      method Teacher (line 129) | public Teacher() {
      method Teacher (line 133) | public Teacher(String name) {
      method getName (line 138) | public String getName() {
      method setName (line 142) | public void setName(String name) {
    class StudentVO (line 148) | public static class StudentVO {
      method StudentVO (line 154) | public StudentVO() {
      method StudentVO (line 158) | public StudentVO(String name, int age, TeacherVO teacher, List<Strin...
      method getCourse (line 165) | public List<String> getCourse() {
      method setCourse (line 169) | public void setCourse(List<String> course) {
      method getAge (line 173) | public int getAge() {
      method setAge (line 177) | public void setAge(int age) {
      method getTeacher (line 181) | public TeacherVO getTeacher() {
      method setTeacher (line 185) | public void setTeacher(TeacherVO teacher) {
      method getName (line 189) | public String getName() {
      method setName (line 193) | public void setName(String name) {
    class TeacherVO (line 198) | public static class TeacherVO {
      method TeacherVO (line 201) | public TeacherVO() {
      method TeacherVO (line 205) | public TeacherVO(String name) {
      method getName (line 210) | public String getName() {
      method setName (line 214) | public void setName(String name) {

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/mapper/JsonMapperTest.java
  class JsonMapperTest (line 21) | public class JsonMapperTest {
    method assertJSONEqual (line 23) | public void assertJSONEqual(String s1, String s2) throws JSONException {
    method toJson (line 29) | @Test
    method fromJson (line 70) | @Test
    method nullAndEmpty (line 106) | @Test
    method threeTypeMappers (line 152) | @Test
    method jsonp (line 171) | @Test
    method update (line 182) | @Test
    class TestBean (line 191) | public static class TestBean {
      method TestBean (line 198) | public TestBean() {
      method TestBean (line 201) | public TestBean(String name) {
      method getName (line 205) | public String getName() {
      method setName (line 209) | public void setName(String name) {
      method getDefaultValue (line 213) | public String getDefaultValue() {
      method setDefaultValue (line 217) | public void setDefaultValue(String defaultValue) {
      method getNullValue (line 221) | public String getNullValue() {
      method setNullValue (line 225) | public void setNullValue(String nullValue) {
      method getEmptyValue (line 229) | public List<String> getEmptyValue() {
      method setEmptyValue (line 233) | public void setEmptyValue(List<String> emptyValue) {
      method toString (line 237) | @Override

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/mapper/XmlMapperTest.java
  class XmlMapperTest (line 39) | public class XmlMapperTest {
    method objectToXml (line 41) | @Test
    method xmlToObject (line 55) | @Test
    method toXmlWithListAsRoot (line 69) | @Test
    method generateXmlByDom4j (line 88) | private static String generateXmlByDom4j() {
    method assertXmlByDom4j (line 106) | private static void assertXmlByDom4j(String xml) {
    class User (line 121) | @XmlRootElement
      method getId (line 133) | @XmlAttribute
      method setId (line 138) | public void setId(Long id) {
      method getName (line 142) | public String getName() {
      method setName (line 146) | public void setName(String name) {
      method getPassword (line 151) | @XmlTransient
      method setPassword (line 156) | public void setPassword(String password) {
      method getInterests (line 161) | @XmlElementWrapper(name = "interests")
      method setInterests (line 167) | public void setInterests(List<String> interests) {
      method toString (line 171) | @Override

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/net/IPUtilTest.java
  class IPUtilTest (line 7) | public class IPUtilTest {
    method stringAndInt (line 9) | @Test
    method inetAddress (line 19) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/net/NetUtilTest.java
  class NetUtilTest (line 15) | public class NetUtilTest {
    method localhost (line 17) | @Test
    method portDetect (line 23) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/number/MathUtilTest.java
  class MathUtilTest (line 9) | public class MathUtilTest {
    method power2 (line 11) | @Test
    method caculate (line 47) | @Test
    method divide (line 72) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/number/MoneyUtilTest.java
  class MoneyUtilTest (line 10) | public class MoneyUtilTest {
    method amountConvertTest (line 12) | @Test
    method format (line 26) | @Test
    method parse (line 33) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/number/NumberUtilTest.java
  class NumberUtilTest (line 7) | public class NumberUtilTest {
    method equalsWithin (line 9) | @Test
    method toBytes (line 19) | @Test
    method isNumber (line 51) | @Test
    method toNumber (line 62) | @Test
    method toStringTest (line 181) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/number/RandomUtilTest.java
  class RandomUtilTest (line 7) | public class RandomUtilTest {
    method getRandom (line 9) | @Test
    method randomNumber (line 15) | @Test
    method generateString (line 65) | @Test
    method test0 (line 95) | public void test0() {

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/number/UnitConverterTest.java
  class UnitConverterTest (line 7) | public class UnitConverterTest {
    method convertDurationMillis (line 9) | @Test
    method convertSizeBytes (line 34) | @Test
    method convertToSizeUnit (line 59) | @Test
    method convertToTimeUnit (line 82) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/reflect/ClassUtilTest.java
  class ClassUtilTest (line 11) | public class ClassUtilTest {
    method getMessage (line 13) | @Test
    method getAllClass (line 28) | @Test
    method getSuperClassGenericType (line 54) | @Test
    method classPresent (line 67) | public void classPresent() {
    method testIsSubClassOrInterfaceOf (line 76) | @Test
    class ParentBean (line 88) | public static class ParentBean<T, ID> {
    class TestBean (line 91) | public static class TestBean extends ParentBean<String, Long> {
    class TestBean2 (line 95) | public static class TestBean2 extends ParentBean {
    class TestBean3 (line 98) | public static class TestBean3 {
    type AInterface (line 102) | public interface AInterface {
    type BInterface (line 105) | @CAnnotation
      method hello (line 107) | @FAnnotation
    type CInterface (line 111) | public interface CInterface {
    type DInterface (line 114) | public interface DInterface {
    class AClass (line 142) | @DAnnotation
      method hello2 (line 160) | public void hello2(int i) {
      method hello4 (line 165) | @FAnnotation
      method hello5 (line 171) | @FAnnotation
      method hello6 (line 177) | @FAnnotation
      method hello7 (line 183) | @FAnnotation
    class BClass (line 190) | @BAnnotation
      method hello (line 206) | @Override
      method hello2 (line 213) | public void hello2(int i) {
      method hello3 (line 218) | @FAnnotation
      method hello7 (line 224) | @Override

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/reflect/ClassloaderUtilTest.java
  class ClassloaderUtilTest (line 5) | public class ClassloaderUtilTest {
    method test (line 7) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/reflect/ReflectionUtilTest.java
  class ReflectionUtilTest (line 13) | public class ReflectionUtilTest {
    method getAndSetFieldValue (line 15) | @Test
    method invokeGetterAndSetter (line 57) | @Test
    method invokeMethod (line 68) | @Test
    method invokeConstructor (line 126) | @Test
    method convertReflectionExceptionToUnchecked (line 135) | @Test
    class ParentBean (line 157) | public static class ParentBean<T, ID> {
    class TestBean (line 160) | public static class TestBean extends ParentBean<String, Long> {
      method getPublicField (line 167) | public int getPublicField() {
      method setPublicField (line 172) | public void setPublicField(int publicField) {
      method inspectPrivateField (line 176) | public int inspectPrivateField() {
      method inspectPublicField (line 180) | public int inspectPublicField() {
      method privateMethod (line 184) | private String privateMethod(String text) {
      method integerType (line 189) | public Integer integerType(Integer i) {
      method intType (line 194) | public int intType(int i) {
      method listType (line 199) | public int listType(List<?> list) {
    class TestBean2 (line 204) | public static class TestBean2 extends ParentBean {
    class TestBean3 (line 207) | public static class TestBean3 {
      method TestBean3 (line 209) | public TestBean3() {
      method TestBean3 (line 213) | public TestBean3(int id) {
      method getId (line 220) | public int getId() {
      method setId (line 224) | public void setId(int id) {

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/security/CryptoUtilTest.java
  class CryptoUtilTest (line 10) | public class CryptoUtilTest {
    method mac (line 11) | @Test
    method aes (line 27) | @Test
    method aesWithIV (line 41) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/text/CsvUtilTest.java
  class CsvUtilTest (line 7) | public class CsvUtilTest {
    method toCsvString (line 9) | @Test
    method fromCsvString (line 31) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/text/EncodeUtilTest.java
  class EncodeUtilTest (line 7) | public class EncodeUtilTest {
    method hexEncode (line 9) | @Test
    method base64Encode (line 32) | @Test
    method base64UrlSafeEncode (line 47) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/text/EscapeUtilTest.java
  class EscapeUtilTest (line 7) | public class EscapeUtilTest {
    method urlEncode (line 9) | @Test
    method xmlEncode (line 24) | @Test
    method html (line 32) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/text/HashUtilTest.java
  class HashUtilTest (line 12) | public class HashUtilTest {
    method hashSha1 (line 15) | @Test
    method hashFile (line 47) | @Test
    method crc32 (line 56) | @Test
    method murmurhash (line 67) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/text/MoreStringUtilTest.java
  class MoreStringUtilTest (line 11) | public class MoreStringUtilTest {
    method split (line 12) | @Test
    method charMatch (line 37) | @Test
    method utf8EncodedLength (line 62) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/text/StringBuilderHolderTest.java
  class StringBuilderHolderTest (line 8) | public class StringBuilderHolderTest {
    method test (line 10) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/text/TextValidatorTest.java
  class TextValidatorTest (line 7) | public class TextValidatorTest {
    method isMobileSimple (line 9) | @Test
    method isMobileExact (line 18) | @Test
    method isTel (line 25) | @Test
    method isIdCard (line 38) | @Test
    method isEmail (line 53) | @Test
    method isUrl (line 62) | @Test
    method isDate (line 71) | @Test
    method isIp (line 81) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/text/WildcardMatcherTest.java
  class WildcardMatcherTest (line 7) | public class WildcardMatcherTest {
    method matchString (line 9) | @Test
    method matchPath (line 37) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/time/CachingDatFormatterTest.java
  class CachingDatFormatterTest (line 9) | public class CachingDatFormatterTest {
    method test (line 11) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/time/ClockUtilTest.java
  class ClockUtilTest (line 11) | public class ClockUtilTest {
    method testDummyClock (line 13) | @Test
    method elapsedTime (line 32) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/time/DateFormatUtilTest.java
  class DateFormatUtilTest (line 10) | public class DateFormatUtilTest {
    method isoDateFormat (line 12) | @Test
    method defaultDateFormat (line 20) | @Test
    method formatWithPattern (line 27) | @Test
    method parseWithPattern (line 36) | @Test
    method formatDuration (line 43) | @Test
    method formatFriendlyTimeSpanByNow (line 60) | @Test

FILE: vjkit/src/test/java/com/vip/vjtools/vjkit/time/DateUtilTest.java
  class DateUtilTest (line 9) | public class DateUtilTest {
    method isSameDay (line 11) | @Test
    method truncateAndCelling (line 44) | @Test
    method changeDay (line 98) | @Test
    method setDay (line 136) | @Test
    method getDayOfWeek (line 156) | @Test
    method isLeapYear (line 166) | @Test
    method getXXofXX (line 181) | @Test

FILE: vjmap/src/main/java/com/vip/vjtools/vjmap/ClassStats.java
  class ClassStats (line 13) | public class ClassStats {
    method ClassStats (line 27) | public ClassStats(Klass k) {
    method getDescription (line 32) | public String getDescription() {
    method initDescription (line 41) | public String initDescription() {
    method getInternalName (line 74) | private String getInternalName(Klass k) {
    method getKlass (line 81) | public Klass getKlass() {
    method getCount (line 85) | public long getCount() {
    method getSize (line 89) | public long getSize() {
    method getOldCount (line 93) | public long getOldCount() {
    method getOldSize (line 97) | public long getOldSize() {
    method getSurvivorCount (line 101) | public long getSurvivorCount() {
    method getSurvivorSize (line 105) | public long getSurvivorSize() {
    method getEdenCount (line 109) | public long getEdenCount() {
    method getEdenSize (line 113) | public long getEdenSize() {
    method compare (line 118) | @Override
    method compare (line 125) | @Override
    method compare (line 132) | @Override
    method compare (line 139) | @Override

FILE: vjmap/src/main/java/com/vip/vjtools/vjmap/ResultPrinter.java
  class ResultPrinter (line 10) | public class ResultPrinter {
    method printAllGens (line 15) | public void printAllGens(PrintStream tty, List<ClassStats> list, boole...
    method printSurvivor (line 54) | public void printSurvivor(PrintStream tty, List<ClassStats> list, bool...
    method printOldGen (line 93) | public void printOldGen(PrintStream tty, List<ClassStats> list, boolea...

FILE: vjmap/src/main/java/com/vip/vjtools/vjmap/VJMap.java
  class VJMap (line 22) | public class VJMap {
    method runHeapVisitor (line 31) | public static void runHeapVisitor(int pid, boolean orderByName, long m...
    class HeapProcessor (line 44) | public static class HeapProcessor {
      method HeapProcessor (line 49) | public HeapProcessor(boolean orderByName, long minSize) {
      method printResult (line 54) | public void printResult() {
    method runSurviorAccessor (line 61) | public static void runSurviorAccessor(int age, int minAge, boolean ord...
    method runOldGenAccessor (line 71) | public static void runOldGenAccessor(boolean orderByName, long minSize) {
    class OldGenProcessor (line 79) | public static class OldGenProcessor {
      method OldGenProcessor (line 84) | public OldGenProcessor(boolean orderByName, long minSize) {
      method printResult (line 89) | public void printResult() {
    method printGenAddress (line 96) | public static void printGenAddress() {
    method printLoadedClass (line 101) | public static void printLoadedClass() {
    method main (line 106) | public static void main(String[] args) {
    method triggerGc (line 243) | private static void triggerGc(Integer pid) {
    method printHelp (line 273) | private static void printHelp() {

FILE: vjmap/src/main/java/com/vip/vjtools/vjmap/oops/GenAddressAccessor.java
  class GenAddressAccessor (line 14) | public class GenAddressAccessor {
    method printHeapAddress (line 18) | public void printHeapAddress() {

FILE: vjmap/src/main/java/com/vip/vjtools/vjmap/oops/HeapHistogramVisitor.java
  class HeapHistogramVisitor (line 24) | public class HeapHistogramVisitor implements HeapVisitor {
    method HeapHistogramVisitor (line 42) | public HeapHistogramVisitor() {
    method doObj (line 63) | @Override
    method prologue (line 83) | @Override
    method epilogue (line 89) | @Override
    method updateWith (line 93) | private void updateWith(ClassStats classStats, long objSize, Place pla...
    method getCmsLocation (line 115) | private Place getCmsLocation(Oop obj) {
    method getParLocation (line 131) | public Place getParLocation(Oop obj) {
    method getClassStatsMap (line 147) | public HashMap<Klass, ClassStats> getClassStatsMap() {
    type Place (line 151) | public enum Place {

FILE: vjmap/src/main/java/com/vip/vjtools/vjmap/oops/HeapUtils.java
  class HeapUtils (line 20) | public class HeapUtils {
    method getHeap (line 22) | public static CollectedHeap getHeap() {
    method getObjectHeap (line 26) | public static ObjectHeap getObjectHeap() {
    method isCMSGC (line 30) | public static boolean isCMSGC(CollectedHeap heap) {
    method isParallelGC (line 34) | public static boolean isParallelGC(CollectedHeap heap) {
    method getYoungGenForCMS (line 38) | public static DefNewGeneration getYoungGenForCMS(CollectedHeap heap) {
    method getOldGenForCMS (line 42) | public static ConcurrentMarkSweepGeneration getOldGenForCMS(CollectedH...
    method getYongGenForPar (line 46) | public static PSYoungGen getYongGenForPar(CollectedHeap heap) {
    method getOldGenForPar (line 50) | public static PSOldGen getOldGenForPar(CollectedHeap heap) {
    method getClassStatsList (line 54) | public static List<ClassStats> getClassStatsList(HashMap<Klass, ClassS...
    method getClassStats (line 60) | public static ClassStats getClassStats(Klass klass, HashMap<Klass, Cla...

FILE: vjmap/src/main/java/com/vip/vjtools/vjmap/oops/LoadedClassAccessor.java
  class LoadedClassAccessor (line 15) | public class LoadedClassAccessor {
    method pringLoadedClass (line 19) | public void pringLoadedClass() {
    method getClassLoaderOopFrom (line 53) | private static String getClassLoaderOopFrom(InstanceKlass klass) {
    method getClassNameFrom (line 59) | private static String getClassNameFrom(InstanceKlass klass) {

FILE: vjmap/src/main/java/com/vip/vjtools/vjmap/oops/OldgenAccessor.java
  class OldgenAccessor (line 30) | public class OldgenAccessor {
    method getClassStatsMap (line 38) | public HashMap<Klass, ClassStats> getClassStatsMap() {
    method caculateHistogram (line 42) | public void caculateHistogram() {
    method checkHeapType (line 97) | private CollectedHeap checkHeapType() {
    method printGenSummary (line 106) | private void printGenSummary(ConcurrentMarkSweepGeneration cmsGen) {
    method skipFreeChunk (line 111) | private void skipFreeChunk(final long addressSize) {
    method continueNextAddress (line 121) | private void continueNextAddress(CMSCollector cmsCollector) {

FILE: vjmap/src/main/java/com/vip/vjtools/vjmap/oops/SurvivorAccessor.java
  class SurvivorAccessor (line 27) | public class SurvivorAccessor {
    method caculateHistogram (line 31) | public List<ClassStats> caculateHistogram(int excactAge, int minAge) {

FILE: vjmap/src/main/java/com/vip/vjtools/vjmap/utils/FormatUtils.java
  class FormatUtils (line 3) | public class FormatUtils {
    method toFloatUnit (line 13) | public static String toFloatUnit(long size) {

FILE: vjmap/src/main/java/com/vip/vjtools/vjmap/utils/ProgressNotifier.java
  class ProgressNotifier (line 5) | public class ProgressNotifier {
    method ProgressNotifier (line 17) | public ProgressNotifier(long totalSize) {
    method printHead (line 25) | public void printHead() {
    method printProgress (line 30) | public void printProgress() {

FILE: vjmap/src/main/java/com/vip/vjtools/vjmap/utils/TimeController.java
  class TimeController (line 6) | public class TimeController {
    method checkTimedOut (line 13) | public void checkTimedOut() {
    class TimeoutException (line 19) | public static class TimeoutException extends RuntimeException {

FILE: vjmxcli/src/main/java/com/vip/vjtools/jmx/Client.java
  class Client (line 76) | public class Client {
    method main (line 95) | public static void main(String[] args) {
    method usage (line 113) | protected static void usage() {
    method usage (line 117) | protected static void usage(int exitCode, String message) {
    method Client (line 128) | public Client() {
    method parseUserpass (line 137) | protected String[] parseUserpass(final String userpass) {
    method formatCredentials (line 153) | protected static Map formatCredentials(final String login, final Strin...
    method connect (line 164) | public static JMXConnector connect(final String hostportOrPid, final S...
    method getLocalConnectorAddress (line 184) | public static String getLocalConnectorAddress(String pid) throws IOExc...
    method execute (line 265) | protected void execute(final String[] args) throws Exception {
    method execute (line 317) | protected Object[] execute(final String hostport, final String login, ...
    method executeOneCmd (line 322) | public Object[] executeOneCmd(final String hostport, final String logi...
    method execute (line 341) | protected Object[] execute(final String hostportOrPid, final String lo...
    method getObjectName (line 355) | public static ObjectName getObjectName(final String beanname)
    method notEmpty (line 360) | public static boolean notEmpty(String s) {
    method doBeans (line 364) | protected static Object[] doBeans(final MBeanServerConnection mbsc, fi...
    method doBean (line 413) | protected static Object[] doBean(MBeanServerConnection mbsc, ObjectIns...
    method doSubCommand (line 428) | public static Object doSubCommand(MBeanServerConnection mbsc, ObjectIn...
    method isFeatureInfo (line 504) | protected static boolean isFeatureInfo(MBeanFeatureInfo[] infos, Strin...
    method getFeatureInfo (line 508) | protected static MBeanFeatureInfo getFeatureInfo(MBeanFeatureInfo[] in...
    method recurseTabularData (line 520) | protected static StringBuffer recurseTabularData(StringBuffer buffer, ...
    method recurseCompositeData (line 537) | protected static StringBuffer recurseCompositeData(StringBuffer buffer...
    method addNameToBuffer (line 558) | protected static String addNameToBuffer(StringBuffer buffer, String in...
    class CommandParse (line 573) | protected static class CommandParse {
      method CommandParse (line 577) | protected CommandParse(String command) throws ParseException {
      method parse (line 581) | private void parse(String command) throws ParseException {
      method getCmd (line 595) | protected String getCmd() {
      method getArgs (line 599) | protected String[] getArgs() {
    method doAttributeOperation (line 604) | protected static Object doAttributeOperation(MBeanServerConnection mbs...
    method doBeanOperation (line 633) | protected static Object doBeanOperation(MBeanServerConnection mbsc, Ob...
    method listOptions (line 667) | protected static String listOptions(MBeanServerConnection mbsc, Object...
    class OneLineSimpleLogger (line 714) | private class OneLineSimpleLogger extends SimpleFormatter {
      method OneLineSimpleLogger (line 739) | public OneLineSimpleLogger() {
      method format (line 743) | @Override
    method getJavaMajorVersion (line 773) | private static int getJavaMajorVersion(String javaSpecificationVersion) {

FILE: vjmxcli/src/main/java/com/vip/vjtools/jmx/ExtraCommand.java
  class ExtraCommand (line 6) | public class ExtraCommand {
    method execute (line 8) | public void execute(final String hostportOrPid, final String login, fi...
    method gcUtilCommand (line 21) | private void gcUtilCommand(MBeanServerConnection mbsc, int interval) t...
    method executGCutil (line 50) | private Object[] executGCutil(final String[] commands, GCutilExpressio...
    method getJavaVersion (line 84) | public static int getJavaVersion(final MBeanServerConnection mbsc) thr...

FILE: vjmxcli/src/main/java/com/vip/vjtools/jmx/GCutilExpression.java
  class GCutilExpression (line 11) | public class GCutilExpression {
    method GCutilExpression (line 33) | public GCutilExpression(MBeanServerConnection mbsc) throws Exception {
    method mappingCollctors (line 39) | private void mappingCollctors() throws Exception {
    method mappingPools (line 57) | private void mappingPools() throws Exception {
    method getE (line 77) | public String getE() throws Exception {
    method getS (line 81) | public String getS() throws Exception {
    method getO (line 85) | public String getO() throws Exception {
    method getP (line 89) | public String getP() throws Exception {
    method getCCS (line 93) | public String getCCS() throws Exception {
    method getYGC (line 97) | public Object getYGC() throws Exception {
    method getYGCT (line 101) | public Double getYGCT() throws Exception {
    method getFGC (line 105) | public Object getFGC() throws Exception {
    method getFGCT (line 112) | public Double getFGCT() throws Exception {
    method getGCT (line 119) | public Object getGCT() throws Exception {
    method getAttribute (line 123) | private <T> T getAttribute(ObjectName beanName, String attributeName) ...
    method usedPercentage (line 131) | private String usedPercentage(ObjectName poolObjectName) throws Except...

FILE: vjstar/src/main/java/com/vip/vjstar/gc/CleanUpScheduler.java
  class CleanUpScheduler (line 21) | public class CleanUpScheduler {
    method schedule (line 28) | public void schedule(String schedulePlans, Runnable task) {
    method reschedule (line 35) | public void reschedule(Runnable task) {
    method shutdown (line 45) | public void shutdown(){
    method getDelayMillsList (line 53) | public static List<Long> getDelayMillsList(String schedulePlans) {
    method getDelayMillis (line 67) | public static long getDelayMillis(String time) {
    method getCurrentDateByPlan (line 99) | public static Date getCurrentDateByPlan(String plan, String pattern) {

FILE: vjstar/src/main/java/com/vip/vjstar/gc/ProactiveGcTask.java
  class ProactiveGcTask (line 19) | public class ProactiveGcTask implements Runnable {
    method ProactiveGcTask (line 29) | public ProactiveGcTask(CleanUpScheduler scheduler, int oldGenOccupancy...
    method run (line 42) | public void run() {
    method needTriggerGc (line 66) | private boolean needTriggerGc(long capacityBytes, long usedBytes, int ...
    method doGc (line 73) | protected void doGc() {
    method preGc (line 80) | protected void preGc() {
    method postGc (line 88) | protected void postGc() {
    method logOldGenStatus (line 92) | protected long logOldGenStatus(String hints) {
    method getOldGenMemoryPool (line 100) | private MemoryPoolMXBean getOldGenMemoryPool() {
    method getMemoryPoolMaxOrCommitted (line 117) | private long getMemoryPoolMaxOrCommitted(MemoryPoolMXBean memoryPool) {

FILE: vjstar/src/main/java/com/vip/vjstar/window/AtomicBitSet.java
  class AtomicBitSet (line 9) | public class AtomicBitSet {
    method AtomicBitSet (line 13) | public AtomicBitSet(int size) {
    method set (line 19) | public void set(long n, boolean flag) {
    method get (line 36) | public boolean get(long n) {
    method cardinality (line 43) | public int cardinality() {

FILE: vjstar/src/main/java/com/vip/vjstar/window/RequestSlidingWindow.java
  class RequestSlidingWindow (line 9) | public class RequestSlidingWindow {
    method RequestSlidingWindow (line 30) | public RequestSlidingWindow(int size) {
    method success (line 36) | public void success() {
    method fail (line 41) | public void fail() {
    method setNext (line 46) | private void setNext(boolean flag) {
    method processCapacity (line 51) | private void processCapacity() {
    method getSucessNum (line 58) | public long getSucessNum() {
    method getFailNum (line 62) | public long getFailNum() {

FILE: vjstar/src/main/java/com/vip/vjstar/window/TimeSlidingWindow.java
  class TimeSlidingWindow (line 11) | public class TimeSlidingWindow {
    method TimeSlidingWindow (line 16) | public TimeSlidingWindow(int size) {
    method add (line 24) | public void add() {
    method add (line 30) | void add(long time) {
    method clear (line 52) | private void clear(long time) {
    method count (line 67) | public long count() {
    method count (line 72) | long count(long time) {

FILE: vjstar/src/test/java/com/vip/vjstar/gc/Enchanter.java
  class Enchanter (line 10) | public class Enchanter {
    method makeGarbage (line 17) | public void makeGarbage(String val) {
    method clearGarbage (line 30) | public void clearGarbage() {

FILE: vjstar/src/test/java/com/vip/vjstar/gc/ProactiveGcTaskDemo.java
  class ProactiveGcTaskDemo (line 5) | public class ProactiveGcTaskDemo {
    method main (line 7) | public static void main(String[] args) throws IOException {

FILE: vjstar/src/test/java/com/vip/vjstar/window/RequestSlidingWindowTest.java
  class RequestSlidingWindowTest (line 15) | public class RequestSlidingWindowTest {
    method notOverWindowTest (line 17) | @Test
    method overWindowTest (line 29) | @Test
    method mutiThreadNotOverWindowTest (line 46) | @Test
    method mutiThreadOverWindowTest (line 81) | @Test

FILE: vjstar/src/test/java/com/vip/vjstar/window/TimeSlidingWindowTest.java
  class TimeSlidingWindowTest (line 15) | public class TimeSlidingWindowTest {
    method notOverWindowTest (line 17) | @Test
    method overWindowTest (line 26) | @Test
    method mutiThreadNotOverWindowTest (line 38) | @Test
    method mutiThreadOverWindowTest (line 80) | @Test

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/InteractiveTask.java
  class InteractiveTask (line 12) | public class InteractiveTask implements Runnable {
    method InteractiveTask (line 18) | public InteractiveTask(VJTop app) {
    method inputEnabled (line 24) | public boolean inputEnabled() {
    method run (line 28) | @Override
    method handleCommand (line 58) | public void handleCommand(String command) throws Exception {
    method printStacktrace (line 88) | private void printStacktrace(String command) throws IOException {
    method printTopThreadsStack (line 108) | private void printTopThreadsStack() throws IOException {
    method printAllThreadsName (line 118) | private void printAllThreadsName() throws IOException {
    method printBlockedThreadsStack (line 128) | private void printBlockedThreadsStack() throws IOException {
    method changeDisplayMode (line 138) | private void changeDisplayMode() {
    method changeInterval (line 165) | private void changeInterval(String command) {
    method changeThreadLimit (line 191) | private void changeThreadLimit(String command) {
    method changeThreadFilter (line 217) | private void changeThreadFilter() {
    method printHelp (line 233) | private void printHelp() throws Exception {
    method waitForEnter (line 251) | private void waitForEnter() {
    method readLine (line 255) | private String readLine(String hints) {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/ThreadPrinter.java
  class ThreadPrinter (line 11) | public class ThreadPrinter {
    method ThreadPrinter (line 15) | public ThreadPrinter(VMDetailView view) {
    method printStack (line 22) | public void printStack(long tid) throws IOException {
    method printTopStack (line 37) | public void printTopStack() throws IOException {
    method printSingleThread (line 50) | public StackTraceElement[] printSingleThread(ThreadInfo info) {
    method printAllThreads (line 94) | public void printAllThreads() throws IOException {
    method printBlockedThreads (line 127) | public void printBlockedThreads() throws IOException {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/TopThreadInfo.java
  class TopThreadInfo (line 11) | public class TopThreadInfo {
    method TopThreadInfo (line 19) | public TopThreadInfo(VMInfo vmInfo) throws Exception {
    method topCpuThreads (line 23) | public TopCpuResult topCpuThreads(ThreadInfoMode mode, int threadLimit...
    method topMemoryThreads (line 114) | public TopMemoryResult topMemoryThreads(ThreadInfoMode mode, int threa...
    method getTopThreadInfo (line 170) | public ThreadInfo[] getTopThreadInfo() throws IOException {
    method cleanupThreadsHistory (line 174) | public void cleanupThreadsHistory() {
    class TopCpuResult (line 180) | public static class TopCpuResult {
    class TopMemoryResult (line 197) | public static class TopMemoryResult {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/VJTop.java
  class VJTop (line 20) | public class VJTop {
    method main (line 33) | public static void main(String[] args) {
    method run (line 129) | private void run(VMDetailView view) throws Exception {
    method printHelper (line 166) | public static void printHelper(OptionParser parser) {
    method exit (line 177) | public void exit() {
    method interruptSleep (line 182) | public void interruptSleep() {
    method preventFlush (line 186) | public void preventFlush() {
    method continueFlush (line 190) | public void continueFlush() {
    method waitForInput (line 194) | private void waitForInput() {
    method nextFlushTime (line 200) | public int nextFlushTime() {
    method updateInterval (line 204) | public void updateInterval(int interval) {
    method getInterval (line 209) | public int getInterval() {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/VMDetailView.java
  class VMDetailView (line 14) | @SuppressWarnings("restriction")
    method VMDetailView (line 42) | public VMDetailView(VMInfo vmInfo, OutputFormat format, ContentMode co...
    method printView (line 61) | public void printView() throws Exception {
    method checkState (line 120) | private boolean checkState() {
    method printJvmInfoAsConsole (line 129) | private void printJvmInfoAsConsole() {
    method printJvmInfoAsText (line 204) | private void printJvmInfoAsText() {
    method printTopCpuThreads (line 258) | private void printTopCpuThreads(ThreadInfoMode mode, boolean console) ...
    method printTopMemoryThreads (line 351) | private void printTopMemoryThreads(ThreadInfoMode mode, boolean consol...
    method printWelcome (line 429) | private void printWelcome() {
    method printJmxError (line 456) | private void printJmxError() {
    method printIterationCost (line 466) | private void printIterationCost(long iterationStartTime, long iteratio...
    method switchCpuAndMemory (line 481) | public void switchCpuAndMemory() {
    method shouldExit (line 486) | public boolean shouldExit() {
    method shoulExit (line 493) | public void shoulExit() {
    method setWidth (line 497) | private void setWidth(Integer width) {
    method getThreadNameWidth (line 507) | private int getThreadNameWidth() {
    type ThreadInfoMode (line 511) | public enum ThreadInfoMode {
      method ThreadInfoMode (line 516) | private ThreadInfoMode(boolean isCpuMode) {
      method parse (line 520) | public static ThreadInfoMode parse(String value) {
      method parseInt (line 529) | public static ThreadInfoMode parseInt(String mode) {
    type OutputFormat (line 549) | public enum OutputFormat {
      method OutputFormat (line 552) | OutputFormat(boolean ansi) {
    type ContentMode (line 559) | public enum ContentMode {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/VMInfo.java
  class VMInfo (line 23) | @SuppressWarnings("restriction")
    method VMInfo (line 116) | public VMInfo(JmxClient jmxClient, String vmId) throws Exception {
    method VMInfo (line 124) | private VMInfo() {
    method processNewVM (line 130) | public static VMInfo processNewVM(String pid, String jmxHostAndPort) {
    method createDeadVM (line 155) | public static VMInfo createDeadVM(String pid, VMInfoState state) {
    method init (line 165) | private void init() throws IOException {
    method initThreadInfoAbility (line 200) | public void initThreadInfoAbility() throws IOException {
    method update (line 209) | public void update(boolean needJvmInfo) {
    method updateUpTime (line 250) | private void updateUpTime() {
    method updateProcessStatus (line 255) | private void updateProcessStatus() {
    method updateIO (line 271) | private void updateIO() {
    method updateCpu (line 290) | private void updateCpu() {
    method updateThreads (line 303) | private void updateThreads() {
    method updateClassLoader (line 321) | private void updateClassLoader() {
    method updateMemoryPool (line 336) | private void updateMemoryPool() {
    method updateGC (line 403) | private void updateGC() {
    method updateSafepoint (line 432) | private void updateSafepoint() {
    method getAllThreadIds (line 443) | public long[] getAllThreadIds() throws IOException {
    method getThreadCpuTime (line 447) | public long[] getThreadCpuTime(long[] tids) throws IOException {
    method getThreadUserTime (line 451) | public long[] getThreadUserTime(long[] tids) throws IOException {
    method getThreadInfo (line 455) | public ThreadInfo[] getThreadInfo(long[] tids) throws IOException {
    method getThreadInfo (line 459) | public ThreadInfo getThreadInfo(long tid, int maxDepth) throws IOExcep...
    method getThreadInfo (line 463) | public ThreadInfo[] getThreadInfo(long[] tids, int maxDepth) throws IO...
    method getAllThreadInfo (line 467) | public ThreadInfo[] getAllThreadInfo() throws IOException {
    method getThreadAllocatedBytes (line 471) | public long[] getThreadAllocatedBytes(long[] tids) throws IOException {
    method initPerfCounters (line 475) | private void initPerfCounters(Map<String, Counter> perfCounters) {
    method handleJmxFetchDataError (line 495) | public void handleJmxFetchDataError(Throwable e) {
    method isJmxStateOk (line 509) | public boolean isJmxStateOk() {
    type VMInfoState (line 514) | public enum VMInfoState {
    class Rate (line 518) | public static class Rate {
      method update (line 524) | public void update(long current) {
      method caculateRatePerSecond (line 532) | public void caculateRatePerSecond(long deltaTimeMills) {
    class Usage (line 539) | public static class Usage {
      method Usage (line 544) | public Usage() {
      method Usage (line 547) | public Usage(long used, long committed, long max) {
      method Usage (line 553) | public Usage(MemoryUsage jmxUsage) {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/WarningRule.java
  class WarningRule (line 5) | public class WarningRule {
    method updateProcessor (line 27) | public void updateProcessor(int processors) {
    method updateInterval (line 32) | public void updateInterval(long intervalSeconds) {
    method updateOld (line 47) | public void updateOld(long max) {
    method updatePerm (line 54) | public void updatePerm(long max) {
    method updateCodeCache (line 61) | public void updateCodeCache(long max) {
    class DoubleWarning (line 68) | public static class DoubleWarning {
      method DoubleWarning (line 72) | public DoubleWarning() {
      method DoubleWarning (line 77) | public DoubleWarning(double yellow, double red) {
    class LongWarning (line 83) | public static class LongWarning {
      method LongWarning (line 87) | public LongWarning() {
      method LongWarning (line 92) | public LongWarning(long yellow, long red) {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/data/PerfData.java
  class PerfData (line 16) | @SuppressWarnings("restriction")
    method connect (line 24) | public static PerfData connect(int pid) {
    method PerfData (line 36) | private PerfData(int pid) throws IOException {
    method buildAllCounters (line 45) | private Map<String, Counter> buildAllCounters() {
    method getAllCounters (line 55) | public Map<String, Counter> getAllCounters() {
    method findCounter (line 59) | public Counter findCounter(String counterName) {
    method tickToMills (line 63) | public long tickToMills(LongCounter tickCounter) {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/data/ProcFileData.java
  class ProcFileData (line 12) | public class ProcFileData {
    method getProcStatus (line 19) | public static Map<String, String> getProcStatus(String pid) {
    method getProcIO (line 23) | public static Map<String, String> getProcIO(String pid) {
    method getProcFileAsMap (line 27) | public static Map<String, String> getProcFileAsMap(String filePath) {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/data/jmx/JmxBufferPoolManager.java
  class JmxBufferPoolManager (line 10) | public class JmxBufferPoolManager {
    method JmxBufferPoolManager (line 17) | public JmxBufferPoolManager(MBeanServerConnection connection) throws I...
    method getDirectBufferPoolUsed (line 35) | public long getDirectBufferPoolUsed() {
    method getDirectBufferPoolCapacity (line 39) | public long getDirectBufferPoolCapacity() {
    method getMappedBufferPoolUsed (line 43) | public long getMappedBufferPoolUsed() {
    method getMappedBufferPoolCapacity (line 47) | public long getMappedBufferPoolCapacity() {
    method getMappedBufferPoolCount (line 51) | public long getMappedBufferPoolCount() {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/data/jmx/JmxClient.java
  class JmxClient (line 62) | @SuppressWarnings("restriction")
    method JmxClient (line 84) | public JmxClient() throws IOException {
    method flush (line 87) | public void flush() {
    method connect (line 93) | public void connect(String pid, String jmxHostAndPort) throws Exception {
    method disconnect (line 133) | public void disconnect() {
    method getClassLoadingMXBean (line 144) | public synchronized ClassLoadingMXBean getClassLoadingMXBean() throws ...
    method getRuntimeMXBean (line 152) | public synchronized RuntimeMXBean getRuntimeMXBean() throws IOException {
    method getOperatingSystemMXBean (line 160) | public synchronized OperatingSystemMXBean getOperatingSystemMXBean() t...
    method getHotSpotDiagnosticMXBean (line 168) | public synchronized HotSpotDiagnosticMXBean getHotSpotDiagnosticMXBean...
    method getThreadMXBean (line 176) | public synchronized ThreadMXBean getThreadMXBean() throws IOException {
    method getMemoryPoolManager (line 184) | public synchronized JmxMemoryPoolManager getMemoryPoolManager() throws...
    method getBufferPoolManager (line 191) | public synchronized JmxBufferPoolManager getBufferPoolManager() throws...
    method getGarbageCollectorManager (line 199) | public synchronized JmxGarbageCollectorManager getGarbageCollectorMana...
    method createBeanName (line 206) | private ObjectName createBeanName(String beanName) {
    method toString (line 214) | @Override
    method attachToGetConnectorAddress (line 224) | public String attachToGetConnectorAddress() throws Exception {
    type SnapshotMBeanServerConnection (line 320) | public interface SnapshotMBeanServerConnection extends MBeanServerConn...
      method flush (line 324) | void flush();
    class Snapshot (line 327) | public static class Snapshot {
      method Snapshot (line 328) | private Snapshot() {
      method newSnapshot (line 331) | public static SnapshotMBeanServerConnection newSnapshot(MBeanServerC...
    class SnapshotInvocationHandler (line 338) | static class SnapshotInvocationHandler implements InvocationHandler {
      class NameValueMap (line 344) | @SuppressWarnings("serial")
      method SnapshotInvocationHandler (line 348) | SnapshotInvocationHandler(MBeanServerConnection conn) {
      method flush (line 352) | synchronized void flush() {
      method invoke (line 356) | @Override
      method getAttribute (line 375) | private Object getAttribute(ObjectName objName, String attrName) thr...
      method getAttributes (line 388) | private AttributeList getAttributes(ObjectName objName, String[] att...
      method getCachedAttributes (line 401) | private synchronized NameValueMap getCachedAttributes(ObjectName obj...
      method newMap (line 423) | private static <K, V> Map<K, V> newMap() {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/data/jmx/JmxGarbageCollectorManager.java
  class JmxGarbageCollectorManager (line 11) | public class JmxGarbageCollectorManager {
    method getByGcName (line 18) | public static String getByGcName(String gcName, String defaultName) {
    method JmxGarbageCollectorManager (line 23) | public JmxGarbageCollectorManager(MBeanServerConnection connection) th...
    method getYoungCollector (line 49) | public synchronized GarbageCollectorMXBean getYoungCollector() {
    method getFullCollector (line 53) | public synchronized GarbageCollectorMXBean getFullCollector() {
    method getYgcStrategy (line 57) | public String getYgcStrategy() {
    method getFgcStrategy (line 61) | public String getFgcStrategy() {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/data/jmx/JmxMemoryPoolManager.java
  class JmxMemoryPoolManager (line 10) | public class JmxMemoryPoolManager {
    method JmxMemoryPoolManager (line 30) | public JmxMemoryPoolManager(MBeanServerConnection connection) throws I...
    method getSurvivorMemoryPool (line 53) | public MemoryPoolMXBean getSurvivorMemoryPool() {
    method getEdenMemoryPool (line 57) | public MemoryPoolMXBean getEdenMemoryPool() {
    method getOldMemoryPool (line 61) | public MemoryPoolMXBean getOldMemoryPool() {
    method getPermMemoryPool (line 65) | public MemoryPoolMXBean getPermMemoryPool() {
    method getCodeCacheMemoryPool (line 69) | public MemoryPoolMXBean getCodeCacheMemoryPool() {
    method getCompressedClassSpaceMemoryPool (line 73) | public MemoryPoolMXBean getCompressedClassSpaceMemoryPool() {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/util/Formats.java
  class Formats (line 10) | public class Formats {
    method disableAnsi (line 32) | public static void disableAnsi() {
    method setCleanClearTerminal (line 37) | public static void setCleanClearTerminal() {
    method setTextClearTerminal (line 41) | public static void setTextClearTerminal() {
    method toMBWithColor (line 45) | public static String toMBWithColor(long bytes, LongWarning warning) {
    method toColor (line 50) | public static String toColor(long value, LongWarning warning) {
    method red (line 55) | public static String red(String value) {
    method yellow (line 59) | public static String yellow(String value) {
    method toMB (line 67) | public static String toMB(long bytes) {
    method toSizeUnitWithColor (line 80) | public static String toSizeUnitWithColor(Long size, LongWarning warnin...
    method toSizeUnit (line 85) | public static String toSizeUnit(Long size) {
    method toFixLengthSizeUnit (line 108) | public static String toFixLengthSizeUnit(Long size) {
    method toTimeUnit (line 131) | public static String toTimeUnit(long millis) {
    method formatUsage (line 149) | public static String formatUsage(Usage usage) {
    method formatUsageWithColor (line 157) | public static String formatUsageWithColor(Usage usage, LongWarning war...
    method colorAnsi (line 162) | public static String[] colorAnsi(long value, LongWarning warning) {
    method colorAnsi (line 172) | public static String[] colorAnsi(double value, DoubleWarning warning) {
    method rightStr (line 185) | public static String rightStr(String str, int length) {
    method leftStr (line 192) | public static String leftStr(String str, int length) {
    method shortName (line 201) | public static String shortName(String str, int length, int rightLength) {
    method join (line 213) | public static String join(List<String> list, String delim) {
    method parseFromSize (line 230) | public static long parseFromSize(String str) {
    method clearTerminal (line 278) | public static void clearTerminal() {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/util/LongObjectHashMap.java
  class LongObjectHashMap (line 36) | public class LongObjectHashMap<V> implements LongObjectMap<V> {
    method iterator (line 64) | @Override
    method LongObjectHashMap (line 70) | public LongObjectHashMap() {
    method LongObjectHashMap (line 74) | public LongObjectHashMap(int initialCapacity) {
    method LongObjectHashMap (line 78) | public LongObjectHashMap(int initialCapacity, float loadFactor) {
    method toExternal (line 101) | private static <T> T toExternal(T value) {
    method toInternal (line 106) | @SuppressWarnings("unchecked")
    method get (line 111) | @Override
    method put (line 117) | @Override
    method putAll (line 145) | @Override
    method remove (line 166) | @Override
    method size (line 178) | @Override
    method isEmpty (line 183) | @Override
    method clear (line 188) | @Override
    method containsKey (line 195) | @Override
    method containsValue (line 200) | @Override
    method entries (line 213) | @Override
    method values (line 218) | @Override
    method hashCode (line 250) | @Override
    method equals (line 269) | @Override
    method containsKey (line 299) | @Override
    method get (line 304) | @Override
    method put (line 309) | @Override
    method remove (line 314) | @Override
    method keySet (line 319) | @Override
    method entrySet (line 324) | @Override
    method objectToKey (line 329) | private long objectToKey(Object key) {
    method indexOf (line 339) | private int indexOf(long key) {
    method hashIndex (line 362) | private int hashIndex(long key) {
    method hashCode (line 370) | private static int hashCode(long key) {
    method probeNext (line 377) | private int probeNext(int index) {
    method growSize (line 385) | private void growSize() {
    method removeAt (line 405) | private boolean removeAt(final int index) {
    method calcMaxSize (line 438) | private int calcMaxSize(int capacity) {
    method rehash (line 449) | private void rehash(int newCapacity) {
    method toString (line 484) | @Override
    method keyToString (line 509) | protected String keyToString(long key) {
    class EntrySet (line 516) | private final class EntrySet extends AbstractSet<Entry<Long, V>> {
      method iterator (line 517) | @Override
      method size (line 522) | @Override
    class KeySet (line 531) | private final class KeySet extends AbstractSet<Long> {
      method size (line 532) | @Override
      method contains (line 537) | @Override
      method remove (line 542) | @Override
      method retainAll (line 547) | @Override
      method clear (line 560) | @Override
      method iterator (line 565) | @Override
    class PrimitiveIterator (line 591) | private final class PrimitiveIterator implements Iterator<PrimitiveEnt...
      method scanNext (line 596) | private void scanNext() {
      method hasNext (line 601) | @Override
      method next (line 609) | @Override
      method remove (line 623) | @Override
      method key (line 640) | @Override
      method value (line 645) | @Override
      method setValue (line 650) | @Override
    class MapIterator (line 659) | private final class MapIterator implements Iterator<Entry<Long, V>> {
      method hasNext (line 662) | @Override
      method next (line 667) | @Override
      method remove (line 678) | @Override
    class MapEntry (line 687) | final class MapEntry implements Entry<Long, V> {
      method MapEntry (line 690) | MapEntry(int entryIndex) {
      method getKey (line 694) | @Override
      method getValue (line 700) | @Override
      method setValue (line 706) | @Override
      method verifyExists (line 714) | private void verifyExists() {
    method safeFindNextPositivePowerOfTwo (line 721) | public static int safeFindNextPositivePowerOfTwo(final int value) {
    method findNextPositivePowerOfTwo (line 725) | public static int findNextPositivePowerOfTwo(final int value) {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/util/LongObjectMap.java
  type LongObjectMap (line 22) | public interface LongObjectMap<V> extends Map<Long, V> {
    type PrimitiveEntry (line 29) | interface PrimitiveEntry<V> {
      method key (line 33) | long key();
      method value (line 38) | V value();
      method setValue (line 43) | void setValue(V value);
    method get (line 52) | V get(long key);
    method put (line 61) | V put(long key, V value);
    method remove (line 69) | V remove(long key);
    method entries (line 76) | Iterable<PrimitiveEntry<V>> entries();
    method containsKey (line 81) | boolean containsKey(long key);

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/util/OptionAdvanceParser.java
  class OptionAdvanceParser (line 13) | public class OptionAdvanceParser {
    method parsePid (line 17) | public static String parsePid(OptionParser parser, OptionSet optionSet) {
    method parseOutputFormat (line 38) | public static OutputFormat parseOutputFormat(OptionSet optionSet) {
    method parseContentMode (line 53) | public static ContentMode parseContentMode(OptionSet optionSet) {
    method parseThreadInfoMode (line 67) | public static ThreadInfoMode parseThreadInfoMode(OptionSet optionSet) {
    method createOptionParser (line 76) | public static OptionParser createOptionParser() {
    method parseInterval (line 120) | public static Integer parseInterval(OptionSet optionSet) {

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/util/SelectPid.java
  class SelectPid (line 11) | public class SelectPid {
    method getPidFromJpsList (line 13) | public static Integer getPidFromJpsList(){

FILE: vjtop/src/main/java/com/vip/vjtools/vjtop/util/Utils.java
  class Utils (line 9) | public class Utils {
    method sortAndFilterThreadIdsByValue (line 16) | public static long[] sortAndFilterThreadIdsByValue(LongObjectMap map, ...
    method calcLoad (line 41) | public static double calcLoad(long deltaCpuTime, long deltaUptime) {
    method calcLoad (line 51) | public static double calcLoad(Long deltaCpuTime, long deltaUptime, lon...
    method calcMemoryUtilization (line 58) | public static double calcMemoryUtilization(Long threadBytes, long tota...
    method sleep (line 67) | public static void sleep(long mills) {
    method getJavaMajorVersion (line 74) | public static int getJavaMajorVersion(String javaSpecificationVersion) {

FILE: vjtop/src/test/java/com/vip/vjtools/vjtop/util/FormatsTest.java
  class FormatsTest (line 10) | public class FormatsTest {
    method joinInput0NotNullOutputNotNull (line 14) | @Test
    method joinInput1NullOutputNotNull (line 28) | @Test
    method leftStrInputNotNullNegativeOutputStringIndexOutOfBoundsException (line 43) | @Test
    method leftStrInputNotNullZeroOutputNotNull (line 57) | @Test
    method rightStrInputNotNullNegativeOutputStringIndexOutOfBoundsException (line 71) | @Test
    method rightStrInputNotNullPositiveOutputNotNull (line 85) | @Test
    method shortNameInputNotNullPositivePositiveOutputNotNull (line 99) | @Test
    method shortNameInputNotNullPositiveZeroOutputNotNull (line 114) | @Test
    method shortNameInputNotNullZeroNegativeOutputStringIndexOutOfBoundsException (line 129) | @Test
    method toFixLengthSizeUnitInputNullOutputNotNull (line 144) | @Test
    method toFixLengthSizeUnitInputPositiveOutputNotNull (line 157) | @Test
    method toMBInputNegativeOutputNotNull (line 170) | @Test
    method toMBInputPositiveOutputNotNull (line 183) | @Test
    method toSizeUnitInputNegativeOutputNotNull (line 196) | @Test
    method toSizeUnitInputNullOutputNotNull (line 209) | @Test
    method toSizeUnitInputPositiveOutputNotNull (line 222) | @Test
    method toSizeUnitWithColorInputNullNullOutputNullPointerException (line 235) | @Test

FILE: vjtop/src/test/java/com/vip/vjtools/vjtop/util/UtilsTest.java
  class UtilsTest (line 7) | public class UtilsTest {
    method calcLoadInputNegativeZeroZeroOutputZero (line 9) | @Test
    method calcLoadInputPositivePositiveOutputPositive (line 24) | @Test
    method calcLoadInputPositivePositiveZeroOutputPositiveInfinity (line 38) | @Test
    method calcLoadInputPositiveZeroOutputZero (line 53) | @Test
    method calcLoadInputPositiveZeroZeroOutputZero (line 67) | @Test
    method calcLoadInputZeroZeroOutputZero (line 82) | @Test
    method calcMemoryUtilizationInputNegativePositiveOutputNegative (line 96) | @Test
    method calcMemoryUtilizationInputPositiveZeroOutputZero (line 110) | @Test
Condensed preview — 317 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,166K chars).
[
  {
    "path": ".gitignore",
    "chars": 194,
    "preview": "# Eclipse project files\n.classpath\n.project\n.settings/\n\n# Intellij project files\n*.iml\n.idea/\n\n# Otherse\n*.log\ntarget/\n\n"
  },
  {
    "path": ".travis.yml",
    "chars": 93,
    "preview": "language: java\n\njdk:\n  - openjdk9\n\nbranches:\n  only:\n    - master\n\nscript: mvn clean package\n"
  },
  {
    "path": "LICENSE.txt",
    "chars": 11360,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 1903,
    "preview": "![VJTools](/docs/images/logo.jpg) [![Build Status](https://travis-ci.org/vipshop/vjtools.svg?branch=master)](https://tra"
  },
  {
    "path": "docs/.nojekyll",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/README.md",
    "chars": 62,
    "preview": "All about java in vip.com\n\n- Standard\n- Core Libraries\n- Tools"
  },
  {
    "path": "docs/_coverpage.md",
    "chars": 157,
    "preview": "\n![VJTools](images/logo2.png)\n\n- Standard\n- Core Libraries\n- Tools\n\n[GitHub Project](https://github.com/vipshop/vjtools)"
  },
  {
    "path": "docs/_sidebar.md",
    "chars": 93,
    "preview": "- [GitHub Project](https://github.com/vipshop/vjtools)\n- [Java Coding Guidelines](standard/)\n"
  },
  {
    "path": "docs/index.html",
    "chars": 1411,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>VJTools</title>\n    <meta http-equiv=\"X-UA"
  },
  {
    "path": "docs/other/othertools.md",
    "chars": 616,
    "preview": "# 1.问题排查\n\n## BTrace 系\n\n- [btrace](https://github.com/btraceio/btrace)\n- [greys](https://github.com/oldmanpushcart/greys-"
  },
  {
    "path": "docs/standard/README.md",
    "chars": 1403,
    "preview": "# 《唯品会Java开发手册》1.0.3版\n\n## 1. 概述\n\n[《阿里巴巴Java开发手册》](https://github.com/alibaba/p3c),是首个对外公布的企业级Java开发手册,对整个业界都有重要的意义。\n\n我们结"
  },
  {
    "path": "docs/standard/_sidebar.md",
    "chars": 409,
    "preview": "- [命名规约](standard/chapter01.md)\n- [格式规约](standard/chapter02.md)\n- [注释规约](standard/chapter03.md)\n- [方法设计](standard/chapte"
  },
  {
    "path": "docs/standard/ali.md",
    "chars": 5480,
    "preview": "# 《阿里Java开发手册》定制纪录\n\n只记录较大的改动,对更多条目内容的重新组织与扩写,则未一一冗述。\n\n* [《唯品会Java开发手册》-与阿里手册的比较文学I](http://calvin1978.blogcn.com/?p=1771"
  },
  {
    "path": "docs/standard/chapter01.md",
    "chars": 4352,
    "preview": "# (一) 命名规约\n\n**Rule 1. 【强制】禁止拼音缩写,避免阅读者费劲猜测;尽量不用拼音,除非中国式业务词汇没有通用易懂的英文对应。**\n\n```text\n禁止: DZ[打折] / getPFByName() [评分]\n\n尽量避免"
  },
  {
    "path": "docs/standard/chapter02.md",
    "chars": 1644,
    "preview": "# (二) 格式规约\n\n**Rule 1. 【强制】使用项目组统一的代码格式模板,基于IDE自动的格式化**\n\n1)IDE的默认代码格式模板,能简化绝大部分关于格式规范(如空格,括号)的描述。\n\n2)统一的模板,并在接手旧项目先进行一次全面"
  },
  {
    "path": "docs/standard/chapter03.md",
    "chars": 2096,
    "preview": "# (三) 注释规约\n\n**Rule 1.【推荐】基本的注释要求**\n\n完全没有注释的大段代码对于阅读者形同天书,注释是给自己看的,即使隔很长时间,也能清晰理解当时的思路;注释也是给继任者看的,使其能够快速接替自己的工作。\n\n代码将被大量后"
  },
  {
    "path": "docs/standard/chapter04.md",
    "chars": 3000,
    "preview": "# (四) 方法设计\n\n**Rule 1. 【推荐】方法的长度度量**\n\n方法尽量不要超过100行,或其他团队共同商定的行数。\n\n另外,方法长度超过8000个字节码时,将不会被JIT编译成二进制码。\n\n\n* [Sonar-107: Meth"
  },
  {
    "path": "docs/standard/chapter05.md",
    "chars": 5709,
    "preview": "# (五) 类设计\n\n**Rule 1. 【推荐】类成员与方法的可见性最小化**\n\n任何类、方法、参数、变量,严控访问范围。过于宽泛的访问范围,不利于模块解耦。思考:如果是一个private的方法,想删除就删除,可是一个public的ser"
  },
  {
    "path": "docs/standard/chapter06.md",
    "chars": 2850,
    "preview": "# (六) 控制语句\n\n**Rule 1. 【强制】if, else, for, do, while语句必须使用大括号,即使只有单条语句**\n\n曾经试过合并代码时,因为没加括号,单条语句合并成两条语句后,仍然认为只有单条语句,另一条语句在循"
  },
  {
    "path": "docs/standard/chapter07.md",
    "chars": 6099,
    "preview": "# (七) 基本类型与字符串\n\n**Rule 1. 原子数据类型(int等)与包装类型(Integer等)的使用原则**\n\n**1.1 【推荐】需要序列化的POJO类属性使用包装数据类型**\n\n\n**1.2 【推荐】RPC方法的返回值和参数"
  },
  {
    "path": "docs/standard/chapter08.md",
    "chars": 5318,
    "preview": "# (八) 集合处理\n\n**Rule 1. 【推荐】底层数据结构是数组的集合,指定集合初始大小**\n\n底层数据结构为数组的集合包括 ArrayList,HashMap,HashSet,ArrayDequeue等。\n\n数组有大小限制,当超过容"
  },
  {
    "path": "docs/standard/chapter09.md",
    "chars": 5776,
    "preview": "# (九) 并发处理\n\n**Rule 1. 【强制】创建线程或线程池时请指定有意义的线程名称,方便出错时回溯**\n\n1)创建单条线程时直接指定线程名称\n\n```java\nThread t = new Thread();\nt.setName("
  },
  {
    "path": "docs/standard/chapter10.md",
    "chars": 4593,
    "preview": "# (十) 异常处理\n\n**Rule 1. 【强制】创建异常的消耗大,只用在真正异常的场景**\n\n构造异常时,需要获得整个调用栈,有一定消耗。\n\n不要用来做流程控制,条件控制,因为异常的处理效率比条件判断低。\n\n发生概率较高的条件,应该先进"
  },
  {
    "path": "docs/standard/chapter11.md",
    "chars": 2067,
    "preview": "# (十一) 日志规约\n\n**Rule 1. 【强制】应用中不可直接使用日志库(Log4j、Logback)中的API,而应使用日志框架SLF4J中的API**\n\n使用门面模式的日志框架,有利于维护各个类的日志处理方式统一。\n\n```jav"
  },
  {
    "path": "docs/standard/chapter12.md",
    "chars": 1621,
    "preview": "# (十二) 其他规约\n\n**Rule 1. 【参考】尽量不要让魔法值(即未经定义的数字或字符串常量)直接出现在代码中**\n\n```java\n //WRONG\n String key = \"Id#taobao_\"+tradeId;\n cac"
  },
  {
    "path": "docs/standard/merge.bat",
    "chars": 716,
    "preview": "@echo off\ntype README.md > vip-java-standard.md\ntype chapter01.md >> vip-java-standard.md\ntype chapter02.md >> vip-java-"
  },
  {
    "path": "docs/standard/merge.sh",
    "chars": 657,
    "preview": "#!/bin/sh\n\ncat README.md > vip-java-standard.md\ncat chapter01.md >> vip-java-standard.md\ncat chapter02.md >> vip-java-st"
  },
  {
    "path": "pom.xml",
    "chars": 3451,
    "preview": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocat"
  },
  {
    "path": "standard/README.md",
    "chars": 226,
    "preview": "# Java Standard\n\n| Project | Description |\n| -------- | -------- |\n| [standard](https://vipshop.github.io/vjtools/#/stan"
  },
  {
    "path": "standard/formatter/README.md",
    "chars": 1342,
    "preview": "# 公司通用代码格式化模板\n\n定制原因详见[《唯品会Java开发手册》 第二章:格式规约](https://vipshop.github.io/vjtools/#/standard/chapter02),同时参考了一些Intellij ID"
  },
  {
    "path": "standard/formatter/vjtools-code-conventions-eclipse.xml",
    "chars": 33157,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<profiles version=\"12\">\n<profile kind=\"CodeFormatterProfile\" name"
  },
  {
    "path": "standard/formatter/vjtools-code-conventions-idea.xml",
    "chars": 1447,
    "preview": "<code_scheme name=\"vjtools\">\n  <option name=\"AUTODETECT_INDENTS\" value=\"false\" />\n  <option name=\"LINE_SEPARATOR\" value="
  },
  {
    "path": "standard/sonar-vj/README.md",
    "chars": 1678,
    "preview": "# Sonar VJ 规则\n\n## 概述\n\n我们使用[Sonar](https://www.sonarqube.org/)代码检查工具来辅助[《唯品会Java开发手册》](https://vipshop.github.io/vjtools/"
  },
  {
    "path": "standard/sonar-vj/pom.xml",
    "chars": 3867,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2"
  },
  {
    "path": "standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/SonarCheckRegistrar.java",
    "chars": 913,
    "preview": "package com.vip.vjkit.sonarvj;\n\nimport com.vip.vjkit.sonarvj.checks.*;\nimport org.sonar.plugins.java.api.CheckRegistrar;"
  },
  {
    "path": "standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/SonarDefinition.java",
    "chars": 5703,
    "preview": "\npackage com.vip.vjkit.sonarvj;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.collec"
  },
  {
    "path": "standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/SonarPlugin.java",
    "chars": 326,
    "preview": "package com.vip.vjkit.sonarvj;\n\nimport org.sonar.api.Plugin;\n\n/**\n * Created by cloud.huang on 18/1/5.\n */\npublic class "
  },
  {
    "path": "standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/SonarRulesList.java",
    "chars": 1176,
    "preview": "package com.vip.vjkit.sonarvj;\n\nimport com.google.common.collect.ImmutableList;\nimport com.vip.vjkit.sonarvj.checks.*;\ni"
  },
  {
    "path": "standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/BadConstantNameCheck.java",
    "chars": 4597,
    "preview": "/*\n * SonarQube Java Copyright (C) 2012-2018 SonarSource SA mailto:info AT sonarsource DOT com\n *\n * This program is fre"
  },
  {
    "path": "standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/CatchUsesExceptionWithContextCheck.java",
    "chars": 6675,
    "preview": "package com.vip.vjkit.sonarvj.checks;\n\nimport com.google.common.base.Splitter;\nimport com.google.common.collect.Iterable"
  },
  {
    "path": "standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/HardcodedIpCheck.java",
    "chars": 1789,
    "preview": "package com.vip.vjkit.sonarvj.checks;\n\nimport com.google.common.base.Splitter;\n\nimport org.sonar.check.Rule;\nimport org."
  },
  {
    "path": "standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/MissingCurlyBracesCheck.java",
    "chars": 2923,
    "preview": "package com.vip.vjkit.sonarvj.checks;\n\nimport com.google.common.collect.ImmutableList;\nimport org.sonar.check.Rule;\nimpo"
  },
  {
    "path": "standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/NoSonarCheck.java",
    "chars": 2276,
    "preview": "/*\n * SonarQube Java Copyright (C) 2012-2018 SonarSource SA mailto:info AT sonarsource DOT com\n *\n * This program is fre"
  },
  {
    "path": "standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/OperatorPrecedenceCheck.java",
    "chars": 7565,
    "preview": "/*\n * SonarQube Java\n * Copyright (C) 2012-2017 SonarSource SA\n * mailto:info AT sonarsource DOT com\n *\n * This program "
  },
  {
    "path": "standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/UnusedMethodParameterCheck.java",
    "chars": 6157,
    "preview": "/*\n * SonarQube Java\n * Copyright (C) 2012-2018 SonarSource SA\n * mailto:info AT sonarsource DOT com\n *\n * This program "
  },
  {
    "path": "standard/sonar-vj/src/main/java/com/vip/vjkit/sonarvj/checks/UnusedPrivateFieldCheck.java",
    "chars": 7749,
    "preview": "/*\n * SonarQube Java Copyright (C) 2012-2018 SonarSource SA mailto:info AT sonarsource DOT com\n *\n * This program is fre"
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S1068_java.html",
    "chars": 1553,
    "preview": "<h2>VJ update: 使用lobmok的类不告警</h2>\n<p>If a <code>private</code> field is declared but not used in the program, it can be "
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S1068_java.json",
    "chars": 320,
    "preview": "{\n  \"title\": \"VJ: Unused \\\"private\\\" fields should be removed\",\n  \"type\": \"CODE_SMELL\",\n  \"status\": \"ready\",\n  \"remediat"
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S115_java.html",
    "chars": 482,
    "preview": "<h2>VJ update: 枚举可以是小写</h2>\n<p>Shared coding conventions allow teams to collaborate efficiently. This rule checks that a"
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S115_java.json",
    "chars": 266,
    "preview": "{\n  \"title\": \"VJ: Constant names should comply with a naming convention\",\n  \"type\": \"CODE_SMELL\",\n  \"status\": \"ready\",\n "
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S1166_java.html",
    "chars": 2068,
    "preview": "<h2>VJ update: catch异常的变量名包含ignore,忽略检查</h2>\n<p>When handling a caught exception, the original exception's message and s"
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S1166_java.json",
    "chars": 412,
    "preview": "{\n  \"title\": \"VJ:Exception handlers should preserve the original exceptions\",\n  \"type\": \"CODE_SMELL\",\n  \"status\": \"ready"
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S1172_java.html",
    "chars": 1005,
    "preview": "<h2>VJ update:只判断private函数</h2>\n\n<p>Unused parameters for private method misleading. Whatever the values passed to such "
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S1172_java.json",
    "chars": 340,
    "preview": "{\n  \"title\": \"VJ: Unused private method parameters should be removed\",\n  \"type\": \"CODE_SMELL\",\n  \"status\": \"ready\",\n  \"r"
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S121_java.html",
    "chars": 1533,
    "preview": "<h2>VJ update: IDE自动生成的方法如equals忽略</h2>\n<p>While not technically incorrect, the omission of curly braces can be misleadi"
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S121_java.json",
    "chars": 365,
    "preview": "{\n  \"title\": \"VJ: Control structures should use curly braces\",\n  \"type\": \"CODE_SMELL\",\n  \"status\": \"ready\",\n  \"remediati"
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S1291_java.html",
    "chars": 332,
    "preview": "<h2>VJ update: 忽略在异常捕获语句和System.out后的NOSONAR</h2>\n<p>Any issue to quality rule can be deactivated with the <code>NOSONAR"
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S1291_java.json",
    "chars": 304,
    "preview": "{\n  \"title\": \"VJ: Track uses of \\\"NOSONAR\\\" comments\",\n  \"type\": \"CODE_SMELL\",\n  \"status\": \"ready\",\n  \"remediation\": {\n "
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S1313_java.html",
    "chars": 913,
    "preview": "<h2>VJ update: 忽略\"127.0.0.1\"</h2>\n<p>Hardcoding an IP address into source code is a bad idea for several reasons:</p>\n<u"
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S1313_java.json",
    "chars": 336,
    "preview": "{\n  \"title\": \"VJ: IP addresses should not be hardcoded\",\n  \"type\": \"VULNERABILITY\",\n  \"status\": \"ready\",\n  \"remediation\""
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S864_java.html",
    "chars": 3614,
    "preview": "<h2>VJ update: 三目运算符中的简单表达式可以不要括号</h2>\n<p>The rules of operator precedence are complicated and can lead to errors. For t"
  },
  {
    "path": "standard/sonar-vj/src/main/resources/com/vip/java/rules/S864_java.json",
    "chars": 409,
    "preview": "{\n  \"title\": \"VJ: Limited dependence should be placed on operator precedence rules in expressions\",\n  \"type\": \"CODE_SMEL"
  },
  {
    "path": "vjdump/README.md",
    "chars": 797,
    "preview": "# 1. 概述\n\nVJDump是线上JVM数据紧急收集脚本。 \n\n它可以在紧急场景下(比如马上要对进程进行重启),一键收集jstack、jmap以及GC日志等相关信息,并以zip包保存(默认在目录`/tmp/vjtools/vjdump`下"
  },
  {
    "path": "vjdump/README_EN.md",
    "chars": 1659,
    "preview": "# VJDump\nVJDump comes as a handy script for collecting diagnostic data for JVM during urgent failures to\n**allow for com"
  },
  {
    "path": "vjdump/vjdump.sh",
    "chars": 6395,
    "preview": "#!/bin/bash\n\nUSAGE()\n{\n  echo \"usage: $0 [--liveheap][-nz|--nozip][-i|--interval] <pid>\"\n}\n\nif [ $# -lt 1 ]; then\n  USAG"
  },
  {
    "path": "vjkit/README.md",
    "chars": 1875,
    "preview": "# 1. Overview\n\n唯品会Java开发基础类库,综合各门各派众多开源类库的精华而成, 让开发人员避免底层代码的重复开发,默认就拥有最佳实践,尤其在性能的方面。\n\n\n综合众多开源类库的精华而成, 让开发人员避免底层代码的重复开发,默"
  },
  {
    "path": "vjkit/docs/data_masking.md",
    "chars": 3488,
    "preview": "# 1.简介\nvjmask是唯品会的日志脱敏组件,在业务中广泛使用。基于性能和通用性考虑,采用了现在的方案。让使用方用最少的配置和代码,就可以轻松实现敏感信息过滤。\n\n# 2.使用\n## 2.1 依赖\n\n```\n<dependency>\n "
  },
  {
    "path": "vjkit/docs/direct_3rd.md",
    "chars": 154,
    "preview": "# 建议直接使用的第三方类\n\n\n| Project | Class | \n|--- | --- |\n|Common Lang | StringUtils |\n| | Validate|\n|Guava | Cache |\n| | Orderi"
  },
  {
    "path": "vjkit/pom.xml",
    "chars": 7766,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/BooleanUtil.java",
    "chars": 1623,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport org.apache.commons.lang3.BooleanUtils;\n\n/**\n * 1. 从String(true/false, yes/no"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/EnumUtil.java",
    "chars": 1196,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport java.util.EnumSet;\n\nimport org.apache.commons.lang3.EnumUtils;\n\n/**\n * 枚举工具集"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/ExceptionUtil.java",
    "chars": 5623,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport java.io.PrintWriter;\nimport java.lang.reflect.UndeclaredThrowableException;\n"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/MoreValidate.java",
    "chars": 2639,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport com.vip.vjtools.vjkit.base.annotation.Nullable;\n\n/**\n * 参数校验统一使用Apache Commo"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/ObjectUtil.java",
    "chars": 2839,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport java.util.Arrays;\n\nimport com.google.common.base.Objects;\nimport com.vip.vjt"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/Platforms.java",
    "chars": 1901,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport java.io.File;\n\nimport org.apache.commons.lang3.SystemUtils;\n\n/**\n * 关于系统设定,平"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/PropertiesUtil.java",
    "chars": 2152,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.io.Reader"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/RuntimeUtil.java",
    "chars": 3057,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport java.lang.management.ManagementFactory;\nimport java.util.List;\nimport java.u"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/SystemPropertiesUtil.java",
    "chars": 6815,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport java.util.List;\nimport java.util.Properties;\nimport java.util.concurrent.Cop"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/ValueValidator.java",
    "chars": 1554,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport org.apache.commons.lang3.StringUtils;\n\n/**\n * 数值校验取值器 \n * \n * 提供对配置值进行校验,并根据"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/annotation/NotNull.java",
    "chars": 261,
    "preview": "package com.vip.vjtools.vjkit.base.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Tar"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/annotation/Nullable.java",
    "chars": 261,
    "preview": "package com.vip.vjtools.vjkit.base.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Tar"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/annotation/VisibleForTesting.java",
    "chars": 132,
    "preview": "package com.vip.vjtools.vjkit.base.annotation;\n\n/**\n * 标注因为方便UT,将方法/属性的可访问范围扩大了,参考Guava\n */\npublic @interface VisibleFor"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/type/CloneableException.java",
    "chars": 1617,
    "preview": "package com.vip.vjtools.vjkit.base.type;\n\nimport com.vip.vjtools.vjkit.base.ExceptionUtil;\n\n/**\n * 适用于异常信息需要变更的情况, 可通过cl"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/type/CloneableRuntimeException.java",
    "chars": 1526,
    "preview": "package com.vip.vjtools.vjkit.base.type;\n\nimport com.vip.vjtools.vjkit.base.ExceptionUtil;\n\n/**\n * 适用于异常信息需要变更的情况, 可通过cl"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/type/Pair.java",
    "chars": 1461,
    "preview": "package com.vip.vjtools.vjkit.base.type;\n\nimport com.vip.vjtools.vjkit.base.annotation.Nullable;\n\n/**\n * 引入一个简简单单的Pair, "
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/type/Triple.java",
    "chars": 1896,
    "preview": "package com.vip.vjtools.vjkit.base.type;\n\nimport com.vip.vjtools.vjkit.base.annotation.Nullable;\n\n/**\n * 引入一个简简单单的Triple"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/base/type/UncheckedException.java",
    "chars": 406,
    "preview": "package com.vip.vjtools.vjkit.base.type;\n\n/**\n * CheckedException的wrapper.\n * \n * 返回Message时, 将返回内层Exception的Message.\n *"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/ArrayUtil.java",
    "chars": 3396,
    "preview": "package com.vip.vjtools.vjkit.collection;\n\nimport java.lang.reflect.Array;\nimport java.util.Arrays;\nimport java.util.Col"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/CollectionUtil.java",
    "chars": 4361,
    "preview": "package com.vip.vjtools.vjkit.collection;\n\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.C"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/ListUtil.java",
    "chars": 9408,
    "preview": "package com.vip.vjtools.vjkit.collection;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Co"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/MapUtil.java",
    "chars": 10190,
    "preview": "package com.vip.vjtools.vjkit.collection;\n\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Compa"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/QueueUtil.java",
    "chars": 1956,
    "preview": "package com.vip.vjtools.vjkit.collection;\n\nimport java.util.ArrayDeque;\nimport java.util.Deque;\nimport java.util.LinkedL"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/SetUtil.java",
    "chars": 4399,
    "preview": "package com.vip.vjtools.vjkit.collection;\n\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.H"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/ConcurrentHashSet.java",
    "chars": 1754,
    "preview": "package com.vip.vjtools.vjkit.collection.type;\n\nimport java.util.AbstractSet;\nimport java.util.Collection;\nimport java.u"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/MoreLists.java",
    "chars": 592,
    "preview": "package com.vip.vjtools.vjkit.collection.type;\n\nimport java.util.Comparator;\n\n/**\n * 特殊的List类型\n */\npublic class MoreList"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/MoreMaps.java",
    "chars": 4135,
    "preview": "package com.vip.vjtools.vjkit.collection.type;\n\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util."
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/MoreQueues.java",
    "chars": 1186,
    "preview": "package com.vip.vjtools.vjkit.collection.type;\n\nimport java.util.ArrayDeque;\nimport java.util.Collections;\nimport java.u"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/SortedArrayList.java",
    "chars": 5370,
    "preview": "// Copyright (c) 2003-present, Jodd Team (http://jodd.org)\n// All rights reserved.\n//\n// Redistribution and use in sourc"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/primitive/IntObjectHashMap.java",
    "chars": 19123,
    "preview": "/*\n * Copyright 2014 The Netty Project\n *\n * The Netty Project licenses this file to you under the Apache License, versi"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/primitive/IntObjectMap.java",
    "chars": 2441,
    "preview": "/*\n * Copyright 2014 The Netty Project\n *\n * The Netty Project licenses this file to you under the Apache License, versi"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/primitive/LongObjectHashMap.java",
    "chars": 18999,
    "preview": "/*\n * Copyright 2014 The Netty Project\n *\n * The Netty Project licenses this file to you under the Apache License, versi"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/collection/type/primitive/LongObjectMap.java",
    "chars": 2445,
    "preview": "/*\n * Copyright 2014 The Netty Project\n *\n * The Netty Project licenses this file to you under the Apache License, versi"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/Concurrents.java",
    "chars": 2450,
    "preview": "package com.vip.vjtools.vjkit.concurrent;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.Cycli"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/ThreadDumpper.java",
    "chars": 2896,
    "preview": "package com.vip.vjtools.vjkit.concurrent;\n\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.concurrent"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/ThreadUtil.java",
    "chars": 840,
    "preview": "package com.vip.vjtools.vjkit.concurrent;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 线程相关工具类.\n * \n * 1. 处理了Interrupt"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/jsr166e/LongAdder.java",
    "chars": 5288,
    "preview": "/*\n * Written by Doug Lea with assistance from members of JCP JSR-166\n * Expert Group and released to the public domain,"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/jsr166e/Striped64.java",
    "chars": 10772,
    "preview": "/*\n * Written by Doug Lea with assistance from members of JCP JSR-166\n * Expert Group and released to the public domain,"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/limiter/RateLimiterUtil.java",
    "chars": 2720,
    "preview": "package com.vip.vjtools.vjkit.concurrent.limiter;\n\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/limiter/Sampler.java",
    "chars": 1493,
    "preview": "package com.vip.vjtools.vjkit.concurrent.limiter;\n\nimport org.apache.commons.lang3.Validate;\n\nimport com.vip.vjtools.vjk"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/limiter/TimeIntervalLimiter.java",
    "chars": 619,
    "preview": "package com.vip.vjtools.vjkit.concurrent.limiter;\n\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.ato"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/threadpool/AbortPolicyWithReport.java",
    "chars": 1362,
    "preview": "package com.vip.vjtools.vjkit.concurrent.threadpool;\n\nimport java.util.concurrent.RejectedExecutionException;\nimport jav"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/threadpool/QueuableCachedThreadPool.java",
    "chars": 5101,
    "preview": "package com.vip.vjtools.vjkit.concurrent.threadpool;\n\nimport java.util.concurrent.LinkedBlockingQueue;\nimport java.util."
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/threadpool/ThreadPoolBuilder.java",
    "chars": 10331,
    "preview": "package com.vip.vjtools.vjkit.concurrent.threadpool;\n\nimport java.util.concurrent.ArrayBlockingQueue;\nimport java.util.c"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/threadpool/ThreadPoolUtil.java",
    "chars": 3100,
    "preview": "package com.vip.vjtools.vjkit.concurrent.threadpool;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.conc"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/type/BasicFuture.java",
    "chars": 3974,
    "preview": "/*\n * ==================================================================== Licensed to the Apache Software Foundation (A"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/concurrent/type/ThreadLocalContext.java",
    "chars": 1226,
    "preview": "package com.vip.vjtools.vjkit.concurrent.type;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * 存储于ThreadLocal的M"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/DataMask.java",
    "chars": 1902,
    "preview": "package com.vip.vjtools.vjkit.datamasking;\n\nimport com.alibaba.fastjson.JSON;\nimport com.vip.vjtools.vjkit.datamasking.s"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/DataMaskJsonFilter.java",
    "chars": 3199,
    "preview": "package com.vip.vjtools.vjkit.datamasking;\n\nimport com.alibaba.fastjson.serializer.BeanContext;\nimport com.alibaba.fastj"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/MaskMapping.java",
    "chars": 2648,
    "preview": "package com.vip.vjtools.vjkit.datamasking;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.IOE"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/MaskStrategy.java",
    "chars": 140,
    "preview": "package com.vip.vjtools.vjkit.datamasking;\n\n/**\n * 脱敏策略接口\n */\npublic interface MaskStrategy {\n\n\tString mask(String sourc"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/Sensitive.java",
    "chars": 582,
    "preview": "package com.vip.vjtools.vjkit.datamasking;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Inherit"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/SensitiveType.java",
    "chars": 1068,
    "preview": "package com.vip.vjtools.vjkit.datamasking;\n\nimport com.vip.vjtools.vjkit.datamasking.strategy.EmailMask;\nimport com.vip."
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/strategy/EmailMask.java",
    "chars": 587,
    "preview": "package com.vip.vjtools.vjkit.datamasking.strategy;\n\nimport com.vip.vjtools.vjkit.datamasking.MaskStrategy;\n\n/**\n * 电子邮件"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/strategy/HashMask.java",
    "chars": 745,
    "preview": "package com.vip.vjtools.vjkit.datamasking.strategy;\n\nimport com.vip.vjtools.vjkit.datamasking.MaskStrategy;\nimport com.v"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/strategy/NameMask.java",
    "chars": 506,
    "preview": "package com.vip.vjtools.vjkit.datamasking.strategy;\n\nimport com.vip.vjtools.vjkit.datamasking.MaskStrategy;\n\n/**\n * 姓名掩码"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/datamasking/strategy/PartMask.java",
    "chars": 1548,
    "preview": "package com.vip.vjtools.vjkit.datamasking.strategy;\n\nimport com.vip.vjtools.vjkit.datamasking.MaskStrategy;\n\nimport java"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/id/IdUtil.java",
    "chars": 334,
    "preview": "package com.vip.vjtools.vjkit.id;\n\nimport java.util.UUID;\nimport java.util.concurrent.ThreadLocalRandom;\n\npublic class I"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/io/FilePathUtil.java",
    "chars": 2241,
    "preview": "package com.vip.vjtools.vjkit.io;\n\nimport org.apache.commons.lang3.StringUtils;\n\nimport com.google.common.io.Files;\nimpo"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/io/FileTreeWalker.java",
    "chars": 3965,
    "preview": "package com.vip.vjtools.vjkit.io;\n\nimport java.io.File;\nimport java.util.List;\nimport java.util.regex.Pattern;\n\nimport c"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/io/FileUtil.java",
    "chars": 12869,
    "preview": "package com.vip.vjtools.vjkit.io;\n\nimport java.io.BufferedReader;\nimport java.io.BufferedWriter;\nimport java.io.File;\nim"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/io/IOUtil.java",
    "chars": 3866,
    "preview": "package com.vip.vjtools.vjkit.io;\n\nimport java.io.BufferedReader;\nimport java.io.ByteArrayInputStream;\nimport java.io.Cl"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/io/ResourceUtil.java",
    "chars": 3188,
    "preview": "package com.vip.vjtools.vjkit.io;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.URL;\nimport j"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/io/URLResourceUtil.java",
    "chars": 2566,
    "preview": "package com.vip.vjtools.vjkit.io;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.IOException"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/io/type/StringBuilderWriter.java",
    "chars": 4499,
    "preview": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE\n"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/logging/PerformanceUtil.java",
    "chars": 4308,
    "preview": "package com.vip.vjtools.vjkit.logging;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.slf4j.Logger;\n\n/**\n "
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/mapper/BeanMapper.java",
    "chars": 1609,
    "preview": "package com.vip.vjtools.vjkit.mapper;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.dozer.DozerBeanMap"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/mapper/JsonMapper.java",
    "chars": 4571,
    "preview": "package com.vip.vjtools.vjkit.mapper;\n\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.Map;\n\ni"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/mapper/XmlMapper.java",
    "chars": 4304,
    "preview": "package com.vip.vjtools.vjkit.mapper;\n\nimport java.io.StringReader;\nimport java.io.StringWriter;\nimport java.util.Collec"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/net/IPUtil.java",
    "chars": 3018,
    "preview": "package com.vip.vjtools.vjkit.net;\n\nimport java.net.Inet4Address;\nimport java.net.InetAddress;\nimport java.net.UnknownHo"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/net/NetUtil.java",
    "chars": 6542,
    "preview": "package com.vip.vjtools.vjkit.net;\n\nimport java.net.Inet6Address;\nimport java.net.InetAddress;\nimport java.net.NetworkIn"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/number/MathUtil.java",
    "chars": 2650,
    "preview": "package com.vip.vjtools.vjkit.number;\n\nimport java.math.RoundingMode;\n\nimport com.google.common.math.IntMath;\nimport com"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/number/MoneyUtil.java",
    "chars": 3982,
    "preview": "package com.vip.vjtools.vjkit.number;\n\nimport java.math.BigDecimal;\nimport java.math.RoundingMode;\nimport java.text.Deci"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/number/NumberUtil.java",
    "chars": 7164,
    "preview": "package com.vip.vjtools.vjkit.number;\n\nimport java.util.Locale;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/number/RandomUtil.java",
    "chars": 7884,
    "preview": "package com.vip.vjtools.vjkit.number;\n\nimport java.security.NoSuchAlgorithmException;\nimport java.security.SecureRandom;"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/number/SizeUnit.java",
    "chars": 3952,
    "preview": "package com.vip.vjtools.vjkit.number;\n\n/**\n * Representation of basic size units,just like TimeUnit.\n * \n * Usage exampl"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/number/UnitConverter.java",
    "chars": 5415,
    "preview": "/*\n * Copyright (C) 2012 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may no"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/reflect/AnnotationUtil.java",
    "chars": 4073,
    "preview": "package com.vip.vjtools.vjkit.reflect;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Field;\nimport j"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/reflect/ClassLoaderUtil.java",
    "chars": 1251,
    "preview": "package com.vip.vjtools.vjkit.reflect;\n\npublic class ClassLoaderUtil {\n\n\t/**\n\t * Copy from Spring, 按顺序获取默认ClassLoader\n\t "
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/reflect/ClassUtil.java",
    "chars": 4152,
    "preview": "package com.vip.vjtools.vjkit.reflect;\n\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimpor"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/reflect/ReflectionUtil.java",
    "chars": 10107,
    "preview": "package com.vip.vjtools.vjkit.reflect;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetExcepti"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/security/CryptoUtil.java",
    "chars": 4997,
    "preview": "package com.vip.vjtools.vjkit.security;\n\nimport java.security.GeneralSecurityException;\nimport java.security.SecureRando"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/text/Charsets.java",
    "chars": 699,
    "preview": "package com.vip.vjtools.vjkit.text;\n\nimport java.nio.charset.Charset;\nimport java.nio.charset.StandardCharsets;\n\n/**\n * "
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/text/CsvUtil.java",
    "chars": 4493,
    "preview": "// Copyright (c) 2003-present, Jodd Team (http://jodd.org)\n// All rights reserved.\n//\n// Redistribution and use in sourc"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/text/EncodeUtil.java",
    "chars": 1237,
    "preview": "package com.vip.vjtools.vjkit.text;\n\nimport com.google.common.io.BaseEncoding;\n\n/**\n * string/url -> hex/base64 编解码工具集(v"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/text/EscapeUtil.java",
    "chars": 1959,
    "preview": "package com.vip.vjtools.vjkit.text;\n\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLDecoder;\nimport jav"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/text/HashUtil.java",
    "chars": 6187,
    "preview": "package com.vip.vjtools.vjkit.text;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.security.Messag"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/text/MoreStringUtil.java",
    "chars": 3803,
    "preview": "package com.vip.vjtools.vjkit.text;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.commons.lang3"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/text/StringBuilderHolder.java",
    "chars": 1699,
    "preview": "package com.vip.vjtools.vjkit.text;\n\n/**\n * 参考Netty的InternalThreadLocalMap 与 BigDecimal, 放在threadLocal中重用的StringBuilder,"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/text/TextValidator.java",
    "chars": 4389,
    "preview": "package com.vip.vjtools.vjkit.text;\n\nimport java.util.regex.Pattern;\n\nimport org.apache.commons.lang3.StringUtils;\n\nimpo"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/text/WildcardMatcher.java",
    "chars": 8384,
    "preview": "// Copyright (c) 2003-present, Jodd Team (http://jodd.org)\n// All rights reserved.\n//\n// Redistribution and use in sourc"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/time/CachingDateFormatter.java",
    "chars": 1805,
    "preview": "package com.vip.vjtools.vjkit.time;\n\nimport java.util.concurrent.atomic.AtomicReference;\n\nimport org.apache.commons.lang"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/time/ClockUtil.java",
    "chars": 3005,
    "preview": "package com.vip.vjtools.vjkit.time;\n\nimport java.util.Date;\n\n/**\n * 日期提供者, 使用它而不是直接取得系统时间, 方便测试.\n * \n * 平时使用DEFAULT,测试时替"
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/time/DateFormatUtil.java",
    "chars": 5154,
    "preview": "package com.vip.vjtools.vjkit.time;\n\nimport java.text.ParseException;\nimport java.util.Date;\n\nimport org.apache.commons."
  },
  {
    "path": "vjkit/src/main/java/com/vip/vjtools/vjkit/time/DateUtil.java",
    "chars": 10170,
    "preview": "package com.vip.vjtools.vjkit.time;\n\nimport java.util.Calendar;\nimport java.util.Date;\n\nimport org.apache.commons.lang3."
  },
  {
    "path": "vjkit/src/main/resources/sys_data_mask.properties",
    "chars": 219,
    "preview": "Name=chineseName,userName\nPhone=phone,phoneNum,mobile,tel,telephone\nIDCard=IDCard,IdNo\nBankCard=bankCard\nAddress=address"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/test/data/RandomData.java",
    "chars": 927,
    "preview": "package com.vip.vjtools.test.data;\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Random;\n\n/**\n "
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/test/log/LogbackListAppender.java",
    "chars": 3159,
    "preview": "package com.vip.vjtools.test.log;\n\nimport java.util.List;\n\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.col"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/test/log/LogbackListAppenderTest.java",
    "chars": 2239,
    "preview": "package com.vip.vjtools.test.log;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport org.junit.Test;\nimp"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/test/rule/TestProgress.java",
    "chars": 663,
    "preview": "package com.vip.vjtools.test.rule;\n\nimport org.junit.rules.TestWatcher;\nimport org.junit.runner.Description;\n\n/**\n * 在Co"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/base/BooleanUtilTest.java",
    "chars": 1311,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport org.junit.Test;\n\npublic cl"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/base/EnumUtilTest.java",
    "chars": 1117,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport org.junit.Test;\n\nimport co"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/base/ExceptionUtilTest.java",
    "chars": 6488,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport java.io.IOException;\nimpor"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/base/MoreValidateTest.java",
    "chars": 4214,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.assertj"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/base/ObjectUtilTest.java",
    "chars": 1346,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport org.junit.Test;\n\nimport co"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/base/PairTest.java",
    "chars": 1611,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport org.junit.Test;\n\nimport co"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/base/PlatformsTest.java",
    "chars": 1324,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport org.junit.Test;\n\npublic cl"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/base/PropertiesUtilTest.java",
    "chars": 1535,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport java.util.Properties;\n\nimp"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/base/RuntimeUtilTest.java",
    "chars": 607,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport org.junit.Test;\n\npublic cl"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/base/SystemPropertiesUtilTest.java",
    "chars": 5736,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.assertj"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/base/ValueValidatorTest.java",
    "chars": 616,
    "preview": "package com.vip.vjtools.vjkit.base;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport org.junit.Test;\n\n"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/collection/ArrayUtilTest.java",
    "chars": 1913,
    "preview": "package com.vip.vjtools.vjkit.collection;\n\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.a"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/collection/CollectionUtilTest.java",
    "chars": 3560,
    "preview": "package com.vip.vjtools.vjkit.collection;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport java.util.List;\nimpo"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/collection/ListUtilTest.java",
    "chars": 4586,
    "preview": "package com.vip.vjtools.vjkit.collection;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport java.util.List;\nimpo"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/collection/MapUtilTest.java",
    "chars": 8392,
    "preview": "package com.vip.vjtools.vjkit.collection;\n\nimport static org.assertj.core.api.Assertions.*;\nimport static org.assertj.co"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/collection/QueueUtilTest.java",
    "chars": 1611,
    "preview": "package com.vip.vjtools.vjkit.collection;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport java.util.ArrayDeque"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/collection/SetUtilTest.java",
    "chars": 2757,
    "preview": "package com.vip.vjtools.vjkit.collection;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport java.util.HashSet;\ni"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/collection/type/ConcurrentHashSetTest.java",
    "chars": 1682,
    "preview": "package com.vip.vjtools.vjkit.collection.type;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport org.junit.Test;"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/collection/type/SortedArrayListTest.java",
    "chars": 1187,
    "preview": "package com.vip.vjtools.vjkit.collection.type;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport org.junit.Test;"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/ConcurrentsTest.java",
    "chars": 386,
    "preview": "package com.vip.vjtools.vjkit.concurrent;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport org.junit.Test;\n\nimp"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/ThreadDumpperTest.java",
    "chars": 1443,
    "preview": "package com.vip.vjtools.vjkit.concurrent;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport java.util.concurrent"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/ThreadUtilTest.java",
    "chars": 1377,
    "preview": "package com.vip.vjtools.vjkit.concurrent;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport org.junit.Test;\n\nimp"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/limiter/RateLimiterUtilTest.java",
    "chars": 628,
    "preview": "package com.vip.vjtools.vjkit.concurrent.limiter;\n\nimport java.lang.reflect.Field;\n\nimport org.junit.Assert;\nimport org."
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/limiter/SamplerTest.java",
    "chars": 1501,
    "preview": "package com.vip.vjtools.vjkit.concurrent.limiter;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport org.junit.Te"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/limiter/TimeIntervalLimiterTest.java",
    "chars": 717,
    "preview": "package com.vip.vjtools.vjkit.concurrent.limiter;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport jav"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/threadpool/AbortPolicyWithReportTest.java",
    "chars": 828,
    "preview": "package com.vip.vjtools.vjkit.concurrent.threadpool;\n\nimport org.junit.Test;\n\nimport java.util.concurrent.Executors;\nimp"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/threadpool/QueuableCachedThreadPoolTest.java",
    "chars": 1343,
    "preview": "package com.vip.vjtools.vjkit.concurrent.threadpool;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport java.util"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/threadpool/ThreadPoolBuilderTest.java",
    "chars": 5749,
    "preview": "package com.vip.vjtools.vjkit.concurrent.threadpool;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport java.util"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/threadpool/ThreadPoolUtilTest.java",
    "chars": 4593,
    "preview": "package com.vip.vjtools.vjkit.concurrent.threadpool;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport "
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/type/BasicFutureTest.java",
    "chars": 2088,
    "preview": "package com.vip.vjtools.vjkit.concurrent.type;\n\nimport static org.assertj.core.api.Assertions.*;\n\nimport java.util.concu"
  },
  {
    "path": "vjkit/src/test/java/com/vip/vjtools/vjkit/concurrent/type/ThreadLocalContextTest.java",
    "chars": 1326,
    "preview": "package com.vip.vjtools.vjkit.concurrent.type;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent."
  }
]

// ... and 117 more files (download for full content)

About this extraction

This page contains the full source code of the vipshop/vjtools GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 317 files (1022.4 KB), approximately 319.6k tokens, and a symbol index with 2264 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!