main 055165d101be cached
143 files
200.2 KB
48.3k tokens
571 symbols
1 requests
Download .txt
Showing preview only (240K chars total). Download the full file or copy to clipboard to get everything.
Repository: chuntungho/free-mybatis-plugin
Branch: main
Commit: 055165d101be
Files: 143
Total size: 200.2 KB

Directory structure:
gitextract_isxqlwmr/

├── .gitignore
├── LICENSE
├── README.md
├── build.gradle
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src/
    └── main/
        ├── java/
        │   └── com/
        │       └── wuzhizhan/
        │           └── mybatis/
        │               ├── action/
        │               │   └── MybatisTypedHandler.java
        │               ├── alias/
        │               │   ├── AliasClassReference.java
        │               │   ├── AliasDesc.java
        │               │   ├── AliasFacade.java
        │               │   ├── AliasResolver.java
        │               │   ├── AliasResolverFactory.java
        │               │   ├── AnnotationAliasResolver.java
        │               │   ├── BeanAliasResolver.java
        │               │   ├── ConfigPackageAliasResolver.java
        │               │   ├── InnerAliasResolver.java
        │               │   ├── PackageAliasResolver.java
        │               │   └── SingleAliasResolver.java
        │               ├── annotation/
        │               │   └── Annotation.java
        │               ├── contributor/
        │               │   ├── JavaMenthodCompletionContributor.java
        │               │   ├── SqlParamCompletionContributor.java
        │               │   └── TestParamContributor.java
        │               ├── definitionsearch/
        │               │   └── MapperDefinitionSearch.java
        │               ├── dom/
        │               │   ├── MapperBacktrackingUtils.java
        │               │   ├── converter/
        │               │   │   ├── AliasConverter.java
        │               │   │   ├── ConverterAdaptor.java
        │               │   │   ├── DaoMethodConverter.java
        │               │   │   ├── IdBasedTagConverter.java
        │               │   │   ├── ParameterMapConverter.java
        │               │   │   ├── PropertyConverter.java
        │               │   │   ├── ResultMapConverter.java
        │               │   │   └── SqlConverter.java
        │               │   ├── description/
        │               │   │   ├── ConfigurationDescription.java
        │               │   │   └── MapperDescription.java
        │               │   └── model/
        │               │       ├── Arg.java
        │               │       ├── Association.java
        │               │       ├── Bean.java
        │               │       ├── BeanProperty.java
        │               │       ├── Beans.java
        │               │       ├── Bind.java
        │               │       ├── Cache.java
        │               │       ├── CacheRef.java
        │               │       ├── Case.java
        │               │       ├── Choose.java
        │               │       ├── Collection.java
        │               │       ├── Configuration.java
        │               │       ├── Constructor.java
        │               │       ├── Delete.java
        │               │       ├── Discriminator.java
        │               │       ├── Foreach.java
        │               │       ├── GroupFour.java
        │               │       ├── GroupOne.java
        │               │       ├── GroupThree.java
        │               │       ├── GroupTwo.java
        │               │       ├── Id.java
        │               │       ├── IdArg.java
        │               │       ├── IdDomElement.java
        │               │       ├── If.java
        │               │       ├── Include.java
        │               │       ├── Insert.java
        │               │       ├── Mapper.java
        │               │       ├── Otherwise.java
        │               │       ├── Package.java
        │               │       ├── Parameter.java
        │               │       ├── ParameterMap.java
        │               │       ├── Property.java
        │               │       ├── PropertyGroup.java
        │               │       ├── Result.java
        │               │       ├── ResultMap.java
        │               │       ├── ResultMapGroup.java
        │               │       ├── Select.java
        │               │       ├── SelectKey.java
        │               │       ├── Set.java
        │               │       ├── Sql.java
        │               │       ├── Trim.java
        │               │       ├── TypeAlias.java
        │               │       ├── TypeAliases.java
        │               │       ├── Update.java
        │               │       ├── When.java
        │               │       └── Where.java
        │               ├── generate/
        │               │   ├── DeleteGenerator.java
        │               │   ├── GenerateModel.java
        │               │   ├── InsertGenerator.java
        │               │   ├── SelectGenerator.java
        │               │   ├── StatementGenerator.java
        │               │   └── UpdateGenerator.java
        │               ├── inspection/
        │               │   ├── GenericQuickFix.java
        │               │   ├── MapperInspection.java
        │               │   ├── MapperMethodInspection.java
        │               │   ├── MapperXmlInspection.java
        │               │   ├── ResultTypeQuickFix.java
        │               │   └── StatementNotExistsQuickFix.java
        │               ├── intention/
        │               │   ├── GenerateMapperChooser.java
        │               │   ├── GenerateMapperIntention.java
        │               │   ├── GenerateParamAnnotationIntention.java
        │               │   ├── GenerateParamChooser.java
        │               │   ├── GenerateStatementChooser.java
        │               │   ├── GenerateStatementIntention.java
        │               │   ├── GenericIntention.java
        │               │   ├── IntentionChooser.java
        │               │   └── JavaFileIntentionChooser.java
        │               ├── locator/
        │               │   ├── LocateStrategy.java
        │               │   ├── MapperLocator.java
        │               │   ├── MapperXmlPackageProvider.java
        │               │   ├── PackageLocateStrategy.java
        │               │   └── PackageProvider.java
        │               ├── provider/
        │               │   ├── InjectionLineMarkerProvider.java
        │               │   ├── MapperLineMarkerProvider.java
        │               │   ├── MarkerProviderAdaptor.java
        │               │   ├── SimpleLineMarkerProvider.java
        │               │   └── StatementLineMarkerProvider.java
        │               ├── refactoring/
        │               │   └── MapperRefactoringProvider.java
        │               ├── reference/
        │               │   ├── ContextPsiFieldReference.java
        │               │   ├── ContextReferenceSetResolver.java
        │               │   ├── PsiFieldReferenceSetResolver.java
        │               │   ├── ReferenceSetResolverFactory.java
        │               │   └── ResultPropertyReferenceSet.java
        │               ├── service/
        │               │   ├── AnnotationService.java
        │               │   ├── EditorService.java
        │               │   ├── JavaService.java
        │               │   └── TableInfoService.java
        │               ├── setting/
        │               │   ├── MybatisConfigurable.java
        │               │   ├── MybatisSetting.java
        │               │   ├── MybatisSettingForm.form
        │               │   └── MybatisSettingForm.java
        │               ├── template/
        │               │   └── MybatisFileTemplateDescriptorFactory.java
        │               ├── ui/
        │               │   ├── ClickableListener.java
        │               │   ├── ExecutableListener.java
        │               │   ├── ListSelectionListener.java
        │               │   └── UiComponentFacade.java
        │               └── util/
        │                   ├── ArrayUtils.java
        │                   ├── CollectionUtils.java
        │                   ├── DomUtils.java
        │                   ├── Icons.java
        │                   ├── JTextFieldHintListener.java
        │                   ├── JavaUtils.java
        │                   ├── MapperUtils.java
        │                   ├── MybatisConstants.java
        │                   └── StringUtils.java
        └── resources/
            ├── META-INF/
            │   └── plugin.xml
            ├── fileTemplates/
            │   └── j2ee/
            │       └── Mybatis Mapper.xml.ft
            └── liveTemplates/
                └── sql.xml

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

================================================
FILE: .gitignore
================================================
*.iml

log.roo
.idea/
out/
.DS_Store
.gradle/
gradle/
build/
out/

================================================
FILE: LICENSE
================================================
                                 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 [yyyy] [name of copyright owner]

   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
================================================
# free-mybatis-plugin

## Changes:

- Compatible with Intellij IC edition.
- Not to warn static method or the method with mybatis provider annotation. 
- Remove MyBatis Generator.

================================================
FILE: build.gradle
================================================
buildscript {
    repositories {
        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
        mavenLocal()
        mavenCentral()
    }
}

plugins {
    id 'org.jetbrains.intellij' version '1.2.1'
}

group = 'cn.wuzhizhan.idea.mybatis'
version = '2021.12.09'

apply plugin: 'java'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

buildPlugin {
    buildSearchableOptions.enabled = false
}

intellij {
    version = "IC-2019.1"
    pluginName = 'free-mybatis-plugin'
    sameSinceUntilBuild = false
    patchPluginXml {
        untilBuild = "299.*"
        changeNotes = """
            <ul>
            <li>Fix deprecated api alert</li>
            </ul>
         """
    }
}

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}


================================================
FILE: gradlew
================================================
#!/usr/bin/env sh

#
# Copyright 2015 the original author or authors.
#
# 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
#
#      https://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.
#

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn () {
    echo "$*"
}

die () {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
  NONSTOP* )
    nonstop=true
    ;;
esac

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar


# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`

    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=`expr $i + 1`
    done
    case $i in
        0) set -- ;;
        1) set -- "$args0" ;;
        2) set -- "$args0" "$args1" ;;
        3) set -- "$args0" "$args1" "$args2" ;;
        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Escape application args
save () {
    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
    echo " "
}
APP_ARGS=`save "$@"`

# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"

exec "$JAVACMD" "$@"


================================================
FILE: gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem      https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem

@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar


@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: settings.gradle
================================================
rootProject.name = 'free-mybatis-plugin'



================================================
FILE: src/main/java/com/wuzhizhan/mybatis/action/MybatisTypedHandler.java
================================================
package com.wuzhizhan.mybatis.action;

import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.editorActions.TypedHandlerDelegate;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.wuzhizhan.mybatis.util.DomUtils;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class MybatisTypedHandler extends TypedHandlerDelegate {

    @Override
    public Result checkAutoPopup(char charTyped, final Project project, final Editor editor, PsiFile file) {
        if (charTyped == '.' && DomUtils.isMybatisFile(file)) {
            autoPopupParameter(project, editor);
            return Result.STOP;
        }
        return super.checkAutoPopup(charTyped, project, editor, file);
    }

    @Override
    public Result charTyped(char c, final Project project, @NotNull final Editor editor, @NotNull PsiFile file) {
        int index = editor.getCaretModel().getOffset() - 2;
        PsiFile topLevelFile = InjectedLanguageUtil.getTopLevelFile(file);
        boolean parameterCase = c == '{' &&
                index >= 0 &&
                editor.getDocument().getText().charAt(index) == '#' &&
//                file instanceof SqlFile &&
                DomUtils.isMybatisFile(topLevelFile);
        if (parameterCase) {
            autoPopupParameter(project, editor);
            return Result.STOP;
        }
        return super.charTyped(c, project, editor, file);
    }

    private static void autoPopupParameter(final Project project, final Editor editor) {
        AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, psiFile -> true);
    }


}

================================================
FILE: src/main/java/com/wuzhizhan/mybatis/alias/AliasClassReference.java
================================================
package com.wuzhizhan.mybatis.alias;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReferenceBase;
import com.intellij.psi.xml.XmlAttributeValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;

/**
 * @author yanglin
 */
public class AliasClassReference extends PsiReferenceBase<XmlAttributeValue> {

    private Function<AliasDesc, String> function = new Function<AliasDesc, String>() {
        @Override
        public String apply(AliasDesc input) {
            return input.getAlias();
        }
    };

    public AliasClassReference(@NotNull XmlAttributeValue element) {
        super(element, true);
    }

    @Nullable
    @Override
    public PsiElement resolve() {
        XmlAttributeValue attributeValue = getElement();
        return AliasFacade.getInstance(attributeValue.getProject()).findPsiClass(attributeValue, attributeValue.getValue()).orElse(null);
    }

    @NotNull
    @Override
    public Object[] getVariants() {
        AliasFacade aliasFacade = AliasFacade.getInstance(getElement().getProject());
        Collection<String> result = Collections2.transform(aliasFacade.getAliasDescs(getElement()), function);
        return result.toArray(new String[result.size()]);
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/alias/AliasDesc.java
================================================
package com.wuzhizhan.mybatis.alias;

import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class AliasDesc {

    private PsiClass clazz;

    private String alias;

    public AliasDesc() {
    }

    public static AliasDesc create(@NotNull PsiClass psiClass, @NotNull String alias) {
        return new AliasDesc(psiClass, alias);
    }

    public AliasDesc(PsiClass clazz, String alias) {
        this.clazz = clazz;
        this.alias = alias;
    }

    public PsiClass getClazz() {
        return clazz;
    }

    public void setClazz(PsiClass clazz) {
        this.clazz = clazz;
    }

    public String getAlias() {
        return alias;
    }

    public void setAlias(String alias) {
        this.alias = alias;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        AliasDesc aliasDesc = (AliasDesc) o;

        if (alias != null ? !alias.equalsIgnoreCase(aliasDesc.alias) : aliasDesc.alias != null) {
            return false;
        }
        if (clazz != null ? !clazz.equals(aliasDesc.clazz) : aliasDesc.clazz != null) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        int result = clazz != null ? clazz.hashCode() : 0;
        result = 31 * result + (alias != null ? alias.hashCode() : 0);
        return result;
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/alias/AliasFacade.java
================================================
package com.wuzhizhan.mybatis.alias;

import com.google.common.collect.Lists;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

/**
 * @author yanglin
 */
public class AliasFacade {

    private Project project;

    private JavaPsiFacade javaPsiFacade;

    private List<AliasResolver> resolvers;

    public static final AliasFacade getInstance(@NotNull Project project) {
        return ServiceManager.getService(project, AliasFacade.class);
    }

    public AliasFacade(Project project) {
        this.project = project;
        this.resolvers = Lists.newArrayList();
        this.javaPsiFacade = JavaPsiFacade.getInstance(project);
        initResolvers();
    }

    private void initResolvers() {
        try {
            Class.forName("com.intellij.spring.model.utils.SpringModelUtils");
            this.registerResolver(AliasResolverFactory.createBeanResolver(project));
        } catch (ClassNotFoundException e) {
        }
        this.registerResolver(AliasResolverFactory.createSingleAliasResolver(project));
        this.registerResolver(AliasResolverFactory.createConfigPackageResolver(project));
        this.registerResolver(AliasResolverFactory.createAnnotationResolver(project));
        this.registerResolver(AliasResolverFactory.createInnerAliasResolver(project));
    }

    @NotNull
    public Optional<PsiClass> findPsiClass(@Nullable PsiElement element, @NotNull String shortName) {
        PsiClass clazz = javaPsiFacade.findClass(shortName, GlobalSearchScope.allScope(project));
        if (null != clazz) {
            return Optional.of(clazz);
        }
        for (AliasResolver resolver : resolvers) {
            for (AliasDesc desc : resolver.getClassAliasDescriptions(element)) {
                if (shortName.equalsIgnoreCase(desc.getAlias())) {
                    return Optional.of(desc.getClazz());
                }
            }
        }
        return Optional.empty();
    }

    @NotNull
    public Collection<AliasDesc> getAliasDescs(@Nullable PsiElement element) {
        ArrayList<AliasDesc> result = Lists.newArrayList();
        for (AliasResolver resolver : resolvers) {
            result.addAll(resolver.getClassAliasDescriptions(element));
        }
        return result;
    }

    public Optional<AliasDesc> findAliasDesc(@Nullable PsiClass clazz) {
        if (clazz == null) {
            return Optional.empty();
        }
        for (AliasResolver resolver : resolvers) {
            for (AliasDesc desc : resolver.getClassAliasDescriptions(clazz)) {
                if (clazz.equals(desc.getClazz())) {
                    return Optional.of(desc);
                }
            }
        }
        return Optional.empty();
    }

    public void registerResolver(@NotNull AliasResolver resolver) {
        this.resolvers.add(resolver);
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/alias/AliasResolver.java
================================================
package com.wuzhizhan.mybatis.alias;

import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.wuzhizhan.mybatis.util.JavaUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Optional;
import java.util.Set;

/**
 * @author yanglin
 */
public abstract class AliasResolver {

    protected Project project;

    public AliasResolver(Project project) {
        this.project = project;
    }

    @NotNull
    protected Optional<AliasDesc> addAliasDesc(@NotNull Set<AliasDesc> descs, @Nullable PsiClass clazz, @Nullable String alias) {
        if (null == alias || !JavaUtils.isModelClazz(clazz)) {
            return Optional.empty();
        }
        AliasDesc desc = new AliasDesc();
        descs.add(desc);
        desc.setClazz(clazz);
        desc.setAlias(alias);
        return Optional.of(desc);
    }

    @NotNull
    public abstract Set<AliasDesc> getClassAliasDescriptions(@Nullable PsiElement element);

    public Project getProject() {
        return project;
    }

    public void setProject(Project project) {
        this.project = project;
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/alias/AliasResolverFactory.java
================================================
package com.wuzhizhan.mybatis.alias;

import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class AliasResolverFactory {

    @NotNull
    public static AliasResolver createInnerAliasResolver(@NotNull Project project) {
        return new InnerAliasResolver(project);
    }

    @NotNull
    public static AliasResolver createAnnotationResolver(@NotNull Project project) {
        return new AnnotationAliasResolver(project);
    }

    @NotNull
    public static AliasResolver createBeanResolver(@NotNull Project project) {
        return new BeanAliasResolver(project);
    }

    @NotNull
    public static AliasResolver createConfigPackageResolver(@NotNull Project project) {
        return new ConfigPackageAliasResolver(project);
    }

    @NotNull
    public static AliasResolver createSingleAliasResolver(@NotNull Project project) {
        return new SingleAliasResolver(project);
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/alias/AnnotationAliasResolver.java
================================================
package com.wuzhizhan.mybatis.alias;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.AnnotatedElementsSearch;
import com.wuzhizhan.mybatis.annotation.Annotation;
import com.wuzhizhan.mybatis.util.JavaUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;

/**
 * @author yanglin
 */
public class AnnotationAliasResolver extends AliasResolver {

    private static final Function FUN = new Function<PsiClass, AliasDesc>() {
        @Override
        public AliasDesc apply(PsiClass psiClass) {
            Optional<String> txt = JavaUtils.getAnnotationValueText(psiClass, Annotation.ALIAS);
            if (!txt.isPresent()) return null;
            AliasDesc ad = new AliasDesc();
            ad.setAlias(txt.get());
            ad.setClazz(psiClass);
            return ad;
        }
    };

    public AnnotationAliasResolver(Project project) {
        super(project);
    }

    public static final AnnotationAliasResolver getInstance(@NotNull Project project) {
        return project.getComponent(AnnotationAliasResolver.class);
    }

    @NotNull
    @Override
    public Set<AliasDesc> getClassAliasDescriptions(@Nullable PsiElement element) {
        Optional<PsiClass> clazz = Annotation.ALIAS.toPsiClass(project);
        if (clazz.isPresent()) {
            Collection<PsiClass> res = AnnotatedElementsSearch.searchPsiClasses(clazz.get(), GlobalSearchScope.allScope(project)).findAll();
            return Sets.newHashSet(Collections2.transform(res, FUN));
        }
        return Collections.emptySet();
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/alias/BeanAliasResolver.java
================================================
package com.wuzhizhan.mybatis.alias;

import com.google.common.collect.Sets;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Set;

/**
 * @author yanglin
 */
public class BeanAliasResolver extends PackageAliasResolver {

    private static final String MAPPER_ALIAS_PACKAGE_CLASS = "org.mybatis.spring.SqlSessionFactoryBean";
    private static final String MAPPER_ALIAS_PROPERTY = "typeAliasesPackage";
    private ModuleManager moduleManager;

    public BeanAliasResolver(Project project) {
        super(project);
        this.moduleManager = ModuleManager.getInstance(project);
    }

    @NotNull
    @Override
    public Collection<String> getPackages(@Nullable PsiElement element) {
        Set<String> res = Sets.newHashSet();
//        for (Module module : moduleManager.getModules()) {
//            for (CommonSpringModel springModel : springManager.getCombinedModel(module).getRelatedModels()) {
//                addPackages(res, springModel);
//            }
//        }
        return res;
    }


}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/alias/ConfigPackageAliasResolver.java
================================================
package com.wuzhizhan.mybatis.alias;

import com.google.common.collect.Lists;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.util.Processor;
import com.wuzhizhan.mybatis.dom.model.Package;
import com.wuzhizhan.mybatis.util.MapperUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author yanglin
 */
public class ConfigPackageAliasResolver extends PackageAliasResolver {

    public ConfigPackageAliasResolver(Project project) {
        super(project);
    }

    @NotNull
    @Override
    public Collection<String> getPackages(@Nullable PsiElement element) {
        final ArrayList<String> result = Lists.newArrayList();
        MapperUtils.processConfiguredPackage(project, new Processor<com.wuzhizhan.mybatis.dom.model.Package>() {
            @Override
            public boolean process(Package pkg) {
                result.add(pkg.getName().getStringValue());
                return true;
            }
        });
        return result;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/alias/InnerAliasResolver.java
================================================
package com.wuzhizhan.mybatis.alias;

import com.google.common.collect.ImmutableSet;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.wuzhizhan.mybatis.util.JavaUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Set;

/**
 * @author yanglin
 */
public class InnerAliasResolver extends AliasResolver {

    private final Set<AliasDesc> innerAliasDescs = ImmutableSet.of(
            AliasDesc.create(JavaUtils.findClazz(project, "java.lang.String").get(), "string"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.lang.Byte").get(), "byte"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.lang.Long").get(), "long"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.lang.Short").get(), "short"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.lang.Integer").get(), "int"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.lang.Integer").get(), "integer"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.lang.Double").get(), "double"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.lang.Float").get(), "float"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.lang.Boolean").get(), "boolean"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.util.Date").get(), "date"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.math.BigDecimal").get(), "decimal"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.lang.Object").get(), "object"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.util.Map").get(), "map"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.util.HashMap").get(), "hashmap"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.util.List").get(), "list"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.util.ArrayList").get(), "arraylist"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.util.Collection").get(), "collection"),
            AliasDesc.create(JavaUtils.findClazz(project, "java.util.Iterator").get(), "iterator")
    );

    public InnerAliasResolver(Project project) {
        super(project);
    }

    @NotNull
    @Override
    public Set<AliasDesc> getClassAliasDescriptions(@Nullable PsiElement element) {
        return innerAliasDescs;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/alias/PackageAliasResolver.java
================================================
package com.wuzhizhan.mybatis.alias;

import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Set;

/**
 * @author yanglin
 */
public abstract class PackageAliasResolver extends AliasResolver {

    private JavaPsiFacade javaPsiFacade;

    public PackageAliasResolver(Project project) {
        super(project);
        this.javaPsiFacade = JavaPsiFacade.getInstance(project);
    }

    @NotNull
    @Override
    public Set<AliasDesc> getClassAliasDescriptions(@Nullable PsiElement element) {
        Set<AliasDesc> result = Sets.newHashSet();
        for (String pkgName : getPackages(element)) {
            if (null == pkgName) {
                continue;
            }
            PsiPackage pkg = javaPsiFacade.findPackage(pkgName);
            if (null != pkg) {
                addAliasDesc(result, pkg);
                for (PsiPackage tmp : pkg.getSubPackages()) {
                    addAliasDesc(result, tmp);
                }
            }
        }
        return result;
    }

    private void addAliasDesc(Set<AliasDesc> result, PsiPackage pkg) {
        for (PsiClass clazz : pkg.getClasses()) {
            addAliasDesc(result, clazz, clazz.getName());
        }
    }

    @NotNull
    public abstract Collection<String> getPackages(@Nullable PsiElement element);
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/alias/SingleAliasResolver.java
================================================
package com.wuzhizhan.mybatis.alias;

import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.util.Processor;
import com.wuzhizhan.mybatis.dom.model.TypeAlias;
import com.wuzhizhan.mybatis.util.MapperUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Set;

/**
 * @author yanglin
 */
public class SingleAliasResolver extends AliasResolver {

    public SingleAliasResolver(Project project) {
        super(project);
    }

    @NotNull
    @Override
    public Set<AliasDesc> getClassAliasDescriptions(@Nullable PsiElement element) {
        final Set<AliasDesc> result = Sets.newHashSet();
        MapperUtils.processConfiguredTypeAliases(project, new Processor<TypeAlias>() {
            @Override
            public boolean process(TypeAlias typeAlias) {
                addAliasDesc(result, typeAlias.getType().getValue(), typeAlias.getAlias().getStringValue());
                return true;
            }
        });
        return result;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/annotation/Annotation.java
================================================
package com.wuzhizhan.mybatis.annotation;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;

import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * Simple implementation
 *
 * @author yanglin
 */
public class Annotation implements Cloneable {

    public static final Annotation PARAM = new Annotation("@Param", "org.apache.ibatis.annotations.Param");

    public static final Annotation SELECT = new Annotation("@Select", "org.apache.ibatis.annotations.Select");

    public static final Annotation UPDATE = new Annotation("@Update", "org.apache.ibatis.annotations.Update");

    public static final Annotation INSERT = new Annotation("@Insert", "org.apache.ibatis.annotations.Insert");

    public static final Annotation DELETE = new Annotation("@Delete", "org.apache.ibatis.annotations.Delete");

    public static final Annotation ALIAS = new Annotation("@Alias", "org.apache.ibatis.type.Alias");

    public static final Annotation AUTOWIRED = new Annotation("@Autowired", "org.springframework.beans.factory.annotation.Autowired");

    public static final Annotation RESOURCE = new Annotation("@Resource", "javax.annotation.Resource");

    public static final Annotation SelectProvider = new Annotation("@SelectProvider", "org.apache.ibatis.annotations.SelectProvider");
    public static final Annotation InsertProvider = new Annotation("@InsertProvider", "org.apache.ibatis.annotations.InsertProvider");
    public static final Annotation DeleteProvider = new Annotation("@DeleteProvider", "org.apache.ibatis.annotations.DeleteProvider");
    public static final Annotation UpdateProvider = new Annotation("@UpdateProvider", "org.apache.ibatis.annotations.UpdateProvider");

    public static final Set<Annotation> STATEMENT_SYMMETRIES = ImmutableSet.of(SELECT, UPDATE, INSERT, DELETE,
            SelectProvider, InsertProvider, DeleteProvider, UpdateProvider);

    private final String label;

    private final String qualifiedName;

    private Map<String, AnnotationValue> attributePairs;

    public interface AnnotationValue {
    }

    public static class StringValue implements AnnotationValue {

        private String value;

        public StringValue(@NotNull String value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return "\"" + value + "\"";
        }

    }

    public Annotation(@NotNull String label, @NotNull String qualifiedName) {
        this.label = label;
        this.qualifiedName = qualifiedName;
        attributePairs = Maps.newHashMap();
    }

    private Annotation addAttribute(String key, AnnotationValue value) {
        this.attributePairs.put(key, value);
        return this;
    }

    public Annotation withAttribute(@NotNull String key, @NotNull AnnotationValue value) {
        Annotation copy = this.clone();
        copy.attributePairs = Maps.newHashMap(this.attributePairs);
        return copy.addAttribute(key, value);
    }

    public Annotation withValue(@NotNull AnnotationValue value) {
        return withAttribute("value", value);
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder(label);
        if (!Iterables.isEmpty(attributePairs.entrySet())) {
            builder.append(setupAttributeText());
        }
        return builder.toString();
    }

    private String setupAttributeText() {
        Optional<String> singleValue = getSingleValue();
        return singleValue.isPresent() ? singleValue.get() : getComplexValue();
    }

    private String getComplexValue() {
        StringBuilder builder = new StringBuilder("(");
        for (String key : attributePairs.keySet()) {
            builder.append(key);
            builder.append(" = ");
            builder.append(attributePairs.get(key).toString());
            builder.append(", ");
        }
        builder.deleteCharAt(builder.length() - 1);
        builder.deleteCharAt(builder.length() - 1);
        builder.append(")");
        return builder.toString();
    }

    @NotNull
    public Optional<PsiClass> toPsiClass(@NotNull Project project) {
        return Optional.ofNullable(JavaPsiFacade.getInstance(project).findClass(getQualifiedName(), GlobalSearchScope.allScope(project)));
    }

    private Optional<String> getSingleValue() {
        try {
            String value = Iterables.getOnlyElement(attributePairs.keySet());
            StringBuilder builder = new StringBuilder("(");
            builder.append(attributePairs.get(value).toString());
            builder.append(")");
            return Optional.of(builder.toString());
        } catch (Exception e) {
            return Optional.empty();
        }
    }

    @NotNull
    public String getLabel() {
        return label;
    }

    @NotNull
    public String getQualifiedName() {
        return qualifiedName;
    }

    @Override
    protected Annotation clone() {
        try {
            return (Annotation) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new IllegalStateException();
        }
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/contributor/JavaMenthodCompletionContributor.java
================================================
package com.wuzhizhan.mybatis.contributor;

import com.intellij.codeInsight.completion.CompletionContributor;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.completion.CompletionType;

public class JavaMenthodCompletionContributor extends CompletionContributor {
    @Override
    public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) {
        if (parameters.getCompletionType() != CompletionType.BASIC) {
            return;
        }

        //todo

    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/contributor/SqlParamCompletionContributor.java
================================================
package com.wuzhizhan.mybatis.contributor;

import com.intellij.codeInsight.completion.CompletionContributor;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.injected.editor.DocumentWindow;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.wuzhizhan.mybatis.dom.model.IdDomElement;
import com.wuzhizhan.mybatis.util.DomUtils;
import com.wuzhizhan.mybatis.util.MapperUtils;

import java.util.Optional;


/**
 * @author yanglin
 */
public class SqlParamCompletionContributor extends CompletionContributor {

    @Override
    public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) {
        if (parameters.getCompletionType() != CompletionType.BASIC) {
            return;
        }

        PsiElement position = parameters.getPosition();
        PsiFile topLevelFile = InjectedLanguageUtil.getTopLevelFile(position);
        if (DomUtils.isMybatisFile(topLevelFile)) {
            if (shouldAddElement(position.getContainingFile(), parameters.getOffset())) {
                process(topLevelFile, result, position);
            }
        }
    }

    private void process(PsiFile xmlFile, CompletionResultSet result, PsiElement position) {
        DocumentWindow documentWindow = InjectedLanguageUtil.getDocumentWindow(position);
        if (null != documentWindow) {
            int offset = documentWindow.injectedToHost(position.getTextOffset());
            Optional<IdDomElement> idDomElement = MapperUtils.findParentIdDomElement(xmlFile.findElementAt(offset));
            if (idDomElement.isPresent()) {
                TestParamContributor.addElementForPsiParameter(position.getProject(), result, idDomElement.get());
                result.stopHere();
            }
        }
    }

    private boolean shouldAddElement(PsiFile file, int offset) {
        String text = file.getText();
        for (int i = offset - 1; i > 0; i--) {
            char c = text.charAt(i);
            if (c == '{' && text.charAt(i - 1) == '#') return true;
        }
        return false;
    }
}

================================================
FILE: src/main/java/com/wuzhizhan/mybatis/contributor/TestParamContributor.java
================================================
package com.wuzhizhan.mybatis.contributor;

import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.project.Project;
import com.intellij.patterns.XmlPatterns;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.util.ProcessingContext;
import com.wuzhizhan.mybatis.annotation.Annotation;
import com.wuzhizhan.mybatis.dom.model.IdDomElement;
import com.wuzhizhan.mybatis.util.Icons;
import com.wuzhizhan.mybatis.util.JavaUtils;
import com.wuzhizhan.mybatis.util.MapperUtils;
import com.wuzhizhan.mybatis.util.MybatisConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Optional;

/**
 * @author yanglin
 */
public class TestParamContributor extends CompletionContributor {
    private static final Logger logger = LoggerFactory.getLogger(TestParamContributor.class);

    public TestParamContributor() {
        extend(CompletionType.BASIC,
                XmlPatterns.psiElement()
                        .inside(XmlPatterns.xmlAttributeValue()
                                .inside(XmlPatterns.xmlAttribute().withName("test"))),
                new CompletionProvider<CompletionParameters>() {
                    @Override
                    protected void addCompletions(
                            @NotNull final CompletionParameters parameters,
                            final ProcessingContext context,
                            @NotNull final CompletionResultSet result) {
                        final PsiElement position = parameters.getPosition();
                        addElementForPsiParameter(
                                position.getProject(),
                                result,
                                MapperUtils.findParentIdDomElement(position).orElse(null));
                    }
                });
    }

    static void addElementForPsiParameter(
            @NotNull final Project project,
            @NotNull final CompletionResultSet result,
            @Nullable final IdDomElement element) {
        if (element == null) {
            return;
        }

        final PsiMethod method = JavaUtils.findMethod(project, element).orElse(null);

        if (method == null) {
            logger.info("psiMethod null");
            return;
        }

        final PsiParameter[] parameters = method.getParameterList().getParameters();

        // For a single parameter MyBatis uses its name, while for a multitude they're
        // named as param1, param2, etc. I'll check if the @Param annotation [value] is present
        // and eventually I'll use its text.
        if (parameters.length == 1) {
            final PsiParameter parameter = parameters[0];
            result.addElement(buildLookupElementWithIcon(
                    parameter.getName(),
                    parameter.getType().getPresentableText()));
        } else {
            for (int i = 0; i < parameters.length; i++) {
                final PsiParameter parameter = parameters[i];
                final Optional<String> value = JavaUtils.getAnnotationValueText(parameter, Annotation.PARAM);
                result.addElement(buildLookupElementWithIcon(
                        value.isPresent() ? value.get() : "param" + (i + 1),
                        parameter.getType().getPresentableText()));
            }
        }
    }

    private static LookupElement buildLookupElementWithIcon(
            final String parameterName,
            final String parameterType) {
        return PrioritizedLookupElement.withPriority(
                LookupElementBuilder.create(parameterName)
                        .withTypeText(parameterType)
                        .withIcon(Icons.PARAM_COMPLETION_ICON),
                MybatisConstants.PRIORITY);
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/definitionsearch/MapperDefinitionSearch.java
================================================
package com.wuzhizhan.mybatis.definitionsearch;

import com.intellij.openapi.application.QueryExecutorBase;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiTypeParameterListOwner;
import com.intellij.psi.xml.XmlElement;
import com.intellij.util.Processor;
import com.intellij.util.xml.DomElement;
import com.wuzhizhan.mybatis.service.JavaService;
import org.jetbrains.annotations.NotNull;


/**
 * @author yanglin
 */
public class MapperDefinitionSearch extends QueryExecutorBase<XmlElement, PsiElement> {

    public MapperDefinitionSearch() {
        super(true);
    }

    @Override
    public void processQuery(@NotNull PsiElement queryParameters, @NotNull Processor<? super XmlElement> consumer) {
        if (!(queryParameters instanceof PsiTypeParameterListOwner)) return;

        Processor<DomElement> processor = domElement -> consumer.process(domElement.getXmlElement());

        JavaService.getInstance(queryParameters.getProject()).process(queryParameters, processor);
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/MapperBacktrackingUtils.java
================================================
package com.wuzhizhan.mybatis.dom;

import com.intellij.psi.PsiClass;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomUtil;
import com.wuzhizhan.mybatis.dom.model.Association;
import com.wuzhizhan.mybatis.dom.model.Collection;
import com.wuzhizhan.mybatis.dom.model.ParameterMap;
import com.wuzhizhan.mybatis.dom.model.ResultMap;
import org.jetbrains.annotations.NotNull;

import java.util.Optional;

/**
 * @author yanglin
 */
public final class MapperBacktrackingUtils {

    private MapperBacktrackingUtils() {
        throw new UnsupportedOperationException();
    }

    public static Optional<PsiClass> getPropertyClazz(XmlAttributeValue attributeValue) {
        DomElement domElement = DomUtil.getDomElement(attributeValue);
        if (null == domElement) {
            return Optional.empty();
        }

        Collection collection = DomUtil.getParentOfType(domElement, Collection.class, true);
        if (null != collection && !isWithinSameTag(collection, attributeValue)) {
            return Optional.ofNullable(collection.getOfType().getValue());
        }

        Association association = DomUtil.getParentOfType(domElement, Association.class, true);
        if (null != association && !isWithinSameTag(association, attributeValue)) {
            return Optional.ofNullable(association.getJavaType().getValue());
        }

        ParameterMap parameterMap = DomUtil.getParentOfType(domElement, ParameterMap.class, true);
        if (null != parameterMap && !isWithinSameTag(parameterMap, attributeValue)) {
            return Optional.ofNullable(parameterMap.getType().getValue());
        }

        ResultMap resultMap = DomUtil.getParentOfType(domElement, ResultMap.class, true);
        if (null != resultMap && !isWithinSameTag(resultMap, attributeValue)) {
            return Optional.ofNullable(resultMap.getType().getValue());
        }
        return Optional.empty();
    }

    public static boolean isWithinSameTag(@NotNull DomElement domElement, @NotNull XmlElement xmlElement) {
        XmlTag xmlTag = PsiTreeUtil.getParentOfType(xmlElement, XmlTag.class);
        return null != xmlElement && domElement.getXmlTag().equals(xmlTag);
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/AliasConverter.java
================================================
package com.wuzhizhan.mybatis.dom.converter;

import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.xml.*;
import com.wuzhizhan.mybatis.alias.AliasClassReference;
import com.wuzhizhan.mybatis.alias.AliasFacade;
import com.wuzhizhan.mybatis.util.MybatisConstants;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * @author yanglin
 */
public class AliasConverter extends ConverterAdaptor<PsiClass> implements CustomReferenceConverter<PsiClass> {

    private PsiClassConverter delegate = new PsiClassConverter();

    @Nullable
    @Override
    public PsiClass fromString(@Nullable @NonNls String s, ConvertContext context) {
        if (StringUtil.isEmptyOrSpaces(s)) return null;
        if (!s.contains(MybatisConstants.DOT_SEPARATOR)) {
            return AliasFacade.getInstance(context.getProject()).findPsiClass(context.getXmlElement(), s).orElse(null);
        }
        return DomJavaUtil.findClass(s.trim(), context.getFile(), context.getModule(), GlobalSearchScope.allScope(context.getProject()));
    }

    @Nullable
    @Override
    public String toString(@Nullable PsiClass psiClass, ConvertContext context) {
        return delegate.toString(psiClass, context);
    }

    @NotNull
    @Override
    public PsiReference[] createReferences(GenericDomValue<PsiClass> value, PsiElement element, ConvertContext context) {
        if (((XmlAttributeValue) element).getValue().contains(MybatisConstants.DOT_SEPARATOR)) {
            return delegate.createReferences(value, element, context);
        } else {
            return new PsiReference[]{new AliasClassReference((XmlAttributeValue) element)};
        }
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/ConverterAdaptor.java
================================================
package com.wuzhizhan.mybatis.dom.converter;

import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.ResolvingConverter;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Collections;

/**
 * @author yanglin
 */
public abstract class ConverterAdaptor<T> extends ResolvingConverter<T> {

    @NotNull
    @Override
    public Collection<? extends T> getVariants(ConvertContext context) {
        return Collections.emptyList();
    }

    @Nullable
    @Override
    public String toString(@Nullable T t, ConvertContext context) {
//    throw new UnsupportedOperationException();
        return null;
    }

    @Nullable
    @Override
    public T fromString(@Nullable @NonNls String s, ConvertContext context) {
        return null;
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/DaoMethodConverter.java
================================================
package com.wuzhizhan.mybatis.dom.converter;

import com.intellij.psi.PsiMethod;
import com.intellij.util.xml.ConvertContext;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import com.wuzhizhan.mybatis.util.JavaUtils;
import com.wuzhizhan.mybatis.util.MapperUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;

/**
 * @author yanglin
 */
public class DaoMethodConverter extends ConverterAdaptor<PsiMethod> {

    @Nullable
    @Override
    public PsiMethod fromString(@Nullable @NonNls String id, ConvertContext context) {
        Mapper mapper = MapperUtils.getMapper(context.getInvocationElement());
        return JavaUtils.findMethod(context.getProject(), MapperUtils.getNamespace(mapper), id).orElse(null);
    }

}

================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/IdBasedTagConverter.java
================================================
package com.wuzhizhan.mybatis.dom.converter;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceBase;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.xml.*;
import com.wuzhizhan.mybatis.dom.model.IdDomElement;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import com.wuzhizhan.mybatis.util.MapperUtils;
import com.wuzhizhan.mybatis.util.MybatisConstants;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;

/**
 * @author yanglin
 */
public abstract class IdBasedTagConverter extends ConverterAdaptor<XmlAttributeValue> implements CustomReferenceConverter<XmlAttributeValue> {

    private final boolean crossMapperSupported;

    public IdBasedTagConverter() {
        this(true);
    }

    protected IdBasedTagConverter(boolean crossMapperSupported) {
        this.crossMapperSupported = crossMapperSupported;
    }

    @Nullable
    @Override
    public XmlAttributeValue fromString(@Nullable @NonNls String value, ConvertContext context) {
        return matchIdDomElement(selectStrategy(context).getValue(), value, context).orElse(null);
    }

    @NotNull
    private Optional<XmlAttributeValue> matchIdDomElement(Collection<? extends IdDomElement> idDomElements, String value, ConvertContext context) {
        Mapper contextMapper = MapperUtils.getMapper(context.getInvocationElement());
        for (IdDomElement idDomElement : idDomElements) {
            if (MapperUtils.getIdSignature(idDomElement).equals(value) ||
                    MapperUtils.getIdSignature(idDomElement, contextMapper).equals(value)) {
                return Optional.of(idDomElement.getId().getXmlAttributeValue());
            }
        }
        return Optional.empty();
    }

    @Nullable
    @Override
    public String toString(@Nullable XmlAttributeValue xmlAttribute, ConvertContext context) {
        DomElement domElement = DomUtil.getDomElement(xmlAttribute.getParent().getParent());
        if (!(domElement instanceof IdDomElement)) {
            return null;
        }
        Mapper contextMapper = MapperUtils.getMapper(context.getInvocationElement());
        return MapperUtils.getIdSignature((IdDomElement) domElement, contextMapper);
    }

    private TraverseStrategy selectStrategy(ConvertContext context) {
        return crossMapperSupported ? new CrossMapperStrategy(context) : new InsideMapperStrategy(context);
    }

    /**
     * @param mapper  mapper in the project, null if {@link #crossMapperSupported} is false
     * @param context the dom convert context
     */
    @NotNull
    public abstract Collection<? extends IdDomElement> getComparisons(@Nullable Mapper mapper, ConvertContext context);

    private abstract class TraverseStrategy {
        protected ConvertContext context;

        public TraverseStrategy(@NotNull ConvertContext context) {
            this.context = context;
        }

        public abstract Collection<? extends IdDomElement> getValue();
    }

    private class InsideMapperStrategy extends TraverseStrategy {

        public InsideMapperStrategy(@NotNull ConvertContext context) {
            super(context);
        }

        @Override
        public Collection<? extends IdDomElement> getValue() {
            return getComparisons(null, context);
        }

    }

    private class CrossMapperStrategy extends TraverseStrategy {

        public CrossMapperStrategy(@NotNull ConvertContext context) {
            super(context);
        }

        @Override
        public Collection<? extends IdDomElement> getValue() {
            List<IdDomElement> result = Lists.newArrayList();
            for (Mapper mapper : MapperUtils.findMappers(context.getProject())) {
                result.addAll(getComparisons(mapper, context));
            }
            return result;
        }

    }

    @NotNull
    @Override
    public PsiReference[] createReferences(GenericDomValue<XmlAttributeValue> value, PsiElement element, ConvertContext context) {
        return PsiClassConverter.createJavaClassReferenceProvider(value, null, new ValueReferenceProvider(context)).getReferencesByElement(element);
    }

    private class ValueReferenceProvider extends JavaClassReferenceProvider {

        private ConvertContext context;

        private ValueReferenceProvider(ConvertContext context) {
            this.context = context;
        }

        @Nullable
        @Override
        public GlobalSearchScope getScope(Project project) {
            return GlobalSearchScope.allScope(project);
        }

        /**
         * It looks like hacking here, as it's a little hard to handle so many different cases as JetBrains does
         */
        @NotNull
        @Override
        public PsiReference[] getReferencesByString(String text, @NotNull PsiElement position, int offsetInPosition) {
            List<PsiReference> refs = Lists.newArrayList(super.getReferencesByString(text, position, offsetInPosition));
            ValueReference vr = new ValueReference(position, getTextRange(position), context, text);
            if (!refs.isEmpty() && 0 != vr.getVariants().length) {
                refs.remove(refs.size() - 1);
                refs.add(vr);
            }
            return refs.toArray(new PsiReference[refs.size()]);
        }

        private TextRange getTextRange(PsiElement element) {
            String text = element.getText();
            int index = text.lastIndexOf(MybatisConstants.DOT_SEPARATOR);
            return -1 == index ? ElementManipulators.getValueTextRange(element) : TextRange.create(text.substring(0, index).length() + 1, text.length() - 1);
        }
    }

    private class ValueReference extends PsiReferenceBase<PsiElement> {

        private ConvertContext context;
        private String text;

        public ValueReference(@NotNull PsiElement element, TextRange rng, ConvertContext context, String text) {
            super(element, rng, false);
            this.context = context;
            this.text = text;
        }

        @Nullable
        @Override
        public PsiElement resolve() {
            return IdBasedTagConverter.this.fromString(text, context);
        }

        @NotNull
        @Override
        public Object[] getVariants() {
            Set<String> res = getElement().getText().contains(MybatisConstants.DOT_SEPARATOR) ? setupContextIdSignature() : setupGlobalIdSignature();
            return res.toArray(new String[res.size()]);
        }

        private Set<String> setupContextIdSignature() {
            Set<String> res = Sets.newHashSet();
            String ns = text.substring(0, text.lastIndexOf(MybatisConstants.DOT_SEPARATOR));
            for (IdDomElement ele : selectStrategy(context).getValue()) {
                if (MapperUtils.getNamespace(ele).equals(ns)) {
                    res.add(MapperUtils.getId(ele));
                }
            }
            return res;
        }

        private Set<String> setupGlobalIdSignature() {
            Mapper contextMapper = MapperUtils.getMapper(context.getInvocationElement());
            Collection<? extends IdDomElement> idDomElements = selectStrategy(context).getValue();
            Set<String> res = new HashSet<String>(idDomElements.size());
            for (IdDomElement ele : idDomElements) {
                res.add(MapperUtils.getIdSignature(ele, contextMapper));
            }
            return res;
        }

    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/ParameterMapConverter.java
================================================
package com.wuzhizhan.mybatis.dom.converter;

import com.intellij.util.xml.ConvertContext;
import com.wuzhizhan.mybatis.dom.model.IdDomElement;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;

/**
 * @author yanglin
 */
public class ParameterMapConverter extends IdBasedTagConverter {

    @NotNull
    @Override
    public Collection<? extends IdDomElement> getComparisons(@Nullable Mapper mapper,
                                                             ConvertContext context) {
        return mapper.getParameterMaps();
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/PropertyConverter.java
================================================
package com.wuzhizhan.mybatis.dom.converter;

import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.xml.*;
import com.wuzhizhan.mybatis.reference.ResultPropertyReferenceSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * @author yanglin
 */
public class PropertyConverter extends ConverterAdaptor<XmlAttributeValue> implements CustomReferenceConverter<XmlAttributeValue> {

    @NotNull
    @Override
    public PsiReference[] createReferences(GenericDomValue<XmlAttributeValue> value, PsiElement element, ConvertContext context) {
        final String s = value.getStringValue();
        if (s == null) {
            return PsiReference.EMPTY_ARRAY;
        }
        return new ResultPropertyReferenceSet(s, element, ElementManipulators.getOffsetInElement(element)).getPsiReferences();
    }

    @Nullable
    @Override
    public XmlAttributeValue fromString(@Nullable @NonNls String s, ConvertContext context) {
        DomElement ctxElement = context.getInvocationElement();
        return ctxElement instanceof GenericAttributeValue ? ((GenericAttributeValue) ctxElement).getXmlAttributeValue() : null;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/ResultMapConverter.java
================================================
package com.wuzhizhan.mybatis.dom.converter;

import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.DomElement;
import com.wuzhizhan.mybatis.dom.model.IdDomElement;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import com.wuzhizhan.mybatis.dom.model.ResultMap;
import com.wuzhizhan.mybatis.util.MapperUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;

/**
 * @author yanglin
 */
public class ResultMapConverter extends IdBasedTagConverter {

    @NotNull
    @Override
    public Collection<? extends IdDomElement> getComparisons(@Nullable Mapper mapper, ConvertContext context) {
        DomElement invocationElement = context.getInvocationElement();
        if (isContextElementOfResultMap(mapper, invocationElement)) {
            return doFilterResultMapItself(mapper, (ResultMap) invocationElement.getParent());
        } else {
            return mapper.getResultMaps();
        }
    }

    private boolean isContextElementOfResultMap(Mapper mapper, DomElement invocationElement) {
        return MapperUtils.isMapperWithSameNamespace(MapperUtils.getMapper(invocationElement), mapper)
                && invocationElement.getParent() instanceof ResultMap;
    }

    private Collection<? extends IdDomElement> doFilterResultMapItself(Mapper mapper, final ResultMap resultMap) {
        return Collections2.filter(mapper.getResultMaps(), new Predicate<ResultMap>() {
            @Override
            public boolean apply(ResultMap input) {
                return !MapperUtils.getId(input).equals(MapperUtils.getId(resultMap));
            }
        });
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/SqlConverter.java
================================================
package com.wuzhizhan.mybatis.dom.converter;

import com.intellij.util.xml.ConvertContext;
import com.wuzhizhan.mybatis.dom.model.IdDomElement;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;

/**
 * @author yanglin
 */
public class SqlConverter extends IdBasedTagConverter {

    @NotNull
    @Override
    public Collection<? extends IdDomElement> getComparisons(@Nullable Mapper mapper, ConvertContext context) {
        return mapper.getSqls();
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/description/ConfigurationDescription.java
================================================
package com.wuzhizhan.mybatis.dom.description;

import com.intellij.openapi.module.Module;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.xml.DomFileDescription;
import com.wuzhizhan.mybatis.dom.model.Configuration;
import com.wuzhizhan.mybatis.util.DomUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * @author yanglin
 */
public class ConfigurationDescription extends DomFileDescription<Configuration> {

    public ConfigurationDescription() {
        super(Configuration.class, "configuration");
    }

    @Override
    public boolean isMyFile(@NotNull XmlFile file, @Nullable Module module) {
        return DomUtils.isMybatisConfigurationFile(file);
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/description/MapperDescription.java
================================================
package com.wuzhizhan.mybatis.dom.description;

import com.intellij.openapi.module.Module;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.xml.DomFileDescription;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import com.wuzhizhan.mybatis.util.DomUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * @author yanglin
 */
public class MapperDescription extends DomFileDescription<Mapper> {

    public MapperDescription() {
        super(Mapper.class, "mapper");
    }

    @Override
    public boolean isMyFile(@NotNull XmlFile file, @Nullable Module module) {
        return DomUtils.isMybatisFile(file);
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Arg.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;

/**
 * @author yanglin
 */
public interface Arg extends DomElement {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Association.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.psi.PsiClass;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.GenericAttributeValue;
import com.wuzhizhan.mybatis.dom.converter.AliasConverter;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public interface Association extends GroupFour, ResultMapGroup, PropertyGroup {

    @NotNull
    @Attribute("javaType")
    @Convert(AliasConverter.class)
    public GenericAttributeValue<PsiClass> getJavaType();
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Bean.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.SubTagList;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @author yanglin
 */
public interface Bean extends DomElement {

    @NotNull
    @SubTagList("property")
    public List<BeanProperty> getBeanProperties();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/BeanProperty.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.GenericAttributeValue;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public interface BeanProperty extends DomElement {

    @NotNull
    @Attribute("name")
    public GenericAttributeValue<String> getName();

    @NotNull
    @Attribute("value")
    public GenericAttributeValue<String> getValue();
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Beans.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.SubTagList;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @author yanglin
 */
public interface Beans extends DomElement {

    @NotNull
    @SubTagList("bean")
    public List<Bean> getBeans();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Bind.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;

/**
 * @author yanglin
 */
public interface Bind extends DomElement {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Cache.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.SubTagList;

import java.util.List;

/**
 * @author yanglin
 */
public interface Cache extends DomElement {

    @SubTagList("property")
    public List<Property> getProperties();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/CacheRef.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;

/**
 * @author yanglin
 */
public interface CacheRef extends DomElement {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Case.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Case extends GroupFour {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Choose.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.Required;
import com.intellij.util.xml.SubTag;
import com.intellij.util.xml.SubTagList;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @author yanglin
 */
public interface Choose extends DomElement {

    @NotNull
    @Required
    @SubTagList("when")
    public List<When> getWhens();

    @SubTag("otherwise")
    public Otherwise getOtherwise();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Collection.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.psi.PsiClass;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.GenericAttributeValue;
import com.wuzhizhan.mybatis.dom.converter.AliasConverter;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public interface Collection extends GroupFour, ResultMapGroup, PropertyGroup {

    @NotNull
    @Attribute("ofType")
    @Convert(AliasConverter.class)
    public GenericAttributeValue<PsiClass> getOfType();

}

================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Configuration.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.SubTagList;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @author yanglin
 */
public interface Configuration extends DomElement {

    @NotNull
    @SubTagList("typeAliases")
    public List<TypeAliases> getTypeAliases();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Constructor.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.SubTagList;

import java.util.List;

/**
 * @author yanglin
 */
public interface Constructor extends DomElement {

    @SubTagList("arg")
    public List<Arg> getArgs();

    @SubTagList("idArg")
    public List<IdArg> getIdArgs();
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Delete.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Delete extends GroupTwo {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Discriminator.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.Required;
import com.intellij.util.xml.SubTagList;

import java.util.List;

/**
 * @author yanglin
 */
public interface Discriminator extends DomElement {

    @Required
    @SubTagList("case")
    public List<Case> getCases();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Foreach.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Foreach extends GroupOne {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/GroupFour.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.SubTag;
import com.intellij.util.xml.SubTagList;

import java.util.List;

/**
 * @author yanglin
 */
public interface GroupFour extends DomElement {

    @SubTag("constructor")
    public Constructor getConstructor();

    @SubTagList("id")
    public List<Id> getIds();

    @SubTagList("result")
    public List<Result> getResults();

    @SubTagList("association")
    public List<Association> getAssociations();

    @SubTagList("collection")
    public List<Collection> getCollections();

    @SubTag("discriminator")
    public Discriminator getDiscriminator();
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/GroupOne.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.SubTagList;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @author yanglin
 */
public interface GroupOne extends DomElement {

    @NotNull
    @SubTagList("include")
    public List<Include> getIncludes();

    @NotNull
    @SubTagList("trim")
    public List<Trim> getTrims();

    @NotNull
    @SubTagList("where")
    public List<Where> getWheres();

    @NotNull
    @SubTagList("set")
    public List<Set> getSets();

    @NotNull
    @SubTagList("foreach")
    public List<Foreach> getForeachs();

    @NotNull
    @SubTagList("choose")
    public List<Choose> getChooses();

    @NotNull
    @SubTagList("if")
    public List<If> getIfs();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/GroupThree.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.SubTagList;

import java.util.List;

/**
 * @author yanglin
 */
public interface GroupThree extends GroupTwo {

    @SubTagList("selectKey")
    public List<SelectKey> getSelectKey();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/GroupTwo.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.psi.PsiClass;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.GenericAttributeValue;
import com.intellij.util.xml.SubTagList;
import com.wuzhizhan.mybatis.dom.converter.AliasConverter;
import com.wuzhizhan.mybatis.dom.converter.DaoMethodConverter;
import com.wuzhizhan.mybatis.dom.converter.ParameterMapConverter;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @author yanglin
 */
public interface GroupTwo extends GroupOne, IdDomElement {

    @SubTagList("bind")
    public List<Bind> getBinds();

    @NotNull
    @Attribute("parameterMap")
    @Convert(ParameterMapConverter.class)
    public GenericAttributeValue<XmlTag> getParameterMap();

    @Attribute("id")
    @Convert(DaoMethodConverter.class)
    public GenericAttributeValue<String> getId();

    @NotNull
    @Attribute("parameterType")
    @Convert(AliasConverter.class)
    public GenericAttributeValue<PsiClass> getParameterType();
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Id.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Id extends PropertyGroup {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/IdArg.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;

/**
 * @author yanglin
 */
public interface IdArg extends DomElement {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/IdDomElement.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.*;

/**
 * @author yanglin
 */
public interface IdDomElement extends DomElement {

    @Required
    @NameValue
    @Attribute("id")
    public GenericAttributeValue<String> getId();

    public void setValue(String content);
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/If.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface If extends GroupOne {
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Include.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.psi.xml.XmlTag;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.GenericAttributeValue;
import com.wuzhizhan.mybatis.dom.converter.SqlConverter;

/**
 * @author yanglin
 */
public interface Include extends DomElement {

    @Attribute("refid")
    @Convert(SqlConverter.class)
    public GenericAttributeValue<XmlTag> getRefId();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Insert.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Insert extends GroupThree {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Mapper.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.*;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @author yanglin
 */
public interface Mapper extends DomElement {

    @NotNull
    @SubTagsList({"insert", "update", "delete", "select"})
    public List<IdDomElement> getDaoElements();

    @Required
    @NameValue
    @NotNull
    @Attribute("namespace")
    public GenericAttributeValue<String> getNamespace();

    @NotNull
    @SubTagList("resultMap")
    public List<ResultMap> getResultMaps();

    @NotNull
    @SubTagList("parameterMap")
    public List<ParameterMap> getParameterMaps();

    @NotNull
    @SubTagList("sql")
    public List<Sql> getSqls();

    @NotNull
    @SubTagList("insert")
    public List<Insert> getInserts();

    @NotNull
    @SubTagList("update")
    public List<Update> getUpdates();

    @NotNull
    @SubTagList("delete")
    public List<Delete> getDeletes();

    @NotNull
    @SubTagList("select")
    public List<Select> getSelects();

    @SubTagList("select")
    public Select addSelect();

    @SubTagList("update")
    public Update addUpdate();

    @SubTagList("insert")
    public Insert addInsert();

    @SubTagList("delete")
    public Delete addDelete();
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Otherwise.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Otherwise extends GroupOne {
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Package.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.GenericAttributeValue;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public interface Package extends DomElement {

    @NotNull
    @Attribute("name")
    public GenericAttributeValue<String> getName();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Parameter.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Parameter extends PropertyGroup {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/ParameterMap.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.psi.PsiClass;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.GenericAttributeValue;
import com.intellij.util.xml.SubTagList;
import com.wuzhizhan.mybatis.dom.converter.AliasConverter;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @author yanglin
 */
public interface ParameterMap extends IdDomElement {

    @NotNull
    @Attribute("type")
    @Convert(AliasConverter.class)
    public GenericAttributeValue<PsiClass> getType();

    @SubTagList("parameter")
    public List<Parameter> getParameters();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Property.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;

/**
 * @author yanglin
 */
public interface Property extends DomElement {
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/PropertyGroup.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.GenericAttributeValue;
import com.wuzhizhan.mybatis.dom.converter.PropertyConverter;

/**
 * @author yanglin
 */
public interface PropertyGroup extends DomElement {

    @Attribute("property")
    @Convert(PropertyConverter.class)
    GenericAttributeValue<XmlAttributeValue> getProperty();
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Result.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Result extends PropertyGroup {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/ResultMap.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.psi.PsiClass;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.GenericAttributeValue;
import com.wuzhizhan.mybatis.dom.converter.AliasConverter;
import com.wuzhizhan.mybatis.dom.converter.ResultMapConverter;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public interface ResultMap extends GroupFour, IdDomElement {

    @NotNull
    @Attribute("extends")
    @Convert(ResultMapConverter.class)
    public GenericAttributeValue<XmlAttributeValue> getExtends();

    @NotNull
    @Attribute("type")
    @Convert(AliasConverter.class)
    public GenericAttributeValue<PsiClass> getType();

}

================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/ResultMapGroup.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.psi.xml.XmlTag;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.GenericAttributeValue;
import com.wuzhizhan.mybatis.dom.converter.ResultMapConverter;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public interface ResultMapGroup extends DomElement {

    @NotNull
    @Attribute("resultMap")
    @Convert(ResultMapConverter.class)
    public GenericAttributeValue<XmlTag> getResultMap();
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Select.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.psi.PsiClass;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.GenericAttributeValue;
import com.wuzhizhan.mybatis.dom.converter.AliasConverter;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public interface Select extends GroupTwo, ResultMapGroup {

    @NotNull
    @Attribute("resultType")
    @Convert(AliasConverter.class)
    public GenericAttributeValue<PsiClass> getResultType();
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/SelectKey.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.psi.PsiClass;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.GenericAttributeValue;
import com.wuzhizhan.mybatis.dom.converter.AliasConverter;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public interface SelectKey extends GroupOne {
    @NotNull
    @Attribute("resultType")
    @Convert(AliasConverter.class)
    GenericAttributeValue<PsiClass> getResultType();
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Set.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Set extends GroupOne {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Sql.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Sql extends GroupOne, IdDomElement {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Trim.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Trim extends GroupOne {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/TypeAlias.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.psi.PsiClass;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.GenericAttributeValue;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public interface TypeAlias extends DomElement {

    @NotNull
    @Attribute("type")
    public GenericAttributeValue<PsiClass> getType();

    @NotNull
    @Attribute("alias")
    public GenericAttributeValue<String> getAlias();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/TypeAliases.java
================================================
package com.wuzhizhan.mybatis.dom.model;

import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.SubTagList;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @author yanglin
 */
public interface TypeAliases extends DomElement {

    @NotNull
    @SubTagList("typeAlias")
    public List<TypeAlias> getTypeAlias();

    @NotNull
    @SubTagList("package")
    public List<Package> getPackages();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Update.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Update extends GroupTwo {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/When.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface When extends GroupOne {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Where.java
================================================
package com.wuzhizhan.mybatis.dom.model;

/**
 * @author yanglin
 */
public interface Where extends GroupOne {

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/generate/DeleteGenerator.java
================================================
package com.wuzhizhan.mybatis.generate;

import com.intellij.psi.PsiMethod;
import com.wuzhizhan.mybatis.dom.model.GroupTwo;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class DeleteGenerator extends StatementGenerator {

    public DeleteGenerator(@NotNull String... patterns) {
        super(patterns);
    }

    @NotNull
    @Override
    protected GroupTwo getTarget(@NotNull Mapper mapper, @NotNull PsiMethod method) {
        return mapper.addDelete();
    }

    @NotNull
    @Override
    public String getId() {
        return "DeleteGenerator";
    }

    @NotNull
    @Override
    public String getDisplayText() {
        return "Delete Statement";
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/generate/GenerateModel.java
================================================
package com.wuzhizhan.mybatis.generate;

import java.util.Collection;

/**
 * @author yanglin
 */
public abstract class GenerateModel {

    public static final GenerateModel START_WITH_MODEL = new StartWithModel();

    public static final GenerateModel END_WITH_MODEL = new EndWithModel();

    public static final GenerateModel CONTAIN_MODEL = new ContainModel();

    public static GenerateModel getInstance(String identifier) {
        try {
            return getInstance(Integer.valueOf(identifier));
        } catch (Exception e) {
            return START_WITH_MODEL;
        }
    }

    public static GenerateModel getInstance(int identifier) {
        switch (identifier) {
            case 0:
                return START_WITH_MODEL;
            case 1:
                return END_WITH_MODEL;
            case 2:
                return CONTAIN_MODEL;
            default:
                throw new AssertionError();
        }
    }

    public boolean matchesAny(String[] patterns, String target) {
        for (String pattern : patterns) {
            if (apply(pattern, target)) {
                return true;
            }
        }
        return false;
    }

    public boolean matchesAny(Collection<String> patterns, String target) {
        return matchesAny(patterns.toArray(new String[patterns.size()]), target);
    }

    protected abstract boolean apply(String pattern, String target);

    public abstract int getIdentifier();

    static class StartWithModel extends GenerateModel {

        @Override
        protected boolean apply(String pattern, String target) {
            return target.startsWith(pattern);
        }

        @Override
        public int getIdentifier() {
            return 0;
        }
    }

    static class EndWithModel extends GenerateModel {

        @Override
        protected boolean apply(String pattern, String target) {
            return target.endsWith(pattern);
        }

        @Override
        public int getIdentifier() {
            return 1;
        }
    }

    static class ContainModel extends GenerateModel {

        @Override
        protected boolean apply(String pattern, String target) {
            return target.contains(pattern);
        }

        @Override
        public int getIdentifier() {
            return 2;
        }
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/generate/InsertGenerator.java
================================================
package com.wuzhizhan.mybatis.generate;

import com.intellij.psi.PsiMethod;
import com.wuzhizhan.mybatis.dom.model.GroupTwo;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class InsertGenerator extends StatementGenerator {

    public InsertGenerator(@NotNull String... patterns) {
        super(patterns);
    }

    @NotNull
    @Override
    protected GroupTwo getTarget(@NotNull Mapper mapper, @NotNull PsiMethod method) {
        return mapper.addInsert();
    }

    @NotNull
    @Override
    public String getId() {
        return "InsertGenerator";
    }

    @NotNull
    @Override
    public String getDisplayText() {
        return "Insert Statement";
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/generate/SelectGenerator.java
================================================
package com.wuzhizhan.mybatis.generate;

import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.wuzhizhan.mybatis.dom.model.GroupTwo;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import com.wuzhizhan.mybatis.dom.model.Select;
import org.jetbrains.annotations.NotNull;

import java.util.Optional;

/**
 * @author yanglin
 */
public class SelectGenerator extends StatementGenerator {

    public SelectGenerator(@NotNull String... patterns) {
        super(patterns);
    }

    @NotNull
    @Override
    protected GroupTwo getTarget(@NotNull Mapper mapper, @NotNull PsiMethod method) {
        Select select = mapper.addSelect();
        setupResultType(method, select);
        return select;
    }

    private void setupResultType(PsiMethod method, Select select) {
        Optional<PsiClass> clazz = StatementGenerator.getSelectResultType(method);
        if (clazz.isPresent()) {
            select.getResultType().setValue(clazz.get());
        }
    }

    @NotNull
    @Override
    public String getId() {
        return "SelectGenerator";
    }

    @NotNull
    @Override
    public String getDisplayText() {
        return "Select Statement";
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/generate/StatementGenerator.java
================================================
package com.wuzhizhan.mybatis.generate;

import com.google.common.base.Function;
import com.google.common.collect.*;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.CommonProcessors.CollectProcessor;
import com.wuzhizhan.mybatis.dom.model.GroupTwo;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import com.wuzhizhan.mybatis.service.EditorService;
import com.wuzhizhan.mybatis.service.JavaService;
import com.wuzhizhan.mybatis.setting.MybatisSetting;
import com.wuzhizhan.mybatis.ui.ListSelectionListener;
import com.wuzhizhan.mybatis.ui.UiComponentFacade;
import com.wuzhizhan.mybatis.util.CollectionUtils;
import com.wuzhizhan.mybatis.util.JavaUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * @author yanglin
 */
public abstract class StatementGenerator {

    public static final StatementGenerator UPDATE_GENERATOR = new UpdateGenerator("update", "modify", "set");

    public static final StatementGenerator SELECT_GENERATOR = new SelectGenerator("select", "get", "look", "find", "list", "search", "count", "query");

    public static final StatementGenerator DELETE_GENERATOR = new DeleteGenerator("del", "cancel");

    public static final StatementGenerator INSERT_GENERATOR = new InsertGenerator("insert", "add", "new");

    public static final Set<StatementGenerator> ALL = ImmutableSet.of(UPDATE_GENERATOR, SELECT_GENERATOR, DELETE_GENERATOR, INSERT_GENERATOR);

    private static final Function<Mapper, String> FUN = new Function<Mapper, String>() {
        @Override
        public String apply(Mapper mapper) {
            VirtualFile vf = mapper.getXmlTag().getContainingFile().getVirtualFile();
            if (null == vf) return "";
            return vf.getCanonicalPath();
        }
    };

    public static Optional<PsiClass> getSelectResultType(@Nullable PsiMethod method) {
        if (null == method) {
            return Optional.empty();
        }
        PsiType returnType = method.getReturnType();
        if (returnType instanceof PsiPrimitiveType && returnType != PsiType.VOID) {
            return JavaUtils.findClazz(method.getProject(), ((PsiPrimitiveType) returnType).getBoxedTypeName());
        } else if (returnType instanceof PsiClassReferenceType) {
            PsiClassReferenceType type = (PsiClassReferenceType) returnType;
            if (type.hasParameters()) {
                PsiType[] parameters = type.getParameters();
                if (parameters.length == 1) {
                    type = (PsiClassReferenceType) parameters[0];
                }
            }
            return Optional.ofNullable(type.resolve());
        }
        return Optional.empty();
    }

    private static void doGenerate(@NotNull final StatementGenerator generator, @NotNull final PsiMethod method) {
        (new WriteCommandAction.Simple(method.getProject(), new PsiFile[]{method.getContainingFile()}) {
            protected void run() throws Throwable {
                generator.execute(method);
            }
        }).execute();
    }

    public static void applyGenerate(@Nullable final PsiMethod method) {
        if (null == method) return;
        final Project project = method.getProject();
        final Object[] generators = getGenerators(method);
        if (1 == generators.length) {
            ((StatementGenerator) generators[0]).execute(method);
        } else {
            JBPopupFactory.getInstance().createListPopup(
                    new BaseListPopupStep("[ Statement type for method: " + method.getName() + "]", generators) {
                        @Override
                        public PopupStep onChosen(Object selectedValue, boolean finalChoice) {
                            return this.doFinalStep(new Runnable() {
                                public void run() {
                                    WriteCommandAction.runWriteCommandAction(project, new Runnable() {
                                        public void run() {
                                            StatementGenerator.doGenerate((StatementGenerator) selectedValue, method);
                                        }
                                    });
                                }
                            });
                        }
                    }
            ).showInFocusCenter();
        }
    }

    @NotNull
    public static StatementGenerator[] getGenerators(@NotNull PsiMethod method) {
        GenerateModel model = MybatisSetting.getInstance().getStatementGenerateModel();
        String target = method.getName();
        List<StatementGenerator> result = Lists.newArrayList();
        for (StatementGenerator generator : ALL) {
            if (model.matchesAny(generator.getPatterns(), target)) {
                result.add(generator);
            }
        }
        return CollectionUtils.isNotEmpty(result) ? result.toArray(new StatementGenerator[result.size()]) : ALL.toArray(new StatementGenerator[ALL.size()]);
    }

    private Set<String> patterns;

    public StatementGenerator(@NotNull String... patterns) {
        this.patterns = Sets.newHashSet(patterns);
    }

    public void execute(@NotNull final PsiMethod method) {
        PsiClass psiClass = method.getContainingClass();
        if (null == psiClass) return;
        CollectProcessor processor = new CollectProcessor();
        JavaService.getInstance(method.getProject()).process(psiClass, processor);
        final List<Mapper> mappers = Lists.newArrayList(processor.getResults());
        if (1 == mappers.size()) {
            setupTag(method, (Mapper) Iterables.getOnlyElement(mappers, (Object) null));
        } else if (mappers.size() > 1) {
            Collection<String> paths = Collections2.transform(mappers, FUN);
            UiComponentFacade.getInstance(method.getProject()).showListPopup("Choose target mapper xml to generate", new ListSelectionListener() {
                @Override
                public void selected(int index) {
                    setupTag(method, mappers.get(index));
                }

                @Override
                public boolean isWriteAction() {
                    return true;
                }
            }, paths.toArray(new String[paths.size()]));
        }
    }

    private void setupTag(PsiMethod method, Mapper mapper) {
        GroupTwo target = getTarget(mapper, method);
        target.getId().setStringValue(method.getName());
        target.setValue(" ");
        XmlTag tag = target.getXmlTag();
        int offset = tag.getTextOffset() + tag.getTextLength() - tag.getName().length() + 1;
        EditorService editorService = EditorService.getInstance(method.getProject());
        editorService.format(tag.getContainingFile(), tag);
        editorService.scrollTo(tag, offset);
    }

    @Override
    public String toString() {
        return this.getDisplayText();
    }

    @NotNull
    protected abstract GroupTwo getTarget(@NotNull Mapper mapper, @NotNull PsiMethod method);

    @NotNull
    public abstract String getId();

    @NotNull
    public abstract String getDisplayText();

    public Set<String> getPatterns() {
        return patterns;
    }

    public void setPatterns(Set<String> patterns) {
        this.patterns = patterns;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/generate/UpdateGenerator.java
================================================
package com.wuzhizhan.mybatis.generate;

import com.intellij.psi.PsiMethod;
import com.wuzhizhan.mybatis.dom.model.GroupTwo;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class UpdateGenerator extends StatementGenerator {

    public UpdateGenerator(@NotNull String... patterns) {
        super(patterns);
    }

    @NotNull
    @Override
    protected GroupTwo getTarget(@NotNull Mapper mapper, @NotNull PsiMethod method) {
        return mapper.addUpdate();
    }

    @NotNull
    @Override
    public String getId() {
        return "UpdateGenerator";
    }

    @NotNull
    @Override
    public String getDisplayText() {
        return "Update Statement";
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/inspection/GenericQuickFix.java
================================================
package com.wuzhizhan.mybatis.inspection;

import com.intellij.codeInspection.LocalQuickFix;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public abstract class GenericQuickFix implements LocalQuickFix {

    @NotNull
    @Override
    public String getFamilyName() {
        return getName();
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/inspection/MapperInspection.java
================================================
package com.wuzhizhan.mybatis.inspection;

import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
import com.intellij.codeInspection.ProblemDescriptor;

/**
 * @author yanglin
 */
public abstract class MapperInspection extends BaseJavaLocalInspectionTool {

    public static final ProblemDescriptor[] EMPTY_ARRAY = new ProblemDescriptor[0];

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/inspection/MapperMethodInspection.java
================================================
package com.wuzhizhan.mybatis.inspection;

import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiIdentifier;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.util.xml.DomElement;
import com.wuzhizhan.mybatis.annotation.Annotation;
import com.wuzhizhan.mybatis.dom.model.Select;
import com.wuzhizhan.mybatis.generate.StatementGenerator;
import com.wuzhizhan.mybatis.locator.MapperLocator;
import com.wuzhizhan.mybatis.service.JavaService;
import com.wuzhizhan.mybatis.util.JavaUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author yanglin
 */
public class MapperMethodInspection extends MapperInspection {
    @Nullable
    @Override
    public ProblemDescriptor[] checkMethod(
            @NotNull final PsiMethod method,
            @NotNull final InspectionManager manager,
            final boolean isOnTheFly) {
        if (!MapperLocator.getInstance(method.getProject()).process(method) ||
                JavaUtils.isAnyAnnotationPresent(method, Annotation.STATEMENT_SYMMETRIES)
                || method.getModifierList().hasModifierProperty(PsiModifier.STATIC)) {
            return EMPTY_ARRAY;
        }

        final List<ProblemDescriptor> problems = createProblemDescriptors(method, manager, isOnTheFly);
        return problems.toArray(new ProblemDescriptor[0]);
    }

    private List<ProblemDescriptor> createProblemDescriptors(
            final PsiMethod method,
            final InspectionManager manager,
            final boolean isOnTheFly) {
        final List<ProblemDescriptor> problems = new ArrayList<>(2);
        Optional<ProblemDescriptor> optionalProblem = checkStatementExists(method, manager, isOnTheFly);

        if (optionalProblem.isPresent()) {
            problems.add(optionalProblem.get());
        }

        optionalProblem = checkResultType(method, manager, isOnTheFly);

        if (optionalProblem.isPresent()) {
            problems.add(optionalProblem.get());
        }

        return problems;
    }

    private Optional<ProblemDescriptor> checkResultType(
            final PsiMethod method,
            final InspectionManager manager,
            final boolean isOnTheFly) {
        final Optional<DomElement> optionalDomElement =
                JavaService.getInstance(method.getProject())
                        .findStatement(method);

        if (!optionalDomElement.isPresent()) {
            return Optional.empty();
        }

        final DomElement domElement = optionalDomElement.get();

        if (domElement instanceof Select) {
            final Select selectStatement = (Select) domElement;

            if (selectStatement.getResultMap().getValue() != null) {
                return Optional.empty();
            }

            final Optional<PsiClass> methodResultType = StatementGenerator.getSelectResultType(method);
            final PsiClass selectResultType = selectStatement.getResultType().getValue();
            final PsiIdentifier methodName = method.getNameIdentifier();

            if (methodName != null) {
                if (methodResultType.isPresent()) {
                    if (selectResultType == null ||
                            (selectResultType.getQualifiedName() != null
                                    && !selectResultType.getQualifiedName().equals(methodResultType.get().getQualifiedName())
                                    && !selectResultType.isInheritor(methodResultType.get(), true))) {

                        return Optional.of(
                                manager.createProblemDescriptor(
                                        methodName,
                                        "Result type doesn't match for Select id=\"#ref\"",
                                        new ResultTypeQuickFix(selectStatement, methodResultType.get()),
                                        ProblemHighlightType.GENERIC_ERROR,
                                        isOnTheFly));

                    }
                }
                if (!methodResultType.isPresent() && selectResultType != null) {
                    return Optional.of(
                            manager.createProblemDescriptor(
                                    methodName,
                                    "Result type doesn't match for Select id=\"#ref\"",
                                    (LocalQuickFix) null,
                                    ProblemHighlightType.GENERIC_ERROR,
                                    isOnTheFly));
                }
            }
        }

        return Optional.empty();
    }

    private Optional<ProblemDescriptor> checkStatementExists(
            final PsiMethod method,
            final InspectionManager manager,
            final boolean isOnTheFly) {
        final PsiIdentifier methodName = method.getNameIdentifier();

        if (method.hasModifierProperty(PsiModifier.DEFAULT)) {
            return Optional.empty();
        }

        if (!JavaService.getInstance(method.getProject()).findStatement(method).isPresent() && null != methodName) {
            return Optional.of(manager.createProblemDescriptor(
                    methodName,
                    "Statement with id=\"#ref\" not defined in mapper XML",
                    new StatementNotExistsQuickFix(method),
                    ProblemHighlightType.GENERIC_ERROR,
                    isOnTheFly));
        }

        return Optional.empty();
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/inspection/MapperXmlInspection.java
================================================
package com.wuzhizhan.mybatis.inspection;

import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.highlighting.BasicDomElementsInspection;
import com.intellij.util.xml.highlighting.DomElementAnnotationHolder;
import com.intellij.util.xml.highlighting.DomHighlightingHelper;

/**
 * @author yanglin
 */
public class MapperXmlInspection extends BasicDomElementsInspection<DomElement> {

    public MapperXmlInspection() {
        super(DomElement.class);
    }

    @Override
    protected void checkDomElement(DomElement element, DomElementAnnotationHolder holder, DomHighlightingHelper helper) {
        super.checkDomElement(element, holder, helper);
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/inspection/ResultTypeQuickFix.java
================================================
package com.wuzhizhan.mybatis.inspection;

import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.util.xml.GenericAttributeValue;
import com.wuzhizhan.mybatis.dom.model.Select;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class ResultTypeQuickFix extends GenericQuickFix {

    private Select select;
    private PsiClass target;

    public ResultTypeQuickFix(@NotNull Select select, @NotNull PsiClass target) {
        this.select = select;
        this.target = target;
    }

    @NotNull
    @Override
    public String getName() {
        return "Correct resultType";
    }

    @Override
    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
        GenericAttributeValue<PsiClass> resultType = select.getResultType();
        resultType.setValue(target);
    }

    @NotNull
    public PsiClass getTarget() {
        return target;
    }

    public void setTarget(@NotNull PsiClass target) {
        this.target = target;
    }

    @NotNull
    public Select getSelect() {
        return select;
    }

    public void setSelect(@NotNull Select select) {
        this.select = select;
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/inspection/StatementNotExistsQuickFix.java
================================================
package com.wuzhizhan.mybatis.inspection;

import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiMethod;
import com.wuzhizhan.mybatis.generate.StatementGenerator;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class StatementNotExistsQuickFix extends GenericQuickFix {

    private PsiMethod method;

    public StatementNotExistsQuickFix(@NotNull PsiMethod method) {
        this.method = method;
    }

    @NotNull
    @Override
    public String getName() {
        return "MybatisGenerator statement";
    }

    @Override
    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
        StatementGenerator.applyGenerate(method);
    }

    @NotNull
    public PsiMethod getMethod() {
        return method;
    }

    public void setMethod(@NotNull PsiMethod method) {
        this.method = method;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenerateMapperChooser.java
================================================
package com.wuzhizhan.mybatis.intention;

import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class GenerateMapperChooser extends JavaFileIntentionChooser {

    public static final JavaFileIntentionChooser INSTANCE = new GenerateMapperChooser();

    @Override
    public boolean isAvailable(@NotNull PsiElement element) {
        if (isPositionOfInterfaceDeclaration(element)) {
            PsiClass clazz = PsiTreeUtil.getParentOfType(element, PsiClass.class);
            if (null != clazz) {
                return !isTargetPresentInXml(clazz);
            }
        }
        return false;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenerateMapperIntention.java
================================================
package com.wuzhizhan.mybatis.intention;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.wuzhizhan.mybatis.service.EditorService;
import com.wuzhizhan.mybatis.template.MybatisFileTemplateDescriptorFactory;
import com.wuzhizhan.mybatis.ui.ClickableListener;
import com.wuzhizhan.mybatis.ui.ListSelectionListener;
import com.wuzhizhan.mybatis.ui.UiComponentFacade;
import com.wuzhizhan.mybatis.util.CollectionUtils;
import com.wuzhizhan.mybatis.util.MapperUtils;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.*;

/**
 * @author yanglin
 */
public class GenerateMapperIntention extends GenericIntention {

    public GenerateMapperIntention() {
        super(GenerateMapperChooser.INSTANCE);
    }

    @NotNull
    @Override
    public String getText() {
        return "[Mybatis] MybatisGenerator mapper of xml";
    }

    @Override
    public boolean startInWriteAction() {
        return false;
    }

    @Override
    public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws IncorrectOperationException {
        PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
        PsiClass clazz = PsiTreeUtil.getParentOfType(element, PsiClass.class);
        Collection<PsiDirectory> directories = MapperUtils.findMapperDirectories(project);
        if (CollectionUtils.isEmpty(directories)) {
            handleChooseNewFolder(project, editor, clazz);
        } else {
            handleMutilDirectories(project, editor, clazz, directories);
        }
    }

    private void handleMutilDirectories(Project project,
                                        final Editor editor,
                                        final PsiClass clazz,
                                        Collection<PsiDirectory> directories) {
        final Map<String, PsiDirectory> pathMap = getPathMap(directories);
        final ArrayList<String> keys = Lists.newArrayList(pathMap.keySet());
        ListSelectionListener popupListener = new ListSelectionListener() {
            @Override
            public void selected(int index) {
                processGenerate(editor, clazz, pathMap.get(keys.get(index)));
            }

            @Override
            public boolean isWriteAction() {
                return true;
            }
        };
        UiComponentFacade uiComponentFacade = UiComponentFacade.getInstance(project);
        uiComponentFacade.showListPopupWithSingleClickable("Choose folder",
                popupListener,
                "Choose another",
                getChooseFolderListener(editor, clazz),
                getPathTextForShown(project, keys, pathMap));
    }

    private ClickableListener getChooseFolderListener(final Editor editor, final PsiClass clazz) {
        final Project project = clazz.getProject();
        return new ClickableListener() {
            @Override
            public void clicked() {
                handleChooseNewFolder(project, editor, clazz);
            }

            @Override
            public boolean isWriteAction() {
                return false;
            }
        };
    }

    private void handleChooseNewFolder(Project project, Editor editor, PsiClass clazz) {
        UiComponentFacade uiComponentFacade = UiComponentFacade.getInstance(project);
        VirtualFile baseDir = project.getBaseDir();
        VirtualFile vf = uiComponentFacade.showSingleFolderSelectionDialog("Select target folder", baseDir, baseDir);
        if (null != vf) {
            processGenerate(editor, clazz, PsiManager.getInstance(project).findDirectory(vf));
        }
    }

    private String[] getPathTextForShown(Project project, List<String> paths, final Map<String, PsiDirectory> pathMap) {
        Collections.sort(paths);
        final String projectBasePath = project.getBasePath();
        Collection<String> result = Lists.newArrayList(Collections2.transform(paths, new Function<String, String>() {
            @Override
            public String apply(String input) {
                String relativePath = FileUtil.getRelativePath(projectBasePath, input, File.separatorChar);
                Module module = ModuleUtil.findModuleForPsiElement(pathMap.get(input));
                return null == module ? relativePath : ("[" + module.getName() + "] " + relativePath);
            }
        }));
        return result.toArray(new String[result.size()]);
    }

    private Map<String, PsiDirectory> getPathMap(Collection<PsiDirectory> directories) {
        Map<String, PsiDirectory> result = Maps.newHashMap();
        for (PsiDirectory directory : directories) {
            String presentableUrl = directory.getVirtualFile().getPresentableUrl();
            if (presentableUrl != null) {
                result.put(presentableUrl, directory);
            }
        }
        return result;
    }

    private void processGenerate(Editor editor, PsiClass clazz, PsiDirectory directory) {
        if (null == directory) {
            return;
        }
        if (!directory.isWritable()) {
            HintManager.getInstance().showErrorHint(editor, "Target directory is not writable");
            return;
        }
        try {
            Properties properties = new Properties();
            properties.setProperty("NAMESPACE", clazz.getQualifiedName());
            PsiElement psiFile = MapperUtils.createMapperFromFileTemplate(MybatisFileTemplateDescriptorFactory.MYBATIS_MAPPER_XML_TEMPLATE,
                    clazz.getName(), directory, properties);
            EditorService.getInstance(clazz.getProject()).scrollTo(psiFile, 0);
        } catch (Exception e) {
            HintManager.getInstance().showErrorHint(editor, "Failed: " + e.getCause());
        }
    }

}

================================================
FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenerateParamAnnotationIntention.java
================================================
package com.wuzhizhan.mybatis.intention;

import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.wuzhizhan.mybatis.service.AnnotationService;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class GenerateParamAnnotationIntention extends GenericIntention {

    public GenerateParamAnnotationIntention() {
        super(GenerateParamChooser.INSTANCE);
    }

    @NotNull
    @Override
    public String getText() {
        return "[Mybatis] MybatisGenerator @Param";
    }

    @Override
    public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
        PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
        PsiParameter parameter = PsiTreeUtil.getParentOfType(element, PsiParameter.class);
        AnnotationService annotationService = AnnotationService.getInstance(project);
        if (null != parameter) {
            annotationService.addAnnotationWithParameterName(parameter);
        } else {
            PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
            if (null != method) {
                annotationService.addAnnotationWithParameterNameForMethodParameters(method);
            }
        }
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenerateParamChooser.java
================================================
package com.wuzhizhan.mybatis.intention;

import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.util.PsiTreeUtil;
import com.wuzhizhan.mybatis.annotation.Annotation;
import com.wuzhizhan.mybatis.util.JavaUtils;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class GenerateParamChooser extends JavaFileIntentionChooser {

    public static final JavaFileIntentionChooser INSTANCE = new GenerateParamChooser();

    @Override
    public boolean isAvailable(@NotNull PsiElement element) {
        PsiParameter parameter = PsiTreeUtil.getParentOfType(element, PsiParameter.class);
        PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
        return (null != parameter && !JavaUtils.isAnnotationPresent(parameter, Annotation.PARAM)) ||
                (null != method && !JavaUtils.isAllParameterWithAnnotation(method, Annotation.PARAM));
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenerateStatementChooser.java
================================================
package com.wuzhizhan.mybatis.intention;

import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
import com.wuzhizhan.mybatis.annotation.Annotation;
import com.wuzhizhan.mybatis.util.JavaUtils;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class GenerateStatementChooser extends JavaFileIntentionChooser {

    public static final JavaFileIntentionChooser INSTANCE = new GenerateStatementChooser();

    @Override
    public boolean isAvailable(@NotNull PsiElement element) {
        if (!isPositionOfMethodDeclaration(element)) {
            return false;
        }
        PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
        PsiClass clazz = PsiTreeUtil.getParentOfType(element, PsiClass.class);
        return null != method && null != clazz &&
                !JavaUtils.isAnyAnnotationPresent(method, Annotation.STATEMENT_SYMMETRIES) &&
                !isTargetPresentInXml(method) &&
                isTargetPresentInXml(clazz);
    }
}

================================================
FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenerateStatementIntention.java
================================================
package com.wuzhizhan.mybatis.intention;

import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.wuzhizhan.mybatis.generate.StatementGenerator;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class GenerateStatementIntention extends GenericIntention {

    public GenerateStatementIntention() {
        super(GenerateStatementChooser.INSTANCE);
    }

    @NotNull
    @Override
    public String getText() {
        return "[Mybatis] MybatisGenerator new statement";
    }

    @Override
    public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
        PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
        StatementGenerator.applyGenerate(PsiTreeUtil.getParentOfType(element, PsiMethod.class));
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenericIntention.java
================================================
package com.wuzhizhan.mybatis.intention;

import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public abstract class GenericIntention implements IntentionAction {

    protected IntentionChooser chooser;

    public GenericIntention(@NotNull IntentionChooser chooser) {
        this.chooser = chooser;
    }

    @NotNull
    @Override
    public String getFamilyName() {
        return getText();
    }

    @Override
    public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
        return chooser.isAvailable(project, editor, file);
    }

    @Override
    public boolean startInWriteAction() {
        return true;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/intention/IntentionChooser.java
================================================
package com.wuzhizhan.mybatis.intention;

import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public interface IntentionChooser {

    public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file);

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/intention/JavaFileIntentionChooser.java
================================================
package com.wuzhizhan.mybatis.intention;

import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.wuzhizhan.mybatis.service.JavaService;
import com.wuzhizhan.mybatis.util.JavaUtils;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public abstract class JavaFileIntentionChooser implements IntentionChooser {

    @Override
    public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
        if (!(file instanceof PsiJavaFile))
            return false;
        PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
        return null != element && JavaUtils.isElementWithinInterface(element) && isAvailable(element);
    }

    public abstract boolean isAvailable(@NotNull PsiElement element);

    public boolean isPositionOfParameterDeclaration(@NotNull PsiElement element) {
        return element.getParent() instanceof PsiParameter;
    }

    public boolean isPositionOfMethodDeclaration(@NotNull PsiElement element) {
        return element.getParent() instanceof PsiMethod;
    }

    public boolean isPositionOfInterfaceDeclaration(@NotNull PsiElement element) {
        return element.getParent() instanceof PsiClass;
    }

    public boolean isTargetPresentInXml(@NotNull PsiElement element) {
        return JavaService.getInstance(element.getProject()).findWithFindFirstProcessor(element).isPresent();
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/locator/LocateStrategy.java
================================================
package com.wuzhizhan.mybatis.locator;

import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public abstract class LocateStrategy {

    public abstract boolean apply(@NotNull PsiClass clazz);

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/locator/MapperLocator.java
================================================
package com.wuzhizhan.mybatis.locator;

import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.wuzhizhan.mybatis.util.JavaUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * @author yanglin
 */
public class MapperLocator {

    public static LocateStrategy dfltLocateStrategy = new PackageLocateStrategy();

    public static MapperLocator getInstance(@NotNull Project project) {
        return ServiceManager.getService(project, MapperLocator.class);
    }

    public boolean process(@Nullable PsiMethod method) {
        return null != method && process(method.getContainingClass());
    }

    public boolean process(@Nullable PsiClass clazz) {
        return null != clazz && JavaUtils.isElementWithinInterface(clazz) && dfltLocateStrategy.apply(clazz);
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/locator/MapperXmlPackageProvider.java
================================================
package com.wuzhizhan.mybatis.locator;

import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import com.wuzhizhan.mybatis.util.MapperUtils;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * @author yanglin
 */
public class MapperXmlPackageProvider extends PackageProvider {

    @NotNull
    @Override
    public Set<PsiPackage> getPackages(@NotNull Project project) {
        HashSet<PsiPackage> res = Sets.newHashSet();
        Collection<Mapper> mappers = MapperUtils.findMappers(project);
        JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
        for (Mapper mapper : mappers) {
            String namespace = MapperUtils.getNamespace(mapper);
            PsiClass clazz = javaPsiFacade.findClass(namespace, GlobalSearchScope.allScope(project));
            if (null != clazz) {
                PsiFile file = clazz.getContainingFile();
                if (file instanceof PsiJavaFile) {
                    String packageName = ((PsiJavaFile) file).getPackageName();
                    PsiPackage pkg = javaPsiFacade.findPackage(packageName);
                    if (null != pkg) {
                        res.add(pkg);
                    }
                }
            }
        }
        return res;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/locator/PackageLocateStrategy.java
================================================
package com.wuzhizhan.mybatis.locator;

import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.PsiPackage;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class PackageLocateStrategy extends LocateStrategy {

    private PackageProvider provider = new MapperXmlPackageProvider();

    @Override
    public boolean apply(@NotNull PsiClass clazz) {
        String packageName = ((PsiJavaFile) clazz.getContainingFile()).getPackageName();
        PsiPackage pkg = JavaPsiFacade.getInstance(clazz.getProject()).findPackage(packageName);
        for (PsiPackage tmp : provider.getPackages(clazz.getProject())) {
            if (tmp.equals(pkg)) {
                return true;
            }
        }
        return false;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/locator/PackageProvider.java
================================================
package com.wuzhizhan.mybatis.locator;

import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiPackage;
import org.jetbrains.annotations.NotNull;

import java.util.Set;

/**
 * @author yanglin
 */
public abstract class PackageProvider {

    @NotNull
    public abstract Set<PsiPackage> getPackages(@NotNull Project project);

}

================================================
FILE: src/main/java/com/wuzhizhan/mybatis/provider/InjectionLineMarkerProvider.java
================================================
package com.wuzhizhan.mybatis.provider;

import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider;
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.wuzhizhan.mybatis.annotation.Annotation;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import com.wuzhizhan.mybatis.util.Icons;
import com.wuzhizhan.mybatis.util.JavaUtils;
import com.wuzhizhan.mybatis.util.MapperUtils;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.Optional;

/**
 * @author yanglin
 */
public class InjectionLineMarkerProvider extends RelatedItemLineMarkerProvider {

    @Override
    protected void collectNavigationMarkers(@NotNull PsiElement element, @NotNull Collection<? super RelatedItemLineMarkerInfo> result) {
        if (!(element instanceof PsiField)) return;
        PsiField field = (PsiField) element;
        if (!isTargetField(field)) return;

        PsiType type = field.getType();
        if (!(type instanceof PsiClassReferenceType)) return;

        Optional<PsiClass> clazz = JavaUtils.findClazz(element.getProject(), type.getCanonicalText());
        if (!clazz.isPresent()) return;

        PsiClass psiClass = clazz.get();
        Optional<Mapper> mapper = MapperUtils.findFirstMapper(element.getProject(), psiClass);
        if (!mapper.isPresent()) return;

        NavigationGutterIconBuilder<PsiElement> builder =
                NavigationGutterIconBuilder.create(Icons.SPRING_INJECTION_ICON)
                        .setAlignment(GutterIconRenderer.Alignment.CENTER)
                        .setTarget(psiClass)
                        .setTooltipTitle("Data access object found - " + psiClass.getQualifiedName());
        result.add(builder.createLineMarkerInfo(field.getNameIdentifier()));
    }

    private boolean isTargetField(PsiField field) {
        if (JavaUtils.isAnnotationPresent(field, Annotation.AUTOWIRED)) {
            return true;
        }
        Optional<PsiAnnotation> resourceAnno = JavaUtils.getPsiAnnotation(field, Annotation.RESOURCE);
        if (resourceAnno.isPresent()) {
            PsiAnnotationMemberValue nameValue = resourceAnno.get().findAttributeValue("name");
            String name = nameValue.getText().replaceAll("\"", "");
            return StringUtils.isBlank(name) || name.equals(field.getName());
        }
        return false;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/provider/MapperLineMarkerProvider.java
================================================
package com.wuzhizhan.mybatis.provider;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider;
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNameIdentifierOwner;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.CommonProcessors;
import com.intellij.util.xml.DomElement;
import com.wuzhizhan.mybatis.dom.model.IdDomElement;
import com.wuzhizhan.mybatis.service.JavaService;
import com.wuzhizhan.mybatis.util.Icons;
import com.wuzhizhan.mybatis.util.JavaUtils;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;

/**
 * @author yanglin
 */
public class MapperLineMarkerProvider extends RelatedItemLineMarkerProvider {

    private static final Function<DomElement, XmlTag> FUN = new Function<DomElement, XmlTag>() {
        @Override
        public XmlTag apply(DomElement domElement) {
            return domElement.getXmlTag();
        }
    };

    @Override
    protected void collectNavigationMarkers(@NotNull PsiElement element, @NotNull Collection<? super RelatedItemLineMarkerInfo> result) {
        if (element instanceof PsiNameIdentifierOwner && JavaUtils.isElementWithinInterface(element)) {
            CommonProcessors.CollectProcessor<IdDomElement> processor = new CommonProcessors.CollectProcessor<IdDomElement>();
            JavaService.getInstance(element.getProject()).process(element, processor);
            Collection<IdDomElement> results = processor.getResults();
            if (!results.isEmpty()) {
                NavigationGutterIconBuilder<PsiElement> builder =
                        NavigationGutterIconBuilder.create(Icons.MAPPER_LINE_MARKER_ICON)
                                .setAlignment(GutterIconRenderer.Alignment.CENTER)
                                .setTargets(Collections2.transform(results, FUN))
                                .setTooltipTitle("Navigation to target in mapper xml");
                result.add(builder.createLineMarkerInfo(((PsiNameIdentifierOwner) element).getNameIdentifier()));
            }
        }
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/provider/MarkerProviderAdaptor.java
================================================
package com.wuzhizhan.mybatis.provider;

import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.LineMarkerProvider;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.List;

/**
 * @author yanglin
 */
public abstract class MarkerProviderAdaptor implements LineMarkerProvider {

    @Override
    public void collectSlowLineMarkers(@NotNull List<PsiElement> elements, @NotNull Collection<LineMarkerInfo> result) {

    }

    @Nullable
    @Override
    public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
        return null;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/provider/SimpleLineMarkerProvider.java
================================================
package com.wuzhizhan.mybatis.provider;

import com.intellij.codeHighlighting.Pass;
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.pom.Navigatable;
import com.intellij.psi.PsiElement;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

/**
 * @author yanglin
 */
public abstract class SimpleLineMarkerProvider<F extends PsiElement, T> extends MarkerProviderAdaptor {

    @Override
    public void collectSlowLineMarkers(@NotNull List<PsiElement> elements, @NotNull Collection<LineMarkerInfo> result) {
    }

    @SuppressWarnings("unchecked")
    @Nullable
    @Override
    public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
        if (!isTheElement(element)) return null;

        Optional<T> processResult = apply((F) element);
        return processResult.isPresent() ? new LineMarkerInfo<F>(
                (F) element,
                element.getTextRange(),
                getIcon(),
                getTooltipProvider(processResult.get()),
                getNavigationHandler(processResult.get()),
                GutterIconRenderer.Alignment.CENTER
        ) : null;
    }

    private Function<F, String> getTooltipProvider(final T target) {
        return new Function<F, String>() {
            @Override
            public String fun(F from) {
                return getTooltip(from, target);
            }
        };
    }

    private GutterIconNavigationHandler<F> getNavigationHandler(final T target) {
        return new GutterIconNavigationHandler<F>() {
            @Override
            public void navigate(MouseEvent e, F from) {
                getNavigatable(from, target).navigate(true);
            }
        };
    }

    public abstract boolean isTheElement(@NotNull PsiElement element);

    @NotNull
    public abstract Optional<T> apply(@NotNull F from);

    @NotNull
    public abstract Navigatable getNavigatable(@NotNull F from, @NotNull T target);

    @NotNull
    public abstract String getTooltip(@NotNull F from, @NotNull T target);

    @NotNull
    public abstract Icon getIcon();
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/provider/StatementLineMarkerProvider.java
================================================
package com.wuzhizhan.mybatis.provider;

import com.google.common.collect.ImmutableList;
import com.intellij.pom.Navigatable;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomUtil;
import com.wuzhizhan.mybatis.dom.model.*;
import com.wuzhizhan.mybatis.util.Icons;
import com.wuzhizhan.mybatis.util.JavaUtils;
import com.wuzhizhan.mybatis.util.MapperUtils;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.util.Optional;

/**
 * @author yanglin
 */
public class StatementLineMarkerProvider extends SimpleLineMarkerProvider<XmlTag, PsiMethod> {

    private static final ImmutableList<Class<? extends GroupTwo>> TARGET_TYPES = ImmutableList.of(
            Select.class,
            Update.class,
            Insert.class,
            Delete.class
    );

    @Override
    public boolean isTheElement(@NotNull PsiElement element) {
        return element instanceof XmlTag
                && MapperUtils.isElementWithinMybatisFile(element)
                && isTargetType(element);
    }

    @SuppressWarnings("unchecked")
    @NotNull
    @Override
    public Optional<PsiMethod> apply(@NotNull XmlTag from) {
        DomElement domElement = DomUtil.getDomElement(from);
        return null == domElement ? Optional.empty() : JavaUtils.findMethod(from.getProject(), (IdDomElement) domElement);
    }

    private boolean isTargetType(PsiElement element) {
        DomElement domElement = DomUtil.getDomElement(element);
        for (Class<?> clazz : TARGET_TYPES) {
            if (clazz.isInstance(domElement))
                return true;
        }
        return false;
    }

    @SuppressWarnings("unchecked")
    @NotNull
    @Override
    public Navigatable getNavigatable(@NotNull XmlTag from, @NotNull PsiMethod target) {
        return (Navigatable) target.getNavigationElement();
    }

    @NotNull
    @Override
    public String getTooltip(@NotNull XmlTag from, @NotNull PsiMethod target) {
        return "Data access object found - " + target.getContainingClass().getQualifiedName();
    }

    @NotNull
    @Override
    public Icon getIcon() {
        return Icons.STATEMENT_LINE_MARKER_ICON;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/refactoring/MapperRefactoringProvider.java
================================================
package com.wuzhizhan.mybatis.refactoring;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.listeners.RefactoringElementListenerProvider;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import com.wuzhizhan.mybatis.util.MapperUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.util.Collection;

/**
 * @author yanglin
 */
public class MapperRefactoringProvider implements RefactoringElementListenerProvider {

    @Nullable
    @Override
    public RefactoringElementListener getListener(final PsiElement element) {
        if (!(element instanceof PsiClass)) return null;
        return new RefactoringElementListener() {
            @Override
            public void elementMoved(@NotNull PsiElement newElement) {
            }

            @Override
            public void elementRenamed(@NotNull final PsiElement newElement) {
                if (newElement instanceof PsiClass) {
                    ApplicationManager.getApplication().runWriteAction(new Runnable() {
                        @Override
                        public void run() {
                            renameMapperXml((PsiClass) element, (PsiClass) newElement);
                        }
                    });
                }
            }
        };
    }

    private void renameMapperXml(@NotNull final PsiClass oldClazz, @NotNull final PsiClass newClazz) {
        Collection<Mapper> mappers = MapperUtils.findMappers(oldClazz.getProject(), oldClazz);
        try {
            for (Mapper mapper : mappers) {
                VirtualFile vf = mapper.getXmlTag().getOriginalElement().getContainingFile().getVirtualFile();
                if (null != vf) {
                    vf.rename(MapperRefactoringProvider.this, newClazz.getName() + "." + vf.getExtension());
                }
            }
        } catch (IOException e) {
        }
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/reference/ContextPsiFieldReference.java
================================================
package com.wuzhizhan.mybatis.reference;

import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceBase;
import com.intellij.psi.xml.XmlAttributeValue;
import com.wuzhizhan.mybatis.dom.MapperBacktrackingUtils;
import com.wuzhizhan.mybatis.service.JavaService;
import com.wuzhizhan.mybatis.util.JavaUtils;
import com.wuzhizhan.mybatis.util.MybatisConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Optional;

/**
 * @author yanglin
 */
public class ContextPsiFieldReference extends PsiReferenceBase<XmlAttributeValue> {

    protected ContextReferenceSetResolver resolver;

    protected int index;

    public ContextPsiFieldReference(XmlAttributeValue element, TextRange range, int index) {
        super(element, range, false);
        this.index = index;
        resolver = ReferenceSetResolverFactory.createPsiFieldResolver(element);
    }

    @SuppressWarnings("unchecked")
    @Nullable
    @Override
    public PsiElement resolve() {
        Optional<PsiElement> resolved = resolver.resolve(index);
        return resolved.orElse(null);
    }

    @NotNull
    @Override
    public Object[] getVariants() {
        Optional<PsiClass> clazz = getTargetClazz();
        return clazz.isPresent() ? JavaUtils.findSettablePsiFields(clazz.get()) : PsiReference.EMPTY_ARRAY;
    }

    @SuppressWarnings("unchecked")
    private Optional<PsiClass> getTargetClazz() {
        if (getElement().getValue().contains(MybatisConstants.DOT_SEPARATOR)) {
            int ind = 0 == index ? 0 : index - 1;
            Optional<PsiElement> resolved = resolver.resolve(ind);
            if (resolved.isPresent()) {
                return JavaService.getInstance(myElement.getProject()).getReferenceClazzOfPsiField(resolved.get());
            }
        } else {
            return MapperBacktrackingUtils.getPropertyClazz(myElement);
        }
        return Optional.empty();
    }

    public ContextReferenceSetResolver getResolver() {
        return resolver;
    }

    public void setResolver(ContextReferenceSetResolver resolver) {
        this.resolver = resolver;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/reference/ContextReferenceSetResolver.java
================================================
package com.wuzhizhan.mybatis.reference;

import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.wuzhizhan.mybatis.util.MybatisConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Optional;

/**
 * @author yanglin
 */
public abstract class ContextReferenceSetResolver<F extends PsiElement, K extends PsiElement> {

    private static final Splitter SPLITTER = Splitter.on(MybatisConstants.DOT_SEPARATOR);

    protected Project project;

    protected F element;

    protected List<String> texts;

    protected ContextReferenceSetResolver(@NotNull F element) {
        this.element = element;
        this.project = element.getProject();
        this.texts = Lists.newArrayList(SPLITTER.split(getText()));
    }

    @NotNull
    public final Optional<? extends PsiElement> resolve(int index) {
        Optional<K> startElement = getStartElement();
        return startElement.isPresent() ? (texts.size() > 1 ? parseNext(startElement, texts, index) : startElement) : Optional.empty();
    }

    private Optional<K> parseNext(Optional<K> current, List<String> texts, int index) {
        int ind = 1;
        while (current.isPresent() && ind <= index) {
            String text = texts.get(ind);
            if (text.contains(" ")) {
                return Optional.empty();
            }
            current = resolve(current.get(), text);
            ind++;
        }
        return current;
    }

    public Optional<K> getStartElement() {
        return getStartElement(Iterables.getFirst(texts, null));
    }

    @NotNull
    public abstract Optional<K> getStartElement(@Nullable String firstText);

    @NotNull
    public abstract String getText();

    @NotNull
    public abstract Optional<K> resolve(@NotNull K current, @NotNull String text);

    public F getElement() {
        return element;
    }

    public void setElement(F element) {
        this.element = element;
    }

    public Project getProject() {
        return project;
    }

    public void setProject(Project project) {
        this.project = project;
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/reference/PsiFieldReferenceSetResolver.java
================================================
package com.wuzhizhan.mybatis.reference;

import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiType;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.xml.XmlAttributeValue;
import com.wuzhizhan.mybatis.dom.MapperBacktrackingUtils;
import com.wuzhizhan.mybatis.util.JavaUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Optional;

/**
 * @author yanglin
 */
public class PsiFieldReferenceSetResolver extends ContextReferenceSetResolver<XmlAttributeValue, PsiField> {

    protected PsiFieldReferenceSetResolver(XmlAttributeValue from) {
        super(from);
    }

    @NotNull
    @Override
    public String getText() {
        return getElement().getValue();
    }

    @NotNull
    @Override
    public Optional<PsiField> resolve(@NotNull PsiField current, @NotNull String text) {
        PsiType type = current.getType();
        if (type instanceof PsiClassReferenceType && !((PsiClassReferenceType) type).hasParameters()) {
            PsiClass clazz = ((PsiClassReferenceType) type).resolve();
            if (null != clazz) {
                return JavaUtils.findSettablePsiField(clazz, text);
            }
        }
        return Optional.empty();
    }

    @NotNull
    @Override
    public Optional<PsiField> getStartElement(@Nullable String firstText) {
        Optional<PsiClass> clazz = MapperBacktrackingUtils.getPropertyClazz(getElement());
        return clazz.flatMap(psiClass -> JavaUtils.findSettablePsiField(psiClass, firstText));
    }

}

================================================
FILE: src/main/java/com/wuzhizhan/mybatis/reference/ReferenceSetResolverFactory.java
================================================
package com.wuzhizhan.mybatis.reference;

import com.intellij.psi.xml.XmlAttributeValue;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public final class ReferenceSetResolverFactory {

    private ReferenceSetResolverFactory() {
        throw new UnsupportedOperationException();
    }

    public static <F extends XmlAttributeValue> ContextReferenceSetResolver createPsiFieldResolver(@NotNull F target) {
        return new PsiFieldReferenceSetResolver(target);
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/reference/ResultPropertyReferenceSet.java
================================================
package com.wuzhizhan.mybatis.reference;

import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.util.ReferenceSetBase;
import com.intellij.psi.xml.XmlAttributeValue;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * @author yanglin
 */
public class ResultPropertyReferenceSet extends ReferenceSetBase<PsiReference> {

    public ResultPropertyReferenceSet(String text, @NotNull PsiElement element, int offset) {
        super(text, element, offset, DOT_SEPARATOR);
    }

    @Nullable
    @NonNls
    @Override
    protected PsiReference createReference(TextRange range, int index) {
        XmlAttributeValue element = (XmlAttributeValue) getElement();
        return null == element ? null : new ContextPsiFieldReference(element, range, index);
    }

}

================================================
FILE: src/main/java/com/wuzhizhan/mybatis/service/AnnotationService.java
================================================
package com.wuzhizhan.mybatis.service;

import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.wuzhizhan.mybatis.annotation.Annotation;
import com.wuzhizhan.mybatis.util.JavaUtils;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class AnnotationService {

    private Project project;

    public AnnotationService(Project project) {
        this.project = project;
    }

    public static AnnotationService getInstance(@NotNull Project project) {
        return ServiceManager.getService(project, AnnotationService.class);
    }

    public void addAnnotation(@NotNull PsiModifierListOwner parameter, @NotNull Annotation annotation) {
        PsiModifierList modifierList = parameter.getModifierList();
        if (JavaUtils.isAnnotationPresent(parameter, annotation) || null == modifierList) {
            return;
        }
        JavaService.getInstance(parameter.getProject()).importClazz((PsiJavaFile) parameter.getContainingFile(), annotation.getQualifiedName());

        PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
        PsiAnnotation psiAnnotation = elementFactory.createAnnotationFromText(annotation.toString(), parameter);
        modifierList.add(psiAnnotation);
        JavaCodeStyleManager.getInstance(project).shortenClassReferences(psiAnnotation.getParent());
    }

    public void addAnnotationWithParameterNameForMethodParameters(@NotNull PsiMethod method) {
        PsiParameterList parameterList = method.getParameterList();
        if (null == parameterList) {
            return;
        }
        PsiParameter[] parameters = parameterList.getParameters();
        for (PsiParameter param : parameters) {
            addAnnotationWithParameterName(param);
        }
    }

    public void addAnnotationWithParameterName(@NotNull PsiParameter parameter) {
        String name = parameter.getName();
        if (null != name) {
            AnnotationService.getInstance(parameter.getProject()).addAnnotation(parameter, Annotation.PARAM.withValue(new Annotation.StringValue(name)));
        }
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/service/EditorService.java
================================================
package com.wuzhizhan.mybatis.service;

import com.intellij.codeInsight.navigation.NavigationUtil;
import com.intellij.formatting.FormatTextRanges;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade;
import org.jetbrains.annotations.NotNull;

/**
 * @author yanglin
 */
public class EditorService {

    private Project project;

    private FileEditorManager fileEditorManager;

    private CodeFormatterFacade codeFormatterFacade;

    public EditorService(Project project) {
        this.project = project;
        this.fileEditorManager = FileEditorManager.getInstance(project);
    }

    public static EditorService getInstance(@NotNull Project project) {
        return ServiceManager.getService(project, EditorService.class);
    }

    public void format(@NotNull PsiFile file, @NotNull PsiElement element) {
        this.codeFormatterFacade = new CodeFormatterFacade(CodeStyleSettingsManager.getSettings(element.getProject()), element.getLanguage());
        codeFormatterFacade.processText(file, new FormatTextRanges(element.getTextRange(), true), true);
    }

    public void scrollTo(@NotNull PsiElement element, int offset) {
        NavigationUtil.activateFileWithPsiElement(element, true);
        Editor editor = fileEditorManager.getSelectedTextEditor();
        if (null != editor) {
            editor.getCaretModel().moveToOffset(offset);
            editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
        }
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/service/JavaService.java
================================================
package com.wuzhizhan.mybatis.service;

import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import com.intellij.util.xml.DomElement;
import com.wuzhizhan.mybatis.dom.model.IdDomElement;
import com.wuzhizhan.mybatis.dom.model.Mapper;
import com.wuzhizhan.mybatis.util.JavaUtils;
import com.wuzhizhan.mybatis.util.MapperUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Optional;

/**
 * @author yanglin
 */
public class JavaService {

    private Project project;

    private JavaPsiFacade javaPsiFacade;

    private EditorService editorService;

    public JavaService(Project project) {
        this.project = project;
        this.javaPsiFacade = JavaPsiFacade.getInstance(project);
        this.editorService = EditorService.getInstance(project);
    }

    public static JavaService getInstance(@NotNull Project project) {
        return ServiceManager.getService(project, JavaService.class);
    }

    public Optional<PsiClass> getReferenceClazzOfPsiField(@NotNull PsiElement field) {
        if (!(field instanceof PsiField)) {
            return Optional.empty();
        }
        PsiType type = ((PsiField) field).getType();
        return type instanceof PsiClassReferenceType ? Optional.ofNullable(((PsiClassReferenceType) type).resolve()) : Optional.empty();
    }

    public Optional<DomElement> findStatement(@Nullable PsiMethod method) {
        CommonProcessors.FindFirstProcessor<DomElement> processor = new CommonProcessors.FindFirstProcessor<DomElement>();
        process(method, processor);
        return processor.isFound() ? Optional.ofNullable(processor.getFoundValue()) : Optional.empty();
    }

    @SuppressWarnings("unchecked")
    public void process(@NotNull PsiMethod psiMethod, @NotNull Processor<IdDomElement> processor) {
        PsiClass psiClass = psiMethod.getContainingClass();
        if (null == psiClass) return;
        String id = psiClass.getQualifiedName() + "." + psiMethod.getName();
        for (Mapper mapper : MapperUtils.findMappers(psiMethod.getProject())) {
            for (IdDomElement idDomElement : mapper.getDaoElements()) {
                if (MapperUtils.getIdSignature(idDomElement).equals(id)) {
                    processor.process(idDomElement);
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    public void process(@NotNull PsiClass clazz, @NotNull Processor<Mapper> processor) {
        String ns = clazz.getQualifiedName();
        for (Mapper mapper : MapperUtils.findMappers(clazz.getProject())) {
            if (MapperUtils.getNamespace(mapper).equals(ns)) {
                processor.process(mapper);
            }
        }
    }

    public void process(@NotNull PsiElement target, @NotNull Processor processor) {
        if (target instanceof PsiMethod) {
            process((PsiMethod) target, processor);
        } else if (target instanceof PsiClass) {
            process((PsiClass) target, processor);
        }
    }

    public <T> Optional<T> findWithFindFirstProcessor(@NotNull PsiElement target) {
        CommonProcessors.FindFirstProcessor<T> processor = new CommonProcessors.FindFirstProcessor<T>();
        process(target, processor);
        return Optional.ofNullable(processor.getFoundValue());
    }

    public void importClazz(PsiJavaFile file, String clazzName) {
        if (!JavaUtils.hasImportClazz(file, clazzName)) {
            Optional<PsiClass> clazz = JavaUtils.findClazz(project, clazzName);
            PsiImportList importList = file.getImportList();
            if (clazz.isPresent() && null != importList) {
                PsiElementFactory elementFactory = javaPsiFacade.getElementFactory();
                PsiImportStatement statement = elementFactory.createImportStatement(clazz.get());
                importList.add(statement);
                editorService.format(file, statement);
            }
        }
    }
}



================================================
FILE: src/main/java/com/wuzhizhan/mybatis/service/TableInfoService.java
================================================
package com.wuzhizhan.mybatis.service;

import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;

/**
 * 日期 2018-11-30
 *
 * @author 吴志展
 */
public class TableInfoService {
    public static TableInfoService getInstance(@NotNull Project project) {
        return ServiceManager.getService(project, TableInfoService.class);
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/setting/MybatisConfigurable.java
================================================
package com.wuzhizhan.mybatis.setting;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Sets;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.wuzhizhan.mybatis.generate.GenerateModel;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;

import static com.wuzhizhan.mybatis.generate.StatementGenerator.*;

/**
 * @author yanglin
 */
public class MybatisConfigurable implements SearchableConfigurable {

    private MybatisSetting mybatisSetting;

    private MybatisSettingForm mybatisSettingForm;

    private String separator = ";";

    private Splitter splitter = Splitter.on(separator).omitEmptyStrings().trimResults();

    private Joiner joiner = Joiner.on(separator);

    public MybatisConfigurable() {
        mybatisSetting = MybatisSetting.getInstance();
    }

    @Override
    public String getId() {
        return "Mybatis";
    }

    @Override
    public Runnable enableSearch(String option) {
        return null;
    }

    @Nls
    @Override
    public String getDisplayName() {
        return "Free Mybatis";
    }

    @Nullable
    @Override
    public String getHelpTopic() {
        return getId();
    }

    @Nullable
    @Override
    public JComponent createComponent() {
        if (null == mybatisSettingForm) {
            this.mybatisSettingForm = new MybatisSettingForm();
        }
        return mybatisSettingForm.mainPanel;
    }

    @Override
    public boolean isModified() {
        return mybatisSetting.getStatementGenerateModel().getIdentifier() != mybatisSettingForm.modelComboBox.getSelectedIndex()
                || !joiner.join(INSERT_GENERATOR.getPatterns()).equals(mybatisSettingForm.insertPatternTextField.getText())
                || !joiner.join(DELETE_GENERATOR.getPatterns()).equals(mybatisSettingForm.deletePatternTextField.getText())
                || !joiner.join(UPDATE_GENERATOR.getPatterns()).equals(mybatisSettingForm.updatePatternTextField.getText())
                || !joiner.join(SELECT_GENERATOR.getPatterns()).equals(mybatisSettingForm.selectPatternTextField.getText());
    }

    @Override
    public void apply() throws ConfigurationException {
        mybatisSetting.setStatementGenerateModel(GenerateModel.getInstance(mybatisSettingForm.modelComboBox.getSelectedIndex()));
        INSERT_GENERATOR.setPatterns(Sets.newHashSet(splitter.split(mybatisSettingForm.insertPatternTextField.getText())));
        DELETE_GENERATOR.setPatterns(Sets.newHashSet(splitter.split(mybatisSettingForm.deletePatternTextField.getText())));
        UPDATE_GENERATOR.setPatterns(Sets.newHashSet(splitter.split(mybatisSettingForm.updatePatternTextField.getText())));
        SELECT_GENERATOR.setPatterns(Sets.newHashSet(splitter.split(mybatisSettingForm.selectPatternTextField.getText())));
    }

    @Override
    public void reset() {
        mybatisSettingForm.modelComboBox.setSelectedIndex(mybatisSetting.getStatementGenerateModel().getIdentifier());
        mybatisSettingForm.insertPatternTextField.setText(joiner.join(INSERT_GENERATOR.getPatterns()));
        mybatisSettingForm.deletePatternTextField.setText(joiner.join(DELETE_GENERATOR.getPatterns()));
        mybatisSettingForm.updatePatternTextField.setText(joiner.join(UPDATE_GENERATOR.getPatterns()));
        mybatisSettingForm.selectPatternTextField.setText(joiner.join(SELECT_GENERATOR.getPatterns()));
    }

    @Override
    public void disposeUIResources() {
        mybatisSettingForm.mainPanel = null;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/setting/MybatisSetting.java
================================================
package com.wuzhizhan.mybatis.setting;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.wuzhizhan.mybatis.generate.GenerateModel;
import com.wuzhizhan.mybatis.generate.StatementGenerator;
import org.jdom.Element;
import org.jetbrains.annotations.Nullable;

import java.lang.reflect.Type;
import java.util.Set;

import static com.wuzhizhan.mybatis.generate.StatementGenerator.*;

/**
 * @author yanglin
 */
@State(
        name = "MybatisSettings",
        storages = @Storage(file = "$APP_CONFIG$/mybatis.xml"))
public class MybatisSetting implements PersistentStateComponent<Element> {

    private GenerateModel statementGenerateModel;

    private Gson gson = new Gson();

    private Type gsonTypeToken = new TypeToken<Set<String>>() {
    }.getType();

    public MybatisSetting() {
        statementGenerateModel = GenerateModel.START_WITH_MODEL;
    }

    public static MybatisSetting getInstance() {
        return ServiceManager.getService(MybatisSetting.class);
    }

    @Nullable
    @Override
    public Element getState() {
        Element element = new Element("MybatisSettings");
        element.setAttribute(INSERT_GENERATOR.getId(), gson.toJson(INSERT_GENERATOR.getPatterns()));
        element.setAttribute(DELETE_GENERATOR.getId(), gson.toJson(DELETE_GENERATOR.getPatterns()));
        element.setAttribute(UPDATE_GENERATOR.getId(), gson.toJson(UPDATE_GENERATOR.getPatterns()));
        element.setAttribute(SELECT_GENERATOR.getId(), gson.toJson(SELECT_GENERATOR.getPatterns()));
        element.setAttribute("statementGenerateModel", String.valueOf(statementGenerateModel.getIdentifier()));
        return element;
    }

    @Override
    public void loadState(Element state) {
        loadState(state, INSERT_GENERATOR);
        loadState(state, DELETE_GENERATOR);
        loadState(state, UPDATE_GENERATOR);
        loadState(state, SELECT_GENERATOR);
        statementGenerateModel = GenerateModel.getInstance(state.getAttributeValue("statementGenerateModel"));
    }

    private void loadState(Element state, StatementGenerator generator) {
        String attribute = state.getAttributeValue(generator.getId());
        if (null != attribute) {
            generator.setPatterns((Set<String>) gson.fromJson(attribute, gsonTypeToken));
        }
    }

    public GenerateModel getStatementGenerateModel() {
        return statementGenerateModel;
    }

    public void setStatementGenerateModel(GenerateModel statementGenerateModel) {
        this.statementGenerateModel = statementGenerateModel;
    }
}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/setting/MybatisSettingForm.form
================================================
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.wuzhizhan.mybatis.setting.MybatisSettingForm">
  <grid id="27dc6" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
    <margin top="0" left="0" bottom="0" right="0"/>
    <constraints>
      <xy x="20" y="20" width="500" height="400"/>
    </constraints>
    <properties/>
    <border type="none"/>
    <children>
      <grid id="d1e28" binding="mainPanel" layout-manager="GridLayoutManager" row-count="7" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
        <margin top="0" left="0" bottom="0" right="0"/>
        <constraints>
          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties/>
        <border type="none" title="New Mapper Pattern Keywords"/>
        <children>
          <component id="fb090" class="javax.swing.JLabel">
            <constraints>
              <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
            </constraints>
            <properties>
              <text value="Insert"/>
            </properties>
          </component>
          <component id="4d53e" class="javax.swing.JTextField" binding="insertPatternTextField">
            <constraints>
              <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
                <preferred-size width="150" height="-1"/>
              </grid>
            </constraints>
            <properties/>
          </component>
          <component id="45bc" class="javax.swing.JLabel">
            <constraints>
              <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
            </constraints>
            <properties>
              <text value="Delete"/>
            </properties>
          </component>
          <component id="6a666" class="javax.swing.JTextField" binding="deletePatternTextField">
            <constraints>
              <grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
                <preferred-size width="150" height="-1"/>
              </grid>
            </constraints>
            <properties/>
          </component>
          <component id="52010" class="javax.swing.JLabel">
            <constraints>
              <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
            </constraints>
            <properties>
              <text value="Update"/>
            </properties>
          </component>
          <component id="de343" class="javax.swing.JTextField" binding="updatePatternTextField">
            <constraints>
              <grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
                <preferred-size width="150" height="-1"/>
              </grid>
            </constraints>
            <properties/>
          </component>
          <component id="29a0b" class="javax.swing.JLabel">
            <constraints>
              <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
            </constraints>
            <properties>
              <text value="Select"/>
            </properties>
          </component>
          <component id="2b145" class="javax.swing.JTextField" binding="selectPatternTextField">
            <constraints>
              <grid row="5" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
                <preferred-size width="150" height="-1"/>
              </grid>
            </constraints>
            <properties/>
          </component>
          <component id="4f3c9" class="javax.swing.JLabel">
            <constraints>
              <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
            </constraints>
            <properties>
              <text value="Patterns should be separated with &quot;;&quot;"/>
            </properties>
          </component>
          <component id="f7906" class="javax.swing.JComboBox" binding="modelComboBox">
            <constraints>
              <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
            </constraints>
            <properties>
              <model>
                <item value="startWith"/>
                <item value="endWith"/>
                <item value="contain"/>
              </model>
            </properties>
          </component>
          <vspacer id="98e49">
            <constraints>
              <grid row="6" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
            </constraints>
          </vspacer>
          <component id="7d563" class="javax.swing.JLabel">
            <constraints>
              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
            </constraints>
            <properties>
              <text value="Model"/>
            </properties>
          </component>
        </children>
      </grid>
    </children>
  </grid>
</form>


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/setting/MybatisSettingForm.java
================================================
package com.wuzhizhan.mybatis.setting;

import javax.swing.*;

/**
 * @author yanglin
 */
public class MybatisSettingForm {

    public JTextField insertPatternTextField;

    public JTextField deletePatternTextField;

    public JTextField updatePatternTextField;

    public JTextField selectPatternTextField;

    public JPanel mainPanel;

    public JComboBox modelComboBox;

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/template/MybatisFileTemplateDescriptorFactory.java
================================================
package com.wuzhizhan.mybatis.template;

import com.intellij.ide.fileTemplates.FileTemplateDescriptor;
import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptor;
import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptorFactory;
import com.wuzhizhan.mybatis.util.Icons;

/**
 * @author yanglin
 */
public class MybatisFileTemplateDescriptorFactory implements FileTemplateGroupDescriptorFactory {

    public static final String MYBATIS_MAPPER_XML_TEMPLATE = "Mybatis Mapper.xml";

    @Override
    public FileTemplateGroupDescriptor getFileTemplatesDescriptor() {
        FileTemplateGroupDescriptor group = new FileTemplateGroupDescriptor("Mybatis", Icons.MYBATIS_LOGO);
        group.addTemplate(new FileTemplateDescriptor(MYBATIS_MAPPER_XML_TEMPLATE, Icons.MYBATIS_LOGO));
        return group;
    }

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/ui/ClickableListener.java
================================================
package com.wuzhizhan.mybatis.ui;

/**
 * @author yanglin
 */
public interface ClickableListener extends ExecutableListener {

    public void clicked();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/ui/ExecutableListener.java
================================================
package com.wuzhizhan.mybatis.ui;

/**
 * @author yanglin
 */
public interface ExecutableListener {

    public boolean isWriteAction();

}


================================================
FILE: src/main/java/com/wuzhizhan/mybatis/ui/ListSelectionListener.java
================================================
package com.wuzhizhan.mybatis.ui;

/**
 * @author yanglin
 */
public interface ListSelectionListener extends ExecutableListener {

    public void selected(int index);

}

================================================
FILE: src/main/java/com/wuzhizhan/mybatis/ui/UiComponentFacade.java
================================================
package com.wuzhizhan.mybatis.ui;

import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.ui.components.JBList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * @author yanglin
 */
public final class UiComponentFacade {

    private Project project;

    private FileEditorManager fileEditorManager;

    private UiComponentFacade(Project project) {
        this.project = project;
        this.fileEditorManager = FileEditorManager.getInstance(project);
    }

    public static UiComponentFacade getInstance(@NotNull Project project) {
        return new UiComponentFacade(project);
    }

    public VirtualFile showSingleFolderSelectionDialog(@NotNull String title,
                                                       @Nullable VirtualFile toSelect,
                                                       @Nullable VirtualFile... roots) {
        final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
        descriptor.setTitle(title);
        if (null != roots) {
            descriptor.setRoots(roots);
        }
        return FileChooser.chooseFile(descriptor, project, toSelect);
    }

    public JBPopup showListPopupWithSingleClickable(@NotNull String popupTitle,
                                                    @NotNull ListSelectionListener popupListener,
                                                    @NotNull String clickableTitle,
                                                    @Nullable final ClickableListener clickableListener,
                                                    @NotNull Object[] objs) {
        PopupChooserBuilder builder = createListPopupBuilder(popupTitle, popupListener, objs);
        JBCheckBox checkBox = new JBCheckBox(clickableTitle);
        builder.setSouthComponent(checkBox);
        final JBPopup popup = builder.createPopup();
        if (null != clickableListener) {
            final Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    clickableListener.clicked();
                }
            };
            checkBox.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    popup.dispose();
                    setActionForExecutableListener(runnable, clickableListener);
                }
            });
        }
        setPositionForShown(popup);
        return popup;
    }

    public JBPopup showListPopup(@NotNull String title,
                                 @Nullable final ListSelectionListener listener,
                                 @NotNull Object[] objs) {
        PopupChooserBuilder builder = createListPopupBuilder(title, listener, objs);
        JBPopup popup = builder.createPopup();
        setPositionForShown(popup);
        return popup;
    }

    private void setPositionForShown(JBPopup popup) {
        Editor editor = fileEditorManager.getSelectedTextEditor();
        if (null != editor) {
            popup.showInBestPositionFor(editor);
        } else {
            popup.showCenteredInCurrentWindow(project);
        }
    }
Download .txt
gitextract_isxqlwmr/

├── .gitignore
├── LICENSE
├── README.md
├── build.gradle
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src/
    └── main/
        ├── java/
        │   └── com/
        │       └── wuzhizhan/
        │           └── mybatis/
        │               ├── action/
        │               │   └── MybatisTypedHandler.java
        │               ├── alias/
        │               │   ├── AliasClassReference.java
        │               │   ├── AliasDesc.java
        │               │   ├── AliasFacade.java
        │               │   ├── AliasResolver.java
        │               │   ├── AliasResolverFactory.java
        │               │   ├── AnnotationAliasResolver.java
        │               │   ├── BeanAliasResolver.java
        │               │   ├── ConfigPackageAliasResolver.java
        │               │   ├── InnerAliasResolver.java
        │               │   ├── PackageAliasResolver.java
        │               │   └── SingleAliasResolver.java
        │               ├── annotation/
        │               │   └── Annotation.java
        │               ├── contributor/
        │               │   ├── JavaMenthodCompletionContributor.java
        │               │   ├── SqlParamCompletionContributor.java
        │               │   └── TestParamContributor.java
        │               ├── definitionsearch/
        │               │   └── MapperDefinitionSearch.java
        │               ├── dom/
        │               │   ├── MapperBacktrackingUtils.java
        │               │   ├── converter/
        │               │   │   ├── AliasConverter.java
        │               │   │   ├── ConverterAdaptor.java
        │               │   │   ├── DaoMethodConverter.java
        │               │   │   ├── IdBasedTagConverter.java
        │               │   │   ├── ParameterMapConverter.java
        │               │   │   ├── PropertyConverter.java
        │               │   │   ├── ResultMapConverter.java
        │               │   │   └── SqlConverter.java
        │               │   ├── description/
        │               │   │   ├── ConfigurationDescription.java
        │               │   │   └── MapperDescription.java
        │               │   └── model/
        │               │       ├── Arg.java
        │               │       ├── Association.java
        │               │       ├── Bean.java
        │               │       ├── BeanProperty.java
        │               │       ├── Beans.java
        │               │       ├── Bind.java
        │               │       ├── Cache.java
        │               │       ├── CacheRef.java
        │               │       ├── Case.java
        │               │       ├── Choose.java
        │               │       ├── Collection.java
        │               │       ├── Configuration.java
        │               │       ├── Constructor.java
        │               │       ├── Delete.java
        │               │       ├── Discriminator.java
        │               │       ├── Foreach.java
        │               │       ├── GroupFour.java
        │               │       ├── GroupOne.java
        │               │       ├── GroupThree.java
        │               │       ├── GroupTwo.java
        │               │       ├── Id.java
        │               │       ├── IdArg.java
        │               │       ├── IdDomElement.java
        │               │       ├── If.java
        │               │       ├── Include.java
        │               │       ├── Insert.java
        │               │       ├── Mapper.java
        │               │       ├── Otherwise.java
        │               │       ├── Package.java
        │               │       ├── Parameter.java
        │               │       ├── ParameterMap.java
        │               │       ├── Property.java
        │               │       ├── PropertyGroup.java
        │               │       ├── Result.java
        │               │       ├── ResultMap.java
        │               │       ├── ResultMapGroup.java
        │               │       ├── Select.java
        │               │       ├── SelectKey.java
        │               │       ├── Set.java
        │               │       ├── Sql.java
        │               │       ├── Trim.java
        │               │       ├── TypeAlias.java
        │               │       ├── TypeAliases.java
        │               │       ├── Update.java
        │               │       ├── When.java
        │               │       └── Where.java
        │               ├── generate/
        │               │   ├── DeleteGenerator.java
        │               │   ├── GenerateModel.java
        │               │   ├── InsertGenerator.java
        │               │   ├── SelectGenerator.java
        │               │   ├── StatementGenerator.java
        │               │   └── UpdateGenerator.java
        │               ├── inspection/
        │               │   ├── GenericQuickFix.java
        │               │   ├── MapperInspection.java
        │               │   ├── MapperMethodInspection.java
        │               │   ├── MapperXmlInspection.java
        │               │   ├── ResultTypeQuickFix.java
        │               │   └── StatementNotExistsQuickFix.java
        │               ├── intention/
        │               │   ├── GenerateMapperChooser.java
        │               │   ├── GenerateMapperIntention.java
        │               │   ├── GenerateParamAnnotationIntention.java
        │               │   ├── GenerateParamChooser.java
        │               │   ├── GenerateStatementChooser.java
        │               │   ├── GenerateStatementIntention.java
        │               │   ├── GenericIntention.java
        │               │   ├── IntentionChooser.java
        │               │   └── JavaFileIntentionChooser.java
        │               ├── locator/
        │               │   ├── LocateStrategy.java
        │               │   ├── MapperLocator.java
        │               │   ├── MapperXmlPackageProvider.java
        │               │   ├── PackageLocateStrategy.java
        │               │   └── PackageProvider.java
        │               ├── provider/
        │               │   ├── InjectionLineMarkerProvider.java
        │               │   ├── MapperLineMarkerProvider.java
        │               │   ├── MarkerProviderAdaptor.java
        │               │   ├── SimpleLineMarkerProvider.java
        │               │   └── StatementLineMarkerProvider.java
        │               ├── refactoring/
        │               │   └── MapperRefactoringProvider.java
        │               ├── reference/
        │               │   ├── ContextPsiFieldReference.java
        │               │   ├── ContextReferenceSetResolver.java
        │               │   ├── PsiFieldReferenceSetResolver.java
        │               │   ├── ReferenceSetResolverFactory.java
        │               │   └── ResultPropertyReferenceSet.java
        │               ├── service/
        │               │   ├── AnnotationService.java
        │               │   ├── EditorService.java
        │               │   ├── JavaService.java
        │               │   └── TableInfoService.java
        │               ├── setting/
        │               │   ├── MybatisConfigurable.java
        │               │   ├── MybatisSetting.java
        │               │   ├── MybatisSettingForm.form
        │               │   └── MybatisSettingForm.java
        │               ├── template/
        │               │   └── MybatisFileTemplateDescriptorFactory.java
        │               ├── ui/
        │               │   ├── ClickableListener.java
        │               │   ├── ExecutableListener.java
        │               │   ├── ListSelectionListener.java
        │               │   └── UiComponentFacade.java
        │               └── util/
        │                   ├── ArrayUtils.java
        │                   ├── CollectionUtils.java
        │                   ├── DomUtils.java
        │                   ├── Icons.java
        │                   ├── JTextFieldHintListener.java
        │                   ├── JavaUtils.java
        │                   ├── MapperUtils.java
        │                   ├── MybatisConstants.java
        │                   └── StringUtils.java
        └── resources/
            ├── META-INF/
            │   └── plugin.xml
            ├── fileTemplates/
            │   └── j2ee/
            │       └── Mybatis Mapper.xml.ft
            └── liveTemplates/
                └── sql.xml
Download .txt
SYMBOL INDEX (571 symbols across 132 files)

FILE: src/main/java/com/wuzhizhan/mybatis/action/MybatisTypedHandler.java
  class MybatisTypedHandler (line 15) | public class MybatisTypedHandler extends TypedHandlerDelegate {
    method checkAutoPopup (line 17) | @Override
    method charTyped (line 26) | @Override
    method autoPopupParameter (line 42) | private static void autoPopupParameter(final Project project, final Ed...

FILE: src/main/java/com/wuzhizhan/mybatis/alias/AliasClassReference.java
  class AliasClassReference (line 16) | public class AliasClassReference extends PsiReferenceBase<XmlAttributeVa...
    method apply (line 19) | @Override
    method AliasClassReference (line 25) | public AliasClassReference(@NotNull XmlAttributeValue element) {
    method resolve (line 29) | @Nullable
    method getVariants (line 36) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/alias/AliasDesc.java
  class AliasDesc (line 9) | public class AliasDesc {
    method AliasDesc (line 15) | public AliasDesc() {
    method create (line 18) | public static AliasDesc create(@NotNull PsiClass psiClass, @NotNull St...
    method AliasDesc (line 22) | public AliasDesc(PsiClass clazz, String alias) {
    method getClazz (line 27) | public PsiClass getClazz() {
    method setClazz (line 31) | public void setClazz(PsiClass clazz) {
    method getAlias (line 35) | public String getAlias() {
    method setAlias (line 39) | public void setAlias(String alias) {
    method equals (line 43) | @Override
    method hashCode (line 64) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/alias/AliasFacade.java
  class AliasFacade (line 21) | public class AliasFacade {
    method getInstance (line 29) | public static final AliasFacade getInstance(@NotNull Project project) {
    method AliasFacade (line 33) | public AliasFacade(Project project) {
    method initResolvers (line 40) | private void initResolvers() {
    method findPsiClass (line 52) | @NotNull
    method getAliasDescs (line 68) | @NotNull
    method findAliasDesc (line 77) | public Optional<AliasDesc> findAliasDesc(@Nullable PsiClass clazz) {
    method registerResolver (line 91) | public void registerResolver(@NotNull AliasResolver resolver) {

FILE: src/main/java/com/wuzhizhan/mybatis/alias/AliasResolver.java
  class AliasResolver (line 16) | public abstract class AliasResolver {
    method AliasResolver (line 20) | public AliasResolver(Project project) {
    method addAliasDesc (line 24) | @NotNull
    method getClassAliasDescriptions (line 36) | @NotNull
    method getProject (line 39) | public Project getProject() {
    method setProject (line 43) | public void setProject(Project project) {

FILE: src/main/java/com/wuzhizhan/mybatis/alias/AliasResolverFactory.java
  class AliasResolverFactory (line 9) | public class AliasResolverFactory {
    method createInnerAliasResolver (line 11) | @NotNull
    method createAnnotationResolver (line 16) | @NotNull
    method createBeanResolver (line 21) | @NotNull
    method createConfigPackageResolver (line 26) | @NotNull
    method createSingleAliasResolver (line 31) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/alias/AnnotationAliasResolver.java
  class AnnotationAliasResolver (line 24) | public class AnnotationAliasResolver extends AliasResolver {
    method apply (line 27) | @Override
    method AnnotationAliasResolver (line 38) | public AnnotationAliasResolver(Project project) {
    method getInstance (line 42) | public static final AnnotationAliasResolver getInstance(@NotNull Proje...
    method getClassAliasDescriptions (line 46) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/alias/BeanAliasResolver.java
  class BeanAliasResolver (line 16) | public class BeanAliasResolver extends PackageAliasResolver {
    method BeanAliasResolver (line 22) | public BeanAliasResolver(Project project) {
    method getPackages (line 27) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/alias/ConfigPackageAliasResolver.java
  class ConfigPackageAliasResolver (line 18) | public class ConfigPackageAliasResolver extends PackageAliasResolver {
    method ConfigPackageAliasResolver (line 20) | public ConfigPackageAliasResolver(Project project) {
    method getPackages (line 24) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/alias/InnerAliasResolver.java
  class InnerAliasResolver (line 15) | public class InnerAliasResolver extends AliasResolver {
    method InnerAliasResolver (line 38) | public InnerAliasResolver(Project project) {
    method getClassAliasDescriptions (line 42) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/alias/PackageAliasResolver.java
  class PackageAliasResolver (line 18) | public abstract class PackageAliasResolver extends AliasResolver {
    method PackageAliasResolver (line 22) | public PackageAliasResolver(Project project) {
    method getClassAliasDescriptions (line 27) | @NotNull
    method addAliasDesc (line 46) | private void addAliasDesc(Set<AliasDesc> result, PsiPackage pkg) {
    method getPackages (line 52) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/alias/SingleAliasResolver.java
  class SingleAliasResolver (line 17) | public class SingleAliasResolver extends AliasResolver {
    method SingleAliasResolver (line 19) | public SingleAliasResolver(Project project) {
    method getClassAliasDescriptions (line 23) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/annotation/Annotation.java
  class Annotation (line 21) | public class Annotation implements Cloneable {
    type AnnotationValue (line 53) | public interface AnnotationValue {
    class StringValue (line 56) | public static class StringValue implements AnnotationValue {
      method StringValue (line 60) | public StringValue(@NotNull String value) {
      method toString (line 64) | @Override
    method Annotation (line 71) | public Annotation(@NotNull String label, @NotNull String qualifiedName) {
    method addAttribute (line 77) | private Annotation addAttribute(String key, AnnotationValue value) {
    method withAttribute (line 82) | public Annotation withAttribute(@NotNull String key, @NotNull Annotati...
    method withValue (line 88) | public Annotation withValue(@NotNull AnnotationValue value) {
    method toString (line 92) | @Override
    method setupAttributeText (line 101) | private String setupAttributeText() {
    method getComplexValue (line 106) | private String getComplexValue() {
    method toPsiClass (line 120) | @NotNull
    method getSingleValue (line 125) | private Optional<String> getSingleValue() {
    method getLabel (line 137) | @NotNull
    method getQualifiedName (line 142) | @NotNull
    method clone (line 147) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/contributor/JavaMenthodCompletionContributor.java
  class JavaMenthodCompletionContributor (line 8) | public class JavaMenthodCompletionContributor extends CompletionContribu...
    method fillCompletionVariants (line 9) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/contributor/SqlParamCompletionContributor.java
  class SqlParamCompletionContributor (line 21) | public class SqlParamCompletionContributor extends CompletionContributor {
    method fillCompletionVariants (line 23) | @Override
    method process (line 38) | private void process(PsiFile xmlFile, CompletionResultSet result, PsiE...
    method shouldAddElement (line 50) | private boolean shouldAddElement(PsiFile file, int offset) {

FILE: src/main/java/com/wuzhizhan/mybatis/contributor/TestParamContributor.java
  class TestParamContributor (line 28) | public class TestParamContributor extends CompletionContributor {
    method TestParamContributor (line 31) | public TestParamContributor() {
    method addElementForPsiParameter (line 51) | static void addElementForPsiParameter(
    method buildLookupElementWithIcon (line 87) | private static LookupElement buildLookupElementWithIcon(

FILE: src/main/java/com/wuzhizhan/mybatis/definitionsearch/MapperDefinitionSearch.java
  class MapperDefinitionSearch (line 16) | public class MapperDefinitionSearch extends QueryExecutorBase<XmlElement...
    method MapperDefinitionSearch (line 18) | public MapperDefinitionSearch() {
    method processQuery (line 22) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/dom/MapperBacktrackingUtils.java
  class MapperBacktrackingUtils (line 21) | public final class MapperBacktrackingUtils {
    method MapperBacktrackingUtils (line 23) | private MapperBacktrackingUtils() {
    method getPropertyClazz (line 27) | public static Optional<PsiClass> getPropertyClazz(XmlAttributeValue at...
    method isWithinSameTag (line 55) | public static boolean isWithinSameTag(@NotNull DomElement domElement, ...

FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/AliasConverter.java
  class AliasConverter (line 20) | public class AliasConverter extends ConverterAdaptor<PsiClass> implement...
    method fromString (line 24) | @Nullable
    method toString (line 34) | @Nullable
    method createReferences (line 40) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/ConverterAdaptor.java
  class ConverterAdaptor (line 15) | public abstract class ConverterAdaptor<T> extends ResolvingConverter<T> {
    method getVariants (line 17) | @NotNull
    method toString (line 23) | @Nullable
    method fromString (line 30) | @Nullable

FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/DaoMethodConverter.java
  class DaoMethodConverter (line 14) | public class DaoMethodConverter extends ConverterAdaptor<PsiMethod> {
    method fromString (line 16) | @Nullable

FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/IdBasedTagConverter.java
  class IdBasedTagConverter (line 28) | public abstract class IdBasedTagConverter extends ConverterAdaptor<XmlAt...
    method IdBasedTagConverter (line 32) | public IdBasedTagConverter() {
    method IdBasedTagConverter (line 36) | protected IdBasedTagConverter(boolean crossMapperSupported) {
    method fromString (line 40) | @Nullable
    method matchIdDomElement (line 46) | @NotNull
    method toString (line 58) | @Nullable
    method selectStrategy (line 69) | private TraverseStrategy selectStrategy(ConvertContext context) {
    method getComparisons (line 77) | @NotNull
    class TraverseStrategy (line 80) | private abstract class TraverseStrategy {
      method TraverseStrategy (line 83) | public TraverseStrategy(@NotNull ConvertContext context) {
      method getValue (line 87) | public abstract Collection<? extends IdDomElement> getValue();
    class InsideMapperStrategy (line 90) | private class InsideMapperStrategy extends TraverseStrategy {
      method InsideMapperStrategy (line 92) | public InsideMapperStrategy(@NotNull ConvertContext context) {
      method getValue (line 96) | @Override
    class CrossMapperStrategy (line 103) | private class CrossMapperStrategy extends TraverseStrategy {
      method CrossMapperStrategy (line 105) | public CrossMapperStrategy(@NotNull ConvertContext context) {
      method getValue (line 109) | @Override
    method createReferences (line 120) | @NotNull
    class ValueReferenceProvider (line 126) | private class ValueReferenceProvider extends JavaClassReferenceProvider {
      method ValueReferenceProvider (line 130) | private ValueReferenceProvider(ConvertContext context) {
      method getScope (line 134) | @Nullable
      method getReferencesByString (line 143) | @NotNull
      method getTextRange (line 155) | private TextRange getTextRange(PsiElement element) {
    class ValueReference (line 162) | private class ValueReference extends PsiReferenceBase<PsiElement> {
      method ValueReference (line 167) | public ValueReference(@NotNull PsiElement element, TextRange rng, Co...
      method resolve (line 173) | @Nullable
      method getVariants (line 179) | @NotNull
      method setupContextIdSignature (line 186) | private Set<String> setupContextIdSignature() {
      method setupGlobalIdSignature (line 197) | private Set<String> setupGlobalIdSignature() {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/ParameterMapConverter.java
  class ParameterMapConverter (line 14) | public class ParameterMapConverter extends IdBasedTagConverter {
    method getComparisons (line 16) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/PropertyConverter.java
  class PropertyConverter (line 16) | public class PropertyConverter extends ConverterAdaptor<XmlAttributeValu...
    method createReferences (line 18) | @NotNull
    method fromString (line 28) | @Nullable

FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/ResultMapConverter.java
  class ResultMapConverter (line 19) | public class ResultMapConverter extends IdBasedTagConverter {
    method getComparisons (line 21) | @NotNull
    method isContextElementOfResultMap (line 32) | private boolean isContextElementOfResultMap(Mapper mapper, DomElement ...
    method doFilterResultMapItself (line 37) | private Collection<? extends IdDomElement> doFilterResultMapItself(Map...

FILE: src/main/java/com/wuzhizhan/mybatis/dom/converter/SqlConverter.java
  class SqlConverter (line 14) | public class SqlConverter extends IdBasedTagConverter {
    method getComparisons (line 16) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/description/ConfigurationDescription.java
  class ConfigurationDescription (line 14) | public class ConfigurationDescription extends DomFileDescription<Configu...
    method ConfigurationDescription (line 16) | public ConfigurationDescription() {
    method isMyFile (line 20) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/dom/description/MapperDescription.java
  class MapperDescription (line 14) | public class MapperDescription extends DomFileDescription<Mapper> {
    method MapperDescription (line 16) | public MapperDescription() {
    method isMyFile (line 20) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Arg.java
  type Arg (line 8) | public interface Arg extends DomElement {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Association.java
  type Association (line 13) | public interface Association extends GroupFour, ResultMapGroup, Property...
    method getJavaType (line 15) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Bean.java
  type Bean (line 12) | public interface Bean extends DomElement {
    method getBeanProperties (line 14) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/BeanProperty.java
  type BeanProperty (line 11) | public interface BeanProperty extends DomElement {
    method getName (line 13) | @NotNull
    method getValue (line 17) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Beans.java
  type Beans (line 12) | public interface Beans extends DomElement {
    method getBeans (line 14) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Bind.java
  type Bind (line 8) | public interface Bind extends DomElement {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Cache.java
  type Cache (line 11) | public interface Cache extends DomElement {
    method getProperties (line 13) | @SubTagList("property")

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/CacheRef.java
  type CacheRef (line 8) | public interface CacheRef extends DomElement {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Case.java
  type Case (line 6) | public interface Case extends GroupFour {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Choose.java
  type Choose (line 14) | public interface Choose extends DomElement {
    method getWhens (line 16) | @NotNull
    method getOtherwise (line 21) | @SubTag("otherwise")

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Collection.java
  type Collection (line 13) | public interface Collection extends GroupFour, ResultMapGroup, PropertyG...
    method getOfType (line 15) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Configuration.java
  type Configuration (line 12) | public interface Configuration extends DomElement {
    method getTypeAliases (line 14) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Constructor.java
  type Constructor (line 11) | public interface Constructor extends DomElement {
    method getArgs (line 13) | @SubTagList("arg")
    method getIdArgs (line 16) | @SubTagList("idArg")

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Delete.java
  type Delete (line 6) | public interface Delete extends GroupTwo {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Discriminator.java
  type Discriminator (line 12) | public interface Discriminator extends DomElement {
    method getCases (line 14) | @Required

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Foreach.java
  type Foreach (line 6) | public interface Foreach extends GroupOne {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/GroupFour.java
  type GroupFour (line 12) | public interface GroupFour extends DomElement {
    method getConstructor (line 14) | @SubTag("constructor")
    method getIds (line 17) | @SubTagList("id")
    method getResults (line 20) | @SubTagList("result")
    method getAssociations (line 23) | @SubTagList("association")
    method getCollections (line 26) | @SubTagList("collection")
    method getDiscriminator (line 29) | @SubTag("discriminator")

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/GroupOne.java
  type GroupOne (line 12) | public interface GroupOne extends DomElement {
    method getIncludes (line 14) | @NotNull
    method getTrims (line 18) | @NotNull
    method getWheres (line 22) | @NotNull
    method getSets (line 26) | @NotNull
    method getForeachs (line 30) | @NotNull
    method getChooses (line 34) | @NotNull
    method getIfs (line 38) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/GroupThree.java
  type GroupThree (line 10) | public interface GroupThree extends GroupTwo {
    method getSelectKey (line 12) | @SubTagList("selectKey")

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/GroupTwo.java
  type GroupTwo (line 19) | public interface GroupTwo extends GroupOne, IdDomElement {
    method getBinds (line 21) | @SubTagList("bind")
    method getParameterMap (line 24) | @NotNull
    method getId (line 29) | @Attribute("id")
    method getParameterType (line 33) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Id.java
  type Id (line 6) | public interface Id extends PropertyGroup {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/IdArg.java
  type IdArg (line 8) | public interface IdArg extends DomElement {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/IdDomElement.java
  type IdDomElement (line 8) | public interface IdDomElement extends DomElement {
    method getId (line 10) | @Required
    method setValue (line 15) | public void setValue(String content);

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/If.java
  type If (line 6) | public interface If extends GroupOne {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Include.java
  type Include (line 13) | public interface Include extends DomElement {
    method getRefId (line 15) | @Attribute("refid")

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Insert.java
  type Insert (line 6) | public interface Insert extends GroupThree {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Mapper.java
  type Mapper (line 11) | public interface Mapper extends DomElement {
    method getDaoElements (line 13) | @NotNull
    method getNamespace (line 17) | @Required
    method getResultMaps (line 23) | @NotNull
    method getParameterMaps (line 27) | @NotNull
    method getSqls (line 31) | @NotNull
    method getInserts (line 35) | @NotNull
    method getUpdates (line 39) | @NotNull
    method getDeletes (line 43) | @NotNull
    method getSelects (line 47) | @NotNull
    method addSelect (line 51) | @SubTagList("select")
    method addUpdate (line 54) | @SubTagList("update")
    method addInsert (line 57) | @SubTagList("insert")
    method addDelete (line 60) | @SubTagList("delete")

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Otherwise.java
  type Otherwise (line 6) | public interface Otherwise extends GroupOne {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Package.java
  type Package (line 11) | public interface Package extends DomElement {
    method getName (line 13) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Parameter.java
  type Parameter (line 6) | public interface Parameter extends PropertyGroup {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/ParameterMap.java
  type ParameterMap (line 16) | public interface ParameterMap extends IdDomElement {
    method getType (line 18) | @NotNull
    method getParameters (line 23) | @SubTagList("parameter")

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Property.java
  type Property (line 8) | public interface Property extends DomElement {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/PropertyGroup.java
  type PropertyGroup (line 13) | public interface PropertyGroup extends DomElement {
    method getProperty (line 15) | @Attribute("property")

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Result.java
  type Result (line 6) | public interface Result extends PropertyGroup {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/ResultMap.java
  type ResultMap (line 15) | public interface ResultMap extends GroupFour, IdDomElement {
    method getExtends (line 17) | @NotNull
    method getType (line 22) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/ResultMapGroup.java
  type ResultMapGroup (line 14) | public interface ResultMapGroup extends DomElement {
    method getResultMap (line 16) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Select.java
  type Select (line 13) | public interface Select extends GroupTwo, ResultMapGroup {
    method getResultType (line 15) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/SelectKey.java
  type SelectKey (line 13) | public interface SelectKey extends GroupOne {
    method getResultType (line 14) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Set.java
  type Set (line 6) | public interface Set extends GroupOne {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Sql.java
  type Sql (line 6) | public interface Sql extends GroupOne, IdDomElement {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Trim.java
  type Trim (line 6) | public interface Trim extends GroupOne {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/TypeAlias.java
  type TypeAlias (line 12) | public interface TypeAlias extends DomElement {
    method getType (line 14) | @NotNull
    method getAlias (line 18) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/TypeAliases.java
  type TypeAliases (line 12) | public interface TypeAliases extends DomElement {
    method getTypeAlias (line 14) | @NotNull
    method getPackages (line 18) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Update.java
  type Update (line 6) | public interface Update extends GroupTwo {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/When.java
  type When (line 6) | public interface When extends GroupOne {

FILE: src/main/java/com/wuzhizhan/mybatis/dom/model/Where.java
  type Where (line 6) | public interface Where extends GroupOne {

FILE: src/main/java/com/wuzhizhan/mybatis/generate/DeleteGenerator.java
  class DeleteGenerator (line 11) | public class DeleteGenerator extends StatementGenerator {
    method DeleteGenerator (line 13) | public DeleteGenerator(@NotNull String... patterns) {
    method getTarget (line 17) | @NotNull
    method getId (line 23) | @NotNull
    method getDisplayText (line 29) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/generate/GenerateModel.java
  class GenerateModel (line 8) | public abstract class GenerateModel {
    method getInstance (line 16) | public static GenerateModel getInstance(String identifier) {
    method getInstance (line 24) | public static GenerateModel getInstance(int identifier) {
    method matchesAny (line 37) | public boolean matchesAny(String[] patterns, String target) {
    method matchesAny (line 46) | public boolean matchesAny(Collection<String> patterns, String target) {
    method apply (line 50) | protected abstract boolean apply(String pattern, String target);
    method getIdentifier (line 52) | public abstract int getIdentifier();
    class StartWithModel (line 54) | static class StartWithModel extends GenerateModel {
      method apply (line 56) | @Override
      method getIdentifier (line 61) | @Override
    class EndWithModel (line 67) | static class EndWithModel extends GenerateModel {
      method apply (line 69) | @Override
      method getIdentifier (line 74) | @Override
    class ContainModel (line 80) | static class ContainModel extends GenerateModel {
      method apply (line 82) | @Override
      method getIdentifier (line 87) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/generate/InsertGenerator.java
  class InsertGenerator (line 11) | public class InsertGenerator extends StatementGenerator {
    method InsertGenerator (line 13) | public InsertGenerator(@NotNull String... patterns) {
    method getTarget (line 17) | @NotNull
    method getId (line 23) | @NotNull
    method getDisplayText (line 29) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/generate/SelectGenerator.java
  class SelectGenerator (line 15) | public class SelectGenerator extends StatementGenerator {
    method SelectGenerator (line 17) | public SelectGenerator(@NotNull String... patterns) {
    method getTarget (line 21) | @NotNull
    method setupResultType (line 29) | private void setupResultType(PsiMethod method, Select select) {
    method getId (line 36) | @NotNull
    method getDisplayText (line 42) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/generate/StatementGenerator.java
  class StatementGenerator (line 35) | public abstract class StatementGenerator {
    method apply (line 48) | @Override
    method getSelectResultType (line 56) | public static Optional<PsiClass> getSelectResultType(@Nullable PsiMeth...
    method doGenerate (line 76) | private static void doGenerate(@NotNull final StatementGenerator gener...
    method applyGenerate (line 84) | public static void applyGenerate(@Nullable final PsiMethod method) {
    method getGenerators (line 110) | @NotNull
    method StatementGenerator (line 125) | public StatementGenerator(@NotNull String... patterns) {
    method execute (line 129) | public void execute(@NotNull final PsiMethod method) {
    method setupTag (line 153) | private void setupTag(PsiMethod method, Mapper mapper) {
    method toString (line 164) | @Override
    method getTarget (line 169) | @NotNull
    method getId (line 172) | @NotNull
    method getDisplayText (line 175) | @NotNull
    method getPatterns (line 178) | public Set<String> getPatterns() {
    method setPatterns (line 182) | public void setPatterns(Set<String> patterns) {

FILE: src/main/java/com/wuzhizhan/mybatis/generate/UpdateGenerator.java
  class UpdateGenerator (line 11) | public class UpdateGenerator extends StatementGenerator {
    method UpdateGenerator (line 13) | public UpdateGenerator(@NotNull String... patterns) {
    method getTarget (line 17) | @NotNull
    method getId (line 23) | @NotNull
    method getDisplayText (line 29) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/inspection/GenericQuickFix.java
  class GenericQuickFix (line 9) | public abstract class GenericQuickFix implements LocalQuickFix {
    method getFamilyName (line 11) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/inspection/MapperInspection.java
  class MapperInspection (line 9) | public abstract class MapperInspection extends BaseJavaLocalInspectionTo...

FILE: src/main/java/com/wuzhizhan/mybatis/inspection/MapperMethodInspection.java
  class MapperMethodInspection (line 28) | public class MapperMethodInspection extends MapperInspection {
    method checkMethod (line 29) | @Nullable
    method createProblemDescriptors (line 45) | private List<ProblemDescriptor> createProblemDescriptors(
    method checkResultType (line 65) | private Optional<ProblemDescriptor> checkResultType(
    method checkStatementExists (line 122) | private Optional<ProblemDescriptor> checkStatementExists(

FILE: src/main/java/com/wuzhizhan/mybatis/inspection/MapperXmlInspection.java
  class MapperXmlInspection (line 11) | public class MapperXmlInspection extends BasicDomElementsInspection<DomE...
    method MapperXmlInspection (line 13) | public MapperXmlInspection() {
    method checkDomElement (line 17) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/inspection/ResultTypeQuickFix.java
  class ResultTypeQuickFix (line 13) | public class ResultTypeQuickFix extends GenericQuickFix {
    method ResultTypeQuickFix (line 18) | public ResultTypeQuickFix(@NotNull Select select, @NotNull PsiClass ta...
    method getName (line 23) | @NotNull
    method applyFix (line 29) | @Override
    method getTarget (line 35) | @NotNull
    method setTarget (line 40) | public void setTarget(@NotNull PsiClass target) {
    method getSelect (line 44) | @NotNull
    method setSelect (line 49) | public void setSelect(@NotNull Select select) {

FILE: src/main/java/com/wuzhizhan/mybatis/inspection/StatementNotExistsQuickFix.java
  class StatementNotExistsQuickFix (line 12) | public class StatementNotExistsQuickFix extends GenericQuickFix {
    method StatementNotExistsQuickFix (line 16) | public StatementNotExistsQuickFix(@NotNull PsiMethod method) {
    method getName (line 20) | @NotNull
    method applyFix (line 26) | @Override
    method getMethod (line 31) | @NotNull
    method setMethod (line 36) | public void setMethod(@NotNull PsiMethod method) {

FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenerateMapperChooser.java
  class GenerateMapperChooser (line 11) | public class GenerateMapperChooser extends JavaFileIntentionChooser {
    method isAvailable (line 15) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenerateMapperIntention.java
  class GenerateMapperIntention (line 32) | public class GenerateMapperIntention extends GenericIntention {
    method GenerateMapperIntention (line 34) | public GenerateMapperIntention() {
    method getText (line 38) | @NotNull
    method startInWriteAction (line 44) | @Override
    method invoke (line 49) | @Override
    method handleMutilDirectories (line 61) | private void handleMutilDirectories(Project project,
    method getChooseFolderListener (line 86) | private ClickableListener getChooseFolderListener(final Editor editor,...
    method handleChooseNewFolder (line 101) | private void handleChooseNewFolder(Project project, Editor editor, Psi...
    method getPathTextForShown (line 110) | private String[] getPathTextForShown(Project project, List<String> pat...
    method getPathMap (line 124) | private Map<String, PsiDirectory> getPathMap(Collection<PsiDirectory> ...
    method processGenerate (line 135) | private void processGenerate(Editor editor, PsiClass clazz, PsiDirecto...

FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenerateParamAnnotationIntention.java
  class GenerateParamAnnotationIntention (line 17) | public class GenerateParamAnnotationIntention extends GenericIntention {
    method GenerateParamAnnotationIntention (line 19) | public GenerateParamAnnotationIntention() {
    method getText (line 23) | @NotNull
    method invoke (line 29) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenerateParamChooser.java
  class GenerateParamChooser (line 14) | public class GenerateParamChooser extends JavaFileIntentionChooser {
    method isAvailable (line 18) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenerateStatementChooser.java
  class GenerateStatementChooser (line 14) | public class GenerateStatementChooser extends JavaFileIntentionChooser {
    method isAvailable (line 18) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenerateStatementIntention.java
  class GenerateStatementIntention (line 16) | public class GenerateStatementIntention extends GenericIntention {
    method GenerateStatementIntention (line 18) | public GenerateStatementIntention() {
    method getText (line 22) | @NotNull
    method invoke (line 28) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/intention/GenericIntention.java
  class GenericIntention (line 12) | public abstract class GenericIntention implements IntentionAction {
    method GenericIntention (line 16) | public GenericIntention(@NotNull IntentionChooser chooser) {
    method getFamilyName (line 20) | @NotNull
    method isAvailable (line 26) | @Override
    method startInWriteAction (line 31) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/intention/IntentionChooser.java
  type IntentionChooser (line 11) | public interface IntentionChooser {
    method isAvailable (line 13) | public boolean isAvailable(@NotNull Project project, Editor editor, Ps...

FILE: src/main/java/com/wuzhizhan/mybatis/intention/JavaFileIntentionChooser.java
  class JavaFileIntentionChooser (line 13) | public abstract class JavaFileIntentionChooser implements IntentionChoos...
    method isAvailable (line 15) | @Override
    method isAvailable (line 23) | public abstract boolean isAvailable(@NotNull PsiElement element);
    method isPositionOfParameterDeclaration (line 25) | public boolean isPositionOfParameterDeclaration(@NotNull PsiElement el...
    method isPositionOfMethodDeclaration (line 29) | public boolean isPositionOfMethodDeclaration(@NotNull PsiElement eleme...
    method isPositionOfInterfaceDeclaration (line 33) | public boolean isPositionOfInterfaceDeclaration(@NotNull PsiElement el...
    method isTargetPresentInXml (line 37) | public boolean isTargetPresentInXml(@NotNull PsiElement element) {

FILE: src/main/java/com/wuzhizhan/mybatis/locator/LocateStrategy.java
  class LocateStrategy (line 9) | public abstract class LocateStrategy {
    method apply (line 11) | public abstract boolean apply(@NotNull PsiClass clazz);

FILE: src/main/java/com/wuzhizhan/mybatis/locator/MapperLocator.java
  class MapperLocator (line 14) | public class MapperLocator {
    method getInstance (line 18) | public static MapperLocator getInstance(@NotNull Project project) {
    method process (line 22) | public boolean process(@Nullable PsiMethod method) {
    method process (line 26) | public boolean process(@Nullable PsiClass clazz) {

FILE: src/main/java/com/wuzhizhan/mybatis/locator/MapperXmlPackageProvider.java
  class MapperXmlPackageProvider (line 18) | public class MapperXmlPackageProvider extends PackageProvider {
    method getPackages (line 20) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/locator/PackageLocateStrategy.java
  class PackageLocateStrategy (line 12) | public class PackageLocateStrategy extends LocateStrategy {
    method apply (line 16) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/locator/PackageProvider.java
  class PackageProvider (line 12) | public abstract class PackageProvider {
    method getPackages (line 14) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/provider/InjectionLineMarkerProvider.java
  class InjectionLineMarkerProvider (line 23) | public class InjectionLineMarkerProvider extends RelatedItemLineMarkerPr...
    method collectNavigationMarkers (line 25) | @Override
    method isTargetField (line 49) | private boolean isTargetField(PsiField field) {

FILE: src/main/java/com/wuzhizhan/mybatis/provider/MapperLineMarkerProvider.java
  class MapperLineMarkerProvider (line 25) | public class MapperLineMarkerProvider extends RelatedItemLineMarkerProvi...
    method apply (line 28) | @Override
    method collectNavigationMarkers (line 34) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/provider/MarkerProviderAdaptor.java
  class MarkerProviderAdaptor (line 15) | public abstract class MarkerProviderAdaptor implements LineMarkerProvider {
    method collectSlowLineMarkers (line 17) | @Override
    method getLineMarkerInfo (line 22) | @Nullable

FILE: src/main/java/com/wuzhizhan/mybatis/provider/SimpleLineMarkerProvider.java
  class SimpleLineMarkerProvider (line 22) | public abstract class SimpleLineMarkerProvider<F extends PsiElement, T> ...
    method collectSlowLineMarkers (line 24) | @Override
    method getLineMarkerInfo (line 28) | @SuppressWarnings("unchecked")
    method getTooltipProvider (line 45) | private Function<F, String> getTooltipProvider(final T target) {
    method getNavigationHandler (line 54) | private GutterIconNavigationHandler<F> getNavigationHandler(final T ta...
    method isTheElement (line 63) | public abstract boolean isTheElement(@NotNull PsiElement element);
    method apply (line 65) | @NotNull
    method getNavigatable (line 68) | @NotNull
    method getTooltip (line 71) | @NotNull
    method getIcon (line 74) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/provider/StatementLineMarkerProvider.java
  class StatementLineMarkerProvider (line 22) | public class StatementLineMarkerProvider extends SimpleLineMarkerProvide...
    method isTheElement (line 31) | @Override
    method apply (line 38) | @SuppressWarnings("unchecked")
    method isTargetType (line 46) | private boolean isTargetType(PsiElement element) {
    method getNavigatable (line 55) | @SuppressWarnings("unchecked")
    method getTooltip (line 62) | @NotNull
    method getIcon (line 68) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/refactoring/MapperRefactoringProvider.java
  class MapperRefactoringProvider (line 20) | public class MapperRefactoringProvider implements RefactoringElementList...
    method getListener (line 22) | @Nullable
    method renameMapperXml (line 45) | private void renameMapperXml(@NotNull final PsiClass oldClazz, @NotNul...

FILE: src/main/java/com/wuzhizhan/mybatis/reference/ContextPsiFieldReference.java
  class ContextPsiFieldReference (line 21) | public class ContextPsiFieldReference extends PsiReferenceBase<XmlAttrib...
    method ContextPsiFieldReference (line 27) | public ContextPsiFieldReference(XmlAttributeValue element, TextRange r...
    method resolve (line 33) | @SuppressWarnings("unchecked")
    method getVariants (line 41) | @NotNull
    method getTargetClazz (line 48) | @SuppressWarnings("unchecked")
    method getResolver (line 62) | public ContextReferenceSetResolver getResolver() {
    method setResolver (line 66) | public void setResolver(ContextReferenceSetResolver resolver) {
    method getIndex (line 70) | public int getIndex() {
    method setIndex (line 74) | public void setIndex(int index) {

FILE: src/main/java/com/wuzhizhan/mybatis/reference/ContextReferenceSetResolver.java
  class ContextReferenceSetResolver (line 18) | public abstract class ContextReferenceSetResolver<F extends PsiElement, ...
    method ContextReferenceSetResolver (line 28) | protected ContextReferenceSetResolver(@NotNull F element) {
    method resolve (line 34) | @NotNull
    method parseNext (line 40) | private Optional<K> parseNext(Optional<K> current, List<String> texts,...
    method getStartElement (line 53) | public Optional<K> getStartElement() {
    method getStartElement (line 57) | @NotNull
    method getText (line 60) | @NotNull
    method resolve (line 63) | @NotNull
    method getElement (line 66) | public F getElement() {
    method setElement (line 70) | public void setElement(F element) {
    method getProject (line 74) | public Project getProject() {
    method setProject (line 78) | public void setProject(Project project) {

FILE: src/main/java/com/wuzhizhan/mybatis/reference/PsiFieldReferenceSetResolver.java
  class PsiFieldReferenceSetResolver (line 18) | public class PsiFieldReferenceSetResolver extends ContextReferenceSetRes...
    method PsiFieldReferenceSetResolver (line 20) | protected PsiFieldReferenceSetResolver(XmlAttributeValue from) {
    method getText (line 24) | @NotNull
    method resolve (line 30) | @NotNull
    method getStartElement (line 43) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/reference/ReferenceSetResolverFactory.java
  class ReferenceSetResolverFactory (line 9) | public final class ReferenceSetResolverFactory {
    method ReferenceSetResolverFactory (line 11) | private ReferenceSetResolverFactory() {
    method createPsiFieldResolver (line 15) | public static <F extends XmlAttributeValue> ContextReferenceSetResolve...

FILE: src/main/java/com/wuzhizhan/mybatis/reference/ResultPropertyReferenceSet.java
  class ResultPropertyReferenceSet (line 15) | public class ResultPropertyReferenceSet extends ReferenceSetBase<PsiRefe...
    method ResultPropertyReferenceSet (line 17) | public ResultPropertyReferenceSet(String text, @NotNull PsiElement ele...
    method createReference (line 21) | @Nullable

FILE: src/main/java/com/wuzhizhan/mybatis/service/AnnotationService.java
  class AnnotationService (line 14) | public class AnnotationService {
    method AnnotationService (line 18) | public AnnotationService(Project project) {
    method getInstance (line 22) | public static AnnotationService getInstance(@NotNull Project project) {
    method addAnnotation (line 26) | public void addAnnotation(@NotNull PsiModifierListOwner parameter, @No...
    method addAnnotationWithParameterNameForMethodParameters (line 39) | public void addAnnotationWithParameterNameForMethodParameters(@NotNull...
    method addAnnotationWithParameterName (line 50) | public void addAnnotationWithParameterName(@NotNull PsiParameter param...

FILE: src/main/java/com/wuzhizhan/mybatis/service/EditorService.java
  class EditorService (line 19) | public class EditorService {
    method EditorService (line 27) | public EditorService(Project project) {
    method getInstance (line 32) | public static EditorService getInstance(@NotNull Project project) {
    method format (line 36) | public void format(@NotNull PsiFile file, @NotNull PsiElement element) {
    method scrollTo (line 41) | public void scrollTo(@NotNull PsiElement element, int offset) {

FILE: src/main/java/com/wuzhizhan/mybatis/service/JavaService.java
  class JavaService (line 22) | public class JavaService {
    method JavaService (line 30) | public JavaService(Project project) {
    method getInstance (line 36) | public static JavaService getInstance(@NotNull Project project) {
    method getReferenceClazzOfPsiField (line 40) | public Optional<PsiClass> getReferenceClazzOfPsiField(@NotNull PsiElem...
    method findStatement (line 48) | public Optional<DomElement> findStatement(@Nullable PsiMethod method) {
    method process (line 54) | @SuppressWarnings("unchecked")
    method process (line 68) | @SuppressWarnings("unchecked")
    method process (line 78) | public void process(@NotNull PsiElement target, @NotNull Processor pro...
    method findWithFindFirstProcessor (line 86) | public <T> Optional<T> findWithFindFirstProcessor(@NotNull PsiElement ...
    method importClazz (line 92) | public void importClazz(PsiJavaFile file, String clazzName) {

FILE: src/main/java/com/wuzhizhan/mybatis/service/TableInfoService.java
  class TableInfoService (line 12) | public class TableInfoService {
    method getInstance (line 13) | public static TableInfoService getInstance(@NotNull Project project) {

FILE: src/main/java/com/wuzhizhan/mybatis/setting/MybatisConfigurable.java
  class MybatisConfigurable (line 19) | public class MybatisConfigurable implements SearchableConfigurable {
    method MybatisConfigurable (line 31) | public MybatisConfigurable() {
    method getId (line 35) | @Override
    method enableSearch (line 40) | @Override
    method getDisplayName (line 45) | @Nls
    method getHelpTopic (line 51) | @Nullable
    method createComponent (line 57) | @Nullable
    method isModified (line 66) | @Override
    method apply (line 75) | @Override
    method reset (line 84) | @Override
    method disposeUIResources (line 93) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/setting/MybatisSetting.java
  class MybatisSetting (line 22) | @State(
    method MybatisSetting (line 34) | public MybatisSetting() {
    method getInstance (line 38) | public static MybatisSetting getInstance() {
    method getState (line 42) | @Nullable
    method loadState (line 54) | @Override
    method loadState (line 63) | private void loadState(Element state, StatementGenerator generator) {
    method getStatementGenerateModel (line 70) | public GenerateModel getStatementGenerateModel() {
    method setStatementGenerateModel (line 74) | public void setStatementGenerateModel(GenerateModel statementGenerateM...

FILE: src/main/java/com/wuzhizhan/mybatis/setting/MybatisSettingForm.java
  class MybatisSettingForm (line 8) | public class MybatisSettingForm {

FILE: src/main/java/com/wuzhizhan/mybatis/template/MybatisFileTemplateDescriptorFactory.java
  class MybatisFileTemplateDescriptorFactory (line 11) | public class MybatisFileTemplateDescriptorFactory implements FileTemplat...
    method getFileTemplatesDescriptor (line 15) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/ui/ClickableListener.java
  type ClickableListener (line 6) | public interface ClickableListener extends ExecutableListener {
    method clicked (line 8) | public void clicked();

FILE: src/main/java/com/wuzhizhan/mybatis/ui/ExecutableListener.java
  type ExecutableListener (line 6) | public interface ExecutableListener {
    method isWriteAction (line 8) | public boolean isWriteAction();

FILE: src/main/java/com/wuzhizhan/mybatis/ui/ListSelectionListener.java
  type ListSelectionListener (line 6) | public interface ListSelectionListener extends ExecutableListener {
    method selected (line 8) | public void selected(int index);

FILE: src/main/java/com/wuzhizhan/mybatis/ui/UiComponentFacade.java
  class UiComponentFacade (line 25) | public final class UiComponentFacade {
    method UiComponentFacade (line 31) | private UiComponentFacade(Project project) {
    method getInstance (line 36) | public static UiComponentFacade getInstance(@NotNull Project project) {
    method showSingleFolderSelectionDialog (line 40) | public VirtualFile showSingleFolderSelectionDialog(@NotNull String title,
    method showListPopupWithSingleClickable (line 51) | public JBPopup showListPopupWithSingleClickable(@NotNull String popupT...
    method showListPopup (line 79) | public JBPopup showListPopup(@NotNull String title,
    method setPositionForShown (line 88) | private void setPositionForShown(JBPopup popup) {
    method setActionForExecutableListener (line 97) | private void setActionForExecutableListener(Runnable runnable, Executa...
    method createListPopupBuilder (line 106) | public PopupChooserBuilder createListPopupBuilder(@NotNull String title,

FILE: src/main/java/com/wuzhizhan/mybatis/util/ArrayUtils.java
  class ArrayUtils (line 11) | public final class ArrayUtils {
    method ArrayUtils (line 13) | private ArrayUtils() {
    method getOnlyElement (line 17) | @NotNull
    method getOnlyElement (line 22) | @NotNull

FILE: src/main/java/com/wuzhizhan/mybatis/util/CollectionUtils.java
  class CollectionUtils (line 8) | public final class CollectionUtils {
    method CollectionUtils (line 10) | private CollectionUtils() {
    method isEmpty (line 14) | public static boolean isEmpty(Collection collection) {
    method isNotEmpty (line 18) | public static boolean isNotEmpty(Collection collection) {

FILE: src/main/java/com/wuzhizhan/mybatis/util/DomUtils.java
  class DomUtils (line 20) | public final class DomUtils {
    method DomUtils (line 22) | private DomUtils() {
    method findDomElements (line 26) | @NotNull
    method isMybatisFile (line 39) | public static boolean isMybatisFile(@Nullable PsiFile file) {
    method isMybatisConfigurationFile (line 47) | public static boolean isMybatisConfigurationFile(@NotNull PsiFile file) {
    method isBeansFile (line 55) | public static boolean isBeansFile(@NotNull PsiFile file) {
    method isXmlFile (line 63) | static boolean isXmlFile(@NotNull PsiFile file) {

FILE: src/main/java/com/wuzhizhan/mybatis/util/Icons.java
  type Icons (line 11) | public interface Icons {

FILE: src/main/java/com/wuzhizhan/mybatis/util/JTextFieldHintListener.java
  class JTextFieldHintListener (line 12) | public class JTextFieldHintListener implements FocusListener {
    method JTextFieldHintListener (line 16) | public JTextFieldHintListener(JTextField jTextField, String hintText) {
    method focusGained (line 23) | @Override
    method focusLost (line 34) | @Override

FILE: src/main/java/com/wuzhizhan/mybatis/util/JavaUtils.java
  class JavaUtils (line 23) | public final class JavaUtils {
    method JavaUtils (line 25) | private JavaUtils() {
    method isModelClazz (line 29) | public static boolean isModelClazz(@Nullable PsiClass clazz) {
    method findSettablePsiField (line 33) | @NotNull
    method findSettablePsiFields (line 41) | @NotNull
    method isElementWithinInterface (line 61) | public static boolean isElementWithinInterface(@Nullable PsiElement el...
    method findClazz (line 69) | @NotNull
    method findMethod (line 74) | @NotNull
    method findMethod (line 87) | @NotNull
    method isAnnotationPresent (line 92) | public static boolean isAnnotationPresent(@NotNull PsiModifierListOwne...
    method getPsiAnnotation (line 97) | @NotNull
    method getAnnotationAttributeValue (line 103) | @NotNull
    method getAnnotationValue (line 114) | @NotNull
    method getAnnotationValueText (line 119) | public static Optional<String> getAnnotationValueText(@NotNull PsiModi...
    method isAnyAnnotationPresent (line 124) | public static boolean isAnyAnnotationPresent(@NotNull PsiModifierListO...
    method isAllParameterWithAnnotation (line 133) | public static boolean isAllParameterWithAnnotation(@NotNull PsiMethod ...
    method hasImportClazz (line 143) | public static boolean hasImportClazz(@NotNull PsiJavaFile file, @NotNu...

FILE: src/main/java/com/wuzhizhan/mybatis/util/MapperUtils.java
  class MapperUtils (line 27) | public final class MapperUtils {
    method MapperUtils (line 29) | private MapperUtils() {
    method findParentIdDomElement (line 33) | @NotNull
    method createMapperFromFileTemplate (line 45) | public static PsiElement createMapperFromFileTemplate(@NotNull String ...
    method findMapperDirectories (line 53) | @NotNull
    method isElementWithinMybatisFile (line 63) | public static boolean isElementWithinMybatisFile(@NotNull PsiElement e...
    method findMappers (line 68) | @NotNull
    method findMappers (line 74) | @NotNull
    method findMappers (line 86) | @NotNull
    method findMappers (line 91) | @NotNull
    method findFirstMapper (line 97) | @NotNull
    method findFirstMapper (line 104) | @NotNull
    method findFirstMapper (line 111) | @NotNull
    method getMapper (line 118) | @SuppressWarnings("unchecked")
    method getNamespace (line 130) | @NotNull
    method getNamespace (line 137) | @NotNull
    method isMapperWithSameNamespace (line 143) | @NonNls
    method getId (line 148) | @Nullable
    method getIdSignature (line 154) | @NotNull
    method getIdSignature (line 160) | @NotNull
    method processConfiguredTypeAliases (line 173) | public static void processConfiguredTypeAliases(@NotNull Project proje...
    method getMybatisConfigurations (line 186) | private static Collection<Configuration> getMybatisConfigurations(Proj...
    method processConfiguredPackage (line 190) | public static void processConfiguredPackage(@NotNull Project project,

FILE: src/main/java/com/wuzhizhan/mybatis/util/MybatisConstants.java
  class MybatisConstants (line 8) | public final class MybatisConstants {
    method MybatisConstants (line 10) | private MybatisConstants() {

FILE: src/main/java/com/wuzhizhan/mybatis/util/StringUtils.java
  class StringUtils (line 6) | public class StringUtils {
    method dbStringToCamelStyle (line 14) | public static String dbStringToCamelStyle(String str) {
    method isEmpty (line 35) | public static boolean isEmpty(Object str) {
Condensed preview — 143 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (226K chars).
[
  {
    "path": ".gitignore",
    "chars": 65,
    "preview": "*.iml\n\nlog.roo\n.idea/\nout/\n.DS_Store\n.gradle/\ngradle/\nbuild/\nout/"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 179,
    "preview": "# free-mybatis-plugin\n\n## Changes:\n\n- Compatible with Intellij IC edition.\n- Not to warn static method or the method wit"
  },
  {
    "path": "build.gradle",
    "chars": 861,
    "preview": "buildscript {\n    repositories {\n        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }\n        m"
  },
  {
    "path": "gradlew",
    "chars": 5766,
    "preview": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0"
  },
  {
    "path": "gradlew.bat",
    "chars": 2674,
    "preview": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "settings.gradle",
    "chars": 42,
    "preview": "rootProject.name = 'free-mybatis-plugin'\n\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/action/MybatisTypedHandler.java",
    "chars": 1775,
    "preview": "package com.wuzhizhan.mybatis.action;\n\nimport com.intellij.codeInsight.AutoPopupController;\nimport com.intellij.codeInsi"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/alias/AliasClassReference.java",
    "chars": 1377,
    "preview": "package com.wuzhizhan.mybatis.alias;\n\nimport com.google.common.base.Function;\nimport com.google.common.collect.Collectio"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/alias/AliasDesc.java",
    "chars": 1530,
    "preview": "package com.wuzhizhan.mybatis.alias;\n\nimport com.intellij.psi.PsiClass;\nimport org.jetbrains.annotations.NotNull;\n\n/**\n "
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/alias/AliasFacade.java",
    "chars": 3219,
    "preview": "package com.wuzhizhan.mybatis.alias;\n\nimport com.google.common.collect.Lists;\nimport com.intellij.openapi.components.Ser"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/alias/AliasResolver.java",
    "chars": 1193,
    "preview": "package com.wuzhizhan.mybatis.alias;\n\nimport com.intellij.openapi.project.Project;\nimport com.intellij.psi.PsiClass;\nimp"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/alias/AliasResolverFactory.java",
    "chars": 967,
    "preview": "package com.wuzhizhan.mybatis.alias;\n\nimport com.intellij.openapi.project.Project;\nimport org.jetbrains.annotations.NotN"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/alias/AnnotationAliasResolver.java",
    "chars": 1957,
    "preview": "package com.wuzhizhan.mybatis.alias;\n\nimport com.google.common.base.Function;\nimport com.google.common.collect.Collectio"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/alias/BeanAliasResolver.java",
    "chars": 1231,
    "preview": "package com.wuzhizhan.mybatis.alias;\n\nimport com.google.common.collect.Sets;\nimport com.intellij.openapi.module.ModuleMa"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/alias/ConfigPackageAliasResolver.java",
    "chars": 1117,
    "preview": "package com.wuzhizhan.mybatis.alias;\n\nimport com.google.common.collect.Lists;\nimport com.intellij.openapi.project.Projec"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/alias/InnerAliasResolver.java",
    "chars": 2440,
    "preview": "package com.wuzhizhan.mybatis.alias;\n\nimport com.google.common.collect.ImmutableSet;\nimport com.intellij.openapi.project"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/alias/PackageAliasResolver.java",
    "chars": 1593,
    "preview": "package com.wuzhizhan.mybatis.alias;\n\nimport com.google.common.collect.Sets;\nimport com.intellij.openapi.project.Project"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/alias/SingleAliasResolver.java",
    "chars": 1097,
    "preview": "package com.wuzhizhan.mybatis.alias;\n\nimport com.google.common.collect.Sets;\nimport com.intellij.openapi.project.Project"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/annotation/Annotation.java",
    "chars": 5391,
    "preview": "package com.wuzhizhan.mybatis.annotation;\n\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.colle"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/contributor/JavaMenthodCompletionContributor.java",
    "chars": 624,
    "preview": "package com.wuzhizhan.mybatis.contributor;\n\nimport com.intellij.codeInsight.completion.CompletionContributor;\nimport com"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/contributor/SqlParamCompletionContributor.java",
    "chars": 2295,
    "preview": "package com.wuzhizhan.mybatis.contributor;\n\nimport com.intellij.codeInsight.completion.CompletionContributor;\nimport com"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/contributor/TestParamContributor.java",
    "chars": 4010,
    "preview": "package com.wuzhizhan.mybatis.contributor;\n\nimport com.intellij.codeInsight.completion.*;\nimport com.intellij.codeInsigh"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/definitionsearch/MapperDefinitionSearch.java",
    "chars": 1007,
    "preview": "package com.wuzhizhan.mybatis.definitionsearch;\n\nimport com.intellij.openapi.application.QueryExecutorBase;\nimport com.i"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/MapperBacktrackingUtils.java",
    "chars": 2370,
    "preview": "package com.wuzhizhan.mybatis.dom;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.psi.util.PsiTreeUtil;\nimport c"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/converter/AliasConverter.java",
    "chars": 1940,
    "preview": "package com.wuzhizhan.mybatis.dom.converter;\n\nimport com.intellij.openapi.util.text.StringUtil;\nimport com.intellij.psi."
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/converter/ConverterAdaptor.java",
    "chars": 884,
    "preview": "package com.wuzhizhan.mybatis.dom.converter;\n\nimport com.intellij.util.xml.ConvertContext;\nimport com.intellij.util.xml."
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/converter/DaoMethodConverter.java",
    "chars": 760,
    "preview": "package com.wuzhizhan.mybatis.dom.converter;\n\nimport com.intellij.psi.PsiMethod;\nimport com.intellij.util.xml.ConvertCon"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/converter/IdBasedTagConverter.java",
    "chars": 7883,
    "preview": "package com.wuzhizhan.mybatis.dom.converter;\n\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.S"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/converter/ParameterMapConverter.java",
    "chars": 651,
    "preview": "package com.wuzhizhan.mybatis.dom.converter;\n\nimport com.intellij.util.xml.ConvertContext;\nimport com.wuzhizhan.mybatis."
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/converter/PropertyConverter.java",
    "chars": 1343,
    "preview": "package com.wuzhizhan.mybatis.dom.converter;\n\nimport com.intellij.psi.ElementManipulators;\nimport com.intellij.psi.PsiEl"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/converter/ResultMapConverter.java",
    "chars": 1750,
    "preview": "package com.wuzhizhan.mybatis.dom.converter;\n\nimport com.google.common.base.Predicate;\nimport com.google.common.collect."
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/converter/SqlConverter.java",
    "chars": 572,
    "preview": "package com.wuzhizhan.mybatis.dom.converter;\n\nimport com.intellij.util.xml.ConvertContext;\nimport com.wuzhizhan.mybatis."
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/description/ConfigurationDescription.java",
    "chars": 730,
    "preview": "package com.wuzhizhan.mybatis.dom.description;\n\nimport com.intellij.openapi.module.Module;\nimport com.intellij.psi.xml.X"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/description/MapperDescription.java",
    "chars": 675,
    "preview": "package com.wuzhizhan.mybatis.dom.description;\n\nimport com.intellij.openapi.module.Module;\nimport com.intellij.psi.xml.X"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Arg.java",
    "chars": 156,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\n\n/**\n * @author yanglin\n */\npublic in"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Association.java",
    "chars": 551,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.util.xml.Attribute;\nimpo"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Bean.java",
    "chars": 357,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\nimport com.intellij.util.xml.SubTagLi"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/BeanProperty.java",
    "chars": 478,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.Attribute;\nimport com.intellij.util.xml.DomElemen"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Beans.java",
    "chars": 337,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\nimport com.intellij.util.xml.SubTagLi"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Bind.java",
    "chars": 157,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\n\n/**\n * @author yanglin\n */\npublic in"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Cache.java",
    "chars": 295,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\nimport com.intellij.util.xml.SubTagLi"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/CacheRef.java",
    "chars": 161,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\n\n/**\n * @author yanglin\n */\npublic in"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Case.java",
    "chars": 114,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Case extends GroupFour {\n\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Choose.java",
    "chars": 491,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\nimport com.intellij.util.xml.Required"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Collection.java",
    "chars": 546,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.util.xml.Attribute;\nimpo"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Configuration.java",
    "chars": 365,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\nimport com.intellij.util.xml.SubTagLi"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Constructor.java",
    "chars": 346,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\nimport com.intellij.util.xml.SubTagLi"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Delete.java",
    "chars": 115,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Delete extends GroupTwo {\n\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Discriminator.java",
    "chars": 343,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\nimport com.intellij.util.xml.Required"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Foreach.java",
    "chars": 116,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Foreach extends GroupOne {\n\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/GroupFour.java",
    "chars": 682,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\nimport com.intellij.util.xml.SubTag;\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/GroupOne.java",
    "chars": 790,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\nimport com.intellij.util.xml.SubTagLi"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/GroupThree.java",
    "chars": 258,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.SubTagList;\n\nimport java.util.List;\n\n/**\n * @auth"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/GroupTwo.java",
    "chars": 1087,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.psi.xml.XmlTag;\nimport c"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Id.java",
    "chars": 116,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Id extends PropertyGroup {\n\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/IdArg.java",
    "chars": 158,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\n\n/**\n * @author yanglin\n */\npublic in"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/IdDomElement.java",
    "chars": 299,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.*;\n\n/**\n * @author yanglin\n */\npublic interface I"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/If.java",
    "chars": 110,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface If extends GroupOne {\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Include.java",
    "chars": 494,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.psi.xml.XmlTag;\nimport com.intellij.util.xml.Attribute;\nim"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Insert.java",
    "chars": 117,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Insert extends GroupThree {\n\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Mapper.java",
    "chars": 1260,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.*;\nimport org.jetbrains.annotations.NotNull;\n\nimp"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Otherwise.java",
    "chars": 117,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Otherwise extends GroupOne {\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Package.java",
    "chars": 383,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.Attribute;\nimport com.intellij.util.xml.DomElemen"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Parameter.java",
    "chars": 123,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Parameter extends PropertyGroup {\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/ParameterMap.java",
    "chars": 656,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.util.xml.Attribute;\nimpo"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Property.java",
    "chars": 160,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\n\n/**\n * @author yanglin\n */\npublic in"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/PropertyGroup.java",
    "chars": 530,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.psi.xml.XmlAttributeValue;\nimport com.intellij.util.xml.At"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Result.java",
    "chars": 120,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Result extends PropertyGroup {\n\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/ResultMap.java",
    "chars": 779,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.psi.xml.XmlAttributeValu"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/ResultMapGroup.java",
    "chars": 575,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.psi.xml.XmlTag;\nimport com.intellij.util.xml.Attribute;\nim"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Select.java",
    "chars": 534,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.util.xml.Attribute;\nimpo"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/SelectKey.java",
    "chars": 513,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.util.xml.Attribute;\nimpo"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Set.java",
    "chars": 112,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Set extends GroupOne {\n\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Sql.java",
    "chars": 126,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Sql extends GroupOne, IdDomElement"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Trim.java",
    "chars": 113,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Trim extends GroupOne {\n\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/TypeAlias.java",
    "chars": 512,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.util.xml.Attribute;\nimpo"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/TypeAliases.java",
    "chars": 438,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\nimport com.intellij.util.xml.DomElement;\nimport com.intellij.util.xml.SubTagLi"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Update.java",
    "chars": 115,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Update extends GroupTwo {\n\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/When.java",
    "chars": 113,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface When extends GroupOne {\n\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/dom/model/Where.java",
    "chars": 114,
    "preview": "package com.wuzhizhan.mybatis.dom.model;\n\n/**\n * @author yanglin\n */\npublic interface Where extends GroupOne {\n\n}\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/generate/DeleteGenerator.java",
    "chars": 750,
    "preview": "package com.wuzhizhan.mybatis.generate;\n\nimport com.intellij.psi.PsiMethod;\nimport com.wuzhizhan.mybatis.dom.model.Group"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/generate/GenerateModel.java",
    "chars": 2324,
    "preview": "package com.wuzhizhan.mybatis.generate;\n\nimport java.util.Collection;\n\n/**\n * @author yanglin\n */\npublic abstract class "
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/generate/InsertGenerator.java",
    "chars": 749,
    "preview": "package com.wuzhizhan.mybatis.generate;\n\nimport com.intellij.psi.PsiMethod;\nimport com.wuzhizhan.mybatis.dom.model.Group"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/generate/SelectGenerator.java",
    "chars": 1190,
    "preview": "package com.wuzhizhan.mybatis.generate;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.psi.PsiMethod;\nimport com"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/generate/StatementGenerator.java",
    "chars": 7750,
    "preview": "package com.wuzhizhan.mybatis.generate;\n\nimport com.google.common.base.Function;\nimport com.google.common.collect.*;\nimp"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/generate/UpdateGenerator.java",
    "chars": 750,
    "preview": "package com.wuzhizhan.mybatis.generate;\n\nimport com.intellij.psi.PsiMethod;\nimport com.wuzhizhan.mybatis.dom.model.Group"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/inspection/GenericQuickFix.java",
    "chars": 327,
    "preview": "package com.wuzhizhan.mybatis.inspection;\n\nimport com.intellij.codeInspection.LocalQuickFix;\nimport org.jetbrains.annota"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/inspection/MapperInspection.java",
    "chars": 354,
    "preview": "package com.wuzhizhan.mybatis.inspection;\n\nimport com.intellij.codeInspection.BaseJavaLocalInspectionTool;\nimport com.in"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/inspection/MapperMethodInspection.java",
    "chars": 5768,
    "preview": "package com.wuzhizhan.mybatis.inspection;\n\nimport com.intellij.codeInspection.InspectionManager;\nimport com.intellij.cod"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/inspection/MapperXmlInspection.java",
    "chars": 676,
    "preview": "package com.wuzhizhan.mybatis.inspection;\n\nimport com.intellij.util.xml.DomElement;\nimport com.intellij.util.xml.highlig"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/inspection/ResultTypeQuickFix.java",
    "chars": 1271,
    "preview": "package com.wuzhizhan.mybatis.inspection;\n\nimport com.intellij.codeInspection.ProblemDescriptor;\nimport com.intellij.ope"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/inspection/StatementNotExistsQuickFix.java",
    "chars": 951,
    "preview": "package com.wuzhizhan.mybatis.inspection;\n\nimport com.intellij.codeInspection.ProblemDescriptor;\nimport com.intellij.ope"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/intention/GenerateMapperChooser.java",
    "chars": 742,
    "preview": "package com.wuzhizhan.mybatis.intention;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.psi.PsiElement;\nimport c"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/intention/GenerateMapperIntention.java",
    "chars": 6302,
    "preview": "package com.wuzhizhan.mybatis.intention;\n\nimport com.google.common.base.Function;\nimport com.google.common.collect.Colle"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/intention/GenerateParamAnnotationIntention.java",
    "chars": 1545,
    "preview": "package com.wuzhizhan.mybatis.intention;\n\nimport com.intellij.openapi.editor.Editor;\nimport com.intellij.openapi.project"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/intention/GenerateParamChooser.java",
    "chars": 980,
    "preview": "package com.wuzhizhan.mybatis.intention;\n\nimport com.intellij.psi.PsiElement;\nimport com.intellij.psi.PsiMethod;\nimport "
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/intention/GenerateStatementChooser.java",
    "chars": 1096,
    "preview": "package com.wuzhizhan.mybatis.intention;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.psi.PsiElement;\nimport c"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/intention/GenerateStatementIntention.java",
    "chars": 1074,
    "preview": "package com.wuzhizhan.mybatis.intention;\n\nimport com.intellij.openapi.editor.Editor;\nimport com.intellij.openapi.project"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/intention/GenericIntention.java",
    "chars": 856,
    "preview": "package com.wuzhizhan.mybatis.intention;\n\nimport com.intellij.codeInsight.intention.IntentionAction;\nimport com.intellij"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/intention/IntentionChooser.java",
    "chars": 360,
    "preview": "package com.wuzhizhan.mybatis.intention;\n\nimport com.intellij.openapi.editor.Editor;\nimport com.intellij.openapi.project"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/intention/JavaFileIntentionChooser.java",
    "chars": 1468,
    "preview": "package com.wuzhizhan.mybatis.intention;\n\nimport com.intellij.openapi.editor.Editor;\nimport com.intellij.openapi.project"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/locator/LocateStrategy.java",
    "chars": 247,
    "preview": "package com.wuzhizhan.mybatis.locator;\n\nimport com.intellij.psi.PsiClass;\nimport org.jetbrains.annotations.NotNull;\n\n/**"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/locator/MapperLocator.java",
    "chars": 941,
    "preview": "package com.wuzhizhan.mybatis.locator;\n\nimport com.intellij.openapi.components.ServiceManager;\nimport com.intellij.opena"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/locator/MapperXmlPackageProvider.java",
    "chars": 1476,
    "preview": "package com.wuzhizhan.mybatis.locator;\n\nimport com.google.common.collect.Sets;\nimport com.intellij.openapi.project.Proje"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/locator/PackageLocateStrategy.java",
    "chars": 834,
    "preview": "package com.wuzhizhan.mybatis.locator;\n\nimport com.intellij.psi.JavaPsiFacade;\nimport com.intellij.psi.PsiClass;\nimport "
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/locator/PackageProvider.java",
    "chars": 345,
    "preview": "package com.wuzhizhan.mybatis.locator;\n\nimport com.intellij.openapi.project.Project;\nimport com.intellij.psi.PsiPackage;"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/provider/InjectionLineMarkerProvider.java",
    "chars": 2632,
    "preview": "package com.wuzhizhan.mybatis.provider;\n\nimport com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;\nimport com.in"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/provider/MapperLineMarkerProvider.java",
    "chars": 2333,
    "preview": "package com.wuzhizhan.mybatis.provider;\n\nimport com.google.common.base.Function;\nimport com.google.common.collect.Collec"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/provider/MarkerProviderAdaptor.java",
    "chars": 710,
    "preview": "package com.wuzhizhan.mybatis.provider;\n\nimport com.intellij.codeInsight.daemon.LineMarkerInfo;\nimport com.intellij.code"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/provider/SimpleLineMarkerProvider.java",
    "chars": 2415,
    "preview": "package com.wuzhizhan.mybatis.provider;\n\nimport com.intellij.codeHighlighting.Pass;\nimport com.intellij.codeInsight.daem"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/provider/StatementLineMarkerProvider.java",
    "chars": 2280,
    "preview": "package com.wuzhizhan.mybatis.provider;\n\nimport com.google.common.collect.ImmutableList;\nimport com.intellij.pom.Navigat"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/refactoring/MapperRefactoringProvider.java",
    "chars": 2145,
    "preview": "package com.wuzhizhan.mybatis.refactoring;\n\nimport com.intellij.openapi.application.ApplicationManager;\nimport com.intel"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/reference/ContextPsiFieldReference.java",
    "chars": 2395,
    "preview": "package com.wuzhizhan.mybatis.reference;\n\nimport com.intellij.openapi.util.TextRange;\nimport com.intellij.psi.PsiClass;\n"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/reference/ContextReferenceSetResolver.java",
    "chars": 2293,
    "preview": "package com.wuzhizhan.mybatis.reference;\n\nimport com.google.common.base.Splitter;\nimport com.google.common.collect.Itera"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/reference/PsiFieldReferenceSetResolver.java",
    "chars": 1599,
    "preview": "package com.wuzhizhan.mybatis.reference;\n\nimport com.intellij.psi.PsiClass;\nimport com.intellij.psi.PsiField;\nimport com"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/reference/ReferenceSetResolverFactory.java",
    "chars": 497,
    "preview": "package com.wuzhizhan.mybatis.reference;\n\nimport com.intellij.psi.xml.XmlAttributeValue;\nimport org.jetbrains.annotation"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/reference/ResultPropertyReferenceSet.java",
    "chars": 928,
    "preview": "package com.wuzhizhan.mybatis.reference;\n\nimport com.intellij.openapi.util.TextRange;\nimport com.intellij.psi.PsiElement"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/service/AnnotationService.java",
    "chars": 2240,
    "preview": "package com.wuzhizhan.mybatis.service;\n\nimport com.intellij.openapi.components.ServiceManager;\nimport com.intellij.opena"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/service/EditorService.java",
    "chars": 1847,
    "preview": "package com.wuzhizhan.mybatis.service;\n\nimport com.intellij.codeInsight.navigation.NavigationUtil;\nimport com.intellij.f"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/service/JavaService.java",
    "chars": 4152,
    "preview": "package com.wuzhizhan.mybatis.service;\n\nimport com.intellij.openapi.components.ServiceManager;\nimport com.intellij.opena"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/service/TableInfoService.java",
    "chars": 416,
    "preview": "package com.wuzhizhan.mybatis.service;\n\nimport com.intellij.openapi.components.ServiceManager;\nimport com.intellij.opena"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/setting/MybatisConfigurable.java",
    "chars": 3641,
    "preview": "package com.wuzhizhan.mybatis.setting;\n\nimport com.google.common.base.Joiner;\nimport com.google.common.base.Splitter;\nim"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/setting/MybatisSetting.java",
    "chars": 2782,
    "preview": "package com.wuzhizhan.mybatis.setting;\n\nimport com.google.gson.Gson;\nimport com.google.gson.reflect.TypeToken;\nimport co"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/setting/MybatisSettingForm.form",
    "chars": 6034,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class="
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/setting/MybatisSettingForm.java",
    "chars": 382,
    "preview": "package com.wuzhizhan.mybatis.setting;\n\nimport javax.swing.*;\n\n/**\n * @author yanglin\n */\npublic class MybatisSettingFor"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/template/MybatisFileTemplateDescriptorFactory.java",
    "chars": 823,
    "preview": "package com.wuzhizhan.mybatis.template;\n\nimport com.intellij.ide.fileTemplates.FileTemplateDescriptor;\nimport com.intell"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/ui/ClickableListener.java",
    "chars": 157,
    "preview": "package com.wuzhizhan.mybatis.ui;\n\n/**\n * @author yanglin\n */\npublic interface ClickableListener extends ExecutableListe"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/ui/ExecutableListener.java",
    "chars": 140,
    "preview": "package com.wuzhizhan.mybatis.ui;\n\n/**\n * @author yanglin\n */\npublic interface ExecutableListener {\n\n    public boolean "
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/ui/ListSelectionListener.java",
    "chars": 170,
    "preview": "package com.wuzhizhan.mybatis.ui;\n\n/**\n * @author yanglin\n */\npublic interface ListSelectionListener extends ExecutableL"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/ui/UiComponentFacade.java",
    "chars": 5143,
    "preview": "package com.wuzhizhan.mybatis.ui;\n\nimport com.intellij.openapi.application.Application;\nimport com.intellij.openapi.appl"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/util/ArrayUtils.java",
    "chars": 689,
    "preview": "package com.wuzhizhan.mybatis.util;\n\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/util/CollectionUtils.java",
    "chars": 457,
    "preview": "package com.wuzhizhan.mybatis.util;\n\nimport java.util.Collection;\n\n/**\n * @author yanglin\n */\npublic final class Collect"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/util/DomUtils.java",
    "chars": 2226,
    "preview": "package com.wuzhizhan.mybatis.util;\n\nimport com.google.common.base.Function;\nimport com.google.common.collect.Collection"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/util/Icons.java",
    "chars": 585,
    "preview": "package com.wuzhizhan.mybatis.util;\n\nimport com.intellij.openapi.util.IconLoader;\nimport com.intellij.util.PlatformIcons"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/util/JTextFieldHintListener.java",
    "chars": 1112,
    "preview": "package com.wuzhizhan.mybatis.util;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.FocusEvent;\nimport j"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/util/JavaUtils.java",
    "chars": 6582,
    "preview": "package com.wuzhizhan.mybatis.util;\n\nimport com.intellij.openapi.project.Project;\nimport com.intellij.psi.*;\nimport com."
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/util/MapperUtils.java",
    "chars": 7713,
    "preview": "package com.wuzhizhan.mybatis.util;\n\nimport com.google.common.base.Function;\nimport com.google.common.collect.Collection"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/util/MybatisConstants.java",
    "chars": 390,
    "preview": "package com.wuzhizhan.mybatis.util;\n\nimport com.intellij.psi.util.ReferenceSetBase;\n\n/**\n * @author yanglin\n */\npublic f"
  },
  {
    "path": "src/main/java/com/wuzhizhan/mybatis/util/StringUtils.java",
    "chars": 1075,
    "preview": "package com.wuzhizhan.mybatis.util;\n\n/**\n * Created by Owen on 6/18/16.\n */\npublic class StringUtils {\n\n    /**\n     * c"
  },
  {
    "path": "src/main/resources/META-INF/plugin.xml",
    "chars": 4386,
    "preview": "<idea-plugin>\n    <id>cn.wuzhizhan.plugin.mybatis</id>\n    <name>FreeMyBatisPlugin</name>\n    <vendor email=\"wuzhizhan@w"
  },
  {
    "path": "src/main/resources/fileTemplates/j2ee/Mybatis Mapper.xml.ft",
    "chars": 193,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org"
  },
  {
    "path": "src/main/resources/liveTemplates/sql.xml",
    "chars": 516,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<templateSet group=\"Mybatis/SQL\">\n    <template resource-bundle=\"messages.CodeIns"
  }
]

About this extraction

This page contains the full source code of the chuntungho/free-mybatis-plugin GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 143 files (200.2 KB), approximately 48.3k tokens, and a symbol index with 571 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!