├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── LICENSE-svnkit ├── NOTICE ├── README.md ├── THIRD-PARTY-LICENSES ├── arangoDB.ps1 ├── arangoDB.sh ├── pom.xml ├── run.ps1 ├── run.sh ├── setup.sh └── src └── main ├── java └── com │ └── amazon │ └── aws │ └── am2 │ └── appmig │ ├── checkout │ ├── ConfigurationBean.java │ ├── IRepoManager.java │ ├── RepoDetails.java │ ├── RepoManagerFactory.java │ ├── RepoType.java │ ├── SVNRepoManager.java │ ├── SourceCodeManager.java │ └── package-info.java │ ├── constants │ ├── IConstants.java │ └── package-info.java │ ├── estimate │ ├── CodeMetaData.java │ ├── Complexity.java │ ├── DefaultFilter.java │ ├── Dependency.java │ ├── DependencyManager.java │ ├── Estimator.java │ ├── IAnalyzer.java │ ├── IFilter.java │ ├── Main.java │ ├── MavenDependency.java │ ├── Plan.java │ ├── ProjectEstimator.java │ ├── ProjectType.java │ ├── Recommendation.java │ ├── StandardReport.java │ ├── ant │ │ └── AntEstimator.java │ ├── exception │ │ ├── InvalidPathException.java │ │ ├── InvalidRuleException.java │ │ ├── NoRulesFoundException.java │ │ ├── UnsupportedProjectException.java │ │ ├── UnsupportedRepoException.java │ │ └── package-info.java │ ├── gradle │ │ └── GradleEstimator.java │ ├── java │ │ ├── JavaFileAnalyzer.java │ │ └── package-info.java │ ├── mf │ │ ├── ManifestFileAnalyzer.java │ │ └── package-info.java │ ├── mvn │ │ ├── MVNBuildFileAnalyzer.java │ │ ├── MvnEstimator.java │ │ └── package-info.java │ ├── package-info.java │ ├── properties │ │ ├── PropertyFileAnalyzer.java │ │ └── package-info.java │ └── xml │ │ └── XMLFileAnalyzer.java │ ├── glassviewer │ ├── AbstractJavaGlassViewer.java │ ├── IJavaGlassViewer.java │ ├── JavaGlassViewer.java │ ├── constructs │ │ ├── AnnotationConstruct.java │ │ ├── ClassConstruct.java │ │ ├── ConstructMetaData.java │ │ ├── ConstructStaticBlockMetaData.java │ │ ├── ImportConstruct.java │ │ ├── InterfaceConstruct.java │ │ ├── JavaClassConstructListener.java │ │ ├── JavaClassVariableConstructListener.java │ │ ├── JavaConstruct.java │ │ ├── JavaImportConstructListener.java │ │ ├── JavaInterfaceConstructListener.java │ │ ├── JavaMethodConstructListener.java │ │ ├── JavaSearchReferenceListener.java │ │ ├── JavaStaticBlockConstructListener.java │ │ ├── MethodConstruct.java │ │ ├── PackageConstruct.java │ │ ├── ProjectConstruct.java │ │ └── VariableConstruct.java │ ├── db │ │ ├── AppDiscoveryGraphDB.java │ │ ├── IAppDiscoveryGraphDB.java │ │ ├── QueryBuilder.java │ │ └── package-info.java │ └── utils │ │ ├── GlassViewerUtils.java │ │ └── package-info.java │ ├── report │ ├── ReportSingletonFactory.java │ └── package-info.java │ ├── search │ ├── ISearch.java │ └── RegexSearch.java │ └── utils │ ├── RuleFileFilter.java │ ├── Utility.java │ └── package-info.java └── resources ├── Java8Lexer.g4 ├── Java8Parser.g4 ├── configuration.csv ├── ibmmq-to-amazonmq-javarules.json ├── ibmmq-to-amazonmq-recommendations.json ├── lib ├── beautify.min.js ├── bootstrap.min.css ├── chart.js ├── custom.css ├── index.js ├── prism.css └── prism.js ├── log4j.properties ├── oracle-to-postgres-javarules.json ├── oracle-to-postgres-mvnrules.json ├── oracle-to-postgres-properties.json ├── oracle-to-postgres-recommendations.json ├── oracle-to-postgres-xmlrules.json ├── reporttemplate.html ├── sqlreporttemplate.html ├── summaryreporttemplate.html ├── weblogic-to-tomcat-javarules.json ├── weblogic-to-tomcat-mf.json ├── weblogic-to-tomcat-mvnrules.json ├── weblogic-to-tomcat-properties.json ├── weblogic-to-tomcat-recommendations.json ├── weblogic-to-tomcat-xml.json ├── weblogic-to-wildfly-javarules.json ├── weblogic-to-wildfly-mf.json ├── weblogic-to-wildfly-mvnrules.json ├── weblogic-to-wildfly-properties.json ├── weblogic-to-wildfly-recommendations.json └── weblogic-to-wildfly-xml.json /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ "main" ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ "main" ] 20 | schedule: 21 | - cron: '28 4 * * 4' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'java', 'javascript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v3 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v2 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | 52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 53 | # queries: security-extended,security-and-quality 54 | 55 | 56 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 57 | # If this step fails, then you should remove it and run the build manually (see below) 58 | - name: Autobuild 59 | uses: github/codeql-action/autobuild@v2 60 | 61 | # ℹ️ Command-line programs to run using the OS shell. 62 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 63 | 64 | # If the Autobuild fails above, remove it and uncomment the following three lines. 65 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. 66 | 67 | # - run: | 68 | # echo "Run, Build Application using script" 69 | # ./location_of_script_within_repo/buildscript.sh 70 | 71 | - name: Perform CodeQL Analysis 72 | uses: github/codeql-action/analyze@v2 73 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | /target/ 3 | *.log 4 | *.DS_STORE 5 | .classpath 6 | .project 7 | .settings 8 | *.hprof 9 | *.hprof* -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8 2 | RUN mkdir -p /app/app-server-migration 3 | COPY ./target/app-server-migration-1.0.0-SNAPSHOT-jar-with-dependencies.jar /app/app-server-migration 4 | WORKDIR /app/app-server-migration 5 | ENTRYPOINT ["java", "-jar", "app-server-migration-1.0.0-SNAPSHOT-jar-with-dependencies.jar"] 6 | -------------------------------------------------------------------------------- /LICENSE-svnkit: -------------------------------------------------------------------------------- 1 | The TMate Open Source License. 2 | 3 | 4 | This license applies to all portions of TMate SVNKit library, which 5 | are not externally-maintained libraries (e.g. Ganymed SSH library). 6 | 7 | All the source code and compiled classes in package org.tigris.subversion.javahl 8 | except SvnClient class are covered by the license in JAVAHL-LICENSE file 9 | 10 | Copyright (c) 2004-2022 TMate Software. All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without modification, 13 | are permitted provided that the following conditions are met: 14 | 15 | * Redistributions of source code must retain the above copyright notice, 16 | this list of conditions and the following disclaimer. 17 | 18 | * Redistributions in binary form must reproduce the above copyright notice, 19 | this list of conditions and the following disclaimer in the documentation 20 | and/or other materials provided with the distribution. 21 | 22 | * Redistributions in any form must be accompanied by information on how to 23 | obtain complete source code for the software that uses SVNKit and any 24 | accompanying software that uses the software that uses SVNKit. The source 25 | code must either be included in the distribution or be available for no 26 | more than the cost of distribution plus a nominal fee, and must be freely 27 | redistributable under reasonable conditions. For an executable file, complete 28 | source code means the source code for all modules it contains. It does not 29 | include source code for modules or files that typically accompany the major 30 | components of the operating system on which the executable file runs. 31 | 32 | * Redistribution in any form without redistributing source code for software 33 | that uses SVNKit is possible only when such redistribution is explictly permitted 34 | by TMate Software. Please, contact TMate Software at support@svnkit.com to 35 | get such permission. 36 | 37 | THIS SOFTWARE IS PROVIDED BY TMATE SOFTWARE ``AS IS'' AND ANY EXPRESS OR IMPLIED 38 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 39 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE 40 | DISCLAIMED. 41 | 42 | IN NO EVENT SHALL TMATE SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 43 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 44 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 45 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 46 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 47 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 48 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## AppServerMigration 2 | 3 | ### About AppServerMigration 4 | 5 | AppServerMigration, an open-source software solution, analyses Java applications to deliver precise effort estimations in person-days, facilitating a seamless transition from source to target states. This tool adeptly identifies necessary modifications, offers insightful recommendations, and presents a comprehensive HTML report for a well-guided migration. It accelerates the migration journey, eliminating the necessity for re-work, ensuring a successful and efficient transition with minimal setbacks. AppServerMigration employs a rule-based analysis, meticulously examining Java applications according to predefined rules. This method ensures a thorough assessment, enabling precise identification of necessary changes and providing accurate effort estimations. Effort estimations in AppServerMigration leverage QSM's (Quantitative Software Management) industry-standard metrics and incorporate the backtracking technique. Customizations are then applied, drawing from firsthand migration experiences. This tailored approach ensures precise calculations, aligning with project nuances and enhancing the accuracy of migration effort predictions. 6 | 7 | ### Cloning the project 8 | ```bash 9 | git clone git@github.com:awslabs/app-server-migration.git 10 | cd app-server-migration 11 | ``` 12 | 13 | ### Build the project 14 | Prior to building the project, ensure that you have the following tools installed in your machine: 15 | - Java 8 16 | - Docker 17 | - Maven 18 | - Git 19 | 20 | For Linux (Ubuntu, CentOS and RHEL) and Mac OS, you may execute the `./setup.sh` script to install the above dependencies. 21 | For Windows, kindly follow their official documentation guide for installation. 22 | - Java 8 23 | - https://www.java.com/en/download/help/windows_manual_download.html 24 | - https://www.oracle.com/java/technologies/downloads/#java8-windows 25 | - Docker 26 | - https://docs.docker.com/desktop/windows/install/ 27 | - https://docs.microsoft.com/en-us/windows/wsl/tutorials/wsl-containers 28 | - Maven 29 | - https://maven.apache.org/download.cgi 30 | - https://maven.apache.org/guides/getting-started/windows-prerequisites.html 31 | - https://maven.apache.org/install.html 32 | - Git 33 | - https://git-scm.com/download/win 34 | 35 | Build the project using `mvn package` command. 36 | 37 | ### Run the project 38 | #### For Linux and MacOS machines 39 | ```bash 40 | # Run Database 41 | # During installation script may ask for password, enter your system password. 42 | # After installation AurangoDB Web interface is accessible on http://localhost:8529 (using default user name: root and password: openSesame) 43 | bash arangoDB.sh 44 | 45 | # Run Analyzer 46 | Option 1: 47 | # This option is helpful when you want to check out projects from SCM and run the scan 48 | # In this mode we provide repository details of projects(which needs to be scanned) 49 | # in the configuration file and provide path of configuration file as shown below 50 | 51 | ./run.sh config: 52 | 53 | or 54 | Option 2: 55 | # This option is helpful when you already have source code downloaded on your machine 56 | # In this mode we provide local path of the project 57 | 58 | ./run.sh source: 59 | e.g. 60 | ./run.sh source:/usr/example/project/ ~/test-directory root openSesame oracle-to-postgres,weblogic-to-tomcat 61 | 62 | ``` 63 | 64 | #### For Windows machines 65 | ```powershell 66 | # Run Database (default root password will be openSesame) 67 | powershell ./arangoDB.ps1 config: 68 | # Run Analyzer 69 | Option 1: 70 | # This option is helpful when you want to check out projects from SCM and run the scan 71 | # In this mode we provide repository details of projects(which needs to be scanned) 72 | # in the configuration file and provide path of configuration file as shown below 73 | 74 | powershell ./run.ps1 config: 75 | 76 | or 77 | Option 2: 78 | # This option is helpful when you already have source code downloaded on your machine 79 | # In this mode we provide local path of the project 80 | 81 | powershell ./run.ps1 source: 82 | e.g. 83 | powershell ./run.ps1 source:/usr/example/project/ /usr/example/project/reports root openSesame oracle-to-postgres,weblogic-to-tomcat 84 | ``` 85 | 86 | ### Create custom rules 87 | You may create your own rules which can be fed to the rule engine in order to assess to your source files based on your rules. There are 2 files which you need to create `rules.json` and `recommendations.json`. For reference, you can check [oracle-to-postgres-javarules.json](https://github.com/awslabs/app-server-migration/blob/main/src/main/resources/oracle-to-postgres-javarules.json) and [oracle-to-postgres-recommendations.json](https://github.com/awslabs/app-server-migration/blob/main/src/main/resources/oracle-to-postgres-recommendations.json) respectively. 88 | 89 | The `rules.json` file would look like: 90 | 91 | ``` json 92 | { 93 | "analyzer": "com.amazon.aws.am2.appmig.estimate.java.JavaFileAnalyzer", 94 | "file_type": "java", 95 | "rules": [ 96 | { 97 | "id": 1, 98 | "name": "Name", 99 | "description": "Detailed Description", 100 | "complexity": "minor", 101 | "rule_type": "package", 102 | "remove": { 103 | "import": ["java.sql.DriverManager","oracle.jdbc.driver.OracleDriver"] 104 | }, 105 | "recommendation": 12 106 | }, 107 | ] 108 | } 109 | ``` 110 | 111 | Understanding each key of above JSON file: 112 | - `analyzer`: Canonical name of the analyzer class. In the above example, we are using [JavaFileAnalyzer.java](https://github.com/awslabs/app-server-migration/blob/main/src/main/java/com/amazon/aws/am2/appmig/estimate/java/JavaFileAnalyzer.java). You may create your own Analyzer by implementing `IAnalyzer` interface. 113 | - `file_type`: Type of source files which will be assessed 114 | - `rules`: Array of objects, each corresonding to a `rule` 115 | - `id`: Rule identifier 116 | - `name`: Name of the rule 117 | - `description`: A verbose rule description 118 | - `complexity`: AppServerMigration identifies the complexity of migration per application either as minor, major or critical, depending on the features that need to be converted to make the application target compatible. If the changes are only in the configurations and not in the code, then it is minor. Major category involves code changes. There might be features specific to the source server which are not supported on the target server. In such scenarios, the whole functionality needs to be re-written. Such categories fall under critical complexity. For instance, trying to migrate a web application from Oracle WebLogic to Apache Tomcat, which has EJB code. 119 | - `rule_type`: Denotes where to search to find a rule match. In the above example rule, it will look for `import` statements to search for imported packages. The processing logic is coded in the Analyzer. 120 | - `remove`: Action denoting elimination of attributes present inside it. In the above example, the rule will match against any `import` statement having `package` name either `java.sql.DriverManager` or `oracle.jdbc.driver.OracleDriver`. 121 | - `recommendation`: Maps to the identifier of recommendation present in the associated `recommendations.json` file. 122 | 123 | The `recommendations.json` file would look like: 124 | 125 | ``` json 126 | "recommendations": [ 127 | { 128 | "id": 1, 129 | "name": "Replace Oracle database driver with Postgres database driver", 130 | "description": "Review the driver being loaded in this block of code and change the driver from oracle.jdbc.driver.OracleDriver to org.postgresql.Driver" 131 | }, 132 | ] 133 | 134 | ``` 135 | 136 | Understanding each key of above JSON file: 137 | - `recommendations`: Array of objects, each representing a recommendation. 138 | - `id`: Recommendation identifier 139 | - `name`: Name of the recommendation, which will be displayed on the report 140 | - `description`: A verbose recommendation description, which will be displayed on the report 141 | 142 | 143 | # To run ArangoDB in local (alternative to running arango.sh) 144 | --- 145 | ##### Running in-memory graph database ArangoDB 146 | 147 | `docker run -p 8529:8529 -e ARANGO_ROOT_PASSWORD=openSesame arangodb/arangodb:3.8.3` 148 | 149 | ##### Connecting to ArangoDB UI 150 | `http://localhost:8529/` 151 | 152 | ##### You can find the name of the container by running 153 | `docker ps` 154 | 155 | To retrieve the HOST run the following command with container ID obtained from `docker ps` 156 | 157 | `docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <>` 158 | 159 | ##### To stop a ArangoDB database instance, run the following command 160 | `docker stop CONTAINER_NAME` 161 | 162 | 163 | ## Security 164 | 165 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 166 | 167 | ## License 168 | 169 | This project is licensed under the Apache-2.0 License. 170 | 171 | -------------------------------------------------------------------------------- /arangoDB.ps1: -------------------------------------------------------------------------------- 1 | # DESCRIPTION: 2 | # 3 | # Pulls arangodb docker image and runs it in the foreground on port 8529 4 | # 5 | # USAGE: 6 | # ./arangoDB.ps1 7 | 8 | # Running in-memory graph database ArangoDB 9 | 10 | docker run -d -p 8529:8529 -e ARANGO_ROOT_PASSWORD=openSesame arangodb/arangodb:3.8.3 11 | -------------------------------------------------------------------------------- /arangoDB.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o pipefail 4 | set -o nounset 5 | set -o errexit 6 | 7 | # DESCRIPTION: 8 | # 9 | # Pulls arangodb docker image and runs it in the foreground on port 8529 10 | # 11 | # USAGE: 12 | # bash arangoDB.sh 13 | 14 | ## docker 15 | if ! sudo docker info > /dev/null 2>&1; then 16 | echo "This script uses docker, and it isn't running - please start docker and try again!" 17 | exit 1 18 | fi 19 | 20 | # Running in-memory graph database ArangoDB 21 | 22 | sudo docker run -d -p 8529:8529 -e ARANGO_ROOT_PASSWORD=openSesame arangodb/arangodb:3.8.3 23 | 24 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 4.0.0 6 | com.amazon.aws.am2 7 | app-server-migration 8 | 1.0.0-SNAPSHOT 9 | 10 | 11 | com.amazon.aws.am2.appmig.estimate.Main 12 | 8 13 | 8 14 | 4.9.2 15 | 3.8.0 16 | 3.1.1 17 | 2.22.1 18 | 19 | 20 | 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-surefire-plugin 25 | 26 | --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED 27 | 28 | 29 | 30 | org.antlr 31 | antlr4-maven-plugin 32 | ${antlr.version} 33 | 34 | ${basedir} 35 | 36 | src/main/resources/Java8Lexer.g4 37 | src/main/resources/Java8Parser.g4 38 | 39 | false 40 | true 41 | 42 | 43 | 44 | 45 | antlr4 46 | 47 | 48 | 49 | 50 | 51 | org.codehaus.mojo 52 | build-helper-maven-plugin 53 | 3.2.0 54 | 55 | 56 | add-source 57 | generate-sources 58 | 59 | add-source 60 | 61 | 62 | 63 | ${project.basedir}/target/generated-sources/antlr4 64 | 65 | 66 | 67 | 68 | 69 | 70 | maven-compiler-plugin 71 | 3.7.0 72 | 73 | ${maven.compiler.source} 74 | ${maven.compiler.target} 75 | 76 | 77 | 78 | org.apache.maven.plugins 79 | maven-jar-plugin 80 | 2.4 81 | 82 | 83 | 84 | ${main.class} 85 | 86 | 87 | 88 | 89 | 90 | maven-assembly-plugin 91 | 92 | 93 | package 94 | 95 | single 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | ${main.class} 104 | 105 | 106 | 107 | jar-with-dependencies 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | com.opencsv 117 | opencsv 118 | 5.3 119 | 120 | 121 | commons-io 122 | commons-io 123 | 2.14.0 124 | 125 | 126 | org.apache.commons 127 | commons-lang3 128 | 3.9 129 | 130 | 131 | org.apache.logging.log4j 132 | log4j-api 133 | 2.17.1 134 | 135 | 136 | org.apache.logging.log4j 137 | log4j-core 138 | 2.17.1 139 | 140 | 141 | org.slf4j 142 | slf4j-api 143 | 1.7.29 144 | 145 | 146 | org.slf4j 147 | slf4j-log4j12 148 | 1.7.29 149 | 150 | 151 | com.googlecode.json-simple 152 | json-simple 153 | 1.1.1 154 | 155 | 156 | org.apache.maven.plugins 157 | maven-dependency-plugin 158 | 3.1.1 159 | 160 | 161 | org.thymeleaf 162 | thymeleaf 163 | 3.0.11.RELEASE 164 | 165 | 166 | org.json 167 | json 168 | 20231013 169 | 170 | 171 | org.neo4j.driver 172 | neo4j-java-driver 173 | 4.1.1 174 | 175 | 176 | com.arangodb 177 | arangodb-java-driver 178 | 6.14.0 179 | 180 | 181 | org.antlr 182 | antlr4 183 | ${antlr.version} 184 | 185 | 186 | org.tmatesoft.svnkit 187 | svnkit 188 | 1.10.5 189 | 190 | 191 | org.antlr 192 | antlr4-runtime 193 | ${antlr.version} 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /run.ps1: -------------------------------------------------------------------------------- 1 | # DESCRIPTION: 2 | # 3 | # Takes java project path and destination path (ending with html file) as input parameters. 4 | # Destination path will have the generated report 5 | # 6 | # USAGE: 7 | # ./run.ps1 8 | 9 | # run 10 | param ( 11 | [Parameter(Mandatory)] [string]$PathToJavaProject, 12 | [Parameter(Mandatory)] [string]$PathToOutputDirectory, 13 | [Parameter(Mandatory)] [string]$arangoDbUsername, 14 | [Parameter(Mandatory)] [string]$arangoDbPassword, 15 | [Parameter(Mandatory)] [string]$ruleNames 16 | ) 17 | 18 | $USAGE="Usage: ./run.ps1 " 19 | Write-Output $USAGE 20 | 21 | Copy-Item -Path "src/main/resources/lib" -Destination $PathToOutputDirectory -Recurse 22 | java --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED -jar target/app-server-migration-1.0.0-SNAPSHOT-jar-with-dependencies.jar $PathToJavaProject $PathToOutputDirectory $arangoDbUsername $arangoDbPassword $ruleNames -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o pipefail 4 | set -o nounset 5 | set -o errexit 6 | # DESCRIPTION: 7 | # 8 | # Takes java project path and destination path (ending with html file) as input parameters. 9 | # Destination path will have the generated report 10 | # 11 | # USAGE: 12 | # chmod +x run.sh 13 | # .run.sh 14 | 15 | USAGE="Usage: run.sh " 16 | [ $# -ne 5 ] && { echo "$USAGE"; exit; } 17 | 18 | cp -r src/main/resources/lib "$2" 19 | 20 | # run 21 | java --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED -jar target/app-server-migration-1.0.0-SNAPSHOT-jar-with-dependencies.jar "$1" "$2" "$3" "$4" "$5" -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o pipefail 4 | set -o nounset 5 | set -o errexit 6 | 7 | # DESCRIPTION: 8 | # 9 | # Tools Installed: 10 | # Java 8 11 | # Docker 12 | # Maven 13 | # git 14 | # 15 | # USAGE: 16 | # chmod +x setup.sh 17 | # ./setup.sh 18 | 19 | ## java 20 | java_install(){ 21 | if type -p java; then 22 | echo found java executable in PATH 23 | else 24 | echo "no java present on machine, installing openjdk" 25 | sudo $PACKAGE_MANAGER install -y $JAVA_LIB 26 | echo "export JAVA_HOME=`dirname $(dirname $(readlink -f $(which javac)))`" >> ~/.bashrc 27 | fi 28 | version=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}') 29 | echo version of java "$version" 30 | } 31 | ## docker, git 32 | #sudo amazon-linux-extras install -y docker 33 | docker_git_install(){ 34 | #$PACKAGE_MANAGER update -y 35 | $PACKAGE_MANAGER install -y $DOCKER_LIB git 36 | sudo service docker start 37 | sudo usermod -a -G docker `whoami` 38 | } 39 | 40 | 41 | ## maven 42 | maven_install() { 43 | if type -p mvn; then 44 | echo found mvn executable in PATH 45 | else 46 | $PACKAGE_MANAGER install maven -y 47 | fi 48 | } 49 | 50 | app_server_mig_install() { 51 | # app-server-migration 52 | mvn clean package install 53 | } 54 | 55 | arch=$(uname -m) 56 | if [[ $arch == x86_64* ]]; then 57 | echo "X64 Architecture" 58 | else 59 | echo "supporting only x86 architecture" && exit 1 60 | fi 61 | 62 | if command -v apt-get >/dev/null; then 63 | echo "apt-get is used" 64 | PACKAGE_MANAGER="sudo apt-get" 65 | JAVA_LIB="openjdk-8-jdk" 66 | DOCKER_LIB="docker.io" 67 | java_install 68 | docker_git_install 69 | maven_install 70 | elif command -v yum >/dev/null; then 71 | echo "yum is used" 72 | PACKAGE_MANAGER="sudo yum" 73 | JAVA_LIB="java-1.8.0-openjdk java-1.8.0-openjdk-devel.x86_64" 74 | DOCKER_LIB="docker" 75 | java_install 76 | docker_git_install 77 | maven_install 78 | elif command -v brew >/dev/null; then 79 | echo "brew is used" 80 | PACKAGE_MANAGER="brew" 81 | JAVA_LIB="java" 82 | DOCKER_LIB="docker" 83 | java_install 84 | brew install docker git maven 85 | open -a docker 86 | else 87 | echo "package manager not known" 88 | fi 89 | 90 | app_server_mig_install -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/checkout/ConfigurationBean.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.checkout; 2 | 3 | import com.opencsv.bean.CsvBindByPosition; 4 | 5 | public class ConfigurationBean { 6 | @CsvBindByPosition(position = 0) 7 | private String projectName; 8 | 9 | @CsvBindByPosition(position = 1) 10 | private String repoType; 11 | 12 | @CsvBindByPosition(position = 2) 13 | private String userName; 14 | 15 | @CsvBindByPosition(position = 3) 16 | private String password; 17 | 18 | @CsvBindByPosition(position = 4) 19 | private String branchName; 20 | 21 | @CsvBindByPosition(position = 5) 22 | private String repoUrl; 23 | 24 | public String getProjectName() { 25 | return projectName; 26 | } 27 | 28 | public String getRepoType() { 29 | return repoType; 30 | } 31 | 32 | public String getUserName() { 33 | return userName; 34 | } 35 | 36 | public String getPassword() { 37 | return password; 38 | } 39 | 40 | public String getBranchName() { 41 | return branchName; 42 | } 43 | 44 | public String getRepoUrl() { 45 | return repoUrl; 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return "ProjectDetailsBean [name=" + projectName + ", repoType=" + repoType + ", userName=" + userName + ", password=" 51 | + password + ", branchName=" + branchName + ", repoUrl=" + repoUrl + "]"; 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/checkout/IRepoManager.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.checkout; 2 | 3 | public interface IRepoManager { 4 | 5 | public void getSourceCode(String url, String dest); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/checkout/RepoDetails.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.checkout; 2 | 3 | public class RepoDetails { 4 | 5 | private RepoType repoType; 6 | private String userName; 7 | private String password; 8 | 9 | 10 | private RepoDetails() { 11 | 12 | } 13 | 14 | public RepoType getRepoType() { 15 | return repoType; 16 | } 17 | 18 | public String getUserName() { 19 | return userName; 20 | } 21 | 22 | public String getPassword() { 23 | return password; 24 | } 25 | 26 | 27 | public static class Builder { 28 | private RepoType repoType; 29 | private String userName; 30 | private String password; 31 | 32 | public static Builder newInstance() 33 | { 34 | return new Builder(); 35 | } 36 | 37 | private Builder() {} 38 | 39 | public Builder repoType(RepoType repoType) { 40 | this.repoType = repoType; 41 | return this; 42 | } 43 | 44 | public Builder userName(String userName) { 45 | this.userName = userName; 46 | return this; 47 | } 48 | 49 | 50 | public Builder password(String password) { 51 | this.password = password; 52 | return this; 53 | } 54 | 55 | 56 | public RepoDetails build() { 57 | RepoDetails repoDetails = new RepoDetails(); 58 | 59 | repoDetails.repoType = repoType; 60 | repoDetails.userName = userName; 61 | repoDetails.password = password; 62 | 63 | return repoDetails; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/checkout/RepoManagerFactory.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.checkout; 2 | 3 | public class RepoManagerFactory { 4 | 5 | public static IRepoManager getRepoManager(RepoDetails repoDetails) { 6 | 7 | IRepoManager repoMgr = null; 8 | 9 | switch(repoDetails.getRepoType()){ 10 | case SVN: 11 | repoMgr = new SVNRepoManager(repoDetails); 12 | default: 13 | break; 14 | 15 | } 16 | return repoMgr; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/checkout/RepoType.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.checkout; 2 | 3 | public enum RepoType { 4 | 5 | SVN 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/checkout/SVNRepoManager.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.checkout; 2 | 3 | import java.io.File; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.tmatesoft.svn.core.SVNDepth; 8 | import org.tmatesoft.svn.core.SVNException; 9 | import org.tmatesoft.svn.core.SVNURL; 10 | import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; 11 | import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory; 12 | import org.tmatesoft.svn.core.wc.SVNClientManager; 13 | import org.tmatesoft.svn.core.wc.SVNRevision; 14 | import org.tmatesoft.svn.core.wc.SVNUpdateClient; 15 | import org.tmatesoft.svn.core.wc.SVNWCUtil; 16 | 17 | public class SVNRepoManager implements IRepoManager { 18 | 19 | private final static Logger LOGGER = LoggerFactory.getLogger(SVNRepoManager.class); 20 | 21 | private ISVNAuthenticationManager authManager; 22 | private SVNClientManager clientManager; 23 | private SVNUpdateClient updateClient; 24 | 25 | 26 | public SVNRepoManager(RepoDetails projDetails) { 27 | init(projDetails.getUserName(), projDetails.getPassword()); 28 | } 29 | 30 | private void init(String svnUserName, String svnPassword ) 31 | { 32 | DAVRepositoryFactory.setup(); 33 | 34 | //create authentication data 35 | authManager = SVNWCUtil.createDefaultAuthenticationManager(svnUserName, svnPassword.toCharArray()); 36 | 37 | //create client manager and set authentication 38 | clientManager = SVNClientManager.newInstance(); 39 | clientManager.setAuthenticationManager(authManager); 40 | //get SVNUpdateClient to do the export 41 | updateClient = clientManager.getUpdateClient(); 42 | 43 | } 44 | 45 | @Override 46 | public void getSourceCode(String url,String dest) { 47 | 48 | try { 49 | updateClient.setIgnoreExternals(false); 50 | updateClient.doCheckout(SVNURL.parseURIEncoded(url), new File(dest), SVNRevision.HEAD, SVNRevision.HEAD, 51 | SVNDepth.INFINITY, false); 52 | LOGGER.info("Checked out code successfully from "+url); 53 | } catch (SVNException e) { 54 | LOGGER.error("Error message :" + e.getMessage()); 55 | } 56 | 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/checkout/SourceCodeManager.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.checkout; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileReader; 6 | import java.util.List; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.amazon.aws.am2.appmig.estimate.Main; 12 | import com.amazon.aws.am2.appmig.estimate.exception.UnsupportedRepoException; 13 | import com.opencsv.bean.CsvToBeanBuilder; 14 | 15 | public class SourceCodeManager { 16 | private final static Logger LOGGER = LoggerFactory.getLogger(Main.class); 17 | 18 | public static String downloadCode(String configFilePath, String target) throws Exception { 19 | List beans; 20 | FileReader configReader = null; 21 | try { 22 | configReader = new FileReader(configFilePath); 23 | beans = new CsvToBeanBuilder(configReader) 24 | .withType(ConfigurationBean.class) 25 | .withSkipLines(1)//Skip header of CSV File 26 | .build() 27 | .parse(); 28 | } catch (IllegalStateException | FileNotFoundException e) { 29 | LOGGER.error("Error while reading configuration : " + e.getMessage()); 30 | throw e; 31 | } finally { 32 | if (configReader != null) { 33 | configReader.close(); 34 | } 35 | } 36 | for (ConfigurationBean bean : beans) { 37 | RepoDetails details = RepoDetails.Builder.newInstance() 38 | .repoType(RepoType.valueOf(bean.getRepoType())) 39 | .userName(bean.getUserName()) 40 | .password(bean.getPassword()) 41 | .build(); 42 | IRepoManager repomgr = RepoManagerFactory.getRepoManager(details); 43 | if(repomgr != null) { 44 | repomgr.getSourceCode(bean.getRepoUrl(),target + File.separator + bean.getProjectName()); 45 | } 46 | else { 47 | throw new UnsupportedRepoException("Repo type "+bean.getRepoType()+" is not supported "); 48 | } 49 | } 50 | return target; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/checkout/package-info.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.checkout; -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/constants/IConstants.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.constants; 2 | 3 | public interface IConstants { 4 | 5 | String EXT_CLASS = "class"; 6 | String LANG_SQL = "sql"; 7 | String RULE_TYPE_SQL = "sql"; 8 | String DIR_TARGET = "target"; 9 | String DIR_BUILD = "build"; 10 | String DIR_SETTINGS = ".settings"; 11 | String DIR_MVN = ".mvn"; 12 | String EXT_CLASSPATH = "classpath"; 13 | String EXT_GIT = "git"; 14 | String EXT_PROJECT = "project"; 15 | String EXT_DS_STORE = "DS_Store"; 16 | String RESOURCE_FOLDER_PATH = "/src/main/resources/"; 17 | String USER_DIR = "user.dir"; 18 | // File Names 19 | String FILE_MVN_BUILD = "pom.xml"; 20 | String FILE_ANT_BUILD = "build.xml"; 21 | String FILE_GRADLE_BUILD = "build.gradle"; 22 | String FILE_RECOMMENDATIONS = "recommendations.json"; 23 | String SRC_DIR = "src"; 24 | String MAIN_DIR = "main"; 25 | String JAVA_DIR = "java"; 26 | 27 | // Analyzer constants 28 | String RULES = "rules"; 29 | String ANALYZER = "analyzer"; 30 | String FILE_TYPE = "file_type"; 31 | String ANY = "*"; 32 | String ID = "id"; 33 | String NAME = "name"; 34 | String DESCRIPTION = "description"; 35 | String PROJECT_TYPE = "projectType"; 36 | String COMPLEXITY = "complexity"; 37 | String ADD = "add"; 38 | String REMOVE = "remove"; 39 | String SEARCH = "search"; 40 | String DEPENDS_ON = "depends_on"; 41 | String RULE_TYPE = "rule_type"; 42 | String COMPLEXITY_MAJOR = "major"; 43 | String COMPLEXITY_MINOR = "minor"; 44 | String COMPLEXITY_CRITICAL = "critical"; 45 | String PACKAGE = "package"; 46 | String IMPORT = "import"; 47 | String RECOMMENDATION = "recommendation"; 48 | String RECOMMENDATIONS = "recommendations"; 49 | String TAB = " "; 50 | 51 | // ArangoDB constants 52 | String ADB_ID = "_id"; 53 | 54 | // MVN Analyzer constants 55 | String GROUP_ID = "groupId"; 56 | String ARTIFACT_ID = "artifactId"; 57 | String VERSION = "version"; 58 | String TAG_TO_REPLACE = "<$tagname>$tagvalue"; 59 | String TAG_NAME = "$tagname"; 60 | String TAG_VALUE = "$tagvalue"; 61 | String DEPENDENCY = "dependency"; 62 | String PLUGIN = "plugin"; 63 | String PARENT = "parent"; 64 | String PROJECT = "project"; 65 | String MODULES = "modules"; 66 | String MODULE = "module"; 67 | String DEPENDENCIES = "dependencies"; 68 | String PLUGINS = "plugins"; 69 | String DEL_FILES_DIRS = "List of directories and files to be removed"; 70 | 71 | // Properties Analyzer constants 72 | String PROP_NAME = "name"; 73 | String PROP_VALUE = "value"; 74 | String PATTERN = "pattern"; 75 | 76 | // Date formats 77 | String SIMPLE_DT_FORMAT = "dd/MMM/yyyy"; 78 | // Template constants 79 | String TMPL_IS_DANGER = "isDanger"; 80 | String TMPL_REPORT_EXT = ".html"; 81 | String TMPL_STD_REPORT = "reporttemplate.html"; 82 | String TMPL_STD_SQL_REPORT = "sqlreporttemplate.html"; 83 | String TMPL_STD_SUMMARY_REPORT = "summaryreporttemplate.html"; 84 | String SUMMARY_REPORT = "summaryreport.html"; 85 | String TMPL_PH_DATE = "date"; 86 | String TMPL_PH_TOTAL_FILES = "totalfiles"; 87 | String TMPL_PH_FILE_COUNT = "fileCount"; 88 | String TMPL_PH_TOTAL_FILE_CHANGES = "totalFileChanges"; 89 | String TMPL_PH_TOTAL_SQL_STATEMENTS = "totalSQLStatements"; 90 | String TMPL_PH_TOTAL_SELECT_STATEMENTS = "totalSelectStatements"; 91 | String TMPL_PH_TOTAL_CREATE_STATEMENTS = "totalCreateStatements"; 92 | String TMPL_PH_TOTAL_DELETE_STATEMENTS = "totalDeleteStatements"; 93 | String TMPL_PH_TOTAL_UPDATE_STATEMENTS = "totalUpdateStatements"; 94 | String TMPL_PH_TOTAL_INSERT_STATEMENTS = "totalInsertStatements"; 95 | String TMPL_PH_TOTAL_MERGE_STATEMENTS = "totalMergeStatements"; 96 | String TMPL_PH_TOTAL_DROP_STATEMENTS = "totalDropStatements"; 97 | String TMPL_PH_TOTAL_PROJECTS_SCANNED = "totalProjectsScanned"; 98 | String TMPL_PH_TOTAL_MINOR_PROJECTS = "totalMinorProjects"; 99 | String TMPL_PH_TOTAL_MAJOR_PROJECTS = "totalMajorProjects"; 100 | String TMPL_PH_TOTAL_CRITICAL_PROJECTS = "totalCriticalProjects"; 101 | String TMPL_PH_SQL_REPORT_LINK = "inlineSQLReport"; 102 | String TMPL_PH_TOTAL_LOC = "totalLOC"; 103 | String TMPL_PH_TOTAL_CHANGES = "totalchanges"; 104 | String TMPL_PH_COMPLEXITY = "complexity"; 105 | String TMPL_PH_TOTAL_MHRS = "totalmhrs"; 106 | String TMPL_PH_TOTAL_PERSON_DAYS = "totalPersonDays"; 107 | String TMPL_PH_TOTAL_SQL_PERSON_DAYS = "totalSQLPersonDays"; 108 | String TMPL_PH_TOTAL_JAVA_PERSON_DAYS = "totalJavaPersonDays"; 109 | String TMPL_PH_PROJECTS = "totalProjects"; 110 | String TMPL_PH_RECOMMENDATIONS = "recommendations"; 111 | String REPORT_NAME_SUFFIX = "-Report.html"; 112 | String SQL_REPORT_NAME_SUFFIX = "-SQL-Report.html"; 113 | 114 | // Java Construct constants 115 | String JAVA_KEYWORD_PUBLIC = "public"; 116 | String JAVA_KEYWORD_ABSTRACT = "abstract"; 117 | String JAVA_KEYWORD_DEFAULT = "default"; 118 | String JAVA_KEYWORD_FINAL = "final"; 119 | String JAVA_KEYWORD_PRIVATE = "private"; 120 | String JAVA_KEYWORD_PROTECTED = "protected"; 121 | String JAVA_KEYWORD_STATIC = "static"; 122 | 123 | // SQL statement constructs 124 | String SELECT = "select"; 125 | String UPDATE = "update"; 126 | String INSERT = "insert"; 127 | String DELETE = "delete"; 128 | String DROP = "drop"; 129 | String MERGE = "merge"; 130 | String CREATE = "create"; 131 | String TOTAL = "total"; 132 | 133 | /** 134 | * Backfired Function point to calculate the efforts based on the lines of code 135 | */ 136 | enum BFFP { 137 | JAVA(53), SQL(13); 138 | private final int value; 139 | 140 | public int getValue() { 141 | return value; 142 | } 143 | 144 | BFFP(int value) { 145 | this.value = value; 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/constants/package-info.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.constants; -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/CodeMetaData.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate; 2 | 3 | import static com.amazon.aws.am2.appmig.constants.IConstants.TAB; 4 | 5 | public class CodeMetaData implements Comparable { 6 | 7 | private Integer lineNumber; 8 | private String statement; 9 | private String language; 10 | 11 | public CodeMetaData(String statement) { 12 | this.statement = statement; 13 | } 14 | 15 | public CodeMetaData(int lineNumber, String statement) { 16 | this.lineNumber = lineNumber; 17 | this.statement = statement; 18 | } 19 | 20 | public CodeMetaData(int lineNumber, String statement, String language) { 21 | this.lineNumber = lineNumber; 22 | this.statement = statement; 23 | this.language = language; 24 | } 25 | 26 | public Integer getLineNumber() { 27 | return lineNumber; 28 | } 29 | 30 | public void setLineNumber(Integer lineNumber) { 31 | this.lineNumber = lineNumber; 32 | } 33 | 34 | public String getStatement() { 35 | return statement; 36 | } 37 | 38 | public void setStatement(String statement) { 39 | this.statement = statement; 40 | } 41 | 42 | /** 43 | * 44 | * This is to define the CSS class to beautify the code in the report. Depending 45 | * upon the language that is set here, the styling, indentation and coloring is 46 | * done for the corresponding code displayed in the report generated. Returns 47 | * the language string. Possible values are markup, clike, java, javaScript, 48 | * bash, javadoclike, javastacktrace, plsql, powershell, sql, yaml and json5 49 | * 50 | * @return 51 | */ 52 | public String getLanguage() { 53 | return language; 54 | } 55 | 56 | public void setLanguage(String language) { 57 | this.language = language; 58 | } 59 | 60 | @Override 61 | public int hashCode() { 62 | return (lineNumber != null) ? (lineNumber * statement.hashCode()) : statement.hashCode(); 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | return lineNumber + TAB + statement; 68 | } 69 | 70 | @Override 71 | public int compareTo(CodeMetaData obj) { 72 | int comparision = -1; 73 | if (this.lineNumber == null && obj.lineNumber == null) { 74 | comparision = 0; 75 | } else if (obj.lineNumber == null) { 76 | comparision = 1; 77 | } else if (this.lineNumber == null) { 78 | comparision = -1; 79 | } else { 80 | comparision = this.lineNumber.compareTo(obj.getLineNumber()); 81 | } 82 | return comparision; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/Complexity.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate; 2 | 3 | public enum Complexity { 4 | 5 | CRITICAL, MINOR, MAJOR 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/DefaultFilter.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | import java.nio.file.LinkOption; 7 | import java.nio.file.Path; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | import java.util.ArrayList; 11 | 12 | import org.apache.commons.io.FilenameUtils; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | import static com.amazon.aws.am2.appmig.constants.IConstants.*; 17 | 18 | public class DefaultFilter implements IFilter { 19 | 20 | private final String[] arrFileFilter = {EXT_CLASS, EXT_CLASSPATH, EXT_GIT, EXT_DS_STORE, EXT_PROJECT}; 21 | private final String[] arrDirFilter = {DIR_BUILD, DIR_TARGET, DIR_SETTINGS, DIR_MVN}; 22 | private final List subProjDirsFilter; 23 | private final static Logger LOGGER = LoggerFactory.getLogger(DefaultFilter.class); 24 | 25 | public DefaultFilter(List subProjDirsFilter) { 26 | this.subProjDirsFilter = new ArrayList<>(subProjDirsFilter); 27 | } 28 | 29 | public boolean filter(Path path) { 30 | boolean consider; 31 | try { 32 | if (Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) { 33 | consider = applyFilterOnDir(path); 34 | } else if (Files.isRegularFile(path, LinkOption.NOFOLLOW_LINKS)) { 35 | consider = applyFilterOnFile(path); 36 | } else { 37 | consider = false; 38 | } 39 | } catch (Exception e) { 40 | consider = false; 41 | } 42 | return consider; 43 | } 44 | 45 | private boolean applyFilterOnFile(Path path) { 46 | try { 47 | if (Files.isHidden(path)) { 48 | return false; 49 | } 50 | } catch (IOException ioe) { 51 | LOGGER.warn("!Ignoring filter for this file due to unable to read the attributes of the file {} due to {}", path, ioe.getMessage()); 52 | } 53 | String ext = FilenameUtils.getExtension(path.getFileName().toString()); 54 | boolean value = Arrays.asList(arrFileFilter).contains(ext); 55 | return !value; 56 | } 57 | 58 | private boolean applyFilterOnDir(Path path) { 59 | String dirName = path.getFileName().toString(); 60 | String dirAbsPath = path.getParent() + File.separator + dirName; 61 | boolean value1 = Arrays.stream(arrDirFilter).anyMatch(dirName::contentEquals); 62 | // The below filtering process filters the subprojects if they are listed as maven projects 63 | boolean value2 = subProjDirsFilter.stream().anyMatch(dirAbsPath::equals); 64 | return !(value1 || value2); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/Dependency.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public class Dependency { 9 | 10 | private String ruleFile; 11 | private String fileType; 12 | private Map> dependencies; 13 | 14 | public Dependency() { 15 | dependencies = new HashMap<>(); 16 | } 17 | 18 | public Dependency(String ruleFile, String fileType) { 19 | this.ruleFile = ruleFile; 20 | this.fileType = fileType; 21 | dependencies = new HashMap<>(); 22 | } 23 | 24 | public Dependency(String ruleFile, String fileType, Map> dependencies) { 25 | this.ruleFile = ruleFile; 26 | this.fileType = fileType; 27 | this.dependencies = dependencies; 28 | } 29 | 30 | public String getRuleFile() { 31 | return ruleFile; 32 | } 33 | 34 | public void setRuleFile(String ruleFile) { 35 | this.ruleFile = ruleFile; 36 | } 37 | 38 | public String getFileType() { 39 | return fileType; 40 | } 41 | 42 | public void setFileType(String fileType) { 43 | this.fileType = fileType; 44 | } 45 | 46 | public Map> getDependencies() { 47 | return dependencies; 48 | } 49 | 50 | public void setDependencies(Map> dependencies) { 51 | this.dependencies = dependencies; 52 | } 53 | 54 | public boolean isRuleApplied(String fileName, long rule) { 55 | boolean applied = false; 56 | List rulesApplied = dependencies.get(fileName); 57 | if (rulesApplied != null && rulesApplied.contains(rule)) { 58 | applied = true; 59 | } 60 | return applied; 61 | } 62 | 63 | public void applyRule(String fileName, long rule) { 64 | List rules = dependencies.get(fileName); 65 | if (rules != null) { 66 | rules.add(rule); 67 | } else { 68 | rules = new ArrayList(); 69 | rules.add(rule); 70 | dependencies.put(fileName, rules); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/DependencyManager.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class DependencyManager { 7 | 8 | private Map dependencies; 9 | private static DependencyManager INSTANCE; 10 | 11 | private DependencyManager() { 12 | dependencies = new HashMap<>(); 13 | } 14 | 15 | public synchronized static DependencyManager getInstance() { 16 | if (INSTANCE == null) { 17 | INSTANCE = new DependencyManager(); 18 | } 19 | return INSTANCE; 20 | } 21 | 22 | public synchronized boolean isRuleApplied(String ruleFile, String fileName, int rule) { 23 | boolean ruleApplied = false; 24 | Dependency dependency = dependencies.get(ruleFile); 25 | if (dependency != null) { 26 | ruleApplied = dependency.isRuleApplied(fileName, rule); 27 | } 28 | return ruleApplied; 29 | } 30 | 31 | public synchronized void applyRule(String ruleFile, String fileType, String fileName, long rule) { 32 | Dependency dependency = dependencies.get(ruleFile); 33 | if (dependency == null) { 34 | dependency = new Dependency(ruleFile, fileType); 35 | dependency.applyRule(fileName, rule); 36 | dependencies.put(ruleFile, dependency); 37 | } else { 38 | dependency.applyRule(fileName, rule); 39 | } 40 | } 41 | 42 | public Map getAllDependencies() { 43 | return dependencies; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/IAnalyzer.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate; 2 | 3 | import org.json.simple.JSONArray; 4 | import com.amazon.aws.am2.appmig.estimate.exception.InvalidRuleException; 5 | import com.amazon.aws.am2.appmig.estimate.exception.NoRulesFoundException; 6 | 7 | public interface IAnalyzer { 8 | 9 | enum SUPPORTED_LANGUAGES { 10 | 11 | LANG_JAVA("lang-java"), 12 | LANG_BASH("lang-bash"), 13 | LANG_PROPERTIES("lang-properties"), 14 | LANG_MARKUP("lang-markup"), 15 | LANG_CLIKE("lang-clike"), 16 | LANG_JAVASCRIPT("lang-javascript"), 17 | LANG_JAVADOCLIKE("lang-javadoclike"), 18 | LANG_JAVASTACKTRACE("lang-javastacktrace"), 19 | LANG_PLSQL("lang-plsql"), 20 | LANG_POWERSHELL("lang-powershell"), 21 | LANG_SQL("lang-sql"), 22 | LANG_YAML("lang-yaml"), 23 | // .skipBeautify is actually not a language. This is like a flag to skip for the 24 | // elements where beautify is not recommended. e.g., like directory listings, 25 | // absolute or relative file paths etc. 26 | LANG_SKIP_BEAUTIFY(".skipBeautify"), 27 | LANG_JSON("lang-json5"); 28 | 29 | private final String language; 30 | 31 | SUPPORTED_LANGUAGES(String lang) { 32 | this.language = lang; 33 | } 34 | 35 | public String getLanguage() { 36 | return this.language; 37 | } 38 | } 39 | 40 | public boolean analyze(String path) throws NoRulesFoundException, InvalidRuleException; 41 | 42 | public void setRules(JSONArray rules); 43 | 44 | public JSONArray getRules(); 45 | 46 | public String getRuleFileName(); 47 | 48 | public void setRuleFileName(String ruleFileName); 49 | 50 | public String getFileType(); 51 | 52 | public void setFileType(String fileType); 53 | 54 | public void setSource(String src); 55 | 56 | public String getSource(); 57 | 58 | public void setBasePackage(String packageName); 59 | 60 | public String getBasePackage(); 61 | 62 | public void setProjectId(String id); 63 | 64 | public String getProjectId(); 65 | 66 | public int getLOC(); 67 | 68 | public void setLOC(int loc); 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/IFilter.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate; 2 | 3 | import java.nio.file.Path; 4 | 5 | /** 6 | * To be implemented by any class acting as a filter. Filter is applied on each 7 | * and every file in the project directory. The 8 | * {@code public boolean filter(Path path)} method decides whether to perform 9 | * analysis or not on the respective file passed as input argument to the filter 10 | * method 11 | * 12 | * @author agoteti 13 | * 14 | */ 15 | public interface IFilter { 16 | 17 | public boolean filter(Path path); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/MavenDependency.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate; 2 | 3 | import org.apache.maven.model.Dependency; 4 | 5 | public class MavenDependency extends Dependency { 6 | 7 | private static final long serialVersionUID = 1L; 8 | private int artifactLineNum; 9 | private int groupLineNum; 10 | private int versionLineNum; 11 | 12 | public int getArtifactLineNum() { 13 | return artifactLineNum; 14 | } 15 | 16 | public void setArtifactLineNum(int arttifactLineNum) { 17 | this.artifactLineNum = arttifactLineNum; 18 | } 19 | 20 | public int getGroupLineNum() { 21 | return groupLineNum; 22 | } 23 | 24 | public void setGroupLineNum(int groupLineNum) { 25 | this.groupLineNum = groupLineNum; 26 | } 27 | 28 | public int getVersionLineNum() { 29 | return versionLineNum; 30 | } 31 | 32 | public void setVersionLineNum(int versionLineNum) { 33 | this.versionLineNum = versionLineNum; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "Dependency {groupId=" + this.getGroupId() + ", artifactId=" + this.getArtifactId() + ", version=" 39 | + this.getVersion() + ", artifactLineNum=" + artifactLineNum + ", groupLineNum=" + groupLineNum 40 | + ", versionLineNum=" + versionLineNum + "}"; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/Plan.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public class Plan implements Comparable { 10 | 11 | public Plan() { 12 | } 13 | 14 | public Plan(int ruleId, String planName, String planDescription, String complexity, String ruleType) { 15 | this.ruleId = ruleId; 16 | this.planName = planName; 17 | this.planDescription = planDescription; 18 | this.complexity = complexity; 19 | this.ruleType = ruleType; 20 | } 21 | 22 | private int ruleId; 23 | private String planName; 24 | private String planDescription; 25 | private String complexity; 26 | private List addition; 27 | private List deletion; 28 | private Map modifications; 29 | private int recommendation; 30 | private String ruleType; 31 | 32 | public int getRuleId() { 33 | return ruleId; 34 | } 35 | 36 | public String getComplexity() { 37 | return complexity; 38 | } 39 | 40 | public void setComplexity(String complexity) { 41 | this.complexity = complexity; 42 | } 43 | 44 | public String getRuleType() { 45 | return this.ruleType; 46 | } 47 | 48 | public List getAddition() { 49 | if (addition != null) { 50 | Collections.sort(addition); 51 | } 52 | return addition; 53 | } 54 | 55 | public List getDeletion() { 56 | if (deletion != null) { 57 | Collections.sort(deletion); 58 | } 59 | return deletion; 60 | } 61 | 62 | public Map getModifications() { 63 | return modifications; 64 | } 65 | 66 | public void setModifications(Map modifications) { 67 | this.modifications = modifications; 68 | } 69 | 70 | public void addDeletion(CodeMetaData codeMetaData) { 71 | if (deletion == null) { 72 | deletion = new ArrayList(); 73 | } 74 | deletion.add(codeMetaData); 75 | } 76 | 77 | public void addModification(CodeMetaData codeMetaData, CodeMetaData addCodeMetaData) { 78 | if (modifications == null) { 79 | modifications = new HashMap<>(); 80 | } 81 | modifications.put(codeMetaData, addCodeMetaData); 82 | } 83 | 84 | public String getPlanName() { 85 | return planName; 86 | } 87 | 88 | public String getPlanDescription() { 89 | return planDescription; 90 | } 91 | 92 | public Integer getRecommendation() { 93 | return recommendation; 94 | } 95 | 96 | public void setRecommendations(Integer recommendation) { 97 | this.recommendation = recommendation; 98 | } 99 | 100 | public int getTotalChanges(boolean excludeSQL) { 101 | return findSizeOfAdditions(excludeSQL) + findSizeOfModifications(excludeSQL) + findSizeOfDeletions(excludeSQL); 102 | } 103 | 104 | private int findSizeOfDeletions(boolean excludeSQL) { 105 | int totalDeletions = 0; 106 | if (this.deletion != null) { 107 | if (excludeSQL) { 108 | totalDeletions = (int) this.deletion.stream(). 109 | filter(codeMetaData -> !IAnalyzer.SUPPORTED_LANGUAGES.LANG_SQL.getLanguage().equals(codeMetaData.getLanguage())).count(); 110 | } else { 111 | totalDeletions = this.deletion.size(); 112 | } 113 | } 114 | return totalDeletions; 115 | } 116 | 117 | private int findSizeOfModifications(boolean excludeSQL) { 118 | int totalModifications = 0; 119 | if (this.modifications != null) { 120 | if (excludeSQL) { 121 | totalModifications = (int) this.modifications.keySet().stream(). 122 | filter(codeMetaData -> !IAnalyzer.SUPPORTED_LANGUAGES.LANG_SQL.getLanguage().equals(codeMetaData.getLanguage())).count(); 123 | } else { 124 | totalModifications = this.modifications.size(); 125 | } 126 | } 127 | return totalModifications; 128 | } 129 | 130 | private int findSizeOfAdditions(boolean excludeSQL) { 131 | int totalAdditions = 0; 132 | if (this.addition != null) { 133 | if (excludeSQL) { 134 | totalAdditions = (int) this.addition.stream(). 135 | filter(codeMetaData -> !IAnalyzer.SUPPORTED_LANGUAGES.LANG_SQL.getLanguage().equals(codeMetaData.getLanguage())).count(); 136 | } else { 137 | totalAdditions = this.addition.size(); 138 | } 139 | } 140 | return totalAdditions; 141 | } 142 | 143 | @Override 144 | public int compareTo(Plan plan) { 145 | CodeMetaData thisMaxCodeMetaData = Collections.max((this.getDeletion() != null) ? this.getDeletion() : this.getModifications().keySet()); 146 | CodeMetaData paramMaxCodeMetaData = Collections.max((plan.getDeletion() != null) ? plan.getDeletion() : plan.getModifications().keySet()); 147 | return thisMaxCodeMetaData.compareTo(paramMaxCodeMetaData); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/ProjectEstimator.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate; 2 | 3 | import com.amazon.aws.am2.appmig.estimate.ant.AntEstimator; 4 | import com.amazon.aws.am2.appmig.estimate.exception.NoRulesFoundException; 5 | import com.amazon.aws.am2.appmig.estimate.gradle.GradleEstimator; 6 | import com.amazon.aws.am2.appmig.estimate.mvn.MvnEstimator; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.io.File; 11 | 12 | import static com.amazon.aws.am2.appmig.constants.IConstants.*; 13 | 14 | /** 15 | * {@code ProjectEstimator} is a factory class. It identifies the appropriate 16 | * {@code com.amazon.aws.am2.appmig.estimate.Estimator} implementation during 17 | * runtime based on the type of the build. As of now, it supports 3 types of 18 | * builds, MAVEN, Gradle and ANT 19 | * 20 | * @author agoteti 21 | */ 22 | public class ProjectEstimator { 23 | 24 | private final static Logger LOGGER = LoggerFactory.getLogger(ProjectEstimator.class); 25 | 26 | /** 27 | * Returns the appropriate implementation of {@code Estimator} class based on 28 | * the build file present in the source project directory which needs to 29 | * be migrated to the target server compatible code 30 | * 31 | * @param source Project directory which needs to be migrated to target server compatible code 32 | * @return Returns implementation class of {@code Estimator} 33 | */ 34 | public static Estimator getEstimator(String source, String ruleNames) { 35 | Estimator estimator = null; 36 | File dir = new File(source); 37 | File[] files = dir.listFiles(); 38 | if (files == null) { 39 | LOGGER.error("Given path {} is not a directory", source); 40 | } else { 41 | LOGGER.info("Identifying the estimator for the path {}", source); 42 | try { 43 | estimator = findEstimator(dir, ruleNames); 44 | } catch (NoRulesFoundException e) { 45 | throw new RuntimeException(e); 46 | } 47 | } 48 | return estimator; 49 | } 50 | 51 | private static Estimator findEstimator(File dir, String ruleNames) throws NoRulesFoundException { 52 | ProjectType type = ProjectType.UNKNOWN; 53 | Estimator estimator = null; 54 | File buildFile = null; 55 | File mavenBuildFile = new File(dir, FILE_MVN_BUILD); 56 | File antBuildFile = new File(dir, FILE_ANT_BUILD); 57 | File gradleBuildFile = new File(dir, FILE_GRADLE_BUILD); 58 | if (mavenBuildFile.exists()) { 59 | type = ProjectType.MVN; 60 | estimator = new MvnEstimator(ruleNames); 61 | buildFile = mavenBuildFile; 62 | } else if (antBuildFile.exists()) { 63 | type = ProjectType.ANT; 64 | estimator = new AntEstimator(ruleNames); 65 | buildFile = antBuildFile; 66 | } else if (gradleBuildFile.exists()) { 67 | type = ProjectType.GRADLE; 68 | estimator = new GradleEstimator(ruleNames); 69 | buildFile = gradleBuildFile; 70 | } 71 | LOGGER.info("Identified the project type as {}", type); 72 | if (estimator != null) { 73 | estimator.setSource(dir.getAbsolutePath()); 74 | estimator.setBasePackage(buildFile); 75 | } 76 | return estimator; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/ProjectType.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate; 2 | 3 | public enum ProjectType { 4 | 5 | ANT, MVN, MULTI_MODULE_MVN, GRADLE, UNKNOWN 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/Recommendation.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Set; 9 | import com.amazon.aws.am2.appmig.utils.Utility; 10 | 11 | public class Recommendation implements Serializable { 12 | 13 | private static final long serialVersionUID = 1L; 14 | private int id; 15 | private String name; 16 | private String description; 17 | private Map> changes; 18 | 19 | public Recommendation() { 20 | changes = new HashMap<>(); 21 | } 22 | 23 | public Recommendation(int id, String name, String description) { 24 | this.id = id; 25 | this.name = name; 26 | this.description = description; 27 | changes = new HashMap<>(); 28 | } 29 | 30 | public int getId() { 31 | return id; 32 | } 33 | 34 | public void setId(int id) { 35 | this.id = id; 36 | } 37 | 38 | public String getName() { 39 | return name; 40 | } 41 | 42 | public void setName(String name) { 43 | this.name = name; 44 | } 45 | 46 | public String getDescription() { 47 | return description; 48 | } 49 | 50 | public void setDescription(String description) { 51 | this.description = description; 52 | } 53 | 54 | public Map> getChanges() { 55 | return changes; 56 | } 57 | 58 | public void setChanges(Map> changes) { 59 | this.changes = changes; 60 | } 61 | 62 | public void addChange(String fileName, Plan plan) { 63 | List plans = changes.get(fileName); 64 | if (plans == null) { 65 | plans = new ArrayList<>(); 66 | } 67 | plans.add(plan); 68 | changes.put(fileName, plans); 69 | } 70 | 71 | public int getTotalFiles() { 72 | return changes.keySet().size(); 73 | } 74 | 75 | public int getTotalChanges() { 76 | int intChanges = 0; 77 | Set fileNames = changes.keySet(); 78 | for (String fileName : fileNames) { 79 | List lstPlan = changes.get(fileName); 80 | for (Plan plan : lstPlan) { 81 | if (plan.getAddition() != null) { 82 | intChanges = intChanges + plan.getAddition().size(); 83 | } 84 | if (plan.getDeletion() != null) { 85 | intChanges = intChanges + plan.getDeletion().size(); 86 | } 87 | if (plan.getModifications() != null) { 88 | intChanges = intChanges + plan.getModifications().size(); 89 | } 90 | } 91 | } 92 | return intChanges; 93 | } 94 | 95 | public String getComplexity() { 96 | List lstPlan = new ArrayList<>(); 97 | Set fileNames = changes.keySet(); 98 | for (String fileName : fileNames) { 99 | lstPlan.addAll(changes.get(fileName)); 100 | } 101 | return Utility.fetchComplexity(lstPlan); 102 | } 103 | 104 | @Override 105 | public String toString() { 106 | return "id: " + id + " name: " + name + " description: " + description; 107 | } 108 | 109 | @Override 110 | public int hashCode() { 111 | return ((32 * id) + ((name != null) ? name.hashCode() : 0) 112 | + ((description != null) ? description.hashCode() : 0)); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/ant/AntEstimator.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.ant; 2 | 3 | import com.amazon.aws.am2.appmig.estimate.Estimator; 4 | import com.amazon.aws.am2.appmig.estimate.exception.NoRulesFoundException; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.io.File; 9 | 10 | public class AntEstimator extends Estimator { 11 | 12 | private final static Logger LOGGER = LoggerFactory.getLogger(AntEstimator.class); 13 | 14 | public AntEstimator(String ruleFiles) throws NoRulesFoundException { 15 | this.ruleNames = ruleFiles; 16 | loadRules(); 17 | } 18 | 19 | @Override 20 | protected void setBasePackage(File buildFile) { 21 | basePackage = ""; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/exception/InvalidPathException.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.exception; 2 | 3 | public class InvalidPathException extends Exception { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public InvalidPathException(String msg) { 8 | super(msg); 9 | } 10 | 11 | public InvalidPathException(String msg, Throwable cause) { 12 | super(msg, cause); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/exception/InvalidRuleException.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.exception; 2 | 3 | public class InvalidRuleException extends Exception { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public InvalidRuleException(String msg) { 8 | super(msg); 9 | } 10 | 11 | public InvalidRuleException(String msg, Throwable cause) { 12 | super(msg, cause); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/exception/NoRulesFoundException.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.exception; 2 | 3 | public class NoRulesFoundException extends Exception { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public NoRulesFoundException(String msg) { 8 | super(msg); 9 | } 10 | 11 | public NoRulesFoundException(String msg, Throwable cause) { 12 | super(msg, cause); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/exception/UnsupportedProjectException.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.exception; 2 | 3 | public class UnsupportedProjectException extends Exception { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public UnsupportedProjectException(String msg) { 8 | super(msg); 9 | } 10 | 11 | public UnsupportedProjectException(String msg, Throwable cause) { 12 | super(msg, cause); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/exception/UnsupportedRepoException.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.exception; 2 | 3 | public class UnsupportedRepoException extends Exception{ 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public UnsupportedRepoException(String msg) { 8 | super(msg); 9 | } 10 | 11 | public UnsupportedRepoException(String msg, Throwable cause) { 12 | super(msg, cause); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/exception/package-info.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.exception; -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/gradle/GradleEstimator.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.gradle; 2 | 3 | import static com.amazon.aws.am2.appmig.constants.IConstants.JAVA_DIR; 4 | import static com.amazon.aws.am2.appmig.constants.IConstants.MAIN_DIR; 5 | import static com.amazon.aws.am2.appmig.constants.IConstants.SRC_DIR; 6 | 7 | import java.io.File; 8 | import java.io.FileFilter; 9 | import java.nio.file.Files; 10 | import java.nio.file.Path; 11 | import java.nio.file.Paths; 12 | 13 | import com.amazon.aws.am2.appmig.estimate.exception.NoRulesFoundException; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | 17 | import com.amazon.aws.am2.appmig.estimate.Estimator; 18 | 19 | public class GradleEstimator extends Estimator { 20 | 21 | private final static Logger LOGGER = LoggerFactory.getLogger(GradleEstimator.class); 22 | 23 | public GradleEstimator(String ruleFiles) throws NoRulesFoundException { 24 | this.ruleNames = ruleFiles; 25 | loadRules(); 26 | } 27 | 28 | @Override 29 | protected void setBasePackage(File buildFile) { 30 | StringBuilder basePath = new StringBuilder(); 31 | String parentDir = buildFile.getParent(); 32 | Path path = Paths.get(parentDir, SRC_DIR, MAIN_DIR, JAVA_DIR); 33 | if (Files.exists(path)) { 34 | LOGGER.debug("/src/main/java is present in the gradle project directory {}", parentDir); 35 | // Constructing the base package. This has to be replaced with groovy.build 36 | // parsing logic 37 | File file = new File(path.toString()); 38 | boolean flag = true; 39 | do { 40 | if (file.isDirectory()) { 41 | File[] files = file.listFiles(new FileFilter() { 42 | @Override 43 | public boolean accept(File file) { 44 | return !file.isHidden(); 45 | } 46 | }); 47 | if (files.length == 1 && files[0].isDirectory()) { 48 | basePath.append(files[0].getName() + "."); 49 | file = new File(Paths.get(file.getAbsolutePath(), files[0].getName()).toString()); 50 | } else { 51 | flag = false; 52 | } 53 | } else { 54 | flag = false; 55 | } 56 | } while (flag); 57 | } else { 58 | LOGGER.warn("The path src/main/java does not exist in the gradle project directory {}", parentDir); 59 | } 60 | if (basePath.length() > 1) { 61 | basePackage = basePath.substring(0, basePath.length() - 1); 62 | LOGGER.info("Identified the base package as {}", basePackage); 63 | } else { 64 | basePackage = ""; 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/java/JavaFileAnalyzer.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.java; 2 | 3 | import java.io.IOException; 4 | import java.util.Map; 5 | 6 | import com.amazon.aws.am2.appmig.estimate.StandardReport; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.json.simple.JSONArray; 9 | import org.json.simple.JSONObject; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import com.amazon.aws.am2.appmig.estimate.CodeMetaData; 14 | import com.amazon.aws.am2.appmig.estimate.IAnalyzer; 15 | import com.amazon.aws.am2.appmig.estimate.Plan; 16 | import com.amazon.aws.am2.appmig.estimate.exception.InvalidRuleException; 17 | import com.amazon.aws.am2.appmig.estimate.exception.NoRulesFoundException; 18 | import com.amazon.aws.am2.appmig.glassviewer.IJavaGlassViewer; 19 | import com.amazon.aws.am2.appmig.glassviewer.JavaGlassViewer; 20 | import com.amazon.aws.am2.appmig.report.ReportSingletonFactory; 21 | import com.amazon.aws.am2.appmig.utils.Utility; 22 | import com.google.inject.internal.util.Maps; 23 | 24 | import static com.amazon.aws.am2.appmig.constants.IConstants.*; 25 | 26 | public class JavaFileAnalyzer implements IAnalyzer { 27 | 28 | private final static Logger LOGGER = LoggerFactory.getLogger(JavaFileAnalyzer.class); 29 | private JSONArray rules; 30 | private String fileType; 31 | private String ruleFileName; 32 | private String src; 33 | private String basePackage; 34 | private String projectId; 35 | private int loc; 36 | IJavaGlassViewer viewer; 37 | 38 | @Override 39 | public boolean analyze(String path) throws NoRulesFoundException { 40 | viewer = new JavaGlassViewer(); 41 | viewer.setBasePackage(basePackage); 42 | viewer.view(path, projectId); 43 | this.loc = viewer.getLoc(); 44 | viewer.cleanup(); 45 | if (rules == null || rules.isEmpty()) { 46 | throw new NoRulesFoundException("Rules need to be set before calling analyzer!"); 47 | } 48 | boolean taskCompleted = true; 49 | for (Object obj : rules) { 50 | try { 51 | JSONObject rule = (JSONObject) obj; 52 | applyRule(rule, path); 53 | } catch (InvalidRuleException | IOException e) { 54 | taskCompleted = false; 55 | LOGGER.error("Unable to apply rule on path {} due to {}", path, Utility.parse(e)); 56 | } catch (Exception e) { 57 | taskCompleted = false; 58 | LOGGER.error(e.getMessage(), e); 59 | } 60 | } 61 | viewer = null; 62 | return taskCompleted; 63 | } 64 | 65 | @Override 66 | public JSONArray getRules() { 67 | return rules; 68 | } 69 | 70 | @Override 71 | public void setRules(JSONArray rules) { 72 | this.rules = rules; 73 | } 74 | 75 | private void applyRule(JSONObject rule, String path) throws Exception { 76 | StandardReport stdReport = ReportSingletonFactory.getInstance().getStandardReport(); 77 | if (isImportRule(rule)) { 78 | Object removeObj = rule.get(REMOVE); 79 | if (removeObj != null) { 80 | JSONObject remove = (JSONObject) removeObj; 81 | Map references = applyImportRule(remove); 82 | for (Map.Entry e : references.entrySet()) { 83 | Plan plan = Utility.convertRuleToPlan(rule); 84 | plan.addDeletion(new CodeMetaData(e.getKey(), e.getValue(), IAnalyzer.SUPPORTED_LANGUAGES.LANG_JAVA.getLanguage())); 85 | stdReport.addOnlyDeletions(path, plan); 86 | } 87 | } 88 | } else { 89 | Object searchObj = rule.get(SEARCH); 90 | if (searchObj != null) { 91 | JSONObject searchRule = (JSONObject) searchObj; 92 | Map references = applySearchRule(searchRule); 93 | if(!references.isEmpty()) { 94 | stdReport.setSqlReport(true); 95 | } 96 | for (Map.Entry e : references.entrySet()) { 97 | Plan plan = Utility.convertRuleToPlan(rule); 98 | String lang = (plan.getRuleType().equals(LANG_SQL)) ? SUPPORTED_LANGUAGES.LANG_SQL.getLanguage() : SUPPORTED_LANGUAGES.LANG_JAVA.getLanguage(); 99 | // TODO: SQL modifications should be suggested. Change the null to actual modification object 100 | plan.addModification(new CodeMetaData(e.getKey(), e.getValue(), lang), null); 101 | stdReport.addOnlyModifications(path, plan); 102 | } 103 | } 104 | } 105 | } 106 | 107 | private Map applyImportRule(JSONObject remove) throws Exception { 108 | Map references = Maps.newHashMap(); 109 | JSONArray importArray = (JSONArray) remove.get(IMPORT); 110 | if (importArray != null && !importArray.isEmpty()) { 111 | for (Object importToFindObj : importArray) { 112 | String importToFind = (String) importToFindObj; 113 | references.putAll(viewer.searchReferences(importToFind)); 114 | } 115 | } 116 | return references; 117 | } 118 | 119 | private Map applySearchRule(JSONObject searchRule) throws Exception { 120 | Map references = Maps.newHashMap(); 121 | Object patternObj = searchRule.get(PATTERN); 122 | if (patternObj == null) { 123 | throw new InvalidRuleException("pattern is not defined for " + searchRule); 124 | } 125 | String pattern = patternObj.toString(); 126 | references.putAll(viewer.search(pattern)); 127 | return references; 128 | } 129 | 130 | private boolean isImportRule(JSONObject rule) { 131 | String ruleType = (String) rule.get(RULE_TYPE); 132 | return StringUtils.equalsIgnoreCase(ruleType, PACKAGE); 133 | } 134 | 135 | @Override 136 | public String getRuleFileName() { 137 | return ruleFileName; 138 | } 139 | 140 | @Override 141 | public void setRuleFileName(String ruleFileName) { 142 | this.ruleFileName = ruleFileName; 143 | } 144 | 145 | @Override 146 | public String getFileType() { 147 | return fileType; 148 | } 149 | 150 | @Override 151 | public void setFileType(String fileType) { 152 | this.fileType = fileType; 153 | } 154 | 155 | @Override 156 | public String getSource() { 157 | return src; 158 | } 159 | 160 | @Override 161 | public void setSource(String src) { 162 | this.src = src; 163 | } 164 | 165 | @Override 166 | public void setBasePackage(String packageName) { 167 | basePackage = packageName; 168 | } 169 | 170 | @Override 171 | public void setProjectId(String id) { 172 | this.projectId = id; 173 | } 174 | 175 | @Override 176 | public String getProjectId() { 177 | return this.projectId; 178 | } 179 | 180 | @Override 181 | public int getLOC() { 182 | return this.loc; 183 | } 184 | 185 | @Override 186 | public void setLOC(int loc) { 187 | this.loc = loc; 188 | } 189 | 190 | @Override 191 | public String getBasePackage() { 192 | return this.basePackage; 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/java/package-info.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.java; 2 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/mf/ManifestFileAnalyzer.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.mf; 2 | 3 | import static com.amazon.aws.am2.appmig.constants.IConstants.ADD; 4 | import static com.amazon.aws.am2.appmig.constants.IConstants.REMOVE; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import org.apache.commons.lang3.StringUtils; 11 | import org.json.simple.JSONArray; 12 | import org.json.simple.JSONObject; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | import com.amazon.aws.am2.appmig.estimate.CodeMetaData; 17 | import com.amazon.aws.am2.appmig.estimate.IAnalyzer; 18 | import com.amazon.aws.am2.appmig.estimate.Plan; 19 | import com.amazon.aws.am2.appmig.estimate.StandardReport; 20 | import com.amazon.aws.am2.appmig.estimate.exception.InvalidRuleException; 21 | import com.amazon.aws.am2.appmig.estimate.exception.NoRulesFoundException; 22 | import com.amazon.aws.am2.appmig.report.ReportSingletonFactory; 23 | import com.amazon.aws.am2.appmig.utils.Utility; 24 | 25 | public class ManifestFileAnalyzer implements IAnalyzer { 26 | 27 | private String path; 28 | private int loc; 29 | private String ruleFileName; 30 | private String fileType; 31 | private String src; 32 | private String basePackage; 33 | private String projectId; 34 | private JSONArray rules; 35 | private StandardReport stdReport = ReportSingletonFactory.getInstance().getStandardReport(); 36 | private final static Logger LOGGER = LoggerFactory.getLogger(ManifestFileAnalyzer.class); 37 | 38 | @Override 39 | public boolean analyze(String path) throws NoRulesFoundException, InvalidRuleException { 40 | if (rules == null || rules.size() == 0) { 41 | throw new NoRulesFoundException("Rules needs to be set before calling analyzer!"); 42 | } 43 | LOGGER.debug("Analyzing file {}", path); 44 | this.path = path; 45 | boolean taskCompleted = true; 46 | List lines = Utility.readFile(path); 47 | for (Object obj : rules) { 48 | try { 49 | JSONObject rule = (JSONObject) obj; 50 | applyRule(rule, lines); 51 | } catch (InvalidRuleException e) { 52 | taskCompleted = false; 53 | LOGGER.error("Unable to apply rule on path {} due to {}", path, Utility.parse(e)); 54 | } 55 | } 56 | return taskCompleted; 57 | } 58 | 59 | private void applyRule(JSONObject rule, List lines) throws InvalidRuleException { 60 | Plan plan = Utility.convertRuleToPlan(rule); 61 | if (rule.get(REMOVE) != null && rule.get(ADD) == null) { 62 | JSONObject removeRule = (JSONObject) rule.get(REMOVE); 63 | List lstCodeMetaData = processRule(removeRule, lines); 64 | if (lstCodeMetaData != null && lstCodeMetaData.size() > 0) { 65 | for (CodeMetaData cd : lstCodeMetaData) { 66 | plan.addDeletion(cd); 67 | } 68 | stdReport.addOnlyDeletions(path, plan); 69 | } 70 | } 71 | } 72 | 73 | private List processRule(JSONObject rule, List lines) { 74 | List lstCodeMetaData = new ArrayList<>(); 75 | @SuppressWarnings("unchecked") 76 | Set keys = rule.keySet(); 77 | for (String key : keys) { 78 | for (int idx = 0; idx < lines.size(); idx++) { 79 | String line = lines.get(idx); 80 | if (StringUtils.containsIgnoreCase(line, key)) { 81 | lstCodeMetaData.add(new CodeMetaData(idx + 1, line + "
", IAnalyzer.SUPPORTED_LANGUAGES.LANG_PROPERTIES.getLanguage())); 82 | } 83 | } 84 | } 85 | return lstCodeMetaData; 86 | } 87 | 88 | @Override 89 | public void setRules(JSONArray rules) { 90 | this.rules = rules; 91 | } 92 | 93 | @Override 94 | public JSONArray getRules() { 95 | return rules; 96 | } 97 | 98 | @Override 99 | public String getRuleFileName() { 100 | return ruleFileName; 101 | } 102 | 103 | @Override 104 | public void setRuleFileName(String ruleFileName) { 105 | this.ruleFileName = ruleFileName; 106 | } 107 | 108 | @Override 109 | public String getFileType() { 110 | return fileType; 111 | } 112 | 113 | @Override 114 | public void setFileType(String fileType) { 115 | this.fileType = fileType; 116 | } 117 | 118 | @Override 119 | public void setSource(String src) { 120 | this.src = src; 121 | } 122 | 123 | @Override 124 | public String getSource() { 125 | return src; 126 | } 127 | 128 | @Override 129 | public void setBasePackage(String packageName) { 130 | basePackage = packageName; 131 | } 132 | 133 | @Override 134 | public void setProjectId(String id) { 135 | this.projectId = id; 136 | } 137 | 138 | @Override 139 | public String getProjectId() { 140 | return this.projectId; 141 | } 142 | 143 | @Override 144 | public int getLOC() { 145 | return this.loc; 146 | } 147 | 148 | @Override 149 | public void setLOC(int loc) { 150 | this.loc = loc; 151 | } 152 | 153 | @Override 154 | public String getBasePackage() { 155 | return this.basePackage; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/mf/package-info.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.mf; -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/mvn/MvnEstimator.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.mvn; 2 | 3 | import java.io.File; 4 | 5 | import com.amazon.aws.am2.appmig.estimate.exception.NoRulesFoundException; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import com.amazon.aws.am2.appmig.estimate.Estimator; 10 | import com.amazon.aws.am2.appmig.utils.Utility; 11 | 12 | public class MvnEstimator extends Estimator { 13 | 14 | private final static Logger LOGGER = LoggerFactory.getLogger(MvnEstimator.class); 15 | 16 | public MvnEstimator(String ruleFiles) throws NoRulesFoundException { 17 | this.ruleNames = ruleFiles; 18 | loadRules(); 19 | } 20 | 21 | @Override 22 | protected void setBasePackage(File buildFile) { 23 | try { 24 | basePackage = Utility.getBasePackage(buildFile); 25 | } catch (Exception e) { 26 | LOGGER.error("Unable to parse XML file {} ", buildFile.getName()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/mvn/package-info.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.mvn; -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Aditya Goteti 3 | * 4 | */ 5 | package com.amazon.aws.am2.appmig.estimate; -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/estimate/properties/package-info.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.estimate.properties; -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/AbstractJavaGlassViewer.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer; 2 | 3 | import com.amazon.aws.am2.appmig.glassviewer.db.AppDiscoveryGraphDB; 4 | import com.amazon.aws.am2.appmig.glassviewer.utils.GlassViewerUtils; 5 | 6 | import org.antlr.v4.runtime.CharStreams; 7 | import org.antlr.v4.runtime.CommonTokenStream; 8 | import org.antlr.v4.runtime.Lexer; 9 | import org.antlr.v4.runtime.TokenStream; 10 | import org.antlr.v4.runtime.atn.ParserATNSimulator; 11 | import org.antlr.v4.runtime.atn.PredictionContextCache; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import src.main.resources.Java8Lexer; 15 | import src.main.resources.Java8Parser; 16 | 17 | import java.io.BufferedInputStream; 18 | import java.io.FileNotFoundException; 19 | import java.io.InputStream; 20 | import java.nio.file.Files; 21 | import java.nio.file.Paths; 22 | import java.util.Map; 23 | 24 | import static com.amazon.aws.am2.appmig.glassviewer.utils.GlassViewerUtils.parse; 25 | 26 | public abstract class AbstractJavaGlassViewer implements IJavaGlassViewer { 27 | 28 | private final static Logger LOGGER = LoggerFactory.getLogger(AbstractJavaGlassViewer.class); 29 | 30 | protected String filePath; 31 | protected Java8Parser.CompilationUnitContext parseTree; 32 | protected Java8Parser parser; 33 | protected String basePackage; 34 | protected String projectId; 35 | 36 | protected abstract void processImports(); 37 | 38 | protected abstract void processClassVariables(); 39 | 40 | protected abstract void processStaticBlocks(); 41 | 42 | protected abstract void processClasses(); 43 | 44 | protected abstract void processInterfaces(); 45 | 46 | protected abstract void processMethods(); 47 | 48 | protected abstract void store(); 49 | 50 | public abstract Map searchReferences(String importStmt) throws Exception; 51 | 52 | public abstract Map search(String pattern) throws Exception; 53 | 54 | public final void view(String filePath, String projectId) { 55 | try { 56 | this.projectId = projectId; 57 | generateParseTree(filePath); 58 | processClasses(); 59 | processInterfaces(); 60 | processImports(); 61 | processStaticBlocks(); 62 | processClassVariables(); 63 | processMethods(); 64 | store(); 65 | } catch (FileNotFoundException fileException) { 66 | LOGGER.error("Could not proceed with processing the file {} due to {}", filePath, GlassViewerUtils.parse(fileException)); 67 | } catch(Exception exp) { 68 | LOGGER.error("Unable to proceed with processing the file {} due to {}", filePath, GlassViewerUtils.parse(exp)); 69 | } 70 | } 71 | 72 | private void generateParseTree(String filePath) throws FileNotFoundException { 73 | LOGGER.debug("reading and parsing file {}", filePath); 74 | this.filePath = filePath; 75 | try (InputStream inputStream = new BufferedInputStream(Files.newInputStream(Paths.get(filePath)))) { 76 | Lexer lexer = new Java8Lexer(CharStreams.fromStream(inputStream)); 77 | TokenStream tokenStream = new CommonTokenStream(lexer); 78 | parser = new Java8Parser(tokenStream); 79 | parser.setTrimParseTree(true); 80 | parser.setInterpreter(new ParserATNSimulator( 81 | parser, parser.getATN(), parser.getInterpreter().decisionToDFA, new PredictionContextCache())); 82 | parseTree = parser.compilationUnit(); 83 | } catch (Exception e) { 84 | LOGGER.error("Unable to read the file {}", filePath); 85 | throw new FileNotFoundException(parse(e)); 86 | } 87 | } 88 | 89 | public void cleanup() { 90 | try { 91 | AppDiscoveryGraphDB.getInstance().close(); 92 | parser.getInterpreter().clearDFA(); 93 | parser.reset(); 94 | parser = null; 95 | } catch (Exception e) { 96 | LOGGER.error("Unable to close the DB instance due to {}", GlassViewerUtils.parse(e)); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/IJavaGlassViewer.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer; 2 | 3 | import java.util.Map; 4 | 5 | public interface IJavaGlassViewer { 6 | 7 | public String SINGLE_LINE_COMMENT = "//"; 8 | public String MULTI_LINE_COMMENT_START = "/*"; 9 | public String MULTI_LINE_COMMENT_END = "*/"; 10 | 11 | public String SPACE = " "; 12 | public String END_OF_STATEMENT = ";"; 13 | public String OPEN_CURLY_BRACE = "{"; 14 | public String CLOSE_CURLY_BRACE = "}"; 15 | public String DOT = "."; 16 | public String COMMA = ","; 17 | 18 | //Java Keywords 19 | public String KEYWORD_PKG = "package"; 20 | public String KEYWORD_CLASS = "class"; 21 | public String KEYWORD_IMPORT = "import"; 22 | public String KEYWORD_PUBLIC = "public"; 23 | public String KEYWORD_FINAL = "final"; 24 | public String KEYWORD_STATIC = "static"; 25 | public String KEYWORD_EXTENDS = "extends"; 26 | public String KEYWORD_IMPLEMENTS = "implements"; 27 | public String KEYWORD_ABSTRACT = "abstract"; 28 | 29 | //Pattern space 30 | public String PATTERN_SPACES = "\\s+"; 31 | public String PATTERN_SPACE = "\\s"; 32 | 33 | 34 | //Pattern [package] 35 | public String PATTERN_PKG = "^package\\s.*;$"; 36 | 37 | //Pattern [imports] 38 | public String PATTERN_IMPORT = "^import\\s.*;$"; 39 | 40 | //Pattern [class] 41 | public String PATTERN_CLASS = ".*\\sclass\\s.*"; 42 | 43 | public String[] CLASS_TOKENS = {KEYWORD_CLASS, KEYWORD_PUBLIC, KEYWORD_FINAL, KEYWORD_EXTENDS, KEYWORD_IMPLEMENTS}; 44 | 45 | //Pattern [String constants within double quotes] 46 | public String PATTERN_STRING_LITERALS = "\".*\""; 47 | 48 | public void view(String filePath, String projectId); 49 | 50 | public Map searchReferences(String importStmt) throws Exception; 51 | 52 | public Map search(String pattern) throws Exception; 53 | 54 | public void cleanup(); 55 | 56 | void setBasePackage(String packageName); 57 | 58 | int getLoc(); 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/AnnotationConstruct.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | public class AnnotationConstruct implements JavaConstruct { 4 | 5 | private String name; 6 | private final ConstructMetaData metadata = new ConstructMetaData(); 7 | 8 | @Override 9 | public JConstructType getType() { 10 | return JConstructType.ANNOTATION; 11 | } 12 | 13 | @Override 14 | public String getName() { 15 | return name; 16 | } 17 | 18 | @Override 19 | public void setName(String name) { 20 | this.name = name; 21 | } 22 | 23 | @Override 24 | public ConstructMetaData getMetaData() { 25 | return metadata; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "AnnotationConstruct [name=" + name + ", metadata=" + metadata + "]"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/ClassConstruct.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class ClassConstruct implements JavaConstruct { 7 | 8 | private String packageName; 9 | private String name; 10 | private boolean isPublic; 11 | private boolean isDefault; 12 | private boolean isFinal; 13 | private boolean isAbstract; 14 | private List inherits; 15 | private List annotations; 16 | private List methods; 17 | private List classVariables; 18 | private List imports; 19 | private final ConstructMetaData metadata = new ConstructMetaData(); 20 | private String absoluteFilePath; 21 | private List innerClasses = new ArrayList<>(); 22 | private int loc; 23 | 24 | public String getFullClassName() { 25 | return (packageName == null ? "_default_" : packageName) + "." + name; 26 | } 27 | 28 | @Override 29 | public JConstructType getType() { 30 | return JConstructType.CLASS; 31 | } 32 | 33 | public ConstructMetaData getMetaData() { 34 | return metadata; 35 | } 36 | 37 | public int getLOC() { 38 | return this.loc; 39 | } 40 | 41 | public void setLOC(int loc) { 42 | this.loc = loc; 43 | } 44 | 45 | @Override 46 | public String getName() { 47 | return this.name; 48 | } 49 | 50 | @Override 51 | public void setName(String name) { 52 | this.name = name; 53 | } 54 | 55 | public boolean isPublic() { 56 | return isPublic; 57 | } 58 | 59 | public void setPublic(boolean isPublic) { 60 | this.isPublic = isPublic; 61 | } 62 | 63 | public boolean isDefault() { 64 | return isDefault; 65 | } 66 | 67 | public void setDefault(boolean isDefault) { 68 | this.isDefault = isDefault; 69 | } 70 | 71 | public boolean isFinal() { 72 | return isFinal; 73 | } 74 | 75 | public void setFinal(boolean isFinal) { 76 | this.isFinal = isFinal; 77 | } 78 | 79 | public boolean isAbstract() { 80 | return isAbstract; 81 | } 82 | 83 | public void setAbstract(boolean isAbstract) { 84 | this.isAbstract = isAbstract; 85 | } 86 | 87 | public List getInherits() { 88 | return inherits; 89 | } 90 | 91 | public void setInherits(List inherits) { 92 | this.inherits = inherits; 93 | } 94 | 95 | public void setPackageName(String pkgName) { 96 | this.packageName = pkgName; 97 | } 98 | 99 | public String getPackageName() { 100 | return packageName == null ? "_default_" : packageName; 101 | } 102 | 103 | public List getMethods() { 104 | return methods; 105 | } 106 | 107 | public void setMethods(List methods) { 108 | this.methods = methods; 109 | } 110 | 111 | public List getClassVariables() { 112 | return classVariables; 113 | } 114 | 115 | public void setClassVariables(List classVariables) { 116 | this.classVariables = classVariables; 117 | } 118 | 119 | public List getImports() { 120 | return imports; 121 | } 122 | 123 | public void setImports(List imports) { 124 | this.imports = imports; 125 | } 126 | 127 | public String getAbsoluteFilePath() { 128 | return absoluteFilePath; 129 | } 130 | 131 | public void setAbsoluteFilePath(String absoluteFilePath) { 132 | this.absoluteFilePath = absoluteFilePath; 133 | } 134 | 135 | public List getAnnotations() { 136 | return annotations; 137 | } 138 | 139 | public void setAnnotations(List annotations) { 140 | this.annotations = annotations; 141 | } 142 | 143 | @Override 144 | public String toString() { 145 | return getFullClassName(); 146 | } 147 | 148 | public List getInnerClasses() { 149 | return innerClasses; 150 | } 151 | 152 | public ClassConstruct setInnerClasses(List innerClasses) { 153 | this.innerClasses = innerClasses; 154 | return this; 155 | } 156 | 157 | public void addInnerClass(String innerClassName) { 158 | this.innerClasses.add(innerClassName); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/ConstructMetaData.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | public class ConstructMetaData { 4 | 5 | private int startsAt; 6 | private int endsAt; 7 | 8 | public int getStartsAt() { 9 | return startsAt; 10 | } 11 | 12 | public void setStartsAt(int startsAt) { 13 | this.startsAt = startsAt; 14 | } 15 | 16 | public int getEndsAt() { 17 | return endsAt; 18 | } 19 | 20 | public void setEndsAt(int endsAt) { 21 | this.endsAt = endsAt; 22 | } 23 | 24 | @Override public String toString() { 25 | return "ConstructMetaData{" + 26 | "startsAt=" + startsAt + 27 | ", endsAt=" + endsAt + 28 | '}'; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/ConstructStaticBlockMetaData.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | public class ConstructStaticBlockMetaData { 4 | 5 | private int startsAt; 6 | private int endsAt; 7 | 8 | public int getStartsAt() { 9 | return startsAt; 10 | } 11 | 12 | public void setStartsAt(int startsAt) { 13 | this.startsAt = startsAt; 14 | } 15 | 16 | public int getEndsAt() { 17 | return endsAt; 18 | } 19 | 20 | public void setEndsAt(int endsAt) { 21 | this.endsAt = endsAt; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "ConstructStaticBlockMetaData{" + 27 | "startsAt='" + startsAt + '\'' + 28 | "endsAt='" + endsAt + '\'' + 29 | '}'; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/ImportConstruct.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | public class ImportConstruct implements JavaConstruct { 4 | 5 | private String packageName; 6 | private String ClassName; 7 | private int startAt; 8 | 9 | public String getPackageName() { 10 | return packageName; 11 | } 12 | 13 | public ImportConstruct setPackageName(String packageName) { 14 | this.packageName = packageName; 15 | return this; 16 | } 17 | 18 | public String getClassName() { 19 | return ClassName; 20 | } 21 | 22 | public ImportConstruct setClassName(String className) { 23 | ClassName = className; 24 | return this; 25 | } 26 | 27 | public int getStartAt() { 28 | return startAt; 29 | } 30 | 31 | public ImportConstruct setStartAt(int startAt) { 32 | this.startAt = startAt; 33 | return this; 34 | } 35 | 36 | @Override 37 | public JConstructType getType() { 38 | return JConstructType.IMPORT; 39 | } 40 | 41 | @Override 42 | public String getName() { 43 | return null; 44 | } 45 | 46 | @Override 47 | public void setName(String name) { 48 | } 49 | 50 | @Override 51 | public ConstructMetaData getMetaData() { 52 | return null; 53 | } 54 | 55 | @Override public String toString() { 56 | return "ImportConstruct{" + 57 | "packageName='" + packageName + '\'' + 58 | ", ClassName='" + ClassName + '\'' + 59 | ", startAt=" + startAt + 60 | '}'; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/InterfaceConstruct.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | import java.util.List; 4 | 5 | public class InterfaceConstruct implements JavaConstruct { 6 | 7 | private String name; 8 | private List extendsInterfaces; 9 | private String packageName; 10 | private List imports; 11 | private List methods; 12 | private List classVariables; 13 | private List annotations; 14 | private boolean isPublic; 15 | private boolean isDefault; 16 | private String absoluteFilePath; 17 | private int loc; 18 | 19 | private InterfaceConstruct(InterfaceBuilder builder) { 20 | this.name = builder.name; 21 | this.extendsInterfaces = builder.extendsInterfaces; 22 | } 23 | 24 | public List getExtendsInterfaces() { 25 | return extendsInterfaces; 26 | } 27 | 28 | public void setExtendsInterfaces(List extendsInterfaces) { 29 | this.extendsInterfaces = extendsInterfaces; 30 | } 31 | 32 | public String getFullClassName() { 33 | return (packageName == null ? "_default_" : packageName) + "." + name; 34 | } 35 | 36 | @Override 37 | public JConstructType getType() { 38 | return JConstructType.INTERFACE; 39 | } 40 | 41 | @Override 42 | public ConstructMetaData getMetaData() { 43 | return null; 44 | } 45 | 46 | @Override 47 | public String getName() { 48 | return this.name; 49 | } 50 | 51 | @Override 52 | public void setName(String name) { 53 | this.name = name; 54 | } 55 | 56 | public void setPackageName(String pkgName) { 57 | this.packageName = pkgName; 58 | } 59 | 60 | public String getPackageName() { 61 | return packageName == null ? "_default_" : packageName; 62 | } 63 | 64 | public List getImports() { 65 | return imports; 66 | } 67 | 68 | public void setImports(List imports) { 69 | this.imports = imports; 70 | } 71 | 72 | public List getMethods() { 73 | return methods; 74 | } 75 | 76 | public void setMethods(List methods) { 77 | this.methods = methods; 78 | } 79 | 80 | public List getClassVariables() { 81 | return classVariables; 82 | } 83 | 84 | public void setClassVariables(List classVariables) { 85 | this.classVariables = classVariables; 86 | } 87 | 88 | public boolean isPublic() { 89 | return isPublic; 90 | } 91 | 92 | public void setPublic(boolean isPublic) { 93 | this.isPublic = isPublic; 94 | } 95 | 96 | public boolean isDefault() { 97 | return isDefault; 98 | } 99 | 100 | public void setDefault(boolean isDefault) { 101 | this.isDefault = isDefault; 102 | } 103 | 104 | public String getAbsoluteFilePath() { 105 | return absoluteFilePath; 106 | } 107 | 108 | public void setAbsoluteFilePath(String absoluteFilePath) { 109 | this.absoluteFilePath = absoluteFilePath; 110 | } 111 | 112 | public int getLoc() { 113 | return loc; 114 | } 115 | 116 | public void setLoc(int loc) { 117 | this.loc = loc; 118 | } 119 | 120 | public List getAnnotations() { 121 | return annotations; 122 | } 123 | 124 | public void setAnnotations(List annotations) { 125 | this.annotations = annotations; 126 | } 127 | 128 | public static class InterfaceBuilder { 129 | 130 | private String name; 131 | private List extendsInterfaces; 132 | 133 | public InterfaceBuilder name(String name) { 134 | this.name = name; 135 | return this; 136 | } 137 | 138 | public InterfaceBuilder extendsInterfaces(List extendsInterfaces) { 139 | this.extendsInterfaces = extendsInterfaces; 140 | return this; 141 | } 142 | 143 | public InterfaceConstruct build() { 144 | return new InterfaceConstruct(this); 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/JavaClassConstructListener.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | import static com.amazon.aws.am2.appmig.constants.IConstants.JAVA_KEYWORD_PUBLIC; 4 | import static com.amazon.aws.am2.appmig.constants.IConstants.JAVA_KEYWORD_ABSTRACT; 5 | import static com.amazon.aws.am2.appmig.constants.IConstants.JAVA_KEYWORD_DEFAULT; 6 | import static com.amazon.aws.am2.appmig.constants.IConstants.JAVA_KEYWORD_FINAL; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import src.main.resources.Java8Parser; 11 | import src.main.resources.Java8ParserBaseListener; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | public class JavaClassConstructListener extends Java8ParserBaseListener { 17 | 18 | private final static Logger LOGGER = LoggerFactory.getLogger(JavaClassConstructListener.class); 19 | private final ClassConstruct classConstruct = new ClassConstruct(); 20 | private final List annotations = new ArrayList<>(); 21 | 22 | /** 23 | * The way the inner classes are identified is based on the traversal of AST. If 24 | * the method @code enterNormalClassDeclaration is visited more than once, then 25 | * the second visit is to be considered as parsing of inner class if it is 26 | * within the boundaries of the outer class 27 | */ 28 | boolean isInnerClass = false; 29 | 30 | public ClassConstruct getClassConstruct() { 31 | return classConstruct; 32 | } 33 | 34 | @Override 35 | public void enterPackageDeclaration(Java8Parser.PackageDeclarationContext ctx) { 36 | classConstruct.setPackageName(ctx.packageName().getText()); 37 | } 38 | 39 | @Override 40 | public void enterNormalClassDeclaration(Java8Parser.NormalClassDeclarationContext ctx) { 41 | if (ctx.Identifier() == null) { 42 | LOGGER.error("Unable to process normal class declaration {}", ctx); 43 | return; 44 | } 45 | if (!isInnerClass) { 46 | isInnerClass = true; 47 | } else { 48 | classConstruct.addInnerClass(ctx.Identifier().getText()); 49 | return; 50 | } 51 | 52 | classConstruct.setName(ctx.Identifier().getText()); 53 | 54 | if (ctx.classModifier() != null) { 55 | ctx.classModifier().forEach(c -> { 56 | if (JAVA_KEYWORD_PUBLIC.equals(c.getText())) { 57 | classConstruct.setPublic(true); 58 | } else if (JAVA_KEYWORD_ABSTRACT.equals(c.getText())) { 59 | classConstruct.setAbstract(true); 60 | } else if (JAVA_KEYWORD_DEFAULT.equals(c.getText())) { 61 | classConstruct.setDefault(true); 62 | } else if (JAVA_KEYWORD_FINAL.equals(c.getText())) { 63 | classConstruct.setFinal(true); 64 | } else if (c.annotation() != null && !c.annotation().isEmpty()) { 65 | AnnotationConstruct annotation = new AnnotationConstruct(); 66 | annotation.getMetaData().setStartsAt(c.annotation().getStart().getLine()); 67 | annotation.getMetaData().setEndsAt(c.annotation().getStop().getLine()); 68 | annotation.setName(c.annotation().getText().trim()); 69 | annotations.add(annotation); 70 | classConstruct.setAnnotations(annotations); 71 | } 72 | }); 73 | } 74 | } 75 | 76 | @Override 77 | public void exitClassDeclaration(Java8Parser.ClassDeclarationContext ctx) { 78 | classConstruct.setLOC(ctx.stop.getLine()); 79 | } 80 | 81 | @Override 82 | public void enterAnnotationTypeDeclaration(Java8Parser.AnnotationTypeDeclarationContext ctx) { 83 | ctx.getText(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/JavaClassVariableConstructListener.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.antlr.v4.runtime.tree.TerminalNode; 7 | import src.main.resources.Java8Parser; 8 | import src.main.resources.Java8Parser.FieldModifierContext; 9 | import src.main.resources.Java8Parser.UnannPrimitiveTypeContext; 10 | import src.main.resources.Java8Parser.UnannReferenceTypeContext; 11 | import src.main.resources.Java8Parser.VariableDeclaratorContext; 12 | import src.main.resources.Java8Parser.VariableDeclaratorListContext; 13 | import src.main.resources.Java8ParserBaseListener; 14 | 15 | public class JavaClassVariableConstructListener extends Java8ParserBaseListener { 16 | 17 | private final List variableConstructList = new ArrayList<>(); 18 | 19 | public List getClassVariableConstructList() { 20 | return variableConstructList; 21 | } 22 | 23 | @Override 24 | public void enterFieldDeclaration(Java8Parser.FieldDeclarationContext ctx) { 25 | VariableConstruct construct; 26 | VariableDeclaratorListContext variableDeclaratorList = ctx.variableDeclaratorList(); 27 | List fieldModifier = ctx.fieldModifier(); 28 | List modifiers = new ArrayList<>(); 29 | List annotations = new ArrayList<>(); 30 | String variableType = null; 31 | for (FieldModifierContext fieldModifierContext : fieldModifier) { 32 | modifiers.add(fieldModifierContext.getText()); 33 | if (fieldModifierContext.annotation() != null) { 34 | Java8Parser.AnnotationContext variableAnnotation = fieldModifierContext.annotation(); 35 | AnnotationConstruct annotation = new AnnotationConstruct(); 36 | annotation.getMetaData().setStartsAt(variableAnnotation.getStart().getLine()); 37 | annotation.getMetaData().setEndsAt(variableAnnotation.getStop().getLine()); 38 | annotation.setName(variableAnnotation.getText().trim()); 39 | annotations.add(annotation); 40 | } 41 | } 42 | UnannPrimitiveTypeContext unannPrimitiveType = ctx.unannType().unannPrimitiveType(); 43 | UnannReferenceTypeContext unannReferenceType = ctx.unannType().unannReferenceType(); 44 | int startsAt = ctx.start.getLine(); 45 | int endsAt = ctx.stop.getLine(); 46 | if (unannPrimitiveType != null) { 47 | variableType = unannPrimitiveType.getText(); 48 | } else if (unannReferenceType != null) { 49 | variableType = unannReferenceType.getText(); 50 | } 51 | for (VariableDeclaratorContext variable : variableDeclaratorList.variableDeclarator()) { 52 | construct = new VariableConstruct(); 53 | if (variable.variableDeclaratorId() == null) { 54 | continue; 55 | } 56 | TerminalNode identifier = variable.variableDeclaratorId().Identifier(); 57 | // The null check is required in some corner cases, where the assignment of the variable cannot be processed. 58 | // Like the assignment is in a different language which the encoding does not support 59 | construct.setName((identifier != null) ? identifier.getText() : ""); 60 | if (variable.children.size() == 3) { 61 | construct.setValue(variable.children.get(2).getText()); 62 | } 63 | construct.setVariableAnnotations(annotations); 64 | construct.setVariableModifiers(modifiers); 65 | construct.setVariableType(variableType); 66 | construct.getMetaData().setStartsAt(startsAt); 67 | construct.getMetaData().setEndsAt(endsAt); 68 | variableConstructList.add(construct); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/JavaConstruct.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | public interface JavaConstruct { 4 | 5 | enum JConstructType {PACKAGE, CLASS, INTERFACE, ANNOTATION, METHOD, INSTANCE_VARIABLE, LOCAL_VARIABLE, BLOCK, LOOP, CONDITION, INNER_CLASS, STATEMENT, IMPORT} 6 | 7 | JConstructType getType(); 8 | 9 | String getName(); 10 | 11 | void setName(String name); 12 | 13 | ConstructMetaData getMetaData(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/JavaImportConstructListener.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | import src.main.resources.Java8Parser; 4 | import src.main.resources.Java8ParserBaseListener; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class JavaImportConstructListener extends Java8ParserBaseListener { 10 | 11 | private List importConstructList = new ArrayList<>(); 12 | 13 | public List getImportConstructList() { 14 | return importConstructList; 15 | } 16 | 17 | @Override public void enterSingleTypeImportDeclaration(Java8Parser.SingleTypeImportDeclarationContext ctx) { 18 | ImportConstruct ic = new ImportConstruct() 19 | .setClassName(ctx.typeName().Identifier().getText()) 20 | .setPackageName(ctx.typeName().packageOrTypeName() != null ? 21 | ctx.typeName().packageOrTypeName().getText() : "") 22 | .setStartAt(ctx.start.getLine()); 23 | 24 | importConstructList.add(ic); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/JavaInterfaceConstructListener.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | import src.main.resources.Java8Parser; 4 | import src.main.resources.Java8ParserBaseListener; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | public class JavaInterfaceConstructListener extends Java8ParserBaseListener { 11 | 12 | private final List interfaceConstructs = new ArrayList<>(); 13 | private final List annotations = new ArrayList<>(); 14 | 15 | public List getInterfaceConstructs() { 16 | return interfaceConstructs; 17 | } 18 | 19 | @Override public void enterNormalInterfaceDeclaration(Java8Parser.NormalInterfaceDeclarationContext ctx) { 20 | String name = ctx.Identifier().getText(); 21 | 22 | List extendsInterfaces = null; 23 | if(ctx.extendsInterfaces() != null) { 24 | extendsInterfaces = ctx.extendsInterfaces().interfaceTypeList().interfaceType() 25 | .stream() 26 | .map(Java8Parser.InterfaceTypeContext::getText) 27 | .collect(Collectors.toList()); 28 | } 29 | InterfaceConstruct ic = new InterfaceConstruct.InterfaceBuilder().name(name).extendsInterfaces(extendsInterfaces).build(); 30 | if(ctx.interfaceModifier() != null) { 31 | ctx.interfaceModifier().forEach(modifier -> { 32 | if(modifier.annotation() != null) { 33 | AnnotationConstruct annotation = new AnnotationConstruct(); 34 | annotation.setName(modifier.annotation().normalAnnotation().getText().trim()); 35 | annotation.getMetaData().setStartsAt(modifier.annotation().getStart().getLine()); 36 | annotation.getMetaData().setEndsAt(modifier.annotation().getStop().getLine()); 37 | annotations.add(annotation); 38 | ic.setAnnotations(annotations); 39 | } 40 | }); 41 | } 42 | interfaceConstructs.add(ic); 43 | } 44 | 45 | @Override 46 | public void exitInterfaceDeclaration(Java8Parser.InterfaceDeclarationContext ctx) { 47 | if (interfaceConstructs.size() == 1) { 48 | interfaceConstructs.get(0).setLoc(ctx.stop.getLine()); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/JavaMethodConstructListener.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | import src.main.resources.Java8Parser; 4 | import src.main.resources.Java8ParserBaseListener; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | import static com.amazon.aws.am2.appmig.constants.IConstants.*; 11 | 12 | public class JavaMethodConstructListener extends Java8ParserBaseListener { 13 | 14 | private final List methodConstructList = new ArrayList<>(); 15 | 16 | public List getMethodConstructList() { 17 | return methodConstructList; 18 | } 19 | 20 | @Override 21 | public void enterMethodDeclaration(Java8Parser.MethodDeclarationContext ctx) { 22 | String name = ctx.methodHeader().methodDeclarator().Identifier().getText(); 23 | String returnType = ctx.methodHeader().result().getText(); 24 | 25 | // modifiers 26 | boolean isPublic = hasPublicModifier(ctx.methodModifier()); 27 | boolean isProtected = hasProtectedModifier(ctx.methodModifier()); 28 | boolean isPrivate = hasPrivateModifier(ctx.methodModifier()); 29 | boolean isAbstract = hasAbstractModifier(ctx.methodModifier()); 30 | boolean isStatic = hasStaticModifier(ctx.methodModifier()); 31 | 32 | List annotations = ctx.methodModifier() 33 | .stream() 34 | .filter(m -> m.annotation() != null) 35 | .map(m -> createAnnotationConstruct(m.annotation())) 36 | .collect(Collectors.toList()); 37 | 38 | List parameterTypes = new ArrayList<>(); 39 | if (ctx.methodHeader().methodDeclarator().formalParameterList() != null) { 40 | if (ctx.methodHeader().methodDeclarator().formalParameterList().formalParameters() != null) { 41 | ctx.methodHeader().methodDeclarator().formalParameterList().formalParameters().formalParameter() 42 | .forEach(f -> parameterTypes.add(f.getText())); 43 | } 44 | parameterTypes.add(ctx.methodHeader().methodDeclarator().formalParameterList().lastFormalParameter().getText()); 45 | } 46 | 47 | List exceptionTypes = new ArrayList<>(); 48 | if (ctx.methodHeader().throws_() != null) { 49 | ctx.methodHeader().throws_().exceptionTypeList().exceptionType() 50 | .forEach(e -> exceptionTypes.add(e.getText())); 51 | } 52 | 53 | // local variables 54 | if (ctx.methodBody().block() != null && ctx.methodBody().block().blockStatements() != null) { 55 | List localVariables = listLocalVariables(ctx.methodBody().block().blockStatements()); 56 | 57 | MethodConstruct m = new MethodConstruct.MethodBuilder() 58 | .name(name) 59 | .returnType(returnType) 60 | .annotations(annotations) 61 | .parameterTypes(parameterTypes) 62 | .exceptionTypes(exceptionTypes) 63 | .isPublic(isPublic) 64 | .isPrivate(isPrivate) 65 | .isProtected(isProtected) 66 | .isAbstract(isAbstract) 67 | .isStatic(isStatic) 68 | .startLine(ctx.start.getLine()) 69 | .endLine(ctx.stop.getLine()) 70 | .localVariablesAndTypeMap(localVariables) 71 | .build(); 72 | methodConstructList.add(m); 73 | } 74 | } 75 | 76 | private AnnotationConstruct createAnnotationConstruct(Java8Parser.AnnotationContext annotationContext) { 77 | AnnotationConstruct annotationConstruct = new AnnotationConstruct(); 78 | annotationConstruct.setName(annotationContext.getText().trim()); 79 | annotationConstruct.getMetaData().setStartsAt(annotationContext.getStart().getLine()); 80 | annotationConstruct.getMetaData().setEndsAt(annotationContext.getStop().getLine()); 81 | return annotationConstruct; 82 | } 83 | 84 | private boolean hasPublicModifier(List methodModifiers) { 85 | return hasModifier(methodModifiers, JAVA_KEYWORD_PUBLIC); 86 | } 87 | 88 | private boolean hasPrivateModifier(List methodModifiers) { 89 | return hasModifier(methodModifiers, JAVA_KEYWORD_PRIVATE); 90 | } 91 | 92 | private boolean hasProtectedModifier(List methodModifiers) { 93 | return hasModifier(methodModifiers, JAVA_KEYWORD_PROTECTED); 94 | } 95 | 96 | private boolean hasAbstractModifier(List methodModifiers) { 97 | return hasModifier(methodModifiers, JAVA_KEYWORD_ABSTRACT); 98 | } 99 | 100 | private boolean hasStaticModifier(List methodModifiers) { 101 | return hasModifier(methodModifiers, JAVA_KEYWORD_STATIC); 102 | } 103 | 104 | private boolean hasModifier(List methodModifiers, String modifier) { 105 | if (methodModifiers != null) { 106 | for (Java8Parser.MethodModifierContext mm : methodModifiers) { 107 | if (modifier.equals(mm.getText())) { 108 | return true; 109 | } 110 | } 111 | } 112 | return false; 113 | } 114 | 115 | private List listLocalVariables(Java8Parser.BlockStatementsContext blockStatements) { 116 | List variableLst = new ArrayList<>(); 117 | if (blockStatements != null) { 118 | List annotations = new ArrayList<>(); 119 | blockStatements.blockStatement().forEach(b -> { 120 | if (b.localVariableDeclarationStatement() != null) { 121 | String variable = b.localVariableDeclarationStatement() 122 | .localVariableDeclaration() 123 | .variableDeclaratorList() 124 | .variableDeclarator(0) // get first variable 125 | .variableDeclaratorId().getText(); 126 | String type = b.localVariableDeclarationStatement().localVariableDeclaration().unannType().getText(); 127 | List lstModifiers = b.localVariableDeclarationStatement().localVariableDeclaration().variableModifier(); 128 | lstModifiers.stream().forEach(modifier -> { 129 | if(modifier.annotation() != null) { 130 | Java8Parser.AnnotationContext localVarAnnotation = modifier.annotation(); 131 | AnnotationConstruct annotation = new AnnotationConstruct(); 132 | annotation.getMetaData().setStartsAt(localVarAnnotation.getStart().getLine()); 133 | annotation.getMetaData().setEndsAt(localVarAnnotation.getStop().getLine()); 134 | annotation.setName(localVarAnnotation.getText().trim()); 135 | annotations.add(annotation); 136 | } 137 | }); 138 | VariableConstruct variableConstruct = new VariableConstruct(); 139 | if (b.localVariableDeclarationStatement().localVariableDeclaration().variableDeclaratorList().variableDeclarator().size() == 1) { 140 | String value = (b.localVariableDeclarationStatement().localVariableDeclaration().variableDeclaratorList().variableDeclarator().get(0).children.size() == 3) 141 | ? b.localVariableDeclarationStatement().localVariableDeclaration().variableDeclaratorList().variableDeclarator().get(0).children.get(2). 142 | getText() : ""; 143 | variableConstruct.setValue(value); 144 | } 145 | variableConstruct.getMetaData().setStartsAt(b.localVariableDeclarationStatement().localVariableDeclaration().start.getLine()); 146 | variableConstruct.getMetaData().setEndsAt(b.localVariableDeclarationStatement().localVariableDeclaration().stop.getLine()); 147 | variableConstruct.setName(variable); 148 | variableConstruct.setVariableType(type); 149 | variableConstruct.setVariableAnnotations(annotations); 150 | variableLst.add(variableConstruct); 151 | } 152 | }); 153 | } 154 | return variableLst; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/JavaSearchReferenceListener.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | import org.antlr.v4.runtime.ParserRuleContext; 4 | import org.antlr.v4.runtime.misc.Interval; 5 | import src.main.resources.Java8Parser; 6 | import src.main.resources.Java8ParserBaseListener; 7 | 8 | import java.util.*; 9 | import java.util.regex.Pattern; 10 | 11 | public class JavaSearchReferenceListener extends Java8ParserBaseListener { 12 | 13 | private final String importStmt; 14 | private final String importedSimpleClassName; 15 | private final Map mapLineStmt = new HashMap<>(); 16 | private final List filteredClassVariables; 17 | private final List matchingImports; 18 | 19 | public JavaSearchReferenceListener(String importStmt, List filteredClassVariables, List matchingImports) { 20 | this.importStmt = importStmt; 21 | List classComponentsList = Arrays.asList(importStmt.split("\\.")); 22 | importedSimpleClassName = classComponentsList.get(classComponentsList.size() - 1); 23 | 24 | this.filteredClassVariables = filteredClassVariables; 25 | this.matchingImports = matchingImports; 26 | } 27 | 28 | public Map getMapLineStmt() { 29 | return mapLineStmt; 30 | } 31 | 32 | private boolean isDatatypePartOfImport(String datatype) { 33 | boolean result = false; 34 | 35 | if (importedSimpleClassName.equals(datatype)) 36 | result = true; 37 | else if (datatype.contains(".") && importStmt.equals(datatype)) 38 | result = true; 39 | else { 40 | for (String importName : matchingImports) { 41 | String importClass = importName.substring(importName.lastIndexOf(".") + 1); 42 | if (importClass.equals(datatype)) { 43 | result = true; 44 | break; 45 | } 46 | } 47 | } 48 | return result; 49 | } 50 | 51 | private boolean isStatementPartOfImport(String statement) { 52 | boolean result = false; 53 | 54 | String regex = "(.*[^a-zA-Z0-9]|)" + importedSimpleClassName + "[^a-zA-Z0-9]?.*"; 55 | 56 | if (statement.contains(importStmt)) 57 | result = true; 58 | else if (Pattern.matches(regex, statement)) 59 | result = true; 60 | return result; 61 | } 62 | 63 | private boolean isStatementPartOfFilterVariable(String statement, String filterVar) { 64 | boolean result = false; 65 | 66 | String regex = "(.*[^a-zA-Z0-9]|)" + filterVar + "[^a-zA-Z0-9]?.*"; 67 | 68 | if (Pattern.matches(regex, statement)) 69 | result = true; 70 | return result; 71 | } 72 | 73 | @Override 74 | public void enterFieldDeclaration(Java8Parser.FieldDeclarationContext ctx) { 75 | Java8Parser.VariableDeclaratorListContext variableDeclaratorList = ctx.variableDeclaratorList(); 76 | for (Java8Parser.VariableDeclaratorContext vari : variableDeclaratorList.variableDeclarator()) { 77 | String varName = vari.variableDeclaratorId().Identifier().toString(); 78 | if(filteredClassVariables.contains(varName)){ 79 | addToMap(ctx); 80 | } 81 | } 82 | } 83 | 84 | @Override 85 | public void enterMethodDeclaration(Java8Parser.MethodDeclarationContext ctx) { 86 | String returnType = ctx.methodHeader().result().getText(); 87 | 88 | // checking for references in method return type 89 | if (isDatatypePartOfImport(returnType)) { 90 | addToMap(ctx.methodHeader()); 91 | } 92 | 93 | // checking for references in method formal params' type 94 | if (ctx.methodHeader().methodDeclarator().formalParameterList() != null) { 95 | if (ctx.methodHeader().methodDeclarator().formalParameterList().formalParameters() != null) { 96 | ctx.methodHeader().methodDeclarator().formalParameterList().formalParameters().formalParameter() 97 | .forEach(f -> { 98 | if (isDatatypePartOfImport(f.start.getText())) { 99 | addToMap(f); 100 | } 101 | }); 102 | } 103 | Java8Parser.LastFormalParameterContext lastFormalParam = ctx.methodHeader().methodDeclarator().formalParameterList().lastFormalParameter(); 104 | if (isDatatypePartOfImport(lastFormalParam.start.getText())) { 105 | if (!mapLineStmt.containsKey(lastFormalParam.start.getLine())) 106 | addToMap(lastFormalParam); 107 | } 108 | } 109 | 110 | // checking for references in method local variables declaration 111 | List filteredLocalVariables = listFilteredLocalVariables(ctx.methodBody().block().blockStatements()); 112 | 113 | // checking for references in method statements apart from variable declaration 114 | Java8Parser.BlockStatementsContext blockStatements = ctx.methodBody().block().blockStatements(); 115 | if (null != blockStatements) { 116 | blockStatements.blockStatement().forEach(b -> { 117 | if (null == b.localVariableDeclarationStatement()) { 118 | if (isStatementPartOfImport(b.getText())) 119 | addToMap(b); 120 | else if (filteredLocalVariables.stream().anyMatch(v -> isStatementPartOfFilterVariable(b.getText(), v))) 121 | addToMap(b); 122 | else if (filteredClassVariables.stream().anyMatch(v -> isStatementPartOfFilterVariable(b.getText(), v))) 123 | addToMap(b); 124 | } 125 | }); 126 | } 127 | 128 | } 129 | 130 | // returns those variables whose either type OR initialization (if any) has references to import 131 | private List listFilteredLocalVariables(Java8Parser.BlockStatementsContext blockStatements) { 132 | List list = new ArrayList<>(); 133 | if (null != blockStatements) { 134 | blockStatements.blockStatement().forEach(b -> { 135 | if (b.localVariableDeclarationStatement() != null) { 136 | String variable = b.localVariableDeclarationStatement() 137 | .localVariableDeclaration() 138 | .variableDeclaratorList() 139 | .variableDeclarator(0) // get first variable 140 | .variableDeclaratorId().getText(); 141 | String type = b.localVariableDeclarationStatement().localVariableDeclaration().unannType().getText(); 142 | 143 | // checking for references in local variable type 144 | if (isDatatypePartOfImport(type)) { 145 | addToMap(b); 146 | list.add(variable); 147 | } else if (null != b.localVariableDeclarationStatement().localVariableDeclaration().variableDeclaratorList().variableDeclarator(0).variableInitializer() && 148 | isStatementPartOfImport( 149 | b.localVariableDeclarationStatement().localVariableDeclaration().variableDeclaratorList().variableDeclarator(0).variableInitializer().getText())) { 150 | addToMap(b); 151 | list.add(variable); 152 | } 153 | } 154 | }); 155 | } 156 | return list; 157 | } 158 | 159 | private void addToMap(ParserRuleContext ctx) { 160 | String text = ctx.start.getInputStream().getText(Interval.of(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); 161 | mapLineStmt.put(ctx.start.getLine(), text); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/JavaStaticBlockConstructListener.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import src.main.resources.Java8Parser; 7 | import src.main.resources.Java8ParserBaseListener; 8 | 9 | public class JavaStaticBlockConstructListener extends Java8ParserBaseListener { 10 | 11 | private List staticBlockMetaDataList = new ArrayList<>(); 12 | 13 | public List getStaticBlockMetadataList() { 14 | return staticBlockMetaDataList; 15 | } 16 | 17 | @Override public void enterStaticInitializer(Java8Parser.StaticInitializerContext ctx) { 18 | ConstructStaticBlockMetaData construct = new ConstructStaticBlockMetaData(); 19 | construct.setStartsAt(ctx.block().getStart().getLine()); 20 | construct.setEndsAt(ctx.block().getStop().getLine()); 21 | staticBlockMetaDataList.add(construct); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/MethodConstruct.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | import java.util.List; 4 | 5 | public class MethodConstruct implements JavaConstruct { 6 | 7 | /** 8 | * Methods are identified in the database based on ID rather than with name. In case of classes, they are identified 9 | * with full package name. But whereas methods are identified with the ID generated by arangodb to avoid naming 10 | * conflicts. This can be improved later by following conventions like fullpackage#classname#methodname. 11 | */ 12 | private String id; 13 | private String name; 14 | private final String returnType; 15 | private final List parameterTypes; 16 | private final List exceptionTypes; 17 | private List annotations; 18 | private final boolean isPublic; 19 | private final boolean isProtected; 20 | private final boolean isPrivate; 21 | private final boolean isAbstract; 22 | private final boolean isStatic; 23 | private final int startLine; 24 | private final int endLine; 25 | private final List localVariables; 26 | 27 | private MethodConstruct(MethodBuilder builder) { 28 | this.name = builder.name; 29 | this.returnType = builder.returnType; 30 | this.parameterTypes = builder.parameterTypes; 31 | this.exceptionTypes = builder.exceptionTypes; 32 | this.annotations = builder.annotations; 33 | this.isPublic = builder.isPublic; 34 | this.isProtected = builder.isProtected; 35 | this.isPrivate = builder.isPrivate; 36 | this.isAbstract = builder.isAbstract; 37 | this.isStatic = builder.isStatic; 38 | this.startLine = builder.startLine; 39 | this.endLine = builder.endLine; 40 | this.localVariables = builder.localVariables; 41 | } 42 | 43 | public String getId() { 44 | return id; 45 | } 46 | 47 | public void setId(String id) { 48 | this.id = id; 49 | } 50 | 51 | @Override 52 | public JConstructType getType() { 53 | return JConstructType.METHOD; 54 | } 55 | 56 | @Override 57 | public ConstructMetaData getMetaData() { 58 | return null; 59 | } 60 | 61 | @Override 62 | public String getName() { 63 | return name; 64 | } 65 | 66 | @Override 67 | public void setName(String name) { 68 | this.name = name; 69 | } 70 | 71 | public String getReturnType() { 72 | return returnType; 73 | } 74 | 75 | public List getAnnotations() { 76 | return annotations; 77 | } 78 | 79 | public void setAnnotations(List annotations) { 80 | this.annotations = annotations; 81 | } 82 | 83 | public boolean isPublic() { 84 | return isPublic; 85 | } 86 | 87 | public boolean isProtected() { 88 | return isProtected; 89 | } 90 | 91 | public boolean isPrivate() { 92 | return isPrivate; 93 | } 94 | 95 | public boolean isAbstract() { 96 | return isAbstract; 97 | } 98 | 99 | public boolean isStatic() { 100 | return isStatic; 101 | } 102 | 103 | public List getLocalVariables() { 104 | return localVariables; 105 | } 106 | 107 | @Override public String toString() { 108 | return "MethodConstruct{" + 109 | "name='" + name + '\'' + 110 | ", returnType='" + returnType + '\'' + 111 | ", parameterTypes=" + parameterTypes + 112 | ", exceptionTypes=" + exceptionTypes + 113 | ", annotations=" + annotations + 114 | ", isPublic=" + isPublic + 115 | ", isProtected=" + isProtected + 116 | ", isPrivate=" + isPrivate + 117 | ", isAbstract=" + isAbstract + 118 | ", isStatic=" + isStatic + 119 | ", startLine=" + startLine + 120 | ", endLine=" + endLine + 121 | ", localVariablesAndTypeMap=" + localVariables + 122 | '}'; 123 | } 124 | 125 | public static class MethodBuilder { 126 | 127 | private String name; 128 | private String returnType; 129 | private List parameterTypes; 130 | private List exceptionTypes; 131 | private List annotations; 132 | private boolean isPublic; 133 | private boolean isProtected; 134 | private boolean isPrivate; 135 | private boolean isAbstract; 136 | private boolean isStatic; 137 | private int startLine; 138 | private int endLine; 139 | private List localVariables; 140 | 141 | public MethodBuilder name(String name) { 142 | this.name = name; 143 | return this; 144 | } 145 | 146 | public MethodBuilder returnType(String returnType) { 147 | this.returnType = returnType; 148 | return this; 149 | } 150 | 151 | public MethodBuilder parameterTypes(List parameterTypes) { 152 | this.parameterTypes = parameterTypes; 153 | return this; 154 | } 155 | 156 | public MethodBuilder exceptionTypes(List exceptionTypes) { 157 | this.exceptionTypes = exceptionTypes; 158 | return this; 159 | } 160 | 161 | public MethodBuilder annotations(List annotations) { 162 | this.annotations = annotations; 163 | return this; 164 | } 165 | 166 | public MethodBuilder isPublic(boolean isPublic) { 167 | this.isPublic = isPublic; 168 | return this; 169 | } 170 | 171 | public MethodBuilder isProtected(boolean isProtected) { 172 | this.isProtected = isProtected; 173 | return this; 174 | } 175 | 176 | public MethodBuilder isPrivate(boolean isPrivate) { 177 | this.isPrivate = isPrivate; 178 | return this; 179 | } 180 | 181 | public MethodBuilder isAbstract(boolean isAbstract) { 182 | this.isAbstract = isAbstract; 183 | return this; 184 | } 185 | 186 | public MethodBuilder isStatic(boolean isStatic) { 187 | this.isStatic = isStatic; 188 | return this; 189 | } 190 | 191 | public MethodBuilder startLine(int startLine) { 192 | this.startLine = startLine; 193 | return this; 194 | } 195 | 196 | public MethodBuilder endLine(int endLine) { 197 | this.endLine = endLine; 198 | return this; 199 | } 200 | 201 | public MethodBuilder localVariablesAndTypeMap(List localVariables) { 202 | this.localVariables = localVariables; 203 | return this; 204 | } 205 | 206 | public MethodConstruct build() { 207 | return new MethodConstruct(this); 208 | } 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/PackageConstruct.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | public class PackageConstruct implements JavaConstruct { 4 | 5 | private String packageName; 6 | private String fullPackageName; 7 | 8 | public String getPackageName() { 9 | return packageName; 10 | } 11 | 12 | public PackageConstruct setPackageName(String packageName) { 13 | this.packageName = packageName; 14 | return this; 15 | } 16 | 17 | public String getFullPackageName() { 18 | return fullPackageName; 19 | } 20 | 21 | public void setFullPackageName(String fullPackageName) { 22 | this.fullPackageName = fullPackageName; 23 | } 24 | 25 | @Override 26 | public JConstructType getType() { 27 | return JConstructType.IMPORT; 28 | } 29 | 30 | @Override 31 | public String getName() { 32 | return null; 33 | } 34 | 35 | @Override 36 | public void setName(String name) { 37 | } 38 | 39 | @Override 40 | public ConstructMetaData getMetaData() { 41 | return null; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "ImportConstruct{" + 47 | "packageName='" + packageName + '\'' + 48 | ", fullPackageName='" + fullPackageName + '\'' + 49 | '}'; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/ProjectConstruct.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | public class ProjectConstruct { 4 | 5 | /** 6 | * Project folder name 7 | */ 8 | private String name; 9 | private int totalFiles; 10 | private int totalModifications; 11 | /** 12 | * Complexity - Minor, Major, Critical 13 | */ 14 | private String complexity; 15 | 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public void setName(String name) { 22 | this.name = name; 23 | } 24 | 25 | public int getTotalFiles() { 26 | return totalFiles; 27 | } 28 | 29 | public void setTotalFiles(int totalFiles) { 30 | this.totalFiles = totalFiles; 31 | } 32 | 33 | public int getTotalModifications() { 34 | return totalModifications; 35 | } 36 | 37 | public void setTotalModifications(int totalModifications) { 38 | this.totalModifications = totalModifications; 39 | } 40 | 41 | public String getComplexity() { 42 | return complexity; 43 | } 44 | 45 | public void setComplexity(String complexity) { 46 | this.complexity = complexity; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/constructs/VariableConstruct.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.constructs; 2 | 3 | import java.util.List; 4 | 5 | public class VariableConstruct implements JavaConstruct { 6 | 7 | private String variableName; 8 | private String value; 9 | private List variableModifiers; 10 | private String variableType; 11 | private List variableAnnotations; 12 | private final ConstructMetaData metadata = new ConstructMetaData(); 13 | 14 | public List getVariableAnnotations() { 15 | return variableAnnotations; 16 | } 17 | 18 | public void setVariableAnnotations(List variableAnnotations) { 19 | this.variableAnnotations = variableAnnotations; 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return variableName; 25 | } 26 | 27 | @Override 28 | public void setName(String name) { 29 | this.variableName = name; 30 | } 31 | 32 | public List getVariableModifiers() { 33 | return variableModifiers; 34 | } 35 | 36 | public void setVariableModifiers(List variableModifiers) { 37 | this.variableModifiers = variableModifiers; 38 | } 39 | 40 | public String getVariableType() { 41 | return variableType; 42 | } 43 | 44 | public void setVariableType(String variableType) { 45 | this.variableType = variableType; 46 | } 47 | 48 | @Override 49 | public JConstructType getType() { 50 | return JConstructType.INSTANCE_VARIABLE; 51 | } 52 | 53 | @Override 54 | public ConstructMetaData getMetaData() { 55 | return metadata; 56 | } 57 | 58 | public String getValue() { 59 | return value; 60 | } 61 | public void setValue(String value) { 62 | this.value = value; 63 | } 64 | 65 | @Override public String toString() { 66 | return "VariableConstruct{" + 67 | "variableName='" + variableName + '\'' + 68 | ", variableModifiers=" + variableModifiers + 69 | ", variableType='" + variableType + '\'' + 70 | ", variableAnnotations=" + variableAnnotations + 71 | ", metadata=" + metadata + 72 | '}'; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/db/IAppDiscoveryGraphDB.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.db; 2 | 3 | import java.util.List; 4 | 5 | public interface IAppDiscoveryGraphDB { 6 | 7 | public final static String DB_NAME = "app-server-db"; 8 | public final static String GRAPH_NAME = "app-server-graph"; 9 | public final static String GRAPH_PROJ_DEPENDENCIES = "project-dependencies"; 10 | public final static String PROJECT_COLLECTION = "PROJECTS"; 11 | public final static String PACKAGE_COLLECTION = "PACKAGES"; 12 | public final static String CLASS_COLLECTION = "CLASSES"; 13 | public final static String IMPORT_COLLECTION = "IMPORTS"; 14 | public final static String METHOD_COLLECTION = "METHODS"; 15 | public final static String VARIABLE_COLLECTION = "VARIABLES"; 16 | public final static String PROJECT_PACKAGE_EDGE = "HAS_PACKAGE"; 17 | public final static String PACKAGE_CLASS_EDGE = "HAS_CLASS"; 18 | public final static String PARENT_CHILD_EDGE = "CHILD_OF"; 19 | public final static String PROJECT_PROJECT_EDGE = "DEPENDS_ON"; 20 | public final static String CLASS_CLASS_EDGE = "USES_CLASS"; 21 | public final static String CLASS_METHOD_EDGE = "HAS_METHOD"; 22 | public final static String CLASS_IMPORTS_EDGE = "HAS_IMPORT"; 23 | public final static String CLASS_VARIABLE_EDGE = "HAS_CLASS_VARIABLE"; 24 | public final static String METHOD_VARIABLE_EDGE = "HAS_METHOD_VARIABLE"; 25 | 26 | public String saveNode(String query); 27 | 28 | public boolean deleteNode(String query); 29 | 30 | public boolean remove(String query); 31 | 32 | public String exists(String query); 33 | 34 | public List existsRelation(String query); 35 | 36 | public void close() throws Exception; 37 | 38 | public List read(String query); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/db/package-info.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.db; -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/utils/GlassViewerUtils.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.utils; 2 | 3 | import java.io.IOException; 4 | import java.io.PrintWriter; 5 | import java.io.StringWriter; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | public class GlassViewerUtils { 11 | 12 | private final static Logger LOGGER = LoggerFactory.getLogger(GlassViewerUtils.class); 13 | 14 | public static String parse(Throwable exp) { 15 | String strException = null; 16 | try (StringWriter sw = new StringWriter()) { 17 | exp.printStackTrace(new PrintWriter(sw)); 18 | strException = sw.toString(); 19 | } catch (IOException ioe) { 20 | LOGGER.error("Got exception while converting Throwable object to String due to {} ", ioe.getMessage()); 21 | } 22 | return strException; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/glassviewer/utils/package-info.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.glassviewer.utils; -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/report/ReportSingletonFactory.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.report; 2 | 3 | import com.amazon.aws.am2.appmig.estimate.StandardReport; 4 | 5 | public class ReportSingletonFactory { 6 | 7 | private static final ReportSingletonFactory INSTANCE = new ReportSingletonFactory(); 8 | private StandardReport stdReport; 9 | 10 | private ReportSingletonFactory() { 11 | } 12 | 13 | public static ReportSingletonFactory getInstance() { 14 | return INSTANCE; 15 | } 16 | 17 | public synchronized StandardReport getStandardReport() { 18 | if (stdReport == null) { 19 | stdReport = new StandardReport(); 20 | } 21 | return stdReport; 22 | } 23 | 24 | public void invalidate() { 25 | stdReport = null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/report/package-info.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.report; 2 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/search/ISearch.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.search; 2 | 3 | public interface ISearch { 4 | 5 | public boolean find(String pattern, String source, boolean caseInSensitive); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/search/RegexSearch.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.search; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | public class RegexSearch implements ISearch { 7 | 8 | @Override 9 | public boolean find(String strPattern, String source, boolean caseInSensitive) { 10 | if (strPattern == null || source == null || source.isEmpty()) { 11 | return false; 12 | } 13 | Pattern pattern; 14 | if (caseInSensitive) { 15 | pattern = Pattern.compile(strPattern, Pattern.CASE_INSENSITIVE); 16 | } else { 17 | pattern = Pattern.compile(strPattern); 18 | } 19 | Matcher matcher = pattern.matcher(source); 20 | return matcher.find(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/utils/RuleFileFilter.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.utils; 2 | 3 | import java.io.File; 4 | import java.io.FilenameFilter; 5 | import static com.amazon.aws.am2.appmig.constants.IConstants.FILE_RECOMMENDATIONS; 6 | import static com.amazon.aws.am2.appmig.constants.IConstants.RULES; 7 | import static com.amazon.aws.am2.appmig.constants.IConstants.RECOMMENDATION; 8 | 9 | public class RuleFileFilter implements FilenameFilter { 10 | 11 | private String[] ruleFileNames; 12 | private String type; 13 | 14 | public RuleFileFilter() { 15 | } 16 | 17 | public RuleFileFilter(String[] ruleFileNames, String type) { 18 | this.ruleFileNames = ruleFileNames; 19 | this.type = type; 20 | } 21 | 22 | @Override 23 | public boolean accept(File dir, String name) { 24 | for (String ruleName : ruleFileNames) { 25 | if (name.startsWith(ruleName) && ((!name.endsWith(FILE_RECOMMENDATIONS) && type.equalsIgnoreCase(RULES)) 26 | || (name.endsWith(FILE_RECOMMENDATIONS) && type.equalsIgnoreCase(RECOMMENDATION)))) { 27 | return true; 28 | } 29 | } 30 | return false; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/amazon/aws/am2/appmig/utils/package-info.java: -------------------------------------------------------------------------------- 1 | package com.amazon.aws.am2.appmig.utils; -------------------------------------------------------------------------------- /src/main/resources/configuration.csv: -------------------------------------------------------------------------------- 1 | #ProjectName,RepoType,UserName,Password,BranchName,RepoUrl 2 | -------------------------------------------------------------------------------- /src/main/resources/ibmmq-to-amazonmq-javarules.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.java.JavaFileAnalyzer", 3 | "file_type": "java", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "Remove IBM MQ", 8 | "description": "Replace IBM MQ with Amazon MQ", 9 | "complexity": "major", 10 | "rule_type": "package", 11 | "remove": { 12 | "import": [ 13 | "com.ibm.mq" 14 | ] 15 | }, 16 | "recommendation": 3001 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /src/main/resources/ibmmq-to-amazonmq-recommendations.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | { 4 | "id": 3001, 5 | "name": "Replace IBM MQ with Amazon MQ", 6 | "description": "Replace IBM MQ with Amazon MQ" 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /src/main/resources/lib/custom.css: -------------------------------------------------------------------------------- 1 | code { 2 | word-break: break-all; 3 | 4 | } 5 | 6 | /* .bg-previous { 7 | background-color: #fff0f0 8 | } */ 9 | 10 | .number-column { 11 | padding: 22px 0 0 0; 12 | } 13 | 14 | .bg-current { 15 | background-color: #f0f8f0; 16 | } 17 | 18 | .width-100-px { 19 | width: 15px; 20 | } 21 | 22 | .file-name { 23 | word-break: break-all; 24 | } 25 | 26 | .migration-container-wrapper { 27 | max-width: 100%; 28 | } 29 | 30 | .migration-head-wrapper { 31 | max-width: 80%; 32 | } -------------------------------------------------------------------------------- /src/main/resources/lib/index.js: -------------------------------------------------------------------------------- 1 | const codeFormatter = () => { 2 | const sourceElements = document.querySelectorAll("code:not(.skipBeautify)"); 3 | for( let i = 0; i < sourceElements.length; i++ ) { 4 | const souceText = sourceElements[i].innerText; 5 | const formattedCode = js_beautify(souceText); 6 | sourceElements[i].innerHTML = formattedCode ; 7 | } 8 | }; 9 | codeFormatter(); -------------------------------------------------------------------------------- /src/main/resources/lib/prism.css: -------------------------------------------------------------------------------- 1 | /* PrismJS 1.28.0 2 | https://prismjs.com/download.html#themes=prism&languages=markup+clike+javascript+java+javadoc+javadoclike+javastacktrace+json+json5 */ 3 | code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help} 4 | -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=INFO, fileAppender 3 | 4 | # Direct log messages to stdout 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.Target=System.out 7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stdout.layout.ConversionPattern=[%t] %-5p %c %x - %m%n 9 | 10 | #Application Logging 11 | log4j.appender.fileAppender=org.apache.log4j.RollingFileAppender 12 | log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout 13 | log4j.appender.fileAppender.layout.ConversionPattern=[%t] %-5p %c %x - %m%n 14 | log4j.appender.fileAppender.File=app-mig.log -------------------------------------------------------------------------------- /src/main/resources/oracle-to-postgres-javarules.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.java.JavaFileAnalyzer", 3 | "file_type": "java", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "OracleDriver", 8 | "description": "Oracle database drivers", 9 | "complexity": "minor", 10 | "rule_type": "package", 11 | "remove": { 12 | "import": ["java.sql.DriverManager","oracle.jdbc.driver.OracleDriver"] 13 | }, 14 | "recommendation": 1001 15 | }, 16 | { 17 | "id": 4, 18 | "name": "DBSpecific", 19 | "description": "Oracle types", 20 | "complexity": "major", 21 | "rule_type": "package", 22 | "remove": { 23 | "import": ["oracle.jdbc.OracleTypes"] 24 | }, 25 | "recommendation": 1004 26 | }, 27 | { 28 | "id": 5, 29 | "name": "DBSpecific", 30 | "description": "Advanced Queuing features of Oracle for enterprise messaging applications", 31 | "complexity": "critical", 32 | "rule_type": "package", 33 | "remove": { 34 | "import": ["oracle.jdbc.aq"] 35 | }, 36 | "recommendation": 1005 37 | }, 38 | { 39 | "id": 6, 40 | "name": "DBSpecific", 41 | "description": "Oracle JDBC extension that provides interfaces to access the Database Change Notification feature of Oracle.", 42 | "complexity": "critical", 43 | "rule_type": "package", 44 | "remove": { 45 | "import": ["oracle.jdbc.dcn"] 46 | }, 47 | "recommendation": 1006 48 | }, 49 | { 50 | "id": 7, 51 | "name": "DBSpecific", 52 | "description": "Support for Distributed transactions", 53 | "complexity": "critical", 54 | "rule_type": "package", 55 | "remove": { 56 | "import": ["oracle.jdbc.xa","oracle.jdbc.xa.client"] 57 | }, 58 | "recommendation": 1007 59 | }, 60 | { 61 | "id": 8, 62 | "name": "DBSpecific", 63 | "description": "Oracle specific implementation of Connection cache and connection pooling", 64 | "complexity": "critical", 65 | "rule_type": "package", 66 | "remove": { 67 | "import": ["oracle.jdbc.pool"] 68 | }, 69 | "recommendation": 1008 70 | }, 71 | { 72 | "id": 9, 73 | "name": "DBSpecific", 74 | "description": "Oracle database transparent fail-over replay support", 75 | "complexity": "critical", 76 | "rule_type": "package", 77 | "remove": { 78 | "import": ["oracle.jdbc.replay"] 79 | }, 80 | "recommendation": 1009 81 | }, 82 | { 83 | "id": 10, 84 | "name": "Search inline SQL statements in the java files", 85 | "description": "Search inline SQL statements in the java files", 86 | "complexity": "major", 87 | "rule_type": "sql", 88 | "search": { 89 | "pattern": "\\b(^SELECT|FROM)\\b|\\b(^MERGE|USING)\\b|\\b(^INSERT|INTO)\\b|\\b(^DELETE|FROM)\\b|\\b(^UPDATE|SET)\\b|\\b(^CREATE|TABLE)\\b|\\b(^DROP|TABLE)\\b$/m" 90 | }, 91 | "recommendation": 1000 92 | } 93 | ] 94 | } 95 | -------------------------------------------------------------------------------- /src/main/resources/oracle-to-postgres-mvnrules.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.mvn.MVNBuildFileAnalyzer", 3 | "file_type": "pom.xml", 4 | "rules": [ 5 | { 6 | "id": 4, 7 | "name": "Remove Oracle specific Libraries", 8 | "description": "Remove dependency on oracle database specific libraries", 9 | "complexity": "major", 10 | "rule_type": "dependency", 11 | "remove": { 12 | "groupId": "com.oracle.database.jdbc", 13 | "artifactId": "ojdbc6", 14 | "version": "*" 15 | }, 16 | "recommendation": 1010 17 | }, 18 | { 19 | "id": 4, 20 | "name": "Remove Oracle specific Libraries", 21 | "description": "Remove dependency on oracle database specific libraries", 22 | "complexity": "major", 23 | "rule_type": "dependency", 24 | "remove": { 25 | "groupId": "com.oracle.database.jdbc", 26 | "artifactId": "ojdbc8", 27 | "version": "*" 28 | }, 29 | "recommendation": 1010 30 | }, 31 | { 32 | "id": 4, 33 | "name": "Remove Oracle specific Libraries", 34 | "description": "Remove dependency on oracle database specific libraries", 35 | "complexity": "critical", 36 | "rule_type": "major", 37 | "remove": { 38 | "groupId": "com.oracle.database.jdbc", 39 | "artifactId": "ojdbc11", 40 | "version": "*" 41 | }, 42 | "recommendation": 1010 43 | }, 44 | { 45 | "id": 4, 46 | "name": "Remove Oracle specific Libraries", 47 | "description": "Remove dependency on oracle database specific libraries", 48 | "complexity": "major", 49 | "rule_type": "dependency", 50 | "remove": { 51 | "groupId": "com.oracle.database.jdbc", 52 | "artifactId": "ojdbc10", 53 | "version": "*" 54 | }, 55 | "recommendation": 1010 56 | }, 57 | { 58 | "id": 4, 59 | "name": "Remove Oracle specific Libraries", 60 | "description": "Remove dependency on oracle database specific libraries", 61 | "complexity": "major", 62 | "rule_type": "dependency", 63 | "remove": { 64 | "groupId": "com.oracle.jdbc", 65 | "artifactId": "oraclepki", 66 | "version": "*" 67 | }, 68 | "recommendation": 1010 69 | } 70 | ] 71 | } -------------------------------------------------------------------------------- /src/main/resources/oracle-to-postgres-properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.properties.PropertyFileAnalyzer", 3 | "file_type": "properties", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "Search inline SQL statements in properties files", 8 | "description": "Search inline SQL statements in properties files", 9 | "complexity": "major", 10 | "rule_type": "sql", 11 | "search": { 12 | "pattern": "\\b(^SELECT|FROM)\\b|\\b(^MERGE|USING)\\b|\\b(^INSERT|INTO)\\b|\\b(^DELETE|FROM)\\b|\\b(^UPDATE|SET)\\b|\\b(^CREATE|TABLE)\\b|\\b(^DROP|TABLE)\\b$/m" 13 | }, 14 | "recommendation": 1000 15 | }, 16 | { 17 | "id": 2, 18 | "name": "Replace Oracle delegate class for Quartz with PostgreSql delegate class", 19 | "description": "Replace Oracle specific JobStore delegate which is OracleDelegate with PostgreSQL JobStore delegate PostgreSQLDelegate", 20 | "complexity": "major", 21 | "rule_type": "properties", 22 | "remove": { 23 | "name": "org.quartz.jobStore.driverDelegateClass", 24 | "value": "org.quartz.impl.jdbcjobstore.oracle.OracleDelegate" 25 | }, 26 | "recommendation": 1011 27 | }, 28 | { 29 | "id": 3, 30 | "name": "Replace Oracle Database driver with PostgreSQL Database driver", 31 | "description": "Replace oracle jdbc driver oracle.jdbc.driver.OracleDriver with PostgreSQL jdbc driver org.postgresql.Driver ", 32 | "complexity": "major", 33 | "rule_type": "properties", 34 | "remove": { 35 | "value": "oracle.jdbc.driver.OracleDriver" 36 | }, 37 | "recommendation": 1012 38 | }, 39 | { 40 | "id": 4, 41 | "name": "Oracle specific implementation of connection cache and connection pooling", 42 | "description": "Replace oracle specific pool classes with PostgreSQL specific classes from org.postgresql.ds", 43 | "complexity": "critical", 44 | "rule_type": "properties", 45 | "remove": { 46 | "value": "oracle.jdbc.pool.OracleDataSource" 47 | }, 48 | "recommendation": 1008 49 | }, 50 | { 51 | "id": 5, 52 | "name": "Oracle specific implementation of connection cache and connection pooling", 53 | "description": "Replace oracle specific pool classes with PostgreSQL specific classes from org.postgresql.ds", 54 | "complexity": "critical", 55 | "rule_type": "properties", 56 | "remove": { 57 | "value": "oracle.ucp.jdbc.PoolDataSourceImpl" 58 | }, 59 | "recommendation": 1008 60 | }, 61 | { 62 | "id": 6, 63 | "name": "Oracle specific implementation of connection cache and connection pooling", 64 | "description": "Replace oracle specific pool classes with PostgreSQL specific classes from org.postgresql.ds", 65 | "complexity": "critical", 66 | "rule_type": "properties", 67 | "remove": { 68 | "value": "oracle.ucp.jdbc.PoolDataSource" 69 | }, 70 | "recommendation": 1008 71 | } 72 | ] 73 | } -------------------------------------------------------------------------------- /src/main/resources/oracle-to-postgres-recommendations.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | { 4 | "id": 1000, 5 | "name": "Inline SQL code", 6 | "description": "Review the inline SQL code" 7 | }, 8 | { 9 | "id": 1001, 10 | "name": "Replace Oracle database driver with Postgres database driver", 11 | "description": "Review the driver being loaded in this block of code and change the driver from oracle.jdbc.driver.OracleDriver to org.postgresql.Driver" 12 | }, 13 | { 14 | "id": 1002, 15 | "name": "Review bind parameters that are being set on the statement object", 16 | "description": "Review this part of code for data type of parameters being set on statement and make changes to match the data type" 17 | }, 18 | { 19 | "id": 1003, 20 | "name": "Review DB procedure calls", 21 | "description": "Review this part of code for Syntax of DB procedure invocations and make sure they are of the format '{ call my_db_procedure() }', In case of db procedure is returning cursor make sure auto commit is set to false before invoking such procedures" 22 | }, 23 | { 24 | "id": 1004, 25 | "name": "Replace data type references made using OracleTypes with Standard sql data types", 26 | "description": "Replace types represented by oracle.jdbc.OracleTypes with corresponding types from java.sql.Types" 27 | }, 28 | { 29 | "id": 1005, 30 | "name": "Re-write Advanced Queuing features of Oracle database", 31 | "description": "Advanced queuing features are specific to Oracle and this part of code needs to be completely re-written based on the use-case" 32 | }, 33 | { 34 | "id": 1006, 35 | "name": "Re-write Database Change Notification feature of Oracle database", 36 | "description": "Change Notification features are specific to Oracle database and this part of code needs to be completely re-written based on the use-case" 37 | }, 38 | { 39 | "id": 1007, 40 | "name": "Replace Distributed transaction support implementation of Oracle with Distributed transaction support implementation of Postgres", 41 | "description": "This part of code implements distributed transaction support re-write this part of code referencing postgres specific classes from org.postgresql.xa" 42 | }, 43 | { 44 | "id": 1008, 45 | "name": "Replace oracle specific implementation of connection pooling and connection caching with Postgres specific implementation of connection pooling and connection caching", 46 | "description": "This part of code depends on oracle specific implementation of connection pooling and connection caching re-write this part of code referencing postgres specific classes from org.postgresql.ds" 47 | }, 48 | { 49 | "id": 1009, 50 | "name": "Re-write Oracle specific Database fail over replay feature", 51 | "description": "This part of code depends on oracle specific Database fail over replay feature , this is not supported by postgres database, this part of code needs to be completely re-written based on the use-case" 52 | }, 53 | { 54 | "id": 1010, 55 | "name": "Replace dependency on Oracle database specific libraries with Postgres database specific libraries", 56 | "description": "Remove dependency on Oracle Database specific libraries and replace then Postgres specific database libraries" 57 | }, 58 | { 59 | "id": 1011, 60 | "name": "Remove Oracle specific quartz JobStore delegate", 61 | "description": "Replace Oracle specific JobStore delegate which is OracleDelegate with Postgresql JobStore delegate PostgreSQLDelegate" 62 | }, 63 | { 64 | "id": 1012, 65 | "name": "Remove oracle jdbc driver oracle.jdbc.driver.OracleDriver", 66 | "description": "Replace oracle jdbc driver oracle.jdbc.driver.OracleDriver with Postgresql jdbc driver org.postgresql.Driver" 67 | } 68 | ] 69 | } 70 | -------------------------------------------------------------------------------- /src/main/resources/oracle-to-postgres-xmlrules.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.xml.XMLFileAnalyzer", 3 | "file_type": "xml", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "Oracle specific implementation of connection cache and connection pooling", 8 | "description": "Replace oracle specific pool classes with PostgreSQL specific classes from org.postgresql.ds", 9 | "complexity": "major", 10 | "rule_type": "xml", 11 | "remove": { 12 | "tagName": "Resource", 13 | "attributeName": "factory", 14 | "attributeValue": "oracle.ucp.jdbc.PoolDataSourceImpl" 15 | }, 16 | "recommendation": 1008 17 | }, 18 | { 19 | "id": 2, 20 | "name": "Oracle specific implementation of connection cache and connection pooling", 21 | "description": "Replace oracle specific pool classes with PostgreSQL specific classes from org.postgresql.ds", 22 | "complexity": "major", 23 | "rule_type": "xml", 24 | "remove": { 25 | "tagName": "Resource", 26 | "attributeName": "connectionFactoryClassName", 27 | "attributeValue": "oracle.jdbc.pool.OracleDataSource" 28 | }, 29 | "recommendation": 1008 30 | }, 31 | { 32 | "id": 3, 33 | "name": "Search inline SQL statements in XML files for select", 34 | "description": "Search inline SQL statements in XML files for select", 35 | "complexity": "major", 36 | "rule_type": "sql", 37 | "search": { 38 | "pattern": "\\b(^SELECT|FROM)\\b(?=.*\\bDUAL\\b)|(\\bNVL\\b)|(\\bNVL2\\b)|(\\bSYSDATE\\b)|(\\bROWNUM\\b)|(\\bDECODE\\b)|(NEXTVAL)|(ADD_MONTHS)|(XMLAGG)|(ROWNUM)|(\\bHINTS\\b)|(\\bMINUS\\b)$/m" 39 | }, 40 | "recommendation": 1000 41 | }, 42 | { 43 | "id": 4, 44 | "name": "Search inline SQL statements in XML files for merge", 45 | "description": "Search inline SQL statements in XML files for merge", 46 | "complexity": "major", 47 | "rule_type": "sql", 48 | "search": { 49 | "pattern": "\\b(^MERGE|USING)\\b(?=.*\\bDUAL\\b)|(\\bNVL\\b)|(\\bNVL2\\b)|(\\bSYSDATE\\b)|(\\bROWNUM\\b)|(\\bDECODE\\b)|(NEXTVAL)|(ADD_MONTHS)|(XMLAGG)|(ROWNUM)|(\\bHINTS\\b)|(\\bMINUS\\b)$/m" 50 | }, 51 | "recommendation": 1000 52 | }, 53 | { 54 | "id": 5, 55 | "name": "Search inline SQL statements in XML files for insert", 56 | "description": "Search inline SQL statements in XML files for insert", 57 | "complexity": "major", 58 | "rule_type": "sql", 59 | "search": { 60 | "pattern": "\\b(^INSERT|INTO)\\b(?=.*\\bDUAL\\b)|(\\bNVL\\b)|(\\bNVL2\\b)|(\\bSYSDATE\\b)|(\\bROWNUM\\b)|(NEXTVAL)|(\\bDECODE\\b)|(ADD_MONTHS)|(XMLAGG)|(ROWNUM)|(\\bHINTS\\b)|(\\bMINUS\\b)$/m" 61 | }, 62 | "recommendation": 1000 63 | }, 64 | { 65 | "id": 6, 66 | "name": "Search inline SQL statements in XML files for delete", 67 | "description": "Search inline SQL statements in XML files for delete", 68 | "complexity": "major", 69 | "rule_type": "sql", 70 | "search": { 71 | "pattern": "\\b(^DELETE|FROM)\\b(?=.*\\bDUAL\\b)|(\\bNVL\\b)|(\\bNVL2\\b)|(\\bSYSDATE\\b)|(\\bROWNUM\\b)|(NEXTVAL)|(\\bDECODE\\b)|(ADD_MONTHS)|(XMLAGG)|(ROWNUM)|(\\bHINTS\\b)|(\\bMINUS\\b)$/m" 72 | }, 73 | "recommendation": 1000 74 | }, 75 | { 76 | "id": 7, 77 | "name": "Search inline SQL statements in XML files for update table", 78 | "description": "Search inline SQL statements in XML files for update table", 79 | "complexity": "major", 80 | "rule_type": "sql", 81 | "search": { 82 | "pattern": "\\b(^UPDATE|SET)\\b(?=.*\\bDUAL\\b)|(\\bNVL\\b)|(\\bNVL2\\b)|(\\bSYSDATE\\b)|(\\bROWNUM\\b)|(NEXTVAL)|(\\bDECODE\\b)|(ADD_MONTHS)|(XMLAGG)|(ROWNUM)|(\\bHINTS\\b)|(\\bMINUS\\b)$/m" 83 | }, 84 | "recommendation": 1000 85 | }, 86 | { 87 | "id": 8, 88 | "name": "Search inline SQL statements in XML files for create table", 89 | "description": "Search inline SQL statements in XML files for create table", 90 | "complexity": "major", 91 | "rule_type": "sql", 92 | "search": { 93 | "pattern": "\\b(^CREATE|TABLE)\\b(?=.*\\bDUAL\\b)|(\\bNVL\\b)|(\\bNVL2\\b)|(\\bSYSDATE\\b)|(\\bROWNUM\\b)|(NEXTVAL)|(\\bDECODE\\b)|(ADD_MONTHS)|(XMLAGG)|(ROWNUM)|(\\bHINTS\\b)|(\\bMINUS\\b)$/m" 94 | }, 95 | "recommendation": 1000 96 | }, 97 | { 98 | "id": 9, 99 | "name": "Search inline SQL statements in XML files for drop table", 100 | "description": "Search inline SQL statements in XML files for drop table", 101 | "complexity": "major", 102 | "rule_type": "sql", 103 | "search": { 104 | "pattern": "\\b(^DROP|TABLE)\\b(?=.*\\bDUAL\\b)|(\\bNVL\\b)|(\\bNVL2\\b)|(\\bSYSDATE\\b)|(\\bROWNUM\\b)|(\\bDECODE\\b)|(NEXTVAL)|(ADD_MONTHS)|(XMLAGG)|(ROWNUM)|(\\bHINTS\\b)|(\\bMINUS\\b)$/m" 105 | }, 106 | "recommendation": 1000 107 | } 108 | ] 109 | } -------------------------------------------------------------------------------- /src/main/resources/summaryreporttemplate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AppServerMigration-SQL-Report 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 28 |
29 |
30 |
31 |

32 | AppServerMigration, an open-source software solution, evaluates Java 33 | applications for seamless migration from 34 | source to the target state. It efficiently pinpoints required 35 | modifications and offers recommendations, 36 | presenting them through a detailed HTML report for a streamlined 37 | migration process. Expedites the migration 38 | process, eradicates the need for re-work, and guarantees a smooth 39 | and successful transition, enhancing overall 40 | efficiency and minimizing potential setbacks. 41 |

42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |

Summary

50 |
51 |
52 |
Total Projects Scanned
53 |
54 |
55 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
Build Tool
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
Total Person Days (SQL)
74 |
75 |
76 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
Total Person Days (JAVA)
85 |
86 |
87 |
89 |
90 |
91 |
92 |
93 |
94 | 95 |
96 |
97 |
99 |
Person Days
100 |

102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
Project Reports
112 |
113 |
114 |
115 |
116 |
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 133 | 134 | 141 | 151 | 152 | 153 | 154 |
#SeverityReport NameJava Report (Person Days)SQL Report (Person Days)Person Days
131 | View 135 | Report 136 | 138 | ( 139 | ) 140 | 142 |
143 | View 144 | Report 147 | () 149 |
150 |
155 |
156 | 157 | 221 | 222 | 223 | 224 | -------------------------------------------------------------------------------- /src/main/resources/weblogic-to-tomcat-javarules.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.java.JavaFileAnalyzer", 3 | "file_type": "java", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "Remove coherence dependency", 8 | "description": "Remove coherence package and code", 9 | "complexity": "major", 10 | "rule_type": "package", 11 | "remove": { 12 | "import": [ 13 | "com.tangosol", 14 | "com.oracle.coherence" 15 | ] 16 | }, 17 | "recommendation": 2 18 | },{ 19 | "id": 2, 20 | "name": "WebLogic FTP Adapter", 21 | "description": "Remove WebLogic FTP adapter", 22 | "complexity": "major", 23 | "rule_type": "package", 24 | "remove": { 25 | "import": [ 26 | "oracle.tip.adapter.ftp" 27 | ] 28 | }, 29 | "recommendation": 3 30 | },{ 31 | "id": 3, 32 | "name": "EJB", 33 | "description": "EJB", 34 | "complexity": "critical", 35 | "rule_type": "package", 36 | "remove": { 37 | "import": [ 38 | "javax.ejb" 39 | ] 40 | }, 41 | "recommendation": 4 42 | },{ 43 | "id": 4, 44 | "name": "T3StartupDef", 45 | "description": "T3StartupDef", 46 | "complexity": "critical", 47 | "rule_type": "package", 48 | "remove": { 49 | "import": [ 50 | "weblogic.common" 51 | ] 52 | }, 53 | "recommendation": 5 54 | },{ 55 | "id": 5, 56 | "name": "WebLogic logging", 57 | "description": "WebLogic proprietary logging", 58 | "complexity": "major", 59 | "rule_type": "package", 60 | "remove": { 61 | "import": [ 62 | "weblogic.logger" 63 | ] 64 | }, 65 | "recommendation": 6 66 | },{ 67 | "id": 6, 68 | "name": "WebLogic Servlet", 69 | "description": "WebLogic specific annotations", 70 | "complexity": "major", 71 | "rule_type": "package", 72 | "remove": { 73 | "import": [ 74 | "weblogic.servlet.annotation", 75 | "weblogic.application", 76 | "weblogic.security", 77 | "weblogic.wsee", 78 | "weblogic.jws" 79 | ] 80 | }, 81 | "recommendation": 7 82 | },{ 83 | "id": 7, 84 | "name": "WebLogic JMS", 85 | "description": "WebLogic specific JMS", 86 | "complexity": "major", 87 | "rule_type": "package", 88 | "remove": { 89 | "import": [ 90 | "oracle.jms", 91 | "weblogic.jms", 92 | "javax.naming.weblogic" 93 | ] 94 | }, 95 | "recommendation": 8 96 | }, 97 | { 98 | "id": 8, 99 | "name": "Transactions", 100 | "description": "Tomcat does not support transactions", 101 | "complexity": "major", 102 | "rule_type": "package", 103 | "remove": { 104 | "import": ["org.springframework.transaction", 105 | "org.springframework.test.context.transaction"] 106 | }, 107 | "recommendation": 11 108 | }, 109 | { 110 | "id": 10, 111 | "name": "TuxedoAdapter", 112 | "complexity": "critical", 113 | "rule_type": "package", 114 | "remove": { 115 | "import": ["com.oracle.tuxedo.TuxedoAdapter", 116 | "weblogic.wtc.jatmi.TPException"] 117 | }, 118 | "recommendation": 14 119 | }, 120 | { 121 | "id": 11, 122 | "name": "JNDI", 123 | "complexity": "major", 124 | "rule_type": "package", 125 | "remove": { 126 | "import": ["weblogic.jndi"] 127 | }, 128 | "recommendation": 0 129 | } 130 | ] 131 | } 132 | -------------------------------------------------------------------------------- /src/main/resources/weblogic-to-tomcat-mf.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.mf.ManifestFileAnalyzer", 3 | "file_type": "MF", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "Remove weblogic-spring", 8 | "description": "Remove WebLogic-spring from the manifest file", 9 | "complexity": "minor", 10 | "rule_type": "manifest", 11 | "remove": { 12 | "WeblogicSpring-Extension-Name": "weblogic-spring", 13 | "Extension-List": "WeblogicSpring", 14 | "WeblogicSpring-Specification-Version": "*", 15 | "WeblogicSpring-Implementation-Version": "*" 16 | }, 17 | "recommendation": 10 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /src/main/resources/weblogic-to-tomcat-mvnrules.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.mvn.MVNBuildFileAnalyzer", 3 | "file_type": "pom.xml", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "Remove EAR and Oracle WebLogic specific files and directories", 8 | "description": "This rule finds out ear modules as they are not required and compatible in Apache Tomcat server", 9 | "complexity": "minor", 10 | "rule_type": "modules", 11 | "remove": { 12 | "module": "ear" 13 | }, 14 | "recommendation": 12 15 | }, 16 | { 17 | "id": 2, 18 | "name": "Remove WebLogic Quartz dependency", 19 | "description": "Remove WebLogic specific quartz packages and add standard quatz package for Tomcat", 20 | "complexity": "minor", 21 | "rule_type": "dependency", 22 | "remove": { 23 | "artifactId": "quartz-weblogic" 24 | }, 25 | "recommendation": 1 26 | }, 27 | { 28 | "id": 3, 29 | "name": "Remove WebLogic Coherence dependency", 30 | "description": "Remove WebLogic specific oracle coherence packages and respective code blocks", 31 | "complexity": "major", 32 | "rule_type": "dependency", 33 | "remove": { 34 | "groupId": "com.oracle.coherence", 35 | "artifactId": "coherence", 36 | "version": "*" 37 | }, 38 | "recommendation": 2 39 | }, 40 | { 41 | "id": 4, 42 | "name": "Remove Oracle datastore", 43 | "description": "Remove Oracle datastore", 44 | "complexity": "major", 45 | "rule_type": "dependency", 46 | "remove": { 47 | "groupId": "com.oracle.jdbc", 48 | "artifactId": "ojdbc6", 49 | "version": "*" 50 | }, 51 | "recommendation": 9 52 | } 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /src/main/resources/weblogic-to-tomcat-properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.properties.PropertyFileAnalyzer", 3 | "file_type": "properties", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "Remove weblogic Oracle Delegate class", 8 | "description": "Remove WebLogic specific JobStore which is WebLogicOracleDelegate with standard JobStore StdJDBCDelegate", 9 | "complexity": "minor", 10 | "rule_type": "properties", 11 | "remove": { 12 | "name": "org.quartz.jobStore.driverDelegateClass", 13 | "value": "org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate" 14 | }, 15 | "recommendation": 1 16 | }, 17 | { 18 | "id": 2, 19 | "name": "Remove weblogic JMS context factory", 20 | "description": "Remove WebLogic specific context factory for JMS connection", 21 | "complexity": "minor", 22 | "rule_type": "properties", 23 | "remove": { 24 | "name": "java.naming.factory.initial", 25 | "value": "weblogic.jndi.WLInitialContextFactory" 26 | }, 27 | "recommendation": 8 28 | }, 29 | { 30 | "id": 2, 31 | "name": "Remove weblogic JMS connection factory", 32 | "description": "Remove WebLogic specific connection factory for JMS", 33 | "complexity": "minor", 34 | "rule_type": "properties", 35 | "remove": { 36 | "value": "weblogic.jms.XAConnectionFactory" 37 | }, 38 | "recommendation": 8 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /src/main/resources/weblogic-to-tomcat-recommendations.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | { 4 | "id": 0, 5 | "name": "No related recommendations", 6 | "description": "No related recommendations." 7 | }, 8 | { 9 | "id": 1, 10 | "name": "quartz related changes/recommendations", 11 | "description": "Quartz is an open source job scheduling library that can be integrated with any java application. For more information, visit . To migrate Quarz scheduler from Oracle WebLogic to Apache Tomcat, we need to replace WebLogic specific dependencies with generic Quartz dependencies. In Quartz, JobStore's are responsible to keep track of all the work data that you give to the scheduler. You declare which JobStore your scheduler should use in the properties file. If you would like to change the persistence JobStore, then you need to make those changes respectively. For more information about Job Stores, please visit " 12 | }, 13 | { 14 | "id": 2, 15 | "name": "Coherence related changes/recommendations", 16 | "description": "Possible different options on migrating coherence from Oracle WebLogic to Apache Tomcat are as follows. Redis is a data structure store software that can be used as a cache, message broker, and database. It is open source and BSD licensed, which means that it's completely free to use and constantly being refined by its user community. For more information, visit Memcached is memory object caching software. Notable customers include LiveJournal, Wikipedia, Bebo, Flickr, Mixi, Craigslist and WordPress. com. The original version of Memcached was developed for LiveJournal by Brad Fitzpatrick back in 2003 and now has an enormous list of contributors, which can be viewed on the memcached website http://memcached.org/
  • LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values. For more information, visit leveldb" 17 | }, 18 | { 19 | "id": 3, 20 | "name": "FTPAdapter related changes/recommendations", 21 | "description": "The File Transfer Protocol (FTP) is a simple network protocol which allows you to transfer files between two computers on the Internet. Spring Integration supports sending and receiving files over FTP/FTPS by providing three client side endpoints: Inbound Channel Adapter, Outbound Channel Adapter, and Outbound Gateway. It also provides convenient namespace-based configuration options for defining these client components. For more information, visit https://docs.spring.io/spring-integration/reference/html/ftp.html" 22 | }, 23 | { 24 | "id": 4, 25 | "name": "EJB related changes/recommendations", 26 | "description": "There's no direct equivalent for EJBs. We need to have Micro-service architecture approach as well as RESTful approach to EJB and containers" 27 | }, 28 | { 29 | "id": 5, 30 | "name": "T3StartupDef related changes/recommendations", 31 | "description": "A class will be automatically launched when the WebLogic Server starts up, and its startup method will be called. A Listener element defines a component that performs actions when specific events occur, usually Tomcat starting or Tomcat stopping. Listeners may be nested inside a Server, Engine, Host or Context. Some Listeners are only intended to be nested inside specific elements. For more information visit https://tomcat.apache.org/tomcat-9.0-doc/config/listeners.html" 32 | }, 33 | { 34 | "id": 6, 35 | "name": "WebLogic logging related changes/recommendations", 36 | "description": "The internal logging for Apache Tomcat uses JULI, a packaged renamed fork of Apache Commons Logging that, by default, is hard-coded to use the java.util.logging framework. This ensures that Tomcat's internal logging and any web application logging will remain independent, even if a web application uses Apache Commons Logging. For more information visit https://tomcat.apache.org/tomcat-8.0-doc/logging.html" 37 | }, 38 | { 39 | "id": 7, 40 | "name": "WebLogic Servlet related changes/recommendations", 41 | "description": "The default servlet in Apache Tomcat is the servlet which serves static resources as well as serves the directory listings. For more information visit https://tomcat.apache.org/tomcat-7.0-doc/default-servlet.html" 42 | }, 43 | { 44 | "id": 8, 45 | "name": "WebLogic JMS related changes/recommendations", 46 | "description": "Tomcat doesn’t supports JMS itself but using external library ( ActiveMQ, RabbitMQ) we can accomplish it. For more information visit
  • https://www.rabbitmq.com/
  • https://activemq.apache.org/jms
  • " 47 | }, 48 | { 49 | "id": 9, 50 | "name": "Oracle datastore related changes/recommendations", 51 | "description": "Java Database Connectivity (JDBC) is an application programming interface (API) for the programming language Java, which defines how a client may access a database. It is a Java-based data access technology used for Java database connectivity.It provides methods to query and update data in a database, and is oriented towards relational databases. Spring JdbcTemplate is a powerful mechanism to connect to the database and execute SQL queries. It internally uses JDBC api, but eliminates a lot of problems of JDBC API. For more information visit relational-data-access" 52 | }, 53 | { 54 | "id": 10, 55 | "name": "Weblogic Spring related changes/recommendations", 56 | "description": "Spring makes programming Java quicker, easier, and safer for everybody. Spring’s focus on speed, simplicity, and productivity has made it the world's most popular Java framework. For more information visit https://spring.io/" 57 | }, 58 | { 59 | "id": 11, 60 | "name": "Transactions", 61 | "description": "As Apache Tomcat is not an application server, it does not support transactions. We can achieve it using third party frameworks like Atomikos, JOTM etc." 62 | }, 63 | { 64 | "id": 12, 65 | "name": "Remove EAR and Oracle WebLogic specific files and directories", 66 | "description": "This directory can be completely deleted" 67 | }, 68 | { 69 | "id": 13, 70 | "name": "Replace Oracle database with other database", 71 | "description": "Prerequisite: Database migration should already be done. This code snippet identifies the places in the java code that needs to be replaced with target database related calls." 72 | }, 73 | { 74 | "id": 14, 75 | "name": "Re-factor Oracle Tuxedo application", 76 | "description": "Replacing Tuxedo middleware applications requires complete re-factor of code" 77 | } 78 | ] 79 | } -------------------------------------------------------------------------------- /src/main/resources/weblogic-to-tomcat-xml.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.xml.XMLFileAnalyzer", 3 | "file_type": "xml", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "Remove EAR and Oracle WebLogic specific files and directories", 8 | "description": "This rule finds out ear modules as they are not required and compatible in Apache Tomcat server", 9 | "complexity": "minor", 10 | "rule_type": "xml", 11 | "remove": { 12 | "tagName": "listener-class", 13 | "tagContent": "weblogic.spring.monitoring.WeblogicContextLoaderListener" 14 | }, 15 | "recommendation": 12 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /src/main/resources/weblogic-to-wildfly-javarules.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.java.JavaFileAnalyzer", 3 | "file_type": "java", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "Instantiate initial context", 8 | "description": "Instantiate initial context as per Portable JNDI Syntax", 9 | "complexity": "minor", 10 | "rule_type": "package", 11 | "remove": { 12 | "import": [ 13 | "javax.naming.InitialContext", 14 | "javax.naming.Context" 15 | ] 16 | }, 17 | "recommendation": 2001 18 | }, 19 | { 20 | "id": 2, 21 | "name": "Servlet Authentication", 22 | "description": "Servlet Authentication", 23 | "complexity": "major", 24 | "rule_type": "package", 25 | "remove": { 26 | "import": [ 27 | "weblogic.servlet.security.ServletAuthentication" 28 | ] 29 | }, 30 | "recommendation": 2002 31 | }, 32 | { 33 | "id": 3, 34 | "name": "WebLogic NonCatalogLogger", 35 | "description": "The WebLogic NonCatalogLogger is not supported in WildFly", 36 | "complexity": "major", 37 | "rule_type": "package", 38 | "remove": { 39 | "import": [ 40 | "weblogic.logging.NonCatalogLogger", 41 | "weblogic.i18n.logging.NonCatalogLogger" 42 | ] 43 | }, 44 | "recommendation": 2003 45 | }, 46 | { 47 | "id": 4, 48 | "name": "WebLogic interface T3ServicesDef", 49 | "description": "WebLogic interface T3ServicesDef usage not supported in WildFly", 50 | "complexity": "major", 51 | "rule_type": "package", 52 | "remove": { 53 | "import": [ 54 | "weblogic.common.T3ServicesDef" 55 | ] 56 | }, 57 | "recommendation": 2004 58 | }, 59 | { 60 | "id": 5, 61 | "name": "WebLogic interface T3StartupDef", 62 | "description": "WebLogic interface T3StartupDef usage not supported in WildFly", 63 | "complexity": "critical", 64 | "rule_type": "package", 65 | "remove": { 66 | "import": [ 67 | "weblogic.common.T3StartupDef" 68 | ] 69 | }, 70 | "recommendation": 2005 71 | }, 72 | { 73 | "id": 6, 74 | "name": "WebLogic JNDI Environment", 75 | "description": "WebLogic JNDI Environment usage not supported in WildFly", 76 | "complexity": "critical", 77 | "rule_type": "package", 78 | "remove": { 79 | "import": [ 80 | "weblogic.jndi.Environment" 81 | ] 82 | }, 83 | "recommendation": 2006 84 | }, 85 | { 86 | "id": 7, 87 | "name": "WebLogic TransactionManager extensions", 88 | "description": "WebLogic TransactionManager extensions not supported in WildFly", 89 | "complexity": "major", 90 | "rule_type": "package", 91 | "remove": { 92 | "import": [ 93 | "weblogic.transaction.*", 94 | "weblogic.transaction.TxHelper", 95 | "weblogic.transaction.Transaction", 96 | "weblogic.transaction.TxConstants", 97 | "weblogic.transaction.RollbackException", 98 | "weblogic.transaction.TransactionManager", 99 | "weblogic.transaction.TransactionHelper", 100 | "weblogic.transaction.ClientTransactionManager" 101 | ] 102 | }, 103 | "recommendation": 2007 104 | }, 105 | { 106 | "id": 8, 107 | "name": "WebLogic EJB classes", 108 | "description": "WebLogic EJB classes not supported in WildFly", 109 | "complexity": "major", 110 | "rule_type": "package", 111 | "remove": { 112 | "import": [ 113 | "weblogic.ejb.*", 114 | "weblogic.ejb.GenericSessionBean", 115 | "weblogic.ejb.GenericMessageDrivenBean", 116 | "weblogic.ejb.GenericEnterpriseBean", 117 | "weblogic.ejb.GenericEntityBean", 118 | "weblogic.ejb.WLTimerInfo" 119 | ] 120 | }, 121 | "recommendation": 2008 122 | }, 123 | { 124 | "id": 9, 125 | "name": "WebLogic Proprietary Annotations", 126 | "description": "WebLogic Proprietary Annotations not supported in WildFly", 127 | "complexity": "minor", 128 | "rule_type": "package", 129 | "remove": { 130 | "import": [ 131 | "weblogic.servlet.annotation.*", 132 | "weblogic.servlet.annotation.WLFilter", 133 | "weblogic.servlet.annotation.WLInitParam", 134 | "weblogic.servlet.annotation.WLServlet" 135 | ] 136 | }, 137 | "recommendation": 2009 138 | }, 139 | { 140 | "id": 10, 141 | "name": "WebLogic ApplicationLifecycleListener", 142 | "description": "WebLogic ApplicationLifecycleListener not supported in WildFly", 143 | "complexity": "major", 144 | "rule_type": "package", 145 | "remove": { 146 | "import": [ 147 | "weblogic.application.*", 148 | "weblogic.application.ApplicationLifecycleListener" 149 | ] 150 | }, 151 | "recommendation": 2010 152 | } 153 | ] 154 | } -------------------------------------------------------------------------------- /src/main/resources/weblogic-to-wildfly-mf.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awslabs/app-server-migration/eb8ed9799491f1bc068ab30e0829a1d78fb485c4/src/main/resources/weblogic-to-wildfly-mf.json -------------------------------------------------------------------------------- /src/main/resources/weblogic-to-wildfly-mvnrules.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.mvn.MVNBuildFileAnalyzer", 3 | "file_type": "pom.xml", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "Remove WebLogic Quartz dependency", 8 | "description": "Remove WebLogic specific quartz packages and add standard quartz package for WildFly/JBoss", 9 | "complexity": "minor", 10 | "rule_type": "dependency", 11 | "remove": { 12 | "artifactId": "quartz-weblogic" 13 | }, 14 | "recommendation": 2017 15 | }, 16 | { 17 | "id": 2, 18 | "name": "Remove WebLogic Specific dependency", 19 | "description": "Replace WebLogic specific dependency, it may not be compatible with WildFly", 20 | "complexity": "minor", 21 | "rule_type": "dependency", 22 | "remove": { 23 | "groupId": "com.oracle.weblogic", 24 | "artifactId": "weblogic-server-pom" 25 | }, 26 | "recommendation": 2018 27 | }, 28 | { 29 | "id": 3, 30 | "name": "Remove WebLogic Specific plugin", 31 | "description": "WebLogic specific plugin found, it's not compatible with WildFly", 32 | "complexity": "minor", 33 | "rule_type": "plugin", 34 | "remove": { 35 | "groupId": "com.oracle.weblogic", 36 | "artifactId": "weblogic-maven-plugin" 37 | }, 38 | "recommendation": 2019 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /src/main/resources/weblogic-to-wildfly-properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.properties.PropertyFileAnalyzer", 3 | "file_type": "properties", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "Remove WebLogic specific properties", 8 | "description": "Remove WebLogic specific properties", 9 | "complexity": "minor", 10 | "rule_type": "properties", 11 | "remove": { 12 | "name": "weblogic.*" 13 | }, 14 | "recommendation": 2020 15 | }, 16 | { 17 | "id": 2, 18 | "name": "Remove weblogic Oracle Delegate class", 19 | "description": "Remove WebLogic specific JobStore which is WebLogicOracleDelegate with standard JobStore StdJDBCDelegate", 20 | "complexity": "minor", 21 | "rule_type": "properties", 22 | "remove": { 23 | "name": "org.quartz.jobStore.driverDelegateClass", 24 | "value": "org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate" 25 | }, 26 | "recommendation": 2017 27 | }, 28 | { 29 | "id": 3, 30 | "name": "Remove weblogic JMS context factory", 31 | "description": "Remove WebLogic specific context factory for JMS connection", 32 | "complexity": "minor", 33 | "rule_type": "properties", 34 | "remove": { 35 | "name": "java.naming.factory.initial", 36 | "value": "weblogic.jndi.WLInitialContextFactory" 37 | }, 38 | "recommendation": 2016 39 | }, 40 | { 41 | "id": 4, 42 | "name": "Remove weblogic JMS connection factory", 43 | "description": "Remove WebLogic specific connection factory for JMS", 44 | "complexity": "minor", 45 | "rule_type": "properties", 46 | "remove": { 47 | "value": "weblogic.jms.XAConnectionFactory" 48 | }, 49 | "recommendation": 2016 50 | } 51 | ] 52 | } -------------------------------------------------------------------------------- /src/main/resources/weblogic-to-wildfly-xml.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "com.amazon.aws.am2.appmig.estimate.xml.XMLFileAnalyzer", 3 | "file_type": "xml", 4 | "rules": [ 5 | { 6 | "id": 1, 7 | "name": "Remove WebLogic specific xml file weblogic-ejb-jar.xml", 8 | "description": "This file is proprietary to WebLogic and not supported in WildFly", 9 | "complexity": "major", 10 | "rule_type": "xml", 11 | "remove": { 12 | "tagName": "weblogic-ejb-jar" 13 | }, 14 | "recommendation": 2011 15 | }, 16 | { 17 | "id": 2, 18 | "name": "Remove WebLogic specific xml file weblogic-plan.xml", 19 | "description": "This file is proprietary to WebLogic and not supported in WildFly", 20 | "complexity": "major", 21 | "rule_type": "xml", 22 | "remove": { 23 | "tagName": "deployment-plan" 24 | }, 25 | "recommendation": 2012 26 | }, 27 | { 28 | "id": 3, 29 | "name": "Remove WebLogic specific xml file weblogic.xml", 30 | "description": "This file is proprietary to WebLogic and not supported in WildFly", 31 | "complexity": "major", 32 | "rule_type": "xml", 33 | "remove": { 34 | "tagName": "weblogic-web-app" 35 | }, 36 | "recommendation": 2013 37 | }, 38 | { 39 | "id": 4, 40 | "name": "Remove WebLogic specific xml file weblogic-application.xml", 41 | "description": "This file is proprietary to WebLogic and not supported in WildFly", 42 | "complexity": "major", 43 | "rule_type": "xml", 44 | "remove": { 45 | "tagName": "weblogic-application" 46 | }, 47 | "recommendation": 2014 48 | }, 49 | { 50 | "id": 5, 51 | "name": "Remove WebLogic specific xml file weblogic-cmp-rdbms-jar.xml", 52 | "description": "This file is proprietary to WebLogic and not supported in WildFly", 53 | "complexity": "major", 54 | "rule_type": "xml", 55 | "remove": { 56 | "tagName": "weblogic-rdbms-jar" 57 | }, 58 | "recommendation": 2015 59 | }, 60 | { 61 | "id": 6, 62 | "name": "Remove WebLogic specific xml file weblogic-jms.xml", 63 | "description": "This file is proprietary to WebLogic and not supported in WildFly", 64 | "complexity": "major", 65 | "rule_type": "xml", 66 | "remove": { 67 | "tagName": "weblogic-jms" 68 | }, 69 | "recommendation": 2016 70 | } 71 | ] 72 | } --------------------------------------------------------------------------------