├── .circleci └── config.yml ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ ├── build-main.yml │ ├── publish.yml │ └── pull_request.yml ├── .gitignore ├── .sdkmanrc ├── LICENSE ├── README.md ├── build.gradle ├── buildSrc ├── build.gradle ├── settings.gradle └── src │ └── main │ └── groovy │ ├── jig.base-conventions.gradle │ ├── jig.cli-conventions.gradle │ ├── jig.java-conventions.gradle │ └── jig.ossrh-conventions.gradle ├── docs ├── adr │ ├── collections-usage.md │ ├── defensive_programming_policy.md │ ├── gradle_version_support_policy.md │ └── record_field_access_policy.md ├── architecture.png ├── banner.png ├── legend.gv ├── logo.png └── overview.png ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jig-cli ├── README.md ├── build.gradle └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── dddjava │ │ │ └── jig │ │ │ └── cli │ │ │ ├── CliConfig.java │ │ │ ├── CliRunner.java │ │ │ ├── CommandLineApplication.java │ │ │ ├── DirectoryCollector.java │ │ │ └── Mode.java │ └── resources │ │ ├── application.yml │ │ ├── banner.txt │ │ └── logback.xml │ └── test │ └── java │ └── org │ └── dddjava │ └── jig │ └── cli │ └── CliConfigTest.java ├── jig-core ├── build.gradle └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── dddjava │ │ │ └── jig │ │ │ ├── HandleResult.java │ │ │ ├── JigContext.java │ │ │ ├── JigExecutor.java │ │ │ ├── adapter │ │ │ ├── Adapter.java │ │ │ ├── CompositeAdapter.java │ │ │ ├── HandleDocument.java │ │ │ ├── diagram │ │ │ │ ├── DiagramAdapter.java │ │ │ │ ├── DotCommandRunner.java │ │ │ │ ├── GraphvizDiagramWriter.java │ │ │ │ ├── ProcessExecutor.java │ │ │ │ └── ProcessResult.java │ │ │ ├── excel │ │ │ │ ├── GlossaryAdapter.java │ │ │ │ ├── ListAdapter.java │ │ │ │ ├── ReportBook.java │ │ │ │ ├── ReportItem.java │ │ │ │ └── ReportSheet.java │ │ │ └── html │ │ │ │ ├── IndexView.java │ │ │ │ ├── PackageSummaryView.java │ │ │ │ ├── SummaryAdapter.java │ │ │ │ ├── SummaryModel.java │ │ │ │ ├── TableView.java │ │ │ │ ├── ThymeleafSummaryWriter.java │ │ │ │ ├── TreeComponent.java │ │ │ │ ├── TreeComposite.java │ │ │ │ ├── TreeLeaf.java │ │ │ │ ├── dialect │ │ │ │ ├── JigDialect.java │ │ │ │ ├── JigEntrypointExpressionObject.java │ │ │ │ ├── JigExpressionObject.java │ │ │ │ ├── JigExpressionObjectFactory.java │ │ │ │ ├── JigOptionalUtextAttributeProcessor.java │ │ │ │ └── package-info.java │ │ │ │ └── mermaid │ │ │ │ ├── EntrypointMermaidDiagram.java │ │ │ │ ├── Mermaid.java │ │ │ │ ├── SequenceMermaidDiagram.java │ │ │ │ ├── TypeMermaidDiagram.java │ │ │ │ └── UsecaseMermaidDiagram.java │ │ │ ├── annotation │ │ │ ├── Repository.java │ │ │ └── Service.java │ │ │ ├── application │ │ │ ├── GlossaryRepository.java │ │ │ ├── JigDataProvider.java │ │ │ ├── JigDocumentGenerator.java │ │ │ ├── JigDocumentWriter.java │ │ │ ├── JigEventRepository.java │ │ │ ├── JigService.java │ │ │ ├── JigTypesWithRelationships.java │ │ │ └── package-info.java │ │ │ ├── domain │ │ │ └── model │ │ │ │ ├── data │ │ │ │ ├── enums │ │ │ │ │ ├── EnumConstant.java │ │ │ │ │ ├── EnumModel.java │ │ │ │ │ └── EnumModels.java │ │ │ │ ├── members │ │ │ │ │ ├── JigMemberOwnership.java │ │ │ │ │ ├── JigMemberVisibility.java │ │ │ │ │ ├── fields │ │ │ │ │ │ ├── JigFieldAttribute.java │ │ │ │ │ │ ├── JigFieldFlag.java │ │ │ │ │ │ ├── JigFieldHeader.java │ │ │ │ │ │ └── JigFieldIdentifier.java │ │ │ │ │ ├── instruction │ │ │ │ │ │ ├── BasicInstruction.java │ │ │ │ │ │ ├── ClassReference.java │ │ │ │ │ │ ├── DynamicMethodCall.java │ │ │ │ │ │ ├── FieldAccess.java │ │ │ │ │ │ ├── IfInstruction.java │ │ │ │ │ │ ├── Instruction.java │ │ │ │ │ │ ├── Instructions.java │ │ │ │ │ │ ├── JumpTarget.java │ │ │ │ │ │ ├── LambdaExpressionCall.java │ │ │ │ │ │ ├── MethodCall.java │ │ │ │ │ │ ├── SwitchInstruction.java │ │ │ │ │ │ ├── TryCatchInstruction.java │ │ │ │ │ │ └── package-info.java │ │ │ │ │ ├── methods │ │ │ │ │ │ ├── JavaMethodDeclarator.java │ │ │ │ │ │ ├── JigMethodAttribute.java │ │ │ │ │ │ ├── JigMethodFlag.java │ │ │ │ │ │ ├── JigMethodHeader.java │ │ │ │ │ │ └── JigMethodIdentifier.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── package-info.java │ │ │ │ ├── packages │ │ │ │ │ ├── PackageDepth.java │ │ │ │ │ ├── PackageIdentifier.java │ │ │ │ │ ├── PackageIdentifiers.java │ │ │ │ │ ├── PackageNumber.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── rdbaccess │ │ │ │ │ ├── MyBatisStatement.java │ │ │ │ │ ├── MyBatisStatementId.java │ │ │ │ │ ├── MyBatisStatements.java │ │ │ │ │ ├── Query.java │ │ │ │ │ ├── SqlReadStatus.java │ │ │ │ │ ├── SqlType.java │ │ │ │ │ ├── Table.java │ │ │ │ │ ├── Tables.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── terms │ │ │ │ │ ├── Glossary.java │ │ │ │ │ ├── Term.java │ │ │ │ │ ├── TermIdentifier.java │ │ │ │ │ ├── TermKind.java │ │ │ │ │ └── package-info.java │ │ │ │ └── types │ │ │ │ │ ├── JavaTypeDeclarationKind.java │ │ │ │ │ ├── JigAnnotationInstanceElement.java │ │ │ │ │ ├── JigAnnotationInstanceElementValue.java │ │ │ │ │ ├── JigAnnotationReference.java │ │ │ │ │ ├── JigBaseTypeDataBundle.java │ │ │ │ │ ├── JigTypeArgument.java │ │ │ │ │ ├── JigTypeAttributeData.java │ │ │ │ │ ├── JigTypeHeader.java │ │ │ │ │ ├── JigTypeModifier.java │ │ │ │ │ ├── JigTypeParameter.java │ │ │ │ │ ├── JigTypeReference.java │ │ │ │ │ ├── JigTypeVisibility.java │ │ │ │ │ ├── TypeIdentifier.java │ │ │ │ │ ├── TypeIdentifiers.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── documents │ │ │ │ ├── diagrams │ │ │ │ │ ├── ArchitectureDiagram.java │ │ │ │ │ ├── ArchitectureRelations.java │ │ │ │ │ ├── CategoryDiagram.java │ │ │ │ │ ├── CategoryUsageDiagram.java │ │ │ │ │ ├── ClassRelationDiagram.java │ │ │ │ │ ├── CompositeUsecaseDiagram.java │ │ │ │ │ ├── CompositeUsecases.java │ │ │ │ │ ├── PackageRelationDiagram.java │ │ │ │ │ ├── ServiceMethodCallHierarchyDiagram.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── documentformat │ │ │ │ │ ├── DocumentName.java │ │ │ │ │ ├── JigDiagramFormat.java │ │ │ │ │ ├── JigDocument.java │ │ │ │ │ ├── JigDocumentLabel.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── package-info.java │ │ │ │ └── stationery │ │ │ │ │ ├── AdditionalText.java │ │ │ │ │ ├── DiagramSource.java │ │ │ │ │ ├── DiagramSourceWriter.java │ │ │ │ │ ├── DiagramSources.java │ │ │ │ │ ├── JigDiagramOption.java │ │ │ │ │ ├── JigDocumentContext.java │ │ │ │ │ ├── JigPropertyHolder.java │ │ │ │ │ ├── Labeler.java │ │ │ │ │ ├── Node.java │ │ │ │ │ ├── NodeEditor.java │ │ │ │ │ ├── NodeRole.java │ │ │ │ │ ├── Nodes.java │ │ │ │ │ ├── RelationText.java │ │ │ │ │ ├── Subgraph.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── information │ │ │ │ ├── Architecture.java │ │ │ │ ├── JigRepository.java │ │ │ │ ├── applications │ │ │ │ │ ├── ServiceMethod.java │ │ │ │ │ ├── ServiceMethods.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── inputs │ │ │ │ │ ├── EntrypointGroup.java │ │ │ │ │ ├── EntrypointMethod.java │ │ │ │ │ ├── EntrypointMethodDetector.java │ │ │ │ │ ├── EntrypointType.java │ │ │ │ │ ├── Entrypoints.java │ │ │ │ │ ├── HttpEndpoint.java │ │ │ │ │ ├── QueueListener.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── members │ │ │ │ │ ├── CallerMethods.java │ │ │ │ │ ├── JigField.java │ │ │ │ │ ├── JigFields.java │ │ │ │ │ ├── JigMethod.java │ │ │ │ │ ├── JigMethodDeclaration.java │ │ │ │ │ ├── JigMethods.java │ │ │ │ │ ├── UsingFields.java │ │ │ │ │ └── UsingMethods.java │ │ │ │ ├── module │ │ │ │ │ ├── JigPackage.java │ │ │ │ │ ├── JigPackageWithJigTypes.java │ │ │ │ │ └── JigPackages.java │ │ │ │ ├── outputs │ │ │ │ │ ├── DatasourceMethod.java │ │ │ │ │ ├── DatasourceMethods.java │ │ │ │ │ ├── RepositoryMethods.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── package-info.java │ │ │ │ ├── relation │ │ │ │ │ ├── graph │ │ │ │ │ │ ├── Edge.java │ │ │ │ │ │ ├── Edges.java │ │ │ │ │ │ └── package-info.java │ │ │ │ │ ├── methods │ │ │ │ │ │ ├── CallerMethodsFactory.java │ │ │ │ │ │ ├── MethodRelation.java │ │ │ │ │ │ ├── MethodRelations.java │ │ │ │ │ │ └── package-info.java │ │ │ │ │ ├── package-info.java │ │ │ │ │ ├── packages │ │ │ │ │ │ ├── PackageMutualDependencies.java │ │ │ │ │ │ ├── PackageMutualDependency.java │ │ │ │ │ │ ├── PackageRelation.java │ │ │ │ │ │ ├── PackageRelations.java │ │ │ │ │ │ ├── RelationNumber.java │ │ │ │ │ │ └── package-info.java │ │ │ │ │ └── types │ │ │ │ │ │ ├── TypeRelationKind.java │ │ │ │ │ │ ├── TypeRelationship.java │ │ │ │ │ │ ├── TypeRelationships.java │ │ │ │ │ │ └── package-info.java │ │ │ │ └── types │ │ │ │ │ ├── JigType.java │ │ │ │ │ ├── JigTypeGlossary.java │ │ │ │ │ ├── JigTypeMembers.java │ │ │ │ │ ├── JigTypeValueKind.java │ │ │ │ │ ├── JigTypes.java │ │ │ │ │ ├── TypeCategory.java │ │ │ │ │ ├── TypeKind.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── knowledge │ │ │ │ ├── adapter │ │ │ │ │ ├── DatasourceAngle.java │ │ │ │ │ └── DatasourceAngles.java │ │ │ │ ├── architecture │ │ │ │ │ └── PackageBasedArchitecture.java │ │ │ │ ├── core │ │ │ │ │ ├── ServiceAngle.java │ │ │ │ │ ├── ServiceAngles.java │ │ │ │ │ ├── Usecase.java │ │ │ │ │ ├── UsecaseCategory.java │ │ │ │ │ └── usecases │ │ │ │ │ │ ├── StringComparingMethodList.java │ │ │ │ │ │ └── package-info.java │ │ │ │ ├── package-info.java │ │ │ │ ├── smell │ │ │ │ │ ├── MethodSmell.java │ │ │ │ │ ├── MethodSmellList.java │ │ │ │ │ ├── MethodWorries.java │ │ │ │ │ └── MethodWorry.java │ │ │ │ └── validations │ │ │ │ │ ├── Validation.java │ │ │ │ │ ├── Validations.java │ │ │ │ │ └── package-info.java │ │ │ │ └── sources │ │ │ │ ├── DefaultJigDataProvider.java │ │ │ │ ├── LocalSource.java │ │ │ │ ├── ReadStatus.java │ │ │ │ ├── SourceBasePath.java │ │ │ │ ├── SourceBasePaths.java │ │ │ │ ├── classsources │ │ │ │ ├── ClassFile.java │ │ │ │ └── ClassFiles.java │ │ │ │ ├── javasources │ │ │ │ ├── JavaFilePaths.java │ │ │ │ └── JavaSourceModel.java │ │ │ │ ├── mybatis │ │ │ │ └── MyBatisStatementsReader.java │ │ │ │ └── package-info.java │ │ │ └── infrastructure │ │ │ ├── asm │ │ │ ├── AsmAnnotationVisitor.java │ │ │ ├── AsmClassSignatureVisitor.java │ │ │ ├── AsmClassSourceReader.java │ │ │ ├── AsmClassVisitor.java │ │ │ ├── AsmFieldVisitor.java │ │ │ ├── AsmMethodSignatureVisitor.java │ │ │ ├── AsmMethodVisitor.java │ │ │ ├── AsmTypeSignatureVisitor.java │ │ │ ├── AsmUtils.java │ │ │ ├── ClassDeclaration.java │ │ │ └── package-info.java │ │ │ ├── configuration │ │ │ ├── Configuration.java │ │ │ ├── JigDocumentContextImpl.java │ │ │ ├── JigProperties.java │ │ │ ├── JigProperty.java │ │ │ ├── JigPropertyLoader.java │ │ │ └── PropertyArchitectureFactory.java │ │ │ ├── javaparser │ │ │ ├── JavaparserClassVisitor.java │ │ │ ├── JavaparserMemberVisitor.java │ │ │ ├── JavaparserReader.java │ │ │ ├── TermFactory.java │ │ │ └── package-info.java │ │ │ ├── javaproductreader │ │ │ ├── ClassOrJavaSourceCollector.java │ │ │ ├── DefaultJigRepositoryFactory.java │ │ │ └── JigTypeFactory.java │ │ │ ├── mybatis │ │ │ └── MyBatisMyBatisStatementsReader.java │ │ │ └── onmemoryrepository │ │ │ └── OnMemoryGlossaryRepository.java │ └── resources │ │ └── templates │ │ ├── application.html │ │ ├── assets │ │ ├── favicon.ico │ │ ├── jig.js │ │ └── style.css │ │ ├── domain.html │ │ ├── entrypoint.html │ │ ├── enum.html │ │ ├── fragment-base.html │ │ ├── fragment-package.html │ │ ├── fragment-type.html │ │ ├── glossary.html │ │ ├── index.html │ │ ├── package.html │ │ └── usecase.html │ └── test │ ├── java │ ├── DefaultPackageClass.java │ ├── org │ │ ├── dddjava │ │ │ └── jig │ │ │ │ ├── JigExecutorTest.java │ │ │ │ ├── adapter │ │ │ │ └── html │ │ │ │ │ └── mermaid │ │ │ │ │ └── SequenceMermaidDiagramTest.java │ │ │ │ ├── application │ │ │ │ ├── BusinessRuleServiceTest.java │ │ │ │ ├── JigDocumentGeneratorTest.java │ │ │ │ ├── PackageDependenciesTest.java │ │ │ │ └── ReadableLabelTest.java │ │ │ │ ├── domain │ │ │ │ └── model │ │ │ │ │ ├── documents │ │ │ │ │ └── diagrams │ │ │ │ │ │ └── PackageEdgeDiagramTest.java │ │ │ │ │ ├── identifier │ │ │ │ │ └── type │ │ │ │ │ │ └── TypeIdentifiersTest.java │ │ │ │ │ ├── implementation │ │ │ │ │ └── datasource │ │ │ │ │ │ └── TablesTest.java │ │ │ │ │ ├── information │ │ │ │ │ ├── applications │ │ │ │ │ │ └── ServiceMethodTest.java │ │ │ │ │ ├── relation │ │ │ │ │ │ ├── graph │ │ │ │ │ │ │ └── EdgesTest.java │ │ │ │ │ │ ├── methods │ │ │ │ │ │ │ └── MethodRelationsTest.java │ │ │ │ │ │ └── types │ │ │ │ │ │ │ └── JigTypeRelationshipCreateTest.java │ │ │ │ │ └── types │ │ │ │ │ │ └── JigTypeTest.java │ │ │ │ │ └── knowledge │ │ │ │ │ ├── core │ │ │ │ │ └── usecases │ │ │ │ │ │ └── StringComparingMethodListTest.java │ │ │ │ │ ├── smell │ │ │ │ │ ├── MemberUsageCheckNormalClass.java │ │ │ │ │ └── MethodSmellListTest.java │ │ │ │ │ └── validations │ │ │ │ │ └── ValidationsTest.java │ │ │ │ └── infrastructure │ │ │ │ ├── LocalFileLocalSourceFactoryTest.java │ │ │ │ ├── asm │ │ │ │ ├── AsmAnnotationVisitorTest.java │ │ │ │ ├── AsmClassSourceReaderTest.java │ │ │ │ ├── AsmClassVisitorTest.java │ │ │ │ ├── AsmFieldVisitorTest.java │ │ │ │ ├── AsmMethodVisitorInstructionTest.java │ │ │ │ ├── AsmMethodVisitorTest.java │ │ │ │ ├── InstructionTest.java │ │ │ │ └── ut │ │ │ │ │ ├── MyClass.java │ │ │ │ │ ├── MyGenericsMadnessInterface.java │ │ │ │ │ ├── MyTypeModifierClass.java │ │ │ │ │ └── field │ │ │ │ │ ├── MyEnumFieldSut.java │ │ │ │ │ └── MySutClass.java │ │ │ │ ├── javaparser │ │ │ │ ├── JavaparserReaderTest.java │ │ │ │ ├── learning │ │ │ │ │ ├── JavaparserLineSeparatorTest.java │ │ │ │ │ ├── JavaparserLocalClassTest.java │ │ │ │ │ └── package-info.java │ │ │ │ └── ut │ │ │ │ │ ├── ParseTargetCanonicalClass.java │ │ │ │ │ ├── package-info.java │ │ │ │ │ ├── package_info_block_comment │ │ │ │ │ └── package-info.java │ │ │ │ │ ├── package_info_javadoc │ │ │ │ │ └── package-info.java │ │ │ │ │ ├── package_info_javadoc_tag_only │ │ │ │ │ └── package-info.java │ │ │ │ │ ├── package_info_no_comment │ │ │ │ │ └── package-info.java │ │ │ │ │ └── package_info_typical │ │ │ │ │ └── package-info.java │ │ │ │ └── mybatis │ │ │ │ └── MyBatisMyBatisStatementReaderTest.java │ │ └── springframework │ │ │ └── stereotype │ │ │ ├── Controller.java │ │ │ ├── Repository.java │ │ │ ├── Service.java │ │ │ └── package-info.java │ ├── stub │ │ ├── application │ │ │ └── service │ │ │ │ ├── CanonicalService.java │ │ │ │ ├── DecisionService.java │ │ │ │ └── SimpleService.java │ │ ├── domain │ │ │ └── model │ │ │ │ ├── ClassJavadocStub.java │ │ │ │ ├── MemberAnnotatedClass.java │ │ │ │ ├── MethodJavadocStub.java │ │ │ │ ├── NotJavadocStub.java │ │ │ │ ├── annotation │ │ │ │ ├── RuntimeRetainedAnnotation.java │ │ │ │ └── package-info.java │ │ │ │ ├── booleans │ │ │ │ ├── BooleanQueryAngleTestTarget.java │ │ │ │ ├── UserByConstructor.java │ │ │ │ ├── UserByField.java │ │ │ │ ├── UserByLambda.java │ │ │ │ ├── UserByMethod.java │ │ │ │ ├── UserByStaticField.java │ │ │ │ └── UserByStaticMethod.java │ │ │ │ ├── category │ │ │ │ ├── BehaviourEnum.java │ │ │ │ ├── HasStaticFieldEnum.java │ │ │ │ ├── ParameterizedEnum.java │ │ │ │ ├── PolymorphismEnum.java │ │ │ │ ├── RelationEnum.java │ │ │ │ ├── RichEnum.java │ │ │ │ └── SimpleEnum.java │ │ │ │ ├── package-info.java │ │ │ │ ├── record │ │ │ │ ├── EmptyComponentRecord.java │ │ │ │ └── SingleStringValueRecord.java │ │ │ │ ├── relation │ │ │ │ ├── ClassDefinition.java │ │ │ │ ├── EnumDefinition.java │ │ │ │ ├── InterfaceDefinition.java │ │ │ │ ├── MethodInstructionTestStub.java │ │ │ │ ├── annotation │ │ │ │ │ ├── UseInAnnotation.java │ │ │ │ │ └── VariableAnnotation.java │ │ │ │ ├── clz │ │ │ │ │ ├── ClassAnnotation.java │ │ │ │ │ ├── GenericsParameter.java │ │ │ │ │ ├── ImplementA.java │ │ │ │ │ ├── ImplementB.java │ │ │ │ │ └── SuperClass.java │ │ │ │ ├── constant │ │ │ │ │ ├── to_primitive_constant │ │ │ │ │ │ └── ConstantFieldHolder.java │ │ │ │ │ └── to_primitive_wrapper_constant │ │ │ │ │ │ └── IntegerConstantFieldHolder.java │ │ │ │ ├── enumeration │ │ │ │ │ ├── ClassReference.java │ │ │ │ │ ├── ConstructorArgument.java │ │ │ │ │ └── EnumField.java │ │ │ │ └── method │ │ │ │ │ ├── ArgumentGenericsParameter.java │ │ │ │ │ ├── CheckedException.java │ │ │ │ │ ├── CheckedExceptionB.java │ │ │ │ │ ├── EnclosedClass.java │ │ │ │ │ ├── Instantiation.java │ │ │ │ │ ├── InstructionField.java │ │ │ │ │ ├── LocalValue.java │ │ │ │ │ ├── MethodAnnotation.java │ │ │ │ │ ├── MethodArgument.java │ │ │ │ │ ├── MethodReference.java │ │ │ │ │ ├── MethodReturn.java │ │ │ │ │ ├── ReferenceConstantInMethod.java │ │ │ │ │ ├── ReferenceConstantOwnerInMethod.java │ │ │ │ │ ├── UncheckedExceptionA.java │ │ │ │ │ ├── UncheckedExceptionB.java │ │ │ │ │ ├── UnusedInstructionMethodReturn.java │ │ │ │ │ ├── UseInLambda.java │ │ │ │ │ └── UsedInstructionMethodReturn.java │ │ │ │ ├── smell │ │ │ │ ├── SmelledClass.java │ │ │ │ └── SmelledRecord.java │ │ │ │ ├── type │ │ │ │ ├── HogeDatasource.java │ │ │ │ ├── HogeRepository.java │ │ │ │ ├── IntegerNumber.java │ │ │ │ ├── LongNumber.java │ │ │ │ ├── PrimitiveIntNumber.java │ │ │ │ ├── PrimitiveLongNumber.java │ │ │ │ ├── SetCollection.java │ │ │ │ ├── SimpleCollection.java │ │ │ │ ├── SimpleDate.java │ │ │ │ ├── SimpleIdentifier.java │ │ │ │ ├── SimpleNumber.java │ │ │ │ ├── SimpleTerm.java │ │ │ │ └── fuga │ │ │ │ │ ├── Fuga.java │ │ │ │ │ ├── FugaIdentifier.java │ │ │ │ │ ├── FugaName.java │ │ │ │ │ └── FugaRepository.java │ │ │ │ └── visibility │ │ │ │ ├── DefaultType.java │ │ │ │ ├── PublicType.java │ │ │ │ └── TypeContainer.java │ │ ├── infrastructure │ │ │ └── datasource │ │ │ │ ├── CanonicalMapper.java │ │ │ │ ├── DecisionDatasource.java │ │ │ │ ├── SampleMapper.java │ │ │ │ └── fuga │ │ │ │ ├── AnnotationMapper.java │ │ │ │ ├── FugaDatasource.java │ │ │ │ └── FugaMapper.java │ │ ├── misc │ │ │ └── DecisionClass.java │ │ ├── package-info.java │ │ └── presentation │ │ │ └── controller │ │ │ ├── DecisionController.java │ │ │ ├── SimpleController.java │ │ │ └── SimpleRestController.java │ └── testing │ │ ├── JigServiceTest.java │ │ ├── JigTestExtension.java │ │ ├── TestSupport.java │ │ ├── package-info.java │ │ └── xlsx │ │ └── XlsxAssertions.java │ └── resources │ ├── logback.xml │ ├── marker.properties │ └── stub │ └── infrastructure │ └── datasource │ ├── CanonicalMapper.xml │ ├── SampleMapper.xml │ └── fuga │ └── FugaMapper.xml ├── jig-gradle-plugin ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── dddjava │ │ └── jig │ │ └── gradle │ │ ├── GradleProject.java │ │ ├── JigConfig.java │ │ ├── JigGradlePlugin.java │ │ ├── JigReportsTask.java │ │ └── VerifyJigEnvironmentTask.java │ └── test │ └── java │ └── jig │ ├── JigPluginFunctionalTest.java │ ├── JigPluginUnitTest.java │ └── SupportGradleVersion.java ├── jig-maven-plugin ├── README.md ├── build.gradle └── src │ └── main │ └── java │ └── org │ └── dddjava │ └── jig │ └── maven │ └── JigMojo.java └── settings.gradle /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: 動作しないとか、出力がおかしいとか 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## 不具合の内容 11 | 不具合の内容を教えてください 12 | 13 | ## 環境 14 | - JIGのバージョン: - 15 | - 実行方法: CLI / GradlePlugin 16 | - Javaのバージョン: - 17 | - OS: - 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: 機能追加や改善の要望 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ご自由に 11 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gradle 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "07:00" 8 | open-pull-requests-limit: 10 9 | 10 | -------------------------------------------------------------------------------- /.github/workflows/build-main.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | jobs: 6 | build: 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | matrix: 10 | os: [ ubuntu-latest, windows-latest ] 11 | java-version: [ '17' ] 12 | name: build Java ${{ matrix.java-version }} (${{ matrix.os }}) 13 | env: 14 | GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dfile.encoding=UTF-8' 15 | steps: 16 | - uses: actions/checkout@v3 17 | - uses: actions/setup-java@v3 18 | with: 19 | distribution: 'temurin' 20 | java-version: ${{ matrix.java-version }} 21 | - name: Cache Gradle 22 | uses: actions/cache@v3 23 | with: 24 | path: | 25 | ~/.gradle/caches 26 | ~/.gradle/wrapper 27 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} 28 | - name: Set UTF-8 encoding for Windows 29 | if: runner.os == 'Windows' 30 | run: chcp.com 65001 31 | - name: Run Build 32 | run: | 33 | ./gradlew build --continue 34 | - name: Upload test failure report 35 | uses: actions/upload-artifact@v4 36 | if: failure() 37 | with: 38 | name: test-failure-reports-${{ matrix.java-version }}-${{ runner.os }} 39 | path: build/reports/tests/ 40 | retention-days: 3 -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_dispatch: 3 | inputs: 4 | version: 5 | description: 'release version' 6 | required: true 7 | default: '0.0.0-SNAPSHOT' 8 | jobs: 9 | publish: 10 | runs-on: ubuntu-latest 11 | env: 12 | GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dfile.encoding=UTF-8' 13 | steps: 14 | - uses: actions/checkout@v4 15 | with: 16 | ref: ${{ inputs.version}} 17 | - uses: actions/setup-java@v3 18 | with: 19 | distribution: 'temurin' 20 | java-version: '17' 21 | - name: Cache Gradle 22 | uses: actions/cache@v3 23 | with: 24 | path: | 25 | ~/.gradle/caches 26 | ~/.gradle/wrapper 27 | key: gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} 28 | - name: Run Build 29 | env: 30 | ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }} 31 | ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }} 32 | ORG_GRADLE_PROJECT_version: ${{ github.event.inputs.version }} 33 | run: | 34 | echo "publish as ${{ github.event.inputs.version }}" 35 | ./gradlew build 36 | echo ./gradlew build :jig-core:publishToSonatype :jig-gradle-plugin:publishPlugins closeAndReleaseSonatypeStagingRepository 37 | - name: Upload artifact 38 | uses: actions/upload-artifact@v4 39 | with: 40 | path: jig-cli/build/libs/jig-cli.jar 41 | - name: Upload test failure report 42 | uses: actions/upload-artifact@v4 43 | if: failure() 44 | with: 45 | name: test-failure-reports-${{ runner.os }} 46 | path: jig-*/build/reports/tests/test/ 47 | retention-days: 3 48 | -------------------------------------------------------------------------------- /.github/workflows/pull_request.yml: -------------------------------------------------------------------------------- 1 | name: Test & Merge PR 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | permissions: 8 | contents: write 9 | 10 | jobs: 11 | build-and-merge: 12 | runs-on: ubuntu-latest 13 | env: 14 | GRADLE_OPTS: '-Dorg.gradle.daemon=false' 15 | steps: 16 | - name: Check out code 17 | uses: actions/checkout@v3 18 | - name: Set up JDK 19 | uses: actions/setup-java@v3 20 | with: 21 | distribution: 'temurin' 22 | java-version: '17' 23 | - name: Cache Gradle 24 | uses: actions/cache@v3 25 | with: 26 | path: | 27 | ~/.gradle/caches 28 | ~/.gradle/wrapper 29 | key: gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} 30 | - name: Build with Tests 31 | run: ./gradlew build 32 | - name: Merge Pull Request 33 | if: success() 34 | env: 35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 36 | run: | 37 | gh pr merge ${{ github.event.pull_request.number }} --merge --delete-branch 38 | - name: Upload Failure Report 39 | uses: actions/upload-artifact@v4 40 | if: failure() 41 | with: 42 | name: test-failure-reports 43 | path: jig-*/build/reports/tests/ 44 | retention-days: 3 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle/ 2 | .idea/ 3 | build/ 4 | out/ 5 | *.iml 6 | node_modules/ 7 | -------------------------------------------------------------------------------- /.sdkmanrc: -------------------------------------------------------------------------------- 1 | # Enable auto-env through the sdkman_auto_env config 2 | # Add key=value pairs of SDKs to use below 3 | java=17.0.13-tem 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JIG 2 | 3 | [![MavenCentral](https://maven-badges.herokuapp.com/maven-central/org.dddjava.jig/jig-core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.dddjava.jig/jig-core) 4 | [![CircleCI](https://circleci.com/gh/dddjava/jig/tree/main.svg?style=svg)](https://circleci.com/gh/dddjava/jig) 5 | [![GitHubActions](https://github.com/dddjava/jig/actions/workflows/build-main.yml/badge.svg)](https://github.com/dddjava/jig/actions/workflows/build-main.yml) 6 | 7 | ![banner](./docs/banner.png) 8 | 9 | JIGはコードでの設計を支援するツールです。思い浮かんだ設計をコーディングすればいい感じに可視化される世界を目指しています。 10 | 11 | 主にバイトコード(classファイル)から一覧や図を出力します。バイトコードが対象なので、JVM言語であれば主要機能は動作します。 12 | 13 | ## サンプル 14 | [サンプルリポジトリ](https://github.com/dddjava/jig-sample) を参照してください。 15 | 16 | ## 使い方 17 | 18 | 実行方法はコマンドラインとGradleプラグインがあります。それぞれのREADMEを参照してください。 19 | 20 | - [コマンドラインでの使い方](./jig-cli) 21 | - [Gradleプラグインでの使い方](./jig-gradle-plugin) 22 | 23 | JIGの実行にはJava17以降が必要です。 24 | プロダクトはJava17以降である必要はありません。 25 | たとえばJava8のプロダクトであっても、Java21で実行するJIGで解析することは可能です。 26 | 27 | より詳しい情報は[Wiki](https://github.com/dddjava/jig/wiki)を参照してください。 28 | うまく動かない場合などは [issue](https://github.com/dddjava/jig/issues/new/choose) でお問い合わせください。 29 | 30 | ## コンセプト 31 | 32 | 三層+ドメインモデルのアーキテクチャで実装されたコードから、以下の分析・設計情報を生成します。 33 | 34 | - ドメインモデルのクラスに記述された業務の概念とビジネスルール 35 | - アプリケーション層に記述された業務機能 36 | 37 | ### 想定するアーキテクチャ 38 | 39 | 三層+ドメインモデルのアーキテクチャでの使用を想定しています。 40 | 41 | ![ドメインモデルのクラスに記述された業務の概念とビジネスルール](./docs/overview.png) 42 | 43 | ![アプリケーション層に記述された業務機能](./docs/architecture.png) 44 | 45 | ## JIGドキュメント 46 | 47 | JIGの生成する分析・設計情報をJIGドキュメントと呼んでいます。 48 | 49 | - 種類は [JigDocument](./jig-core/src/main/java/org/dddjava/jig/domain/model/documents/documentformat/JigDocument.java) を参照してください。 50 | - サンプルは [JIGのドッグフーディング](https://dddjava.github.io/jig/) を参照してください。 51 | 52 | ## LICENSE 53 | 54 | [Apache License 2.0](LICENSE) 55 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'jig.base-conventions' 3 | id 'io.github.gradle-nexus.publish-plugin' version '2.0.0' 4 | id 'test-report-aggregation' 5 | } 6 | 7 | nexusPublishing { 8 | repositories { 9 | sonatype { 10 | nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/")) 11 | snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) 12 | } 13 | } 14 | } 15 | 16 | dependencies { 17 | testReportAggregation project(':jig-core') 18 | // spring-boot-starterのBOM解決ができないとかでうまく収集できない。一旦コメントアウト。 19 | //testReportAggregation project(':jig-cli') 20 | testReportAggregation project(':jig-gradle-plugin') 21 | } 22 | 23 | reporting { 24 | reports { 25 | testAggregateTestReport(AggregateTestReport) { 26 | testSuiteName = "unit-test" 27 | } 28 | } 29 | } 30 | 31 | tasks.register('build') { 32 | dependsOn tasks.named('testAggregateTestReport', TestReport) 33 | } 34 | 35 | subprojects { 36 | plugins.withType(JavaPlugin).configureEach { 37 | test { 38 | reports.html.required = false 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /buildSrc/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'groovy-gradle-plugin' 3 | } 4 | 5 | repositories { 6 | gradlePluginPortal() 7 | } 8 | 9 | dependencies { 10 | implementation libs.spring.boot.plugin 11 | } 12 | -------------------------------------------------------------------------------- /buildSrc/settings.gradle: -------------------------------------------------------------------------------- 1 | dependencyResolutionManagement { 2 | versionCatalogs { 3 | libs { 4 | from(files("../gradle/libs.versions.toml")) 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/jig.base-conventions.gradle: -------------------------------------------------------------------------------- 1 | repositories { 2 | mavenCentral() 3 | } 4 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/jig.cli-conventions.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'jig.java-conventions' 3 | id 'org.springframework.boot' 4 | } 5 | 6 | bootJar { 7 | metaInf { from(rootDir) { include 'LICENSE' } } 8 | archiveFileName = archiveBaseName.get() + "." + archiveExtension.get() 9 | } 10 | 11 | // *-plain.jarを作らない 12 | jar.enabled = false 13 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/jig.java-conventions.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'jig.base-conventions' 3 | id 'java' 4 | } 5 | 6 | sourceCompatibility = '17' 7 | 8 | project.afterEvaluate { 9 | def defaultEncoding = 'UTF-8' 10 | [AbstractCompile, Javadoc].each { 11 | tasks.withType(it).each { it.options.encoding = defaultEncoding } 12 | } 13 | } 14 | 15 | tasks.withType(JavaCompile) { 16 | options.compilerArgs << "-Xlint:deprecation" 17 | } 18 | 19 | tasks.named('jar') { 20 | metaInf { from(rootDir) { include 'LICENSE' } } 21 | manifest { 22 | attributes "Implementation-Version": project.version 23 | } 24 | } 25 | 26 | tasks.named('javadoc') { 27 | options.addStringOption('Xdoclint:none', '-quiet') 28 | } 29 | 30 | repositories { 31 | mavenCentral() 32 | } 33 | 34 | tasks.named('test') { 35 | useJUnitPlatform() 36 | } 37 | 38 | dependencies { 39 | testImplementation(platform('org.junit:junit-bom:5.12.0')) 40 | testImplementation 'org.junit.jupiter:junit-jupiter' 41 | testRuntimeOnly 'org.junit.platform:junit-platform-launcher' 42 | } -------------------------------------------------------------------------------- /docs/adr/collections-usage.md: -------------------------------------------------------------------------------- 1 | # コレクションの扱い 2 | 3 | 1. **ファーストクラスコレクション** を採用し、コレクションクラスはドメインオブジェクト内の責務を表現するクラスとして使用します。 4 | 2. APIのインタフェースでは柔軟性を重視し、必要に応じて `Collection` やその具体的なサブタイプ(`List` や `Set`)、あるいは `Stream` を使用することを許容します。 5 | 6 | ### ファーストクラスコレクション 7 | 8 | - `List` や `Set` などCollectionsFrameworkの直接使用を避け、その責務を表現するファーストクラスコレクションを設計します。 9 | - ファーストクラスコレクション内では、適切なコレクション操作を実装し、ロジックの一貫性と安全性を高めます。 10 | - ファーストクラスコレクションは実質的イミュータブルとして扱います。イミュータブルを保証するためのコンストラクタや取得での防御的コピーは行いません。 11 | - コレクション要素に対する破壊的操作はファーストクラスコレクション内でのみ行い、該当する操作を行う場合は新たなコレクションインスタンスを生成します。 12 | - ファーストクラスコレクションのコンポーネントやコレクションの要素に `null` は使用しません。 13 | - ファーストクラスコレクションが一つのみの場合、名称は要素の複数形を許容しますが、可能限りコレクションの目的に応じた名称を使用します。 14 | - これにより同じコンポーネントを持つ複数のファーストクラスコレクションが存在することになります。 15 | 16 | ### Collections Frameworkインタフェースの使用基準 17 | 18 | ファーストクラスコレクションのコンポーネントやAPIインタフェースにて使用するCollectionsFrameworkを以下のようにします。 19 | 20 | - 順序が必要な場合は `List` を使用します。 21 | - 順序に関するドキュメントを記述します。 22 | - ファーストクラスコレクションのコンストラクタではソートしない。ソートはファクトリメソッドで行います。 23 | - 重複を防ぐ場合で `equals` / `hashCode` が適切な場合は `Set` を使用します。 24 | - 明確な理由がない場合は `Collection` を使用し、特定の型(例: `List`, `Set`)を避けます。 25 | 26 | ### 実装例 27 | 28 | ```java 29 | import java.util.ArrayList; 30 | 31 | record Items(List items) { 32 | 33 | static Items from(Collection items) { 34 | return new Items(items.stream().sorted().toList()); 35 | } 36 | 37 | public Items addItem(Item item) { 38 | var list = new ArrayList<>(items); 39 | list.add(item); 40 | return new Items(list); 41 | } 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /docs/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dddjava/jig/b531cc369f11dfeb92c04bfd8140bb5ddf2b099a/docs/architecture.png -------------------------------------------------------------------------------- /docs/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dddjava/jig/b531cc369f11dfeb92c04bfd8140bb5ddf2b099a/docs/banner.png -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dddjava/jig/b531cc369f11dfeb92c04bfd8140bb5ddf2b099a/docs/logo.png -------------------------------------------------------------------------------- /docs/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dddjava/jig/b531cc369f11dfeb92c04bfd8140bb5ddf2b099a/docs/overview.png -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | group=org.dddjava.jig 2 | version=0.0.1-SNAPSHOT 3 | org.gradle.jvmargs=-Dfile.encoding=UTF-8 4 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | poi = "5.4.1" 3 | spring-boot = { strictly = "3.3.4" } 4 | spring = { strictly = "6.1.13" } 5 | 6 | [libraries] 7 | # SpringBootにあわせる 8 | slf4j-api = { module = "org.slf4j:slf4j-api", version = { strictly = "2.0.16" } } 9 | log4j-to-slf4j = { module = "org.apache.logging.log4j:log4j-to-slf4j", version = { strictly = "2.23.1" } } 10 | logback-classic = { module = "ch.qos.logback:logback-classic", version = { strictly = "1.5.8" } } 11 | thymeleaf = { module = "org.thymeleaf:thymeleaf", version = { strictly = "3.1.2.RELEASE" } } 12 | 13 | asm = "org.ow2.asm:asm:9.8" 14 | javaparser = "com.github.javaparser:javaparser-core:3.26.4" 15 | mybatis = "org.mybatis:mybatis:3.5.19" 16 | caffeine = "com.github.ben-manes.caffeine:caffeine:3.2.0" 17 | 18 | micrometer = "io.micrometer:micrometer-core:1.15.0" 19 | micrometer-prometheus = "io.micrometer:micrometer-registry-prometheus:1.15.0" 20 | 21 | poi = { module = "org.apache.poi:poi", version.ref = "poi" } 22 | poi-ooxml = { module = "org.apache.poi:poi-ooxml", version.ref = "poi" } 23 | 24 | spring-boot-plugin = { module = "org.springframework.boot:spring-boot-gradle-plugin", version.ref = "spring-boot" } 25 | 26 | spring-context = { module = "org.springframework:spring-context", version.ref = "spring" } 27 | spring-web = { module = "org.springframework:spring-web", version.ref = "spring" } 28 | spring-test = { module = "org.springframework:spring-test", version.ref = "spring" } 29 | 30 | mockito = "org.mockito:mockito-core:5.18.0" 31 | 32 | [bundles] 33 | poi = ['poi', 'poi-ooxml'] 34 | micrometer = ['micrometer', 'micrometer-prometheus'] 35 | 36 | [plugins] 37 | gradle-plugin-publish = { id = "com.gradle.plugin-publish", version = "1.3.1" } 38 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dddjava/jig/b531cc369f11dfeb92c04bfd8140bb5ddf2b099a/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /jig-cli/README.md: -------------------------------------------------------------------------------- 1 | # JIG: コマンドライン版 2 | 3 | 以下のドキュメントを出力するコマンドラインツールです。 4 | 5 | 6 | ## Getting Started 7 | 8 | Gradleを使用したシンプルなJavaプロジェクトを想定した手順です。 9 | Mavenなど他のビルドツールを使用していたり、ソースやターゲットディレクトリを変更している場合などは設定が必要になります。 10 | 11 | 1. JIGのダウンロード 12 | 1. プロジェクトのビルド 13 | 1. JIGの実行 14 | 15 | ### JIGのダウンロード 16 | 17 | [直近のリリース](https://github.com/dddjava/jig/releases/latest)から `jig-cli.jar` をダウンロードしてください。 18 | 19 | ### プロジェクトのビルド 20 | 21 | 対象プロジェクトをビルドします。 22 | 23 | ``` 24 | $ cd {対象プロジェクトのディレクトリ} 25 | $ gradle clean build 26 | ``` 27 | 28 | ### JIGの実行 29 | 30 | プロジェクトのルートディレクトリで実行します。 31 | 32 | ``` 33 | $ java -jar {JIGをダウンロードしたディレクトリ}/jig-cli.jar 34 | ``` 35 | 36 | `./build/jig` ディレクトリにJIGドキュメントが出力されます。 37 | コードを変更したら、再度プロジェクトのビルドから実行してください。 38 | 39 | ## 設定 40 | 41 | 次のように `--`に続けて指定します。 42 | 43 | ``` 44 | $ java -jar jig-cli.jar --jig.document.types=ServiceMethodCallHierarchyDiagram 45 | ``` 46 | 47 | 設定できるプロパティは [application.properties](./src/main/resources/application.properties) を参照してください。 48 | 49 | ## 困ったら 50 | 51 | [HELP](https://github.com/dddjava/jig/wiki/HELP) を参照してみてください。 52 | -------------------------------------------------------------------------------- /jig-cli/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'jig.cli-conventions' 3 | } 4 | 5 | dependencies { 6 | implementation project(':jig-core') 7 | 8 | implementation platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) 9 | implementation 'org.springframework.boot:spring-boot-starter' 10 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 11 | } -------------------------------------------------------------------------------- /jig-cli/src/main/java/org/dddjava/jig/cli/CommandLineApplication.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.cli; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class CommandLineApplication { 8 | 9 | public static void main(String[] args) { 10 | var context = SpringApplication.run(CommandLineApplication.class, args); 11 | 12 | var cliRunner = context.getBean(CliRunner.class); 13 | cliRunner.run(args); 14 | 15 | System.exit(SpringApplication.exit(context)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /jig-cli/src/main/java/org/dddjava/jig/cli/Mode.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.cli; 2 | 3 | /** 4 | * 動作モード 5 | */ 6 | public enum Mode { 7 | /** 8 | * Mavenのディレクトリ構成にします。 9 | */ 10 | MAVEN, 11 | 12 | /** 13 | * 軽量(動作的な意味ではない) 14 | */ 15 | LIGHT, 16 | 17 | /** 18 | * 何もしない 19 | */ 20 | DEFAULT 21 | } 22 | -------------------------------------------------------------------------------- /jig-cli/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | logging: 2 | level: 3 | root: WARN 4 | org.dddjava.jig: INFO 5 | 6 | jig: 7 | # Output targets (multiple specifications with commas) 8 | #document: 9 | # types: ServiceMethodCallHierarchyDiagram,PackageRelationDiagram,BusinessRuleList 10 | output: 11 | directory: ./build/jig 12 | diagram: 13 | format: svg 14 | # Domain class pattern (regular expression) 15 | #pattern: 16 | # domain: .+\.domain\.(model|type)\..+ 17 | 18 | # Root directory to read information 19 | project: 20 | path: ./ 21 | 22 | # Directories to read information (Gradle standard) 23 | directory: 24 | classes: build/classes/java/main 25 | resources: build/resources/main 26 | sources: src/main/java -------------------------------------------------------------------------------- /jig-cli/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------ 2 | JIG - Command Line Edition 3 | 4 | Build: ${application.version} 5 | ------------------------------------------------------------ 6 | -------------------------------------------------------------------------------- /jig-cli/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | [%5r][%level][%thread][%logger{10}] %message%n 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/JigContext.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig; 2 | 3 | public enum JigContext { 4 | /** 5 | * パッケージの略し方 6 | * initial, numeric 7 | */ 8 | packageAbbreviationMode("initial"); 9 | 10 | private final String value; 11 | 12 | JigContext(String defaultValue) { 13 | this.value = defaultValue; 14 | } 15 | 16 | public String value() { 17 | return value; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/Adapter.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter; 2 | 3 | import org.dddjava.jig.domain.model.documents.documentformat.JigDocument; 4 | 5 | import java.nio.file.Path; 6 | import java.util.List; 7 | 8 | /** 9 | * Adapterのインタフェース。 10 | * このインタフェースを実装したクラスの {@link HandleDocument} メソッドを呼び出してwriterに引き渡す。 11 | * 12 | * @param writerが処理する型。通常はメソッドの戻り値もこの型になります。 13 | */ 14 | public interface Adapter { 15 | 16 | /** 17 | * Adapterの処理結果を書き出せる形に変換します。 18 | * Adapterで実装されているハンドラメソッドの結果がすべてwriterが扱えるなら実装不要。 19 | */ 20 | @SuppressWarnings("unchecked") 21 | default T convertMethodResultToAdapterModel(Object resultModel) { 22 | return (T) resultModel; 23 | } 24 | 25 | List write(T result, JigDocument jigDocument); 26 | } 27 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/HandleDocument.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter; 2 | 3 | import org.dddjava.jig.domain.model.documents.documentformat.JigDocument; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | public @interface HandleDocument { 10 | JigDocument[] value() default {}; 11 | } 12 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/diagram/ProcessResult.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter.diagram; 2 | 3 | 4 | public class ProcessResult { 5 | 6 | boolean success; 7 | String message; 8 | 9 | public ProcessResult(boolean success, String message) { 10 | this.success = success; 11 | this.message = message; 12 | } 13 | 14 | public static ProcessResult success() { 15 | return new ProcessResult(true, ""); 16 | } 17 | 18 | public static ProcessResult failure() { 19 | return new ProcessResult(false, ""); 20 | } 21 | 22 | public static ProcessResult failureWithTimeout() { 23 | return new ProcessResult(false, "timeout"); 24 | } 25 | 26 | public boolean succeed() { 27 | return success; 28 | } 29 | 30 | public boolean failed() { 31 | return !succeed(); 32 | } 33 | 34 | public ProcessResult withMessage(String message) { 35 | return new ProcessResult(this.success, message); 36 | } 37 | 38 | public String message() { 39 | return message; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/excel/GlossaryAdapter.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter.excel; 2 | 3 | import org.dddjava.jig.domain.model.data.terms.Glossary; 4 | import org.dddjava.jig.domain.model.data.terms.Term; 5 | import org.dddjava.jig.domain.model.documents.documentformat.JigDocument; 6 | 7 | import java.nio.file.Path; 8 | import java.util.List; 9 | 10 | public class GlossaryAdapter { 11 | 12 | private static List> reporter() { 13 | return List.of( 14 | ReportItem.ofString("用語(英名)", term -> term.simpleText()), 15 | ReportItem.ofString("用語", term -> term.title()), 16 | ReportItem.ofString("説明", term -> term.description()), 17 | ReportItem.ofString("種類", term -> term.termKind().name()), 18 | ReportItem.ofString("識別子", term -> term.identifier().asText()) 19 | ); 20 | } 21 | 22 | public static List invoke(Glossary glossary, JigDocument jigDocument, Path outputDirectory) { 23 | var modelReports = new ReportBook(new ReportSheet<>("TERM", GlossaryAdapter.reporter(), glossary.list())); 24 | return modelReports.writeXlsx(jigDocument, outputDirectory); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/excel/ReportBook.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter.excel; 2 | 3 | import org.apache.poi.ss.usermodel.Workbook; 4 | import org.apache.poi.xssf.usermodel.XSSFWorkbook; 5 | import org.dddjava.jig.application.JigDocumentWriter; 6 | import org.dddjava.jig.domain.model.documents.documentformat.JigDocument; 7 | 8 | import java.io.IOException; 9 | import java.io.UncheckedIOException; 10 | import java.nio.file.Path; 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | public class ReportBook { 15 | 16 | List> sheets; 17 | 18 | public ReportBook(ReportSheet... reporters) { 19 | this.sheets = Arrays.asList(reporters); 20 | } 21 | 22 | public List writeXlsx(JigDocument jigDocument, Path outputDirectory) { 23 | JigDocumentWriter jigDocumentWriter = new JigDocumentWriter(jigDocument, outputDirectory); 24 | 25 | if (sheets.stream().allMatch(sheet -> sheet.nothingToWriteContent())) { 26 | jigDocumentWriter.markSkip(); 27 | return List.of(); 28 | } 29 | 30 | try (Workbook book = new XSSFWorkbook()) { 31 | for (ReportSheet modelReportInterface : sheets) { 32 | modelReportInterface.writeSheet(book, jigDocumentWriter); 33 | } 34 | 35 | jigDocumentWriter.writeXlsx(book::write); 36 | } catch (IOException e) { 37 | throw new UncheckedIOException(e); 38 | } 39 | 40 | return jigDocumentWriter.outputFilePaths(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/excel/ReportItem.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter.excel; 2 | 3 | import java.util.function.Function; 4 | 5 | public record ReportItem(String label, Function valueResolver) { 6 | 7 | public static ReportItem ofString(String label, Function valueResolver) { 8 | return new ReportItem<>(label, valueResolver); 9 | } 10 | 11 | public static ReportItem ofNumber(String label, Function valueResolver) { 12 | return new ReportItem<>(label, valueResolver); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/html/PackageSummaryView.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter.html; 2 | 3 | import org.dddjava.jig.application.JigDocumentWriter; 4 | import org.dddjava.jig.domain.model.documents.documentformat.JigDocument; 5 | import org.dddjava.jig.domain.model.information.module.JigPackages; 6 | import org.thymeleaf.TemplateEngine; 7 | import org.thymeleaf.context.Context; 8 | 9 | import java.nio.file.Path; 10 | import java.util.List; 11 | import java.util.Locale; 12 | import java.util.Map; 13 | 14 | /** 15 | * パッケージ概要 16 | */ 17 | public class PackageSummaryView { 18 | 19 | private final JigDocument jigDocument; 20 | private final TemplateEngine templateEngine; 21 | 22 | public PackageSummaryView(JigDocument jigDocument, TemplateEngine templateEngine) { 23 | this.jigDocument = jigDocument; 24 | this.templateEngine = templateEngine; 25 | } 26 | 27 | public List write(Path outputDirectory, JigPackages jigPackages) { 28 | JigDocumentWriter jigDocumentWriter = new JigDocumentWriter(jigDocument, outputDirectory); 29 | 30 | Map contextMap = Map.of( 31 | "title", jigDocumentWriter.jigDocument().label(), 32 | "packages", jigPackages.listPackage() 33 | ); 34 | 35 | Context context = new Context(Locale.ROOT, contextMap); 36 | String template = jigDocumentWriter.jigDocument().fileName(); 37 | 38 | jigDocumentWriter.writeTextAs(".html", 39 | writer -> templateEngine.process(template, context, writer)); 40 | return jigDocumentWriter.outputFilePaths(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/html/SummaryModel.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter.html; 2 | 3 | import org.dddjava.jig.domain.model.information.module.JigPackages; 4 | import org.dddjava.jig.domain.model.information.types.JigTypes; 5 | 6 | import java.util.Map; 7 | 8 | public record SummaryModel(JigTypes jigTypes, JigPackages jigPackages, Map additionalMap) { 9 | 10 | static SummaryModel of(JigTypes jigTypes, JigPackages jigPackages) { 11 | return new SummaryModel(jigTypes, jigPackages, Map.of()); 12 | } 13 | 14 | public boolean empty() { 15 | return jigTypes.empty(); 16 | } 17 | 18 | public SummaryModel withAdditionalMap(Map additionalMap) { 19 | return new SummaryModel(jigTypes, jigPackages, additionalMap); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/html/TreeComponent.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter.html; 2 | 3 | public interface TreeComponent extends Comparable { 4 | 5 | String name(); 6 | 7 | String href(); 8 | 9 | default boolean isPackage() { 10 | return this instanceof TreeComposite; 11 | } 12 | 13 | default boolean isDeprecated() { 14 | return false; 15 | } 16 | 17 | @Override 18 | default int compareTo(TreeComponent o) { 19 | // パッケージを優先 20 | if (isPackage() && !o.isPackage()) return -1; 21 | // fqnで比較する 22 | return href().compareTo(o.href()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/html/TreeLeaf.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter.html; 2 | 3 | import org.dddjava.jig.domain.model.information.types.JigType; 4 | 5 | public class TreeLeaf implements TreeComponent { 6 | 7 | JigType jigType; 8 | 9 | public TreeLeaf(JigType jigType) { 10 | this.jigType = jigType; 11 | } 12 | 13 | @Override 14 | public String name() { 15 | return jigType.label(); 16 | } 17 | 18 | @Override 19 | public String href() { 20 | return "#" + jigType.id().fullQualifiedName(); 21 | } 22 | 23 | @Override 24 | public boolean isDeprecated() { 25 | return jigType.isDeprecated(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/html/dialect/JigEntrypointExpressionObject.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter.html.dialect; 2 | 3 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 4 | import org.dddjava.jig.domain.model.information.types.JigType; 5 | import org.thymeleaf.context.IExpressionContext; 6 | 7 | /** 8 | * entrypoint向けのExpressionObject 9 | */ 10 | class JigEntrypointExpressionObject { 11 | public static final String NAME = "jigEntrypoint"; 12 | private final IExpressionContext context; 13 | 14 | public JigEntrypointExpressionObject(IExpressionContext context) { 15 | this.context = context; 16 | } 17 | 18 | public String handlePath(JigType jigType) { 19 | return jigType.annotationValueOf(TypeIdentifier.valueOf("org.springframework.web.bind.annotation.RequestMapping"), "value", "path") 20 | // 空文字列や何も設定されていない場合は "/" として扱う 21 | .map(value -> value.isBlank() ? "" : value) 22 | // Thymeleafのifでnullは空になるのでこれを返している。OptionalをThymeleafに処理させたい。 23 | .orElse(null); 24 | } 25 | 26 | public String tagDescription(JigType jigType) { 27 | return jigType.annotationValueOf(TypeIdentifier.valueOf("io.swagger.v3.oas.annotations.tags.Tag"), "description") 28 | // Thymeleafのifでnullは空になるのでこれを返している。OptionalをThymeleafに処理させたい。 29 | .orElse(null); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/html/dialect/JigExpressionObjectFactory.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter.html.dialect; 2 | 3 | import org.dddjava.jig.domain.model.documents.stationery.JigDocumentContext; 4 | import org.thymeleaf.context.IExpressionContext; 5 | import org.thymeleaf.expression.IExpressionObjectFactory; 6 | 7 | import java.util.Set; 8 | 9 | class JigExpressionObjectFactory implements IExpressionObjectFactory { 10 | private final JigDocumentContext jigDocumentContext; 11 | 12 | public JigExpressionObjectFactory(JigDocumentContext jigDocumentContext) { 13 | this.jigDocumentContext = jigDocumentContext; 14 | } 15 | 16 | @Override 17 | public Set getAllExpressionObjectNames() { 18 | return Set.of(JigExpressionObject.NAME, JigEntrypointExpressionObject.NAME); 19 | } 20 | 21 | @Override 22 | public Object buildObject(IExpressionContext context, String expressionObjectName) { 23 | if (expressionObjectName.equals(JigEntrypointExpressionObject.NAME)) { 24 | return new JigEntrypointExpressionObject(context); 25 | } 26 | return new JigExpressionObject(context, jigDocumentContext); 27 | } 28 | 29 | @Override 30 | public boolean isCacheable(String expressionObjectName) { 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/html/dialect/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Thymeleafの拡張 3 | * 4 | * @see Tutorial: Extending Thymeleaf 5 | */ 6 | package org.dddjava.jig.adapter.html.dialect; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/adapter/html/mermaid/Mermaid.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.adapter.html.mermaid; 2 | 3 | /** 4 | * Mermaid表記 5 | * 6 | * 出力する際に必要なエスケープなどを共通化する 7 | */ 8 | enum Mermaid { 9 | BOX; 10 | 11 | String of(String id, String label) { 12 | var escapedLabel = label.replace("\"", "#quote;").replace("<", "<").replace(">", ">"); 13 | return "%s[\"%s\"]".formatted(id, escapedLabel); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/annotation/Repository.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * カスタムアノテーションに対応する前段階とドッグフーディングのためのマーカーアノテーション 10 | */ 11 | @Retention(RetentionPolicy.CLASS) 12 | @Target(ElementType.TYPE) 13 | public @interface Repository { 14 | } 15 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/annotation/Service.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * カスタムアノテーションに対応する前段階とドッグフーディングのためのマーカーアノテーション 10 | */ 11 | @Retention(RetentionPolicy.CLASS) 12 | @Target(ElementType.TYPE) 13 | public @interface Service { 14 | } 15 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/application/GlossaryRepository.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.application; 2 | 3 | import org.dddjava.jig.domain.model.data.members.fields.JigFieldIdentifier; 4 | import org.dddjava.jig.domain.model.data.members.methods.JavaMethodDeclarator; 5 | import org.dddjava.jig.domain.model.data.packages.PackageIdentifier; 6 | import org.dddjava.jig.domain.model.data.terms.Glossary; 7 | import org.dddjava.jig.domain.model.data.terms.Term; 8 | import org.dddjava.jig.domain.model.data.terms.TermIdentifier; 9 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 10 | 11 | /** 12 | * 別名リポジトリ 13 | */ 14 | public interface GlossaryRepository { 15 | 16 | Term get(TypeIdentifier typeIdentifier); 17 | 18 | Term get(PackageIdentifier packageIdentifier); 19 | 20 | void register(Term term); 21 | 22 | Glossary all(); 23 | 24 | TermIdentifier fromPackageIdentifier(PackageIdentifier packageIdentifier); 25 | 26 | TermIdentifier fromTypeIdentifier(TypeIdentifier typeIdentifier); 27 | 28 | TermIdentifier fromMethodImplementationDeclarator(TypeIdentifier typeIdentifier, JavaMethodDeclarator methodImplementationDeclarator); 29 | 30 | TermIdentifier fromFieldIdentifier(JigFieldIdentifier from); 31 | } 32 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/application/JigDataProvider.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.application; 2 | 3 | import org.dddjava.jig.domain.model.data.enums.EnumModels; 4 | import org.dddjava.jig.domain.model.data.rdbaccess.MyBatisStatements; 5 | import org.dddjava.jig.domain.model.data.rdbaccess.SqlReadStatus; 6 | 7 | import java.util.List; 8 | 9 | public interface JigDataProvider { 10 | 11 | static JigDataProvider none() { 12 | return new JigDataProvider() { 13 | @Override 14 | public MyBatisStatements fetchMybatisStatements() { 15 | return new MyBatisStatements(SqlReadStatus.SQLなし); 16 | } 17 | 18 | @Override 19 | public EnumModels fetchEnumModels() { 20 | return new EnumModels(List.of()); 21 | } 22 | }; 23 | } 24 | 25 | MyBatisStatements fetchMybatisStatements(); 26 | 27 | EnumModels fetchEnumModels(); 28 | } 29 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/application/JigTypesWithRelationships.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.application; 2 | 3 | import org.dddjava.jig.domain.model.information.relation.types.TypeRelationships; 4 | import org.dddjava.jig.domain.model.information.types.JigTypes; 5 | 6 | public record JigTypesWithRelationships(JigTypes jigTypes, TypeRelationships typeRelationships) { 7 | } 8 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/application/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 機能 3 | */ 4 | package org.dddjava.jig.application; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/enums/EnumConstant.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.enums; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Enumの定数 7 | * 8 | * 定数名とコンストラクタの引数リストを持つ 9 | * @param name 定数名 10 | * @param argumentExpressions 引数式(実装されているままのコード)のリスト 11 | */ 12 | public record EnumConstant(String name, List argumentExpressions) { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/enums/EnumModel.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.enums; 2 | 3 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Comparator; 7 | import java.util.List; 8 | 9 | /** 10 | * Enum固有で取得するモデル 11 | */ 12 | public class EnumModel { 13 | TypeIdentifier typeIdentifier; 14 | 15 | /** 16 | * 列挙定数 17 | */ 18 | List enumConstants; 19 | List> constructorArgumentNamesList = new ArrayList<>(); 20 | 21 | public EnumModel(TypeIdentifier typeIdentifier, List enumConstants) { 22 | this.typeIdentifier = typeIdentifier; 23 | this.enumConstants = enumConstants; 24 | } 25 | 26 | public List paramOf(String name) { 27 | return enumConstants.stream() 28 | .filter(enumConstant -> enumConstant.name().equals(name)) 29 | .map(enumConstant -> enumConstant.argumentExpressions()) 30 | .findAny() 31 | .orElseGet(() -> List.of()); 32 | } 33 | 34 | public List constructorArgumentNames() { 35 | return constructorArgumentNamesList.stream().max(Comparator.comparing(List::size)) 36 | .orElse(List.of()); 37 | } 38 | 39 | public void addConstructorArgumentNames(List argumentNames) { 40 | constructorArgumentNamesList.add(argumentNames); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/enums/EnumModels.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.enums; 2 | 3 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.stream.Collectors; 8 | 9 | /** 10 | * Enum固有で取得するモデル 11 | */ 12 | public class EnumModels { 13 | List list; 14 | 15 | public EnumModels(List list) { 16 | this.list = list; 17 | } 18 | 19 | public Map toMap() { 20 | return list.stream() 21 | .collect(Collectors.toMap(enumModel -> enumModel.typeIdentifier, enumModel -> enumModel)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/JigMemberOwnership.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members; 2 | 3 | /** 4 | * メンバの所有関係 5 | */ 6 | public enum JigMemberOwnership { 7 | CLASS, 8 | INSTANCE 9 | } 10 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/JigMemberVisibility.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members; 2 | 3 | /** 4 | * メンバの可視性 5 | */ 6 | public enum JigMemberVisibility { 7 | PUBLIC("+"), 8 | PROTECTED("#"), 9 | PACKAGE("~"), 10 | PRIVATE("-"); 11 | 12 | final String symbol; 13 | 14 | JigMemberVisibility(String symbol) { 15 | this.symbol = symbol; 16 | } 17 | 18 | public boolean isPublic() { 19 | return this == PUBLIC; 20 | } 21 | 22 | public String symbol() { 23 | return symbol; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/fields/JigFieldAttribute.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.fields; 2 | 3 | import org.dddjava.jig.domain.model.data.members.JigMemberVisibility; 4 | import org.dddjava.jig.domain.model.data.types.JigAnnotationReference; 5 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 6 | 7 | import java.util.Collection; 8 | import java.util.EnumSet; 9 | import java.util.stream.Stream; 10 | 11 | /** 12 | * フィールドの属性 13 | */ 14 | record JigFieldAttribute(JigMemberVisibility jigMemberVisibility, 15 | Collection declarationAnnotations, 16 | EnumSet flags) { 17 | Stream allTypeIdentifierStream() { 18 | return declarationAnnotations.stream().map(jigAnnotationReference -> jigAnnotationReference.id()); 19 | } 20 | 21 | public boolean isDeprecated() { 22 | return declarationAnnotations.stream() 23 | .anyMatch(annotation -> annotation.id().equals(TypeIdentifier.from(Deprecated.class))); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/fields/JigFieldFlag.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.fields; 2 | 3 | /** 4 | * フィールドの扱う属性のうちフラグで表現されるもの 5 | * 6 | * クラスファイルでは access_flags として扱われる。 7 | * 可視性と所有関係もフラグだが、この列挙からは除く。 8 | * 9 | * @see 4.5 Fields 10 | */ 11 | public enum JigFieldFlag { 12 | FINAL, 13 | TRANSIENT, 14 | VOLATILE, 15 | SYNTHETIC, 16 | ENUM 17 | } 18 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/fields/JigFieldIdentifier.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.fields; 2 | 3 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 4 | 5 | /** 6 | * フィールドのID 7 | * 8 | * `{クラスの完全修飾名}#{フィールド名}` 9 | */ 10 | public record JigFieldIdentifier(String value) { 11 | 12 | public static JigFieldIdentifier from(TypeIdentifier declaringTypeIdentifier, String name) { 13 | return new JigFieldIdentifier("%s#%s".formatted(declaringTypeIdentifier.fullQualifiedName(), name)); 14 | } 15 | 16 | public String name() { 17 | return value.split("#")[1]; 18 | } 19 | 20 | public TypeIdentifier declaringTypeIdentifier() { 21 | return TypeIdentifier.valueOf(value.split("#")[0]); 22 | } 23 | 24 | public String fqn() { 25 | return value; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/instruction/BasicInstruction.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.instruction; 2 | 3 | /** 4 | * 基本的な命令 5 | * 6 | * JIGではその存在を記録するのみで、パラメタを扱わないものです。 7 | * 8 | * @see JVMS/Chapter 4. The class File Format 9 | */ 10 | public enum BasicInstruction implements Instruction { 11 | 12 | NULL参照, 13 | 14 | RETURN; 15 | } 16 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/instruction/ClassReference.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.instruction; 2 | 3 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 4 | 5 | import java.util.stream.Stream; 6 | 7 | /** 8 | * クラス参照 9 | * 10 | * .classなどでの使用。型引数は付かないので `TypeIdentifier` で扱う。 11 | */ 12 | public record ClassReference(TypeIdentifier typeIdentifier) implements Instruction { 13 | 14 | @Override 15 | public Stream streamAssociatedTypes() { 16 | return Stream.of(typeIdentifier); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/instruction/DynamicMethodCall.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.instruction; 2 | 3 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 4 | 5 | import java.util.List; 6 | import java.util.function.Predicate; 7 | import java.util.stream.Stream; 8 | 9 | /** 10 | * 動的メソッド呼び出し 11 | * 12 | * メソッド参照の場合はmethodCallには対象のメソッドが入る。 13 | * 14 | * @param methodCall 呼び出すメソッド 15 | */ 16 | public record DynamicMethodCall(MethodCall methodCall, TypeIdentifier returnType, 17 | List argumentTypes) implements Instruction { 18 | 19 | @Override 20 | public Stream findMethodCall() { 21 | return Stream.of(methodCall()); 22 | } 23 | 24 | @Override 25 | public Stream streamAssociatedTypes() { 26 | return Stream.of( 27 | methodCall().streamAssociatedTypes(), 28 | argumentTypes().stream(), 29 | Stream.of(returnType()).filter(Predicate.not(TypeIdentifier::isVoid)) 30 | ).flatMap(stream -> stream); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/instruction/FieldAccess.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.instruction; 2 | 3 | import org.dddjava.jig.domain.model.data.members.fields.JigFieldIdentifier; 4 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 5 | 6 | import java.util.stream.Stream; 7 | 8 | public sealed interface FieldAccess extends Instruction 9 | permits GetAccess, SetAccess, UnknownAccess { 10 | 11 | TypeIdentifier typeIdentifier(); 12 | 13 | JigFieldIdentifier jigFieldIdentifier(); 14 | 15 | static FieldAccess set(TypeIdentifier typeIdentifier, JigFieldIdentifier jigFieldIdentifier) { 16 | return new SetAccess(typeIdentifier, jigFieldIdentifier); 17 | } 18 | 19 | static FieldAccess get(TypeIdentifier typeIdentifier, JigFieldIdentifier jigFieldIdentifier) { 20 | return new GetAccess(typeIdentifier, jigFieldIdentifier); 21 | } 22 | 23 | static FieldAccess unknown(TypeIdentifier typeIdentifier, JigFieldIdentifier jigFieldIdentifier) { 24 | return new UnknownAccess(typeIdentifier, jigFieldIdentifier); 25 | } 26 | 27 | @Override 28 | default Stream streamAssociatedTypes() { 29 | return Stream.of(typeIdentifier(), jigFieldIdentifier().declaringTypeIdentifier()); 30 | } 31 | } 32 | 33 | record GetAccess(TypeIdentifier typeIdentifier, JigFieldIdentifier jigFieldIdentifier) implements FieldAccess { 34 | } 35 | 36 | record SetAccess(TypeIdentifier typeIdentifier, JigFieldIdentifier jigFieldIdentifier) implements FieldAccess { 37 | } 38 | 39 | record UnknownAccess(TypeIdentifier typeIdentifier, JigFieldIdentifier jigFieldIdentifier) implements FieldAccess { 40 | } 41 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/instruction/IfInstruction.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.instruction; 2 | 3 | /** 4 | * 分岐 5 | * 6 | * ``` 7 | * ifeq, ifne, ifle, iflt, ifge, ifgt, 8 | * ifnull, ifnonnull, 9 | * if_icmpeq, if_icmpne, if_icmple, if_icmplt, if_icmpge, if_icmpgt, 10 | * if_acmpeq, if_acmpne 11 | * ``` 12 | * 13 | * `jsr, jsr_w, goto, goto_w` は jump or branch instructionで括られるが、これには含まない。 14 | * switchはtargetが複数ある分岐なので別で扱う。 15 | */ 16 | public record IfInstruction(Kind kind, JumpTarget target) implements Instruction { 17 | 18 | public enum Kind { 19 | 比較, 20 | NULL判定, 21 | UNKNOWN 22 | } 23 | 24 | public static Instruction from(Kind kind, String targetId) { 25 | return new IfInstruction(kind, new JumpTarget(targetId)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/instruction/Instruction.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.instruction; 2 | 3 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 4 | 5 | import java.util.stream.Stream; 6 | 7 | /** 8 | * コードで実行される命令 9 | */ 10 | public sealed interface Instruction 11 | permits BasicInstruction, ClassReference, DynamicMethodCall, FieldAccess, 12 | IfInstruction, SwitchInstruction, 13 | TryCatchInstruction, 14 | JumpTarget, 15 | LambdaExpressionCall, MethodCall { 16 | 17 | /** 18 | * メソッド呼び出しの場合に中身がある 19 | * Optionalのほうがいいんだけど、Optionalからstreamへの変換がノイジーなのでstreamにしておく。 20 | */ 21 | default Stream findMethodCall() { 22 | return Stream.empty(); 23 | } 24 | 25 | /** 26 | * この命令によって関連づけられる型のストリーム 27 | */ 28 | default Stream streamAssociatedTypes() { 29 | return Stream.empty(); 30 | } 31 | 32 | /** 33 | * lambdaのメソッド呼び出しをインライン化したもの 34 | */ 35 | default Stream lambdaInlinedMethodCallStream() { 36 | return findMethodCall(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/instruction/JumpTarget.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.instruction; 2 | 3 | /** 4 | * 分岐やswitch、try-catchのターゲット 5 | */ 6 | public record JumpTarget(String id) implements Instruction { 7 | } 8 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/instruction/LambdaExpressionCall.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.instruction; 2 | 3 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 4 | 5 | import java.util.function.Predicate; 6 | import java.util.stream.Stream; 7 | 8 | /** 9 | * Lambda式呼び出し 10 | * 11 | * {@link DynamicMethodCall} の特化型で、呼び出されているLambdaの {@link Instructions} を保持する。 12 | * originのmethodCallはlambda式のコンパイルにより生成される合成メソッド。実装依存だが `lambda$methodName$0` のような名前になる。 13 | */ 14 | public record LambdaExpressionCall(DynamicMethodCall origin, 15 | Instructions lambdaExpressionInstructions) implements Instruction { 16 | public static LambdaExpressionCall from(DynamicMethodCall origin, Instructions instructions) { 17 | return new LambdaExpressionCall(origin, instructions); 18 | } 19 | 20 | @Override 21 | public Stream findMethodCall() { 22 | return Stream.of(origin.methodCall()); 23 | } 24 | 25 | @Override 26 | public Stream lambdaInlinedMethodCallStream() { 27 | // methodCallは合成メソッドなので使用しない 28 | return lambdaExpressionInstructions.lambdaInlinedMethodCallStream(); 29 | } 30 | 31 | @Override 32 | public Stream streamAssociatedTypes() { 33 | return Stream.of( 34 | origin.methodCall().streamAssociatedTypes(), 35 | origin.argumentTypes().stream(), 36 | Stream.of(origin.returnType()).filter(Predicate.not(TypeIdentifier::isVoid)), 37 | // lambdaの中身 38 | lambdaExpressionInstructions.associatedTypeStream() 39 | ).flatMap(stream -> stream); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/instruction/SwitchInstruction.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.instruction; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * switch命令 7 | * 8 | * バイトコード上は lookupswitch と tableswitch があるが、 9 | * 分岐条件をドキュメントで扱っていないのでこのクラス上での差はない。 10 | * 11 | * @see tableswitch 12 | * @see lookupswitcha> 13 | */ 14 | public record SwitchInstruction(JumpTarget defaultTarget, 15 | List caseTargets) implements Instruction { 16 | 17 | public static SwitchInstruction lookup(String defaultTarget, List caseTargets) { 18 | return new SwitchInstruction( 19 | new JumpTarget(defaultTarget), 20 | caseTargets.stream().map(JumpTarget::new).toList() 21 | ); 22 | } 23 | 24 | public static SwitchInstruction table(String defaultTarget, List caseTargets) { 25 | return new SwitchInstruction( 26 | new JumpTarget(defaultTarget), 27 | caseTargets.stream().map(JumpTarget::new).toList() 28 | ); 29 | } 30 | } -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/instruction/TryCatchInstruction.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.instruction; 2 | 3 | public record TryCatchInstruction(JumpTarget start, 4 | JumpTarget end, 5 | JumpTarget handler, 6 | String type) implements Instruction { 7 | } 8 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/instruction/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * メソッドで行われる命令 3 | */ 4 | package org.dddjava.jig.domain.model.data.members.instruction; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/methods/JigMethodAttribute.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.methods; 2 | 3 | import org.dddjava.jig.domain.model.data.members.JigMemberVisibility; 4 | import org.dddjava.jig.domain.model.data.types.JigAnnotationReference; 5 | import org.dddjava.jig.domain.model.data.types.JigTypeReference; 6 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 7 | 8 | import java.util.Collection; 9 | import java.util.EnumSet; 10 | import java.util.List; 11 | import java.util.function.Function; 12 | import java.util.stream.Stream; 13 | 14 | record JigMethodAttribute(JigMemberVisibility jigMemberVisibility, 15 | Collection declarationAnnotations, 16 | JigTypeReference returnType, 17 | List argumentList, 18 | Collection throwTypes, 19 | EnumSet flags) { 20 | 21 | public Stream associatedTypeStream() { 22 | return Stream.of( 23 | declarationAnnotations.stream().flatMap(JigAnnotationReference::allTypeIentifierStream), 24 | returnType.allTypeIentifierStream().filter(typeIdentifier -> !typeIdentifier.isVoid()), 25 | argumentList.stream().flatMap(JigTypeReference::allTypeIentifierStream), 26 | throwTypes.stream().flatMap(JigTypeReference::allTypeIentifierStream)) 27 | .flatMap(Function.identity()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/methods/JigMethodFlag.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.members.methods; 2 | 3 | /** 4 | * Methodの扱うaccess_flagsのうち、可視性と所有関係を除くもの。 5 | * 6 | * @see 4.6 Methods 7 | */ 8 | public enum JigMethodFlag { 9 | /** 10 | * synchronizedメソッド 11 | */ 12 | SYNCHRONIZED, 13 | /** 14 | * コンパイラによって生成されるブリッジメソッド 15 | */ 16 | BRIDGE(true), 17 | /** 18 | * 可変長引数を持つ 19 | */ 20 | VARARGS, 21 | /** 22 | * nativeメソッド 23 | */ 24 | NATIVE, 25 | /** 26 | * abstractメソッド 27 | */ 28 | ABSTRACT, 29 | /** 30 | * strictfpメソッド。廃止されているが定義としてあるので列挙はしておく。 31 | */ 32 | STRICT, 33 | /** 34 | * コンパイラによって生成される合成メソッド 35 | */ 36 | SYNTHETIC(true), 37 | 38 | // -- JIG独自フラグ 39 | /** 40 | * インスタンスイニシャライザおよびコンストラクタ 41 | */ 42 | INITIALIZER(true), 43 | /** 44 | * クラスイニシャライザ 45 | */ 46 | STATIC_INITIALIZER(true), 47 | /** 48 | * enumを定義した際に生成されるvalueOfなど 49 | */ 50 | ENUM_SUPPORT(true), 51 | /** 52 | * lambda式を記述した際にコンパイラによって生成される 53 | */ 54 | LAMBDA_SUPPORT(true), 55 | /** 56 | * recordを定義した際に生成されるアクセサ 57 | */ 58 | RECORD_COMPONENT_ACCESSOR(true); 59 | 60 | private final boolean compilerGenerated; 61 | 62 | JigMethodFlag() { 63 | this(false); 64 | } 65 | 66 | JigMethodFlag(boolean compilerGenerated) { 67 | this.compilerGenerated = compilerGenerated; 68 | } 69 | 70 | public boolean compilerGenerated() { 71 | return compilerGenerated; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/members/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * メンバ 3 | */ 4 | package org.dddjava.jig.domain.model.data.members; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * データ 3 | * 4 | * ソースから生成したもの。任意のソースから生成される。 5 | * JIGの情報はこのデータを元にする。 6 | */ 7 | package org.dddjava.jig.domain.model.data; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/packages/PackageDepth.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.packages; 2 | 3 | /** 4 | * パッケージの深さ 5 | */ 6 | public class PackageDepth { 7 | int value; 8 | 9 | public PackageDepth(int value) { 10 | this.value = value; 11 | } 12 | 13 | public int value() { 14 | return value; 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return Integer.toString(value); 20 | } 21 | 22 | public boolean just(PackageDepth other) { 23 | return this.value == other.value; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/packages/PackageIdentifiers.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.packages; 2 | 3 | import java.util.Comparator; 4 | import java.util.Set; 5 | import java.util.stream.Collectors; 6 | 7 | /** 8 | * パッケージ識別子一覧 9 | */ 10 | public record PackageIdentifiers(Set identifiers) { 11 | 12 | public PackageIdentifiers applyDepth(PackageDepth packageDepth) { 13 | Set set = identifiers.stream() 14 | .map(identifier -> identifier.applyDepth(packageDepth)) 15 | .collect(Collectors.toSet()); 16 | return new PackageIdentifiers(set); 17 | } 18 | 19 | public PackageDepth maxDepth() { 20 | return identifiers.stream() 21 | .map(PackageIdentifier::depth) 22 | .max(Comparator.comparing(PackageDepth::value)) 23 | .orElseGet(() -> new PackageDepth(0)); 24 | } 25 | 26 | public PackageNumber number() { 27 | return new PackageNumber(identifiers.size()); 28 | } 29 | 30 | public boolean isEmpty() { 31 | return identifiers.isEmpty(); 32 | } 33 | 34 | public PackageIdentifiers parent() { 35 | return applyDepth(new PackageDepth(maxDepth().value() - 1)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/packages/PackageNumber.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.packages; 2 | 3 | import java.util.Locale; 4 | 5 | /** 6 | * パッケージ数 7 | */ 8 | public class PackageNumber { 9 | long value; 10 | 11 | public PackageNumber(long value) { 12 | this.value = value; 13 | } 14 | 15 | public String asText() { 16 | return Long.toString(value); 17 | } 18 | 19 | public String localizedLabel() { 20 | Locale locale = Locale.getDefault(); 21 | boolean isEnglish = locale.getLanguage().equals("en"); 22 | return (isEnglish ? "Packages: " : "パッケージ数: ") + value; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/packages/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * パッケージ 3 | */ 4 | package org.dddjava.jig.domain.model.data.packages; 5 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/rdbaccess/MyBatisStatement.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.rdbaccess; 2 | 3 | /** 4 | * SQL 5 | */ 6 | public class MyBatisStatement { 7 | 8 | MyBatisStatementId identifier; 9 | Query query; 10 | SqlType sqlType; 11 | 12 | public MyBatisStatement(MyBatisStatementId identifier, Query query, SqlType sqlType) { 13 | this.identifier = identifier; 14 | this.query = query; 15 | this.sqlType = sqlType; 16 | } 17 | 18 | public SqlType sqlType() { 19 | return sqlType; 20 | } 21 | 22 | public Tables tables() { 23 | return query.extractTable(sqlType); 24 | 25 | } 26 | 27 | public MyBatisStatementId identifier() { 28 | return identifier; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/rdbaccess/Query.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.rdbaccess; 2 | 3 | /** 4 | * クエリ 5 | */ 6 | public class Query { 7 | 8 | String text; 9 | 10 | public Query(String text) { 11 | this.text = text; 12 | } 13 | 14 | public Tables extractTable(SqlType sqlType) { 15 | Table table = text == null ? sqlType.unexpectedTable() : sqlType.extractTable(text); 16 | return new Tables(table); 17 | } 18 | 19 | public static Query unsupported() { 20 | return new Query(null); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/rdbaccess/SqlReadStatus.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.rdbaccess; 2 | 3 | public enum SqlReadStatus { 4 | 成功, 5 | SQLなし, 6 | 読み取り失敗あり, 7 | 失敗, 8 | 未処理; 9 | 10 | public boolean not正常() { 11 | return this != 成功; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/rdbaccess/SqlType.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.rdbaccess; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import java.util.List; 7 | import java.util.regex.Matcher; 8 | import java.util.regex.Pattern; 9 | import java.util.stream.Stream; 10 | 11 | /** 12 | * SQLの種類 13 | */ 14 | public enum SqlType { 15 | INSERT("insert\\s+into\\s+([^\\s(]+).+"), 16 | SELECT("select.+\\sfrom\\s+([^\\s(]+)\\b.*", 17 | "select\\s+(nextval\\('.+'\\)).*"), 18 | UPDATE("update\\s+([^\\s(]+)\\s.+"), 19 | DELETE("delete\\s+from\\s+([^\\s(]+)\\b.*"); 20 | 21 | private static final Logger logger = LoggerFactory.getLogger(SqlType.class); 22 | private final List patterns; 23 | 24 | SqlType(String... patterns) { 25 | this.patterns = Stream.of(patterns) 26 | .map(pattern -> Pattern.compile(pattern, Pattern.CASE_INSENSITIVE)) 27 | .toList(); 28 | } 29 | 30 | public Table extractTable(String sql) { 31 | for (Pattern pattern : patterns) { 32 | Matcher matcher = pattern.matcher(sql.replaceAll("\n", " ")); 33 | if (matcher.matches()) { 34 | return new Table(matcher.group(1)); 35 | } 36 | } 37 | 38 | logger.warn("{} としてテーブル名が解析できませんでした。 [{}]", this, sql); 39 | return unexpectedTable(); 40 | } 41 | 42 | public Table unexpectedTable() { 43 | return new Table("(解析失敗)"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/rdbaccess/Table.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.rdbaccess; 2 | 3 | /** 4 | * テーブル 5 | */ 6 | public class Table { 7 | 8 | String value; 9 | 10 | public Table(String value) { 11 | this.value = value; 12 | } 13 | 14 | String name() { 15 | return value; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/rdbaccess/Tables.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.rdbaccess; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | 8 | /** 9 | * テーブル一覧 10 | */ 11 | public class Tables { 12 | private final List tables; 13 | 14 | public Tables(Table table) { 15 | this(Collections.singletonList(table)); 16 | } 17 | 18 | private Tables(List
tables) { 19 | this.tables = tables; 20 | } 21 | 22 | public static Tables nothing() { 23 | return new Tables(Collections.emptyList()); 24 | } 25 | 26 | public Tables merge(Tables other) { 27 | ArrayList
list = new ArrayList<>(this.tables); 28 | list.addAll(other.tables); 29 | return new Tables(list); 30 | } 31 | 32 | public String asText() { 33 | // 文字列としてユニーク。ソートされてるのは自然なのでメソッド名に含めない。 34 | return tables.stream() 35 | .map(Table::name) 36 | .distinct() 37 | .sorted() 38 | .collect(Collectors.joining(", ", "[", "]")); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/rdbaccess/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * RDBへのアクセス 3 | */ 4 | package org.dddjava.jig.domain.model.data.rdbaccess; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/terms/Glossary.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.terms; 2 | 3 | import java.util.Collection; 4 | import java.util.Comparator; 5 | import java.util.List; 6 | 7 | /** 8 | * 用語集 9 | */ 10 | public record Glossary(Collection terms) { 11 | 12 | public List list() { 13 | return terms.stream() 14 | .sorted(Comparator.comparing(Term::title).thenComparing(term -> term.identifier().asText())) 15 | .toList(); 16 | } 17 | 18 | public Collection findRelated(TermIdentifier termIdentifier) { 19 | return terms.stream() 20 | .filter(term -> term.relatesTo(termIdentifier)) 21 | .toList(); 22 | } 23 | 24 | public Term termOf(String idText, TermKind termKind) { 25 | TermIdentifier termIdentifier = new TermIdentifier(idText); 26 | return terms.stream() 27 | .filter(term -> term.termKind() == termKind) 28 | .filter(term -> term.identifier().equals(termIdentifier)) 29 | .findAny() 30 | .orElseGet(() -> Term.simple(termIdentifier, termIdentifier.simpleText(), termKind)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/terms/Term.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.terms; 2 | 3 | /** 4 | * 用語 5 | */ 6 | public record Term(TermIdentifier identifier, 7 | String title, 8 | String description, 9 | TermKind termKind, 10 | Object additionalInformation) { 11 | public Term { 12 | title = title.isEmpty() ? identifier.simpleText() : title; 13 | } 14 | 15 | public Term(TermIdentifier identifier, String title, String description, TermKind termKind) { 16 | this(identifier, title, description.trim(), termKind, null); 17 | } 18 | 19 | public static Term simple(TermIdentifier termIdentifier, String title, TermKind termKind) { 20 | return new Term(termIdentifier, title, "", termKind); 21 | } 22 | 23 | public String simpleText() { 24 | return identifier.simpleText(); 25 | } 26 | 27 | public String titleAndSimpleName(String delimiter) { 28 | String identifierSimpleText = simpleText(); 29 | if (title.isEmpty() || title.equals(identifierSimpleText)) return identifierSimpleText; 30 | return title + delimiter + identifierSimpleText; 31 | } 32 | 33 | /** 34 | * 用語の関連をIDで判定する 35 | * 36 | * 前方一致していれば関連していると見做す 37 | */ 38 | public boolean relatesTo(TermIdentifier otherIdentifier) { 39 | return identifier().asText().startsWith(otherIdentifier.asText()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/terms/TermIdentifier.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.terms; 2 | 3 | /** 4 | * 用語の識別子 5 | */ 6 | public record TermIdentifier(String value) { 7 | 8 | public String asText() { 9 | return value; 10 | } 11 | 12 | String simpleText() { 13 | int methodStart = value.indexOf('#'); 14 | if (methodStart == -1) { 15 | int lastDot = value.lastIndexOf('.'); 16 | 17 | return lastDot != -1 ? value.substring(lastDot + 1) : value; 18 | } 19 | 20 | int argStart = value.indexOf('('); 21 | if (argStart == -1) { 22 | // ないはず 23 | return value; 24 | } 25 | return value.substring(methodStart + 1, argStart); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/terms/TermKind.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.terms; 2 | 3 | /** 4 | * 用語の種類 5 | */ 6 | public enum TermKind { 7 | パッケージ, 8 | クラス, 9 | フィールド, 10 | メソッド 11 | } 12 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/terms/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 用語 3 | */ 4 | package org.dddjava.jig.domain.model.data.terms; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/types/JavaTypeDeclarationKind.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.types; 2 | 3 | /** 4 | * 実装上の型の種類。 5 | * Java言語の型宣言におけるクラス(class, enum, record)とインタフェース(interface, @interface)に対応する。 6 | * 7 | * @see Classes 8 | * @see Interfaces 9 | */ 10 | public enum JavaTypeDeclarationKind { 11 | CLASS, 12 | INTERFACE, 13 | ANNOTATION, 14 | ENUM, 15 | RECORD 16 | } 17 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/types/JigAnnotationReference.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.types; 2 | 3 | import java.util.Collection; 4 | import java.util.List; 5 | import java.util.Optional; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.Stream; 8 | 9 | /** 10 | * 宣言アノテーションや型アノテーションとして記述されたアノテーション 11 | * 12 | * @param id アノテーションの型を示すID 13 | * @param elements 要素 14 | */ 15 | public record JigAnnotationReference(TypeIdentifier id, 16 | Collection elements) { 17 | 18 | public static JigAnnotationReference from(TypeIdentifier typeIdentifier) { 19 | return new JigAnnotationReference(typeIdentifier, List.of()); 20 | } 21 | 22 | public String simpleTypeName() { 23 | return id.asSimpleText(); 24 | } 25 | 26 | public Stream allTypeIentifierStream() { 27 | // TODO elementがclassやannotationの場合に追加する 28 | return Stream.of(id); 29 | } 30 | 31 | public Optional elementTextOf(String name) { 32 | return elements.stream() 33 | .filter(element -> element.name().equals(name)) 34 | .map(element -> element.valueAsString()) 35 | .findAny(); 36 | } 37 | 38 | public String asText() { 39 | return elements.stream() 40 | .map(element -> "%s=%s".formatted(element.name(), element.valueAsString())) 41 | .collect(Collectors.joining(", ", "[", "]")); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/types/JigBaseTypeDataBundle.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.types; 2 | 3 | import java.util.Collection; 4 | import java.util.List; 5 | import java.util.Optional; 6 | import java.util.Set; 7 | import java.util.stream.Collectors; 8 | import java.util.stream.Stream; 9 | 10 | /** 11 | * @param superType 親クラスの完全修飾クラス名。classの場合は未指定でもObjectが入るが、interfaceなどではempty。 12 | * @param interfaceTypes 実装インタフェースの完全修飾クラス名 13 | */ 14 | public record JigBaseTypeDataBundle( 15 | Optional superType, 16 | Collection interfaceTypes) { 17 | public static JigBaseTypeDataBundle simple() { 18 | return new JigBaseTypeDataBundle(Optional.of(JigTypeReference.fromId(TypeIdentifier.from(Object.class))), List.of()); 19 | } 20 | 21 | public Set typeIdSet() { 22 | return Stream.concat(superType.stream(), interfaceTypes.stream()) 23 | .flatMap(jigBaseTypeData -> Stream.concat( 24 | Stream.of(jigBaseTypeData.id()), 25 | jigBaseTypeData.typeArgumentList().stream() 26 | .map(JigTypeArgument::value) 27 | .map(value -> TypeIdentifier.valueOf(value)) 28 | )) 29 | // "." の含まれていないものは型パラメタとして扱う。デフォルトパッケージのクラスも該当してしまうが、良しとする。 30 | .filter(jigTypeHeaderJigObjectId -> jigTypeHeaderJigObjectId.value().contains(".")) 31 | .collect(Collectors.toSet()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/types/JigTypeArgument.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.types; 2 | 3 | /** 4 | * 型引数 5 | * 6 | * {@link JigTypeParameter 型パラメタ} に対する、具体的な引数。 7 | * 8 | * TODO wildcard対応 9 | */ 10 | public record JigTypeArgument(JigTypeReference jigTypeReference, String wildcard) { 11 | 12 | public static JigTypeArgument primitive(String value) { 13 | return new JigTypeArgument(JigTypeReference.fromId(value), "="); 14 | } 15 | 16 | /** 17 | * ワイルドカードなし 18 | */ 19 | public static JigTypeArgument just(String value) { 20 | return just(JigTypeReference.fromId(value)); 21 | } 22 | 23 | public static JigTypeArgument just(JigTypeReference jigTypeReference) { 24 | return new JigTypeArgument(jigTypeReference, "="); 25 | } 26 | 27 | public String simpleNameWithGenerics() { 28 | return jigTypeReference.simpleNameWithGenerics(); 29 | } 30 | 31 | public boolean notObject() { 32 | return !"java.lang.Object".equals(value()); 33 | } 34 | 35 | public TypeIdentifier typeIdentifier() { 36 | return TypeIdentifier.valueOf(value()); 37 | } 38 | 39 | public String value() { 40 | return jigTypeReference.id().value(); 41 | } 42 | 43 | public String fqnWithGenerics() { 44 | return jigTypeReference.fqnWithGenerics(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/types/JigTypeModifier.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.types; 2 | 3 | /** 4 | * Java言語によるクラス修飾子およびインスタンス修飾子のうち、可視性とアノテーションを除くもの。 5 | * JLSではstrictfpもあるが、使用しないので扱わない。 6 | * 7 | * @see ClassModifier 8 | * @see InstanceModifier 9 | */ 10 | public enum JigTypeModifier { 11 | ABSTRACT, 12 | FINAL, 13 | STATIC, 14 | SEALED, 15 | NON_SEALED 16 | } 17 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/types/JigTypeParameter.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.types; 2 | 3 | import java.util.List; 4 | 5 | import static java.util.stream.Collectors.joining; 6 | 7 | /** 8 | * 型パラメタ 9 | * 10 | * @param name パラメタ名。 `T` などが慣習的に使用されるが、慣習。 11 | * @param bounds 境界型引数 12 | */ 13 | public record JigTypeParameter(String name, List bounds) { 14 | 15 | public String nameAndBounds() { 16 | List outputBounds = this.bounds.stream() 17 | .filter(jigTypeArgument -> jigTypeArgument.notObject()) 18 | .toList(); 19 | return outputBounds.isEmpty() 20 | ? name() 21 | : name() + outputBounds.stream() 22 | .map(jigTypeArgument -> jigTypeArgument.simpleNameWithGenerics()) 23 | .collect(joining(" & ", " extends ", "")); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/types/JigTypeVisibility.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.data.types; 2 | 3 | /** 4 | * 型の可視性 5 | * 6 | * ソースコードではpublic,protected,privateが記述できますが、バイトコードではpublicか否かしかありません。 7 | * 8 | * JVMS/Chapter 4. The class File Format/4.1. The ClassFile Structure/Table 4.1-B. Class access and property modifiers 9 | */ 10 | public enum JigTypeVisibility { 11 | PUBLIC, 12 | NOT_PUBLIC 13 | } 14 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/data/types/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 型 3 | * 4 | * Javaでの宣言部分に由来するもの。メンバを含まない。 5 | */ 6 | package org.dddjava.jig.domain.model.data.types; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/diagrams/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 図 3 | */ 4 | package org.dddjava.jig.domain.model.documents.diagrams; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/documentformat/DocumentName.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.documents.documentformat; 2 | 3 | public class DocumentName { 4 | 5 | JigDocument jigDocument; 6 | String fileName; 7 | String label; 8 | 9 | DocumentName(JigDocument jigDocument, String fileName) { 10 | this.jigDocument = jigDocument; 11 | this.fileName = fileName; 12 | this.label = jigDocument.label(); 13 | } 14 | 15 | public static DocumentName of(JigDocument jigDocument) { 16 | return new DocumentName(jigDocument, jigDocument.fileName()); 17 | } 18 | 19 | public DocumentName withSuffix(String suffix) { 20 | return new DocumentName(this.jigDocument, this.fileName + suffix); 21 | } 22 | 23 | public String withExtension(JigDiagramFormat jigDiagramFormat) { 24 | return fileName + jigDiagramFormat.extension(); 25 | } 26 | 27 | public String fileName() { 28 | return fileName; 29 | } 30 | 31 | public String label() { 32 | return label; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/documentformat/JigDiagramFormat.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.documents.documentformat; 2 | 3 | import java.util.Locale; 4 | 5 | public enum JigDiagramFormat { 6 | SVG, 7 | PNG, 8 | DOT; 9 | 10 | public String extension() { 11 | return '.' + lowerCase(); 12 | } 13 | 14 | private String lowerCase() { 15 | return name().toLowerCase(Locale.ENGLISH); 16 | } 17 | 18 | public String dotOption() { 19 | return "-T" + lowerCase(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/documentformat/JigDocumentLabel.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.documents.documentformat; 2 | 3 | public class JigDocumentLabel { 4 | String japanese; 5 | String english; 6 | 7 | private JigDocumentLabel(String japanese, String english) { 8 | this.japanese = japanese; 9 | this.english = english; 10 | } 11 | 12 | public static JigDocumentLabel of(String japanese, String english) { 13 | return new JigDocumentLabel(japanese, english); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/documentformat/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JIGドキュメントの書式 3 | */ 4 | package org.dddjava.jig.domain.model.documents.documentformat; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JIGドキュメント 3 | */ 4 | package org.dddjava.jig.domain.model.documents; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/stationery/AdditionalText.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.documents.stationery; 2 | 3 | public record AdditionalText(String value) { 4 | 5 | public static AdditionalText empty() { 6 | return new AdditionalText(null); 7 | } 8 | 9 | public boolean enable() { 10 | return value != null; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/stationery/DiagramSourceWriter.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.documents.stationery; 2 | 3 | /** 4 | * DiagramSourcesを出力できる 5 | */ 6 | public interface DiagramSourceWriter { 7 | 8 | default DiagramSources sources(JigDocumentContext jigDocumentContext) { 9 | return sources(); 10 | } 11 | 12 | default DiagramSources sources() { 13 | throw new UnsupportedOperationException(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/stationery/DiagramSources.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.documents.stationery; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | import java.util.function.Consumer; 6 | 7 | public class DiagramSources { 8 | List diagramSources; 9 | 10 | public DiagramSources(List diagramSources) { 11 | this.diagramSources = diagramSources; 12 | } 13 | 14 | public static DiagramSources empty() { 15 | return new DiagramSources(Collections.emptyList()); 16 | } 17 | 18 | public boolean noEntity() { 19 | return diagramSources.isEmpty(); 20 | } 21 | 22 | public void each(Consumer consumer) { 23 | diagramSources.forEach(consumer); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/stationery/JigDiagramOption.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.documents.stationery; 2 | 3 | import org.dddjava.jig.domain.model.documents.documentformat.JigDiagramFormat; 4 | 5 | /** 6 | * ダイアグラム出力オプション 7 | * @param graphvizOutputFormat graphvizの出力フォーマット 8 | * @param transitiveReduction 推移簡約をするかどうか 9 | */ 10 | public record JigDiagramOption( 11 | JigDiagramFormat graphvizOutputFormat, 12 | boolean transitiveReduction 13 | ) { 14 | } 15 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/stationery/JigDocumentContext.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.documents.stationery; 2 | 3 | import org.dddjava.jig.domain.model.data.packages.PackageIdentifier; 4 | import org.dddjava.jig.domain.model.data.terms.Term; 5 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 6 | import org.dddjava.jig.domain.model.documents.documentformat.JigDocument; 7 | 8 | import java.nio.file.Path; 9 | import java.util.List; 10 | 11 | public interface JigDocumentContext { 12 | 13 | Term packageTerm(PackageIdentifier packageIdentifier); 14 | 15 | Term typeTerm(TypeIdentifier typeIdentifier); 16 | 17 | Path outputDirectory(); 18 | 19 | List jigDocuments(); 20 | 21 | JigDiagramOption diagramOption(); 22 | } 23 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/stationery/JigPropertyHolder.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.documents.stationery; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import java.util.Map; 7 | import java.util.Optional; 8 | import java.util.Properties; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | public class JigPropertyHolder { 12 | static Logger logger = LoggerFactory.getLogger(JigPropertyHolder.class); 13 | private static final JigPropertyHolder INSTANCE = new JigPropertyHolder(); 14 | 15 | public static JigPropertyHolder getInstance() { 16 | return INSTANCE; 17 | } 18 | 19 | private JigPropertyHolder() { 20 | } 21 | 22 | private final Map map = new ConcurrentHashMap<>(); 23 | 24 | public void load(Properties input) { 25 | input.forEach((key, value) -> map.put(String.valueOf(key), String.valueOf(value))); 26 | logger.info("loaded property {}", input); 27 | } 28 | 29 | public Optional get(String key) { 30 | return Optional.ofNullable(map.get(key)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/stationery/NodeRole.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.documents.stationery; 2 | 3 | import java.util.function.Function; 4 | 5 | /** 6 | * ダイアグラムでのNodeの役割 7 | * 8 | * 色と文字サイズで表現する。 9 | * 何にどのタイプを使用するかは各ダイアグラムで決める。 10 | */ 11 | public enum NodeRole { 12 | 主役(node -> node.fillColor("lightgoldenrod")), 13 | 準主役(node -> node.fillColor("lemonchiffon")), 14 | 脇役(node -> node.fillColor("whitesmoke")), 15 | モブ(node -> node.fillColor("lightgray")); 16 | final Function editor; 17 | 18 | NodeRole(Function editor) { 19 | this.editor = editor; 20 | } 21 | 22 | Node edit(Node node) { 23 | return editor.apply(node); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/stationery/Subgraph.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.documents.stationery; 2 | 3 | import java.util.StringJoiner; 4 | import java.util.stream.Stream; 5 | 6 | public class Subgraph { 7 | StringJoiner stringJoiner; 8 | 9 | public Subgraph(String name) { 10 | stringJoiner = new StringJoiner("\n", "subgraph \"cluster_" + name + "\" {\n", "\n}"); 11 | } 12 | 13 | public Subgraph label(String label) { 14 | return add("label=\"" + label + "\";"); 15 | } 16 | 17 | public Subgraph borderWidth(int width) { 18 | return add("penwidth=" + width + ";"); 19 | } 20 | 21 | public Subgraph color(String color) { 22 | return add("color=\"" + color + "\";"); 23 | } 24 | 25 | public Subgraph fillColor(String color) { 26 | return add("style=filled;fillcolor=\"" + color + "\";"); 27 | } 28 | 29 | public Subgraph add(CharSequence charSequence) { 30 | stringJoiner.add(charSequence); 31 | return this; 32 | } 33 | 34 | public Subgraph addNodes(Stream nodes) { 35 | // うけとったStreamの終端操作しちゃうのはどうなのよと思いつつ 36 | nodes.map(Node::asText).forEach(this::add); 37 | return this; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return stringJoiner.toString(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/documents/stationery/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 文房具 3 | */ 4 | package org.dddjava.jig.domain.model.documents.stationery; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/Architecture.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information; 2 | 3 | 4 | import org.dddjava.jig.domain.model.information.types.JigType; 5 | 6 | /** 7 | * アーキテクチャ 8 | */ 9 | public interface Architecture { 10 | 11 | boolean isCoreDomain(JigType jigType); 12 | } 13 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/JigRepository.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information; 2 | 3 | import org.dddjava.jig.application.JigDataProvider; 4 | import org.dddjava.jig.domain.model.data.terms.Glossary; 5 | import org.dddjava.jig.domain.model.information.types.JigTypes; 6 | 7 | import java.util.List; 8 | 9 | public interface JigRepository { 10 | 11 | static JigRepository empty() { 12 | return new JigRepository() { 13 | @Override 14 | public JigTypes fetchJigTypes() { 15 | return new JigTypes(List.of()); 16 | } 17 | 18 | @Override 19 | public JigDataProvider jigDataProvider() { 20 | return JigDataProvider.none(); 21 | } 22 | 23 | @Override 24 | public Glossary fetchGlossary() { 25 | return new Glossary(List.of()); 26 | } 27 | }; 28 | } 29 | 30 | JigTypes fetchJigTypes(); 31 | 32 | /** 33 | * JigTypesを通さずにdataにアクセスが必要な時に呼び出すブリッジ 34 | * 使用箇所が増える場合は見直した方がいいかもしれない。 35 | */ 36 | JigDataProvider jigDataProvider(); 37 | 38 | Glossary fetchGlossary(); 39 | } 40 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/applications/ServiceMethods.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.applications; 2 | 3 | import org.dddjava.jig.domain.model.data.members.methods.JigMethodIdentifier; 4 | import org.dddjava.jig.domain.model.information.relation.methods.CallerMethodsFactory; 5 | import org.dddjava.jig.domain.model.information.types.JigTypes; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * サービスメソッド一覧 11 | */ 12 | public record ServiceMethods(List list) { 13 | 14 | public static ServiceMethods from(JigTypes serviceJigTypes, CallerMethodsFactory callerMethodsFactory) { 15 | var list = serviceJigTypes.orderedStream() 16 | .flatMap(jigType -> jigType.instanceJigMethodStream()) 17 | .map(method -> ServiceMethod.from(method, callerMethodsFactory)) 18 | .toList(); 19 | return new ServiceMethods(list); 20 | } 21 | 22 | public boolean empty() { 23 | return list().isEmpty(); 24 | } 25 | 26 | public boolean contains(JigMethodIdentifier jigMethodIdentifier) { 27 | return list().stream() 28 | .anyMatch(serviceMethod -> serviceMethod.method().jigMethodIdentifier().equals(jigMethodIdentifier)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/applications/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 機能 3 | */ 4 | package org.dddjava.jig.domain.model.information.applications; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/inputs/EntrypointGroup.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.inputs; 2 | 3 | import org.dddjava.jig.domain.model.information.types.JigType; 4 | 5 | import java.util.Collection; 6 | import java.util.Optional; 7 | 8 | /** 9 | * エントリーポイントメソッドのグループ。 10 | * グルーピング単位はクラス。 11 | * 12 | * - SpringMVCのControllerのRequestMapping 13 | * - SpringRabbitのRabbitListener 14 | */ 15 | public record EntrypointGroup(JigType jigType, Collection entrypointMethods) { 16 | public EntrypointGroup { 17 | if (entrypointMethods.isEmpty()) throw new IllegalArgumentException("entrypointMethods is empty"); 18 | } 19 | 20 | static Optional from(EntrypointMethodDetector entrypointMethodDetector, JigType jigType) { 21 | var entrypointMethods = entrypointMethodDetector.collectMethod(jigType); 22 | if (!entrypointMethods.isEmpty()) { 23 | return Optional.of(new EntrypointGroup(jigType, entrypointMethods)); 24 | } 25 | // not entrypoint 26 | return Optional.empty(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/inputs/EntrypointMethod.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.inputs; 2 | 3 | import org.dddjava.jig.domain.model.data.packages.PackageIdentifier; 4 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 5 | import org.dddjava.jig.domain.model.information.members.CallerMethods; 6 | import org.dddjava.jig.domain.model.information.members.JigMethod; 7 | import org.dddjava.jig.domain.model.information.types.JigType; 8 | 9 | /** 10 | * ハンドラ 11 | * 12 | * 外部からのリクエストを受け取る起点となるメソッドです。 13 | * 制限事項:RequestMappingをメタアノテーションとした独自アノテーションが付与されたメソッドは、ハンドラとして扱われません。 14 | */ 15 | public record EntrypointMethod(EntrypointType entrypointType, JigType jigType, JigMethod jigMethod) { 16 | 17 | public boolean anyMatch(CallerMethods callerMethods) { 18 | return callerMethods.contains(jigMethod.jigMethodIdentifier()); 19 | } 20 | 21 | public TypeIdentifier typeIdentifier() { 22 | return jigType.id(); 23 | } 24 | 25 | public PackageIdentifier packageIdentifier() { 26 | return jigType.packageIdentifier(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/inputs/EntrypointType.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.inputs; 2 | 3 | public enum EntrypointType { 4 | HTTP_API, 5 | QUEUE_LISTENER, 6 | OTHER; 7 | } 8 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/inputs/QueueListener.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.inputs; 2 | 3 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 4 | 5 | public record QueueListener(EntrypointMethod entrypointMethod) { 6 | 7 | public static QueueListener from(EntrypointMethod entrypointMethod) { 8 | return new QueueListener(entrypointMethod); 9 | } 10 | 11 | public String queueName() { 12 | return entrypointMethod.jigMethod().declarationAnnotationStream() 13 | .filter(jigAnnotationReference -> jigAnnotationReference.id().equals(TypeIdentifier.valueOf("org.springframework.amqp.rabbit.annotation.RabbitListener"))) 14 | .map(jigAnnotationReference -> { 15 | // queueは複数記述できるが、たぶんしないので一件目をとってくる 16 | return jigAnnotationReference.elementTextOf("queues").orElse("???"); 17 | }) 18 | // RabbitListenerアノテーションは複数取れないはずなのでAnyでOK。 19 | .findAny() 20 | .orElse("???"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/inputs/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 入力アダプタ 3 | * 4 | * HTTP APIのエンドポイントとなるController、キューなどのListener、スケジューラーなど、アプリケーションとして処理の起点となるところ。 5 | */ 6 | package org.dddjava.jig.domain.model.information.inputs; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/members/CallerMethods.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.members; 2 | 3 | import org.dddjava.jig.domain.model.data.members.methods.JigMethodIdentifier; 4 | 5 | import java.util.Collection; 6 | import java.util.Set; 7 | import java.util.function.Predicate; 8 | 9 | /** 10 | * 呼び出しメソッド一覧 11 | */ 12 | public record CallerMethods(Set methodIdentifiers) { 13 | 14 | public boolean contains(JigMethodIdentifier jigMethodIdentifier) { 15 | return methodIdentifiers.stream() 16 | .anyMatch(item -> item.equals(jigMethodIdentifier)); 17 | } 18 | 19 | public int size() { 20 | return methodIdentifiers.size(); 21 | } 22 | 23 | public Collection filter(Predicate predicate) { 24 | return methodIdentifiers.stream().filter(predicate).toList(); 25 | } 26 | 27 | public long typeCount() { 28 | return methodIdentifiers.stream().map(JigMethodIdentifier::namespace).distinct().count(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/members/JigField.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.members; 2 | 3 | import org.dddjava.jig.domain.model.data.members.fields.JigFieldHeader; 4 | import org.dddjava.jig.domain.model.data.terms.Term; 5 | import org.dddjava.jig.domain.model.data.types.JigTypeReference; 6 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 7 | 8 | /** 9 | * フィールド  10 | */ 11 | public record JigField(JigFieldHeader jigFieldHeader, Term term) { 12 | 13 | public static JigField from(JigFieldHeader jigFieldHeader, Term term) { 14 | return new JigField(jigFieldHeader, term); 15 | } 16 | 17 | public JigTypeReference jigTypeReference() { 18 | return jigFieldHeader.jigTypeReference(); 19 | } 20 | 21 | public TypeIdentifier typeIdentifier() { 22 | return jigFieldHeader.jigTypeReference().id(); 23 | } 24 | 25 | public String nameText() { 26 | return jigFieldHeader.name(); 27 | } 28 | 29 | public boolean isDeprecated() { 30 | return jigFieldHeader.isDeprecated(); 31 | } 32 | 33 | public String simpleNameWithGenerics() { 34 | return jigFieldHeader.simpleNameWithGenerics(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/members/JigFields.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.members; 2 | 3 | import java.util.Collection; 4 | 5 | public record JigFields(Collection fields) { 6 | 7 | public boolean empty() { 8 | return fields.isEmpty(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/members/UsingFields.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.members; 2 | 3 | import org.dddjava.jig.domain.model.data.members.fields.JigFieldIdentifier; 4 | import org.dddjava.jig.domain.model.data.members.instruction.Instructions; 5 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 6 | 7 | import java.util.Collection; 8 | import java.util.stream.Collectors; 9 | 10 | /** 11 | * メソッドが使用しているフィールド 12 | */ 13 | public class UsingFields { 14 | private final Collection fieldIds; 15 | 16 | private UsingFields(Collection fieldIds) { 17 | this.fieldIds = fieldIds; 18 | } 19 | 20 | static UsingFields from(Instructions instructions) { 21 | return new UsingFields(instructions.fieldReferenceStream().toList()); 22 | } 23 | 24 | public String typeNames() { 25 | return fieldIds.stream() 26 | .map(JigFieldIdentifier::declaringTypeIdentifier) 27 | .map(TypeIdentifier::asSimpleText) 28 | .sorted() 29 | .collect(Collectors.joining(", ", "[", "]")); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/module/JigPackage.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.module; 2 | 3 | import org.dddjava.jig.domain.model.data.packages.PackageIdentifier; 4 | import org.dddjava.jig.domain.model.data.terms.Term; 5 | import org.dddjava.jig.domain.model.information.types.JigType; 6 | 7 | import java.util.Collection; 8 | import java.util.List; 9 | 10 | public record JigPackage(PackageIdentifier packageIdentifier, Term term, Collection jigTypes) { 11 | 12 | public JigPackage(PackageIdentifier packageIdentifier, Term term) { 13 | this(packageIdentifier, term, List.of()); 14 | } 15 | 16 | public String simpleName() { 17 | return packageIdentifier.simpleName(); 18 | } 19 | 20 | /** 21 | * FullQualifiedName 22 | */ 23 | public String fqn() { 24 | return packageIdentifier.asText(); 25 | } 26 | 27 | public String label() { 28 | return term.title(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/module/JigPackageWithJigTypes.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.module; 2 | 3 | import org.dddjava.jig.domain.model.data.packages.PackageIdentifier; 4 | import org.dddjava.jig.domain.model.information.types.JigType; 5 | import org.dddjava.jig.domain.model.information.types.JigTypes; 6 | 7 | import java.util.Comparator; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.stream.Collectors; 11 | 12 | /** 13 | * パッケージ単位のJigTypeのグループ 14 | */ 15 | public record JigPackageWithJigTypes(PackageIdentifier packageIdentifier, List jigTypes) { 16 | 17 | public static List from(JigTypes jigTypes) { 18 | Map> map = jigTypes.orderedStream() 19 | .collect(Collectors.groupingBy(JigType::packageIdentifier)); 20 | return map.entrySet().stream() 21 | .map(entity -> new JigPackageWithJigTypes(entity.getKey(), entity.getValue())) 22 | .sorted(Comparator.comparing(jigPackageWithJigTypes -> jigPackageWithJigTypes.packageIdentifier().asText())) 23 | .toList(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/module/JigPackages.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.module; 2 | 3 | import java.util.Collection; 4 | import java.util.Comparator; 5 | import java.util.List; 6 | 7 | public record JigPackages(Collection jigPackages) { 8 | 9 | public List listPackage() { 10 | return jigPackages.stream() 11 | .sorted(Comparator.comparing(JigPackage::fqn)) 12 | .toList(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/outputs/DatasourceMethod.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.outputs; 2 | 3 | import org.dddjava.jig.domain.model.information.members.JigMethod; 4 | import org.dddjava.jig.domain.model.information.members.UsingMethods; 5 | import org.dddjava.jig.domain.model.information.types.JigType; 6 | 7 | /** 8 | * データソースの構造 9 | */ 10 | public record DatasourceMethod(JigMethod repositoryMethod, JigMethod concreteMethod, JigType interfaceJigType) { 11 | 12 | public UsingMethods usingMethods() { 13 | return concreteMethod().usingMethods(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/outputs/RepositoryMethods.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.outputs; 2 | 3 | import org.dddjava.jig.domain.model.data.members.instruction.MethodCall; 4 | import org.dddjava.jig.domain.model.information.members.JigMethod; 5 | 6 | import java.util.List; 7 | 8 | import static java.util.stream.Collectors.collectingAndThen; 9 | import static java.util.stream.Collectors.toList; 10 | 11 | /** 12 | * リポジトリインタフェースメソッド 13 | */ 14 | public class RepositoryMethods { 15 | 16 | List list; 17 | 18 | RepositoryMethods(List list) { 19 | this.list = list; 20 | } 21 | 22 | public RepositoryMethods filter(List methodCalls) { 23 | return list.stream() 24 | .filter(method -> methodCalls.stream().anyMatch(invokedMethod -> invokedMethod.jigMethodIdentifierIs(method.jigMethodIdentifier()))) 25 | .collect(collectingAndThen(toList(), RepositoryMethods::new)); 26 | } 27 | 28 | public List list() { 29 | return list; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/outputs/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 出力アダプタ 3 | * 4 | * データベースアクセスや外部API呼び出しなど。 5 | */ 6 | package org.dddjava.jig.domain.model.information.outputs; 7 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 情報 3 | * 4 | * データに意味を持たせて整理したもの。 5 | * JIGではバイトコードなどのデータからJIGとして扱いたい事柄に変換したものの位置付け。 6 | */ 7 | package org.dddjava.jig.domain.model.information; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/relation/graph/Edge.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.relation.graph; 2 | 3 | import java.util.Collection; 4 | 5 | /** 6 | * 有向グラフの辺 7 | * 8 | * @param from 始点 9 | * @param to 終点 10 | * @param ノードの型 11 | */ 12 | public record Edge(NODE from, NODE to) implements Comparable> { 13 | 14 | public static Edge of(T from, T to) { 15 | return new Edge<>(from, to); 16 | } 17 | 18 | /** 19 | * 両端のノードが指定されたコレクションに含まれているか確認する。 20 | */ 21 | boolean bothEndpointsIn(Collection nodes) { 22 | return nodes.contains(from) && nodes.contains(to); 23 | } 24 | 25 | /** 26 | * ソートのための他のEdgeとの比較処理。 27 | * NODEにインタフェースを持たせていないので、ノードの文字列表現で比較する。 28 | * NODEをComparableに制限してもいいかもしれない。 29 | */ 30 | @Override 31 | public int compareTo(Edge o) { 32 | int fromComparison = this.from.toString().compareTo(o.from.toString()); 33 | return fromComparison != 0 ? fromComparison : this.to.toString().compareTo(o.to.toString()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/relation/graph/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * グラフ 3 | * 4 | * ノードを両端とするEdgeの集合をグラフと呼ぶ。 5 | */ 6 | package org.dddjava.jig.domain.model.information.relation.graph; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/relation/methods/CallerMethodsFactory.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.relation.methods; 2 | 3 | import org.dddjava.jig.domain.model.data.members.methods.JigMethodIdentifier; 4 | import org.dddjava.jig.domain.model.information.members.CallerMethods; 5 | 6 | public interface CallerMethodsFactory { 7 | CallerMethods callerMethodsOf(JigMethodIdentifier jigMethodIdentifier); 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/relation/methods/MethodRelation.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.relation.methods; 2 | 3 | import org.dddjava.jig.domain.model.data.members.methods.JigMethodIdentifier; 4 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 5 | import org.dddjava.jig.domain.model.information.relation.graph.Edge; 6 | 7 | /** 8 | * メソッドの使用しているメソッド 9 | */ 10 | public record MethodRelation(Edge edge) { 11 | 12 | public static MethodRelation from(JigMethodIdentifier from, JigMethodIdentifier to) { 13 | return new MethodRelation(Edge.of(from, to)); 14 | } 15 | 16 | public JigMethodIdentifier from() { 17 | return edge.from(); 18 | } 19 | 20 | public JigMethodIdentifier to() { 21 | return edge.to(); 22 | } 23 | 24 | public boolean calleeMethodIs(JigMethodIdentifier jigMethodIdentifier) { 25 | return to().equals(jigMethodIdentifier); 26 | } 27 | 28 | public TypeIdentifier toType() { 29 | return to().tuple().declaringTypeIdentifier(); 30 | } 31 | 32 | public TypeIdentifier fromType() { 33 | return from().tuple().declaringTypeIdentifier(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/relation/methods/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * メソッドの関連 3 | */ 4 | package org.dddjava.jig.domain.model.information.relation.methods; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/relation/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 関連 3 | * 4 | * JIGの扱う関連および関連をグラフとして扱うパッケージ。 5 | * 各関連がグラフに依存する。 6 | */ 7 | package org.dddjava.jig.domain.model.information.relation; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/relation/packages/PackageMutualDependency.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.relation.packages; 2 | 3 | import org.dddjava.jig.domain.model.data.packages.PackageIdentifier; 4 | 5 | /** 6 | * パッケージの相互依存 7 | */ 8 | public record PackageMutualDependency(PackageIdentifier left, PackageIdentifier right) { 9 | 10 | public static PackageMutualDependency from(PackageRelation packageRelation) { 11 | return new PackageMutualDependency(packageRelation.from(), packageRelation.to()); 12 | } 13 | 14 | public boolean matches(PackageRelation packageRelation) { 15 | PackageIdentifier fromPackage = packageRelation.from(); 16 | PackageIdentifier toPackage = packageRelation.to(); 17 | if (fromPackage.equals(toPackage)) return false; // 上位との相互依存の場合、containsが一致してしまうので回避 18 | return (left.contains(fromPackage) && right.contains(toPackage)) || 19 | (left.contains(toPackage) && right.contains(fromPackage)); 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return left.asText() + " <-> " + right.asText(); 25 | } 26 | 27 | /** 28 | * DOT言語での関連出力。 29 | * 双方向とするため、 edge[dir=both] で囲むこと。 30 | */ 31 | String dotText() { 32 | return "\"%s\" -> \"%s\";".formatted(left.asText(), right.asText()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/relation/packages/PackageRelation.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.relation.packages; 2 | 3 | import org.dddjava.jig.domain.model.data.packages.PackageDepth; 4 | import org.dddjava.jig.domain.model.data.packages.PackageIdentifier; 5 | import org.dddjava.jig.domain.model.information.relation.graph.Edge; 6 | 7 | /** 8 | * パッケージの依存関係 9 | */ 10 | public record PackageRelation(Edge edge) { 11 | 12 | public static PackageRelation from(PackageIdentifier from, PackageIdentifier to) { 13 | return new PackageRelation(Edge.of(from, to)); 14 | } 15 | 16 | public PackageIdentifier from() { 17 | return edge.from(); 18 | } 19 | 20 | public PackageIdentifier to() { 21 | return edge.to(); 22 | } 23 | 24 | public PackageRelation applyDepth(PackageDepth packageDepth) { 25 | return from(from().applyDepth(packageDepth), to().applyDepth(packageDepth)); 26 | } 27 | 28 | public boolean notSelfRelation() { 29 | return !from().equals(to()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/relation/packages/RelationNumber.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.relation.packages; 2 | 3 | import java.util.Locale; 4 | 5 | /** 6 | * 依存関係の数 7 | */ 8 | public class RelationNumber { 9 | int value; 10 | 11 | public RelationNumber(int value) { 12 | this.value = value; 13 | } 14 | 15 | public String asText() { 16 | return Integer.toString(value); 17 | } 18 | 19 | public String localizedLabel() { 20 | Locale locale = Locale.getDefault(); 21 | boolean isEnglish = locale.getLanguage().equals("en"); 22 | return (isEnglish ? "Relations: " : "関連数: ") + value; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/relation/packages/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * パッケージの関連 3 | * 4 | * 型の関連から導出する。 5 | */ 6 | package org.dddjava.jig.domain.model.information.relation.packages; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/relation/types/TypeRelationKind.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.relation.types; 2 | 3 | public enum TypeRelationKind { 4 | 継承クラス, 5 | 実装インタフェース, 6 | 型引数, 7 | 型パラメータ型, 8 | メソッド引数, 9 | メソッド戻り値, 10 | 使用アノテーション, 11 | 使用アノテーション引数, 12 | 呼び出しメソッドのオーナー, 13 | 呼び出しメソッドの戻り値, 14 | ローカル変数, 15 | 不明 16 | } 17 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/relation/types/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 型の関連 3 | * 4 | * 関連だけでなく関連の種類を持つ。 5 | */ 6 | package org.dddjava.jig.domain.model.information.relation.types; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/types/TypeCategory.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.types; 2 | 3 | public enum TypeCategory { 4 | /** 5 | * ユースケース 6 | * 7 | * いわゆるService。 8 | */ 9 | Usecase, 10 | 11 | /** 12 | * 入力アダプタ 13 | * 14 | * いわゆるController。プレゼンテーションやリクエストをハンドリングするものなど。 15 | */ 16 | InputAdapter, 17 | 18 | /** 19 | * 出力アダプタ 20 | * 21 | * いわゆるRepository。DB書き込みなどの永続化や、外部サービス呼び出しなど。 22 | */ 23 | OutputAdapter, 24 | 25 | /** 26 | * その他のコンポーネント 27 | * 28 | * コアドメインではなく、Controller、Service、Repository以外のアプリケーションを動かすために必要なコンポーネント。 29 | */ 30 | OtherApplicationComponent, 31 | 32 | /** 33 | * 判別できなかったもの 34 | */ 35 | Others; 36 | 37 | /** 38 | * アプリケーションを動作させるためのコンポーネント 39 | */ 40 | public boolean isApplicationComponent() { 41 | return switch (this) { 42 | case Usecase, InputAdapter, OutputAdapter, OtherApplicationComponent -> true; 43 | default -> false; 44 | }; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/types/TypeKind.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.types; 2 | 3 | /** 4 | * 型の種類 5 | */ 6 | public enum TypeKind { 7 | 通常型, 8 | 9 | // finalな型 10 | 列挙型, 11 | // abstractな型 12 | 抽象列挙型, 13 | 14 | // アノテーション、インタフェース、抽象型の判定がAsmClassVisitorで行われていないのでまだ使えない 15 | //アノテーション, 16 | //インタフェース, 17 | //抽象型 18 | 19 | レコード型; 20 | 21 | public boolean isCategory() { 22 | return this == 列挙型 || this == 抽象列挙型; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/information/types/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JIGの扱う型情報 3 | * 4 | * JIGの中心的なモデルである {@code JigType} などを扱うパッケージ。 5 | */ 6 | package org.dddjava.jig.domain.model.information.types; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/knowledge/adapter/DatasourceAngles.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.knowledge.adapter; 2 | 3 | import org.dddjava.jig.domain.model.data.rdbaccess.MyBatisStatements; 4 | import org.dddjava.jig.domain.model.information.members.CallerMethods; 5 | import org.dddjava.jig.domain.model.information.outputs.DatasourceMethod; 6 | import org.dddjava.jig.domain.model.information.outputs.DatasourceMethods; 7 | import org.dddjava.jig.domain.model.information.relation.methods.CallerMethodsFactory; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Comparator; 11 | import java.util.List; 12 | 13 | /** 14 | * データソースの切り口一覧 15 | */ 16 | public class DatasourceAngles { 17 | 18 | List list; 19 | 20 | public DatasourceAngles(DatasourceMethods datasourceMethods, MyBatisStatements myBatisStatements, CallerMethodsFactory callerMethodsFactory) { 21 | List list = new ArrayList<>(); 22 | for (DatasourceMethod datasourceMethod : datasourceMethods.list()) { 23 | CallerMethods callerMethods = callerMethodsFactory.callerMethodsOf(datasourceMethod.repositoryMethod().jigMethodIdentifier()); 24 | list.add(new DatasourceAngle(datasourceMethod, myBatisStatements, callerMethods)); 25 | } 26 | this.list = list; 27 | } 28 | 29 | public List list() { 30 | return list.stream() 31 | .sorted(Comparator.comparing(datasourceAngle -> datasourceAngle.interfaceMethod().jigMethodIdentifier().value())) 32 | .toList(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/knowledge/core/ServiceAngles.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.knowledge.core; 2 | 3 | import org.dddjava.jig.domain.model.information.applications.ServiceMethod; 4 | import org.dddjava.jig.domain.model.information.applications.ServiceMethods; 5 | import org.dddjava.jig.domain.model.information.inputs.Entrypoints; 6 | import org.dddjava.jig.domain.model.information.outputs.DatasourceMethods; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Comparator; 10 | import java.util.List; 11 | 12 | /** 13 | * サービスの切り口一覧 14 | */ 15 | public class ServiceAngles { 16 | 17 | List list; 18 | 19 | public static ServiceAngles from(ServiceMethods serviceMethods, Entrypoints entrypoints, DatasourceMethods datasourceMethods) { 20 | List list = new ArrayList<>(); 21 | for (ServiceMethod serviceMethod : serviceMethods.list()) { 22 | ServiceAngle serviceAngle = ServiceAngle.from(serviceMethods, entrypoints, datasourceMethods, serviceMethod); 23 | list.add(serviceAngle); 24 | } 25 | return new ServiceAngles(list); 26 | } 27 | 28 | public List list() { 29 | return list.stream() 30 | .sorted(Comparator.comparing(serviceAngle -> serviceAngle.serviceMethod().method().jigMethodIdentifier().value())) 31 | .toList(); 32 | } 33 | 34 | private ServiceAngles(List list) { 35 | this.list = list; 36 | } 37 | 38 | public boolean none() { 39 | return list.isEmpty(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/knowledge/core/Usecase.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.knowledge.core; 2 | 3 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 4 | import org.dddjava.jig.domain.model.information.applications.ServiceMethod; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | /** 10 | * ユースケース 11 | */ 12 | public class Usecase { 13 | 14 | ServiceMethod serviceMethod; 15 | UsecaseCategory usecaseCategory; 16 | 17 | public Usecase(ServiceAngle serviceAngle) { 18 | this.serviceMethod = serviceAngle.serviceMethod(); 19 | this.usecaseCategory = UsecaseCategory.resolver(serviceAngle); 20 | } 21 | 22 | public List internalUsingTypes() { 23 | return serviceMethod.internalUsingTypes(); 24 | } 25 | 26 | public Optional primaryType() { 27 | return serviceMethod.primaryType(); 28 | } 29 | 30 | public List requireTypes() { 31 | return serviceMethod.requireTypes(); 32 | } 33 | 34 | public String usecaseIdentifier() { 35 | return serviceMethod.method().fqn(); 36 | } 37 | 38 | public String usecaseLabel() { 39 | return serviceMethod.method().aliasText(); 40 | } 41 | 42 | public String simpleTextWithDeclaringType() { 43 | return serviceMethod.method().simpleText(); 44 | } 45 | 46 | public boolean isHandler() { 47 | return usecaseCategory.handler(); 48 | } 49 | 50 | public TypeIdentifier declaringType() { 51 | return serviceMethod.declaringType(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/knowledge/core/UsecaseCategory.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.knowledge.core; 2 | 3 | /** 4 | * ユースケースの種類 5 | */ 6 | enum UsecaseCategory { 7 | ハンドラ, 8 | その他; 9 | 10 | public static UsecaseCategory resolver(ServiceAngle serviceAngle) { 11 | return serviceAngle.usingFromController() ? ハンドラ : その他; 12 | } 13 | 14 | public boolean handler() { 15 | return this == ハンドラ; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/knowledge/core/usecases/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * ユースケース 3 | */ 4 | package org.dddjava.jig.domain.model.knowledge.core.usecases; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/knowledge/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 知識 3 | * 4 | * 情報に価値を付加したもの。 5 | */ 6 | package org.dddjava.jig.domain.model.knowledge; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/knowledge/smell/MethodSmellList.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.knowledge.smell; 2 | 3 | import org.dddjava.jig.domain.model.information.types.JigTypes; 4 | 5 | import java.util.Collection; 6 | import java.util.Comparator; 7 | import java.util.List; 8 | 9 | /** 10 | * メソッドの不吉なにおい一覧 11 | */ 12 | public record MethodSmellList(Collection smells) { 13 | 14 | public static MethodSmellList from(JigTypes jigTypes) { 15 | return new MethodSmellList(jigTypes.orderedStream() 16 | .flatMap(jigType -> jigType.instanceJigMethodStream() 17 | .flatMap(method -> MethodSmell.createMethodSmell(method, jigType).stream()) 18 | ) 19 | .toList()); 20 | } 21 | 22 | public List list() { 23 | return smells.stream() 24 | .sorted(Comparator.comparing(methodSmell -> methodSmell.method().jigMethodIdentifier().value())) 25 | .toList(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/knowledge/smell/MethodWorries.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.knowledge.smell; 2 | 3 | import org.dddjava.jig.domain.model.information.members.JigMethod; 4 | import org.dddjava.jig.domain.model.information.types.JigType; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | /** 10 | * メソッドの気になるところ 11 | */ 12 | public record MethodWorries(List list) { 13 | 14 | public static MethodWorries from(JigMethod method, JigType contextJigType) { 15 | return new MethodWorries(Arrays.stream(MethodWorry.values()) 16 | .filter(methodWorry -> methodWorry.judge(method, contextJigType)) 17 | .toList()); 18 | } 19 | 20 | public boolean contains(MethodWorry... methodWorries) { 21 | for (MethodWorry methodWorry : methodWorries) { 22 | if (list.contains(methodWorry)) return true; 23 | } 24 | return false; 25 | } 26 | 27 | public boolean empty() { 28 | return list.isEmpty(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/knowledge/validations/Validation.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.knowledge.validations; 2 | 3 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 4 | 5 | /** 6 | * バリデーション 7 | */ 8 | public record Validation(TypeIdentifier typeIdentifier, String memberName, TypeIdentifier memberType, 9 | TypeIdentifier annotationType, String annotationDescription) { 10 | } 11 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/knowledge/validations/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * バリデーション 3 | */ 4 | package org.dddjava.jig.domain.model.knowledge.validations; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/sources/DefaultJigDataProvider.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.sources; 2 | 3 | import org.dddjava.jig.application.JigDataProvider; 4 | import org.dddjava.jig.domain.model.data.enums.EnumModels; 5 | import org.dddjava.jig.domain.model.data.rdbaccess.MyBatisStatements; 6 | import org.dddjava.jig.domain.model.sources.javasources.JavaSourceModel; 7 | 8 | public record DefaultJigDataProvider(JavaSourceModel javaSourceModel, 9 | MyBatisStatements myBatisStatements) implements JigDataProvider { 10 | 11 | @Override 12 | public MyBatisStatements fetchMybatisStatements() { 13 | return myBatisStatements; 14 | } 15 | 16 | @Override 17 | public EnumModels fetchEnumModels() { 18 | return javaSourceModel().enumModels(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/sources/LocalSource.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.sources; 2 | 3 | import org.dddjava.jig.domain.model.sources.classsources.ClassFiles; 4 | import org.dddjava.jig.domain.model.sources.javasources.JavaFilePaths; 5 | 6 | /** 7 | * ローカルにあるJIGの情報源 8 | */ 9 | public record LocalSource(SourceBasePaths sourceBasePaths, JavaFilePaths javaFilePaths, ClassFiles classFiles) { 10 | 11 | public boolean emptyClassSources() { 12 | return classFiles.nothing(); 13 | } 14 | 15 | public boolean emptyJavaSources() { 16 | return javaFilePaths.nothing(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/sources/SourceBasePath.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.sources; 2 | 3 | import java.nio.file.Path; 4 | import java.util.Collection; 5 | import java.util.List; 6 | import java.util.stream.Stream; 7 | 8 | /** 9 | * コードのパス 10 | */ 11 | public record SourceBasePath(Collection paths) { 12 | 13 | public List pathList() { 14 | return paths.stream() 15 | .sorted().distinct() 16 | .toList(); 17 | } 18 | 19 | public SourceBasePath merge(SourceBasePath other) { 20 | return new SourceBasePath(Stream.concat(paths.stream(), other.paths.stream()).toList()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/sources/SourceBasePaths.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.sources; 2 | 3 | import java.nio.file.Path; 4 | import java.util.List; 5 | 6 | /** 7 | * ソースのパス 8 | */ 9 | public record SourceBasePaths(SourceBasePath classFileBasePath, SourceBasePath javaFileBasePath) { 10 | 11 | public List classSourceBasePaths() { 12 | return classFileBasePath.pathList(); 13 | } 14 | 15 | public List javaSourceBasePaths() { 16 | return javaFileBasePath.pathList(); 17 | } 18 | 19 | public SourceBasePaths merge(SourceBasePaths other) { 20 | return new SourceBasePaths(classFileBasePath.merge(other.classFileBasePath), javaFileBasePath.merge(other.javaFileBasePath)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/sources/classsources/ClassFile.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.sources.classsources; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Path; 6 | 7 | /** 8 | * classファイルの中身 9 | */ 10 | public record ClassFile(byte[] bytes, Path path) { 11 | 12 | public static ClassFile readFromPath(Path path) throws IOException { 13 | return new ClassFile(Files.readAllBytes(path), path); 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "ClassSource{bytes.length=" + bytes.length + '}'; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/sources/classsources/ClassFiles.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.sources.classsources; 2 | 3 | import java.util.Collection; 4 | 5 | /** 6 | * classファイル一式 7 | */ 8 | public record ClassFiles(Collection values) { 9 | 10 | public boolean nothing() { 11 | return values.isEmpty(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/sources/javasources/JavaFilePaths.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.sources.javasources; 2 | 3 | import java.nio.file.Path; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | /** 8 | * テキストソース一覧 9 | */ 10 | public record JavaFilePaths(List packageInfos, List javaFiles) { 11 | 12 | public boolean nothing() { 13 | return packageInfos.isEmpty() && javaFiles.isEmpty(); 14 | } 15 | 16 | public Collection packageInfoPaths() { 17 | return packageInfos; 18 | } 19 | 20 | public Collection javaPaths() { 21 | return javaFiles; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/sources/javasources/JavaSourceModel.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.sources.javasources; 2 | 3 | import org.dddjava.jig.domain.model.data.enums.EnumModel; 4 | import org.dddjava.jig.domain.model.data.enums.EnumModels; 5 | 6 | import java.util.List; 7 | import java.util.stream.Stream; 8 | 9 | /** 10 | * javaファイル由来のソース 11 | */ 12 | public class JavaSourceModel { 13 | 14 | List enumModels; 15 | 16 | private JavaSourceModel(List enumModels) { 17 | this.enumModels = enumModels; 18 | } 19 | 20 | public static JavaSourceModel from(List enumModels) { 21 | return new JavaSourceModel(enumModels); 22 | } 23 | 24 | public static JavaSourceModel empty() { 25 | return new JavaSourceModel(List.of()); 26 | } 27 | 28 | public EnumModels enumModels() { 29 | return new EnumModels(enumModels); 30 | } 31 | 32 | public JavaSourceModel merge(JavaSourceModel other) { 33 | return new JavaSourceModel(Stream.concat(enumModels.stream(), other.enumModels.stream()).toList()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/sources/mybatis/MyBatisStatementsReader.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.sources.mybatis; 2 | 3 | import org.dddjava.jig.domain.model.data.rdbaccess.MyBatisStatements; 4 | import org.dddjava.jig.domain.model.data.types.JigTypeHeader; 5 | 6 | import java.nio.file.Path; 7 | import java.util.Collection; 8 | import java.util.List; 9 | 10 | /** 11 | * SQL読み取り機 12 | */ 13 | public interface MyBatisStatementsReader { 14 | 15 | MyBatisStatements readFrom(Collection sources, List classPaths); 16 | } 17 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/domain/model/sources/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JIGの情報源 3 | * 4 | * ソースコードおよびバイトコード 5 | */ 6 | package org.dddjava.jig.domain.model.sources; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/infrastructure/asm/AsmUtils.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.infrastructure.asm; 2 | 3 | import org.dddjava.jig.domain.model.data.members.JigMemberOwnership; 4 | import org.dddjava.jig.domain.model.data.members.JigMemberVisibility; 5 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 6 | import org.objectweb.asm.Opcodes; 7 | import org.objectweb.asm.Type; 8 | 9 | class AsmUtils { 10 | 11 | static JigMemberVisibility resolveMethodVisibility(int access) { 12 | if ((access & Opcodes.ACC_PUBLIC) != 0) return JigMemberVisibility.PUBLIC; 13 | if ((access & Opcodes.ACC_PROTECTED) != 0) return JigMemberVisibility.PROTECTED; 14 | if ((access & Opcodes.ACC_PRIVATE) != 0) return JigMemberVisibility.PRIVATE; 15 | return JigMemberVisibility.PACKAGE; 16 | } 17 | 18 | static JigMemberOwnership jigMemberOwnership(int access) { 19 | return ((access & Opcodes.ACC_STATIC) == 0) ? JigMemberOwnership.INSTANCE : JigMemberOwnership.CLASS; 20 | } 21 | 22 | static TypeIdentifier typeDescriptorToIdentifier(String descriptor) { 23 | Type type = Type.getType(descriptor); 24 | return TypeIdentifier.valueOf(type.getClassName()); 25 | } 26 | 27 | public static TypeIdentifier type2TypeIdentifier(Type typeValue) { 28 | return TypeIdentifier.valueOf(typeValue.getClassName()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/infrastructure/asm/ClassDeclaration.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.infrastructure.asm; 2 | 3 | import org.dddjava.jig.domain.model.data.members.fields.JigFieldHeader; 4 | import org.dddjava.jig.domain.model.data.types.JigTypeHeader; 5 | import org.dddjava.jig.domain.model.information.members.JigMethodDeclaration; 6 | 7 | import java.util.Collection; 8 | 9 | /** 10 | * ASMで読んだクラスの情報 11 | * 12 | * JigTypeに変換するまでの入れ物であり、infrastructureのみで使用する。 13 | */ 14 | public record ClassDeclaration(JigTypeHeader jigTypeHeader, 15 | Collection jigFieldHeaders, 16 | Collection jigMethodDeclarations) { 17 | } 18 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/infrastructure/asm/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * ASMを使用してクラスファイルを読む 3 | * 4 | * クラスファイルの解析はJIGの根幹であるが、ASMを前提にするものではない。 5 | * JEP-457 https://openjdk.org/jeps/457 が正式に採用されたら置き換えるかもしれないので、 6 | * このパッケージ外にはASMを出さないようにする。 7 | */ 8 | package org.dddjava.jig.infrastructure.asm; -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/infrastructure/configuration/JigProperty.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.infrastructure.configuration; 2 | 3 | import java.nio.file.Paths; 4 | 5 | public enum JigProperty { 6 | 7 | OUTPUT_DIRECTORY("") { 8 | @Override 9 | String defaultValue() { 10 | return Paths.get(System.getProperty("user.dir")).resolve(".jig").toAbsolutePath().toString(); 11 | } 12 | }, 13 | OUTPUT_DIAGRAM_FORMAT("SVG"), 14 | 15 | PATTERN_DOMAIN(".+\\.domain\\.(model|type)\\..+"), 16 | ; 17 | 18 | private final String defaultValue; 19 | 20 | JigProperty(String defaultValue) { 21 | this.defaultValue = defaultValue; 22 | } 23 | 24 | String defaultValue() { 25 | return defaultValue; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/infrastructure/configuration/PropertyArchitectureFactory.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.infrastructure.configuration; 2 | 3 | import org.dddjava.jig.domain.model.information.Architecture; 4 | 5 | import java.util.regex.Pattern; 6 | 7 | public class PropertyArchitectureFactory { 8 | 9 | JigProperties jigProperties; 10 | 11 | public PropertyArchitectureFactory(JigProperties jigProperties) { 12 | this.jigProperties = jigProperties; 13 | } 14 | 15 | public Architecture architecture() { 16 | Pattern compilerGeneratedClassPattern = Pattern.compile(".+\\$\\d+"); 17 | Pattern businessRulePattern = Pattern.compile(jigProperties.getDomainPattern()); 18 | 19 | return jigType -> { 20 | String fqn = jigType.id().fullQualifiedName(); 21 | if (fqn.endsWith(".package-info")) return false; 22 | return businessRulePattern.matcher(fqn).matches() 23 | && !compilerGeneratedClassPattern.matcher(fqn).matches(); 24 | }; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /jig-core/src/main/java/org/dddjava/jig/infrastructure/javaparser/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Javaparserを使用してJavaファイルを読む 3 | * 4 | * JIGはコンパイルされたクラスファイルを基本とするが、コンパイルにより失われる情報もあるため、Javaファイルも読み取る必要がある。 5 | * コメントはこちらで読み取るしかない。 6 | */ 7 | package org.dddjava.jig.infrastructure.javaparser; -------------------------------------------------------------------------------- /jig-core/src/main/resources/templates/application.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | application 6 | 7 | 8 |
9 |
10 | 13 |
14 | 15 |
16 | パッケージ表示 17 |
18 |
19 | 20 | 21 |
22 | クラス表示 23 |
24 |
25 |
26 |
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /jig-core/src/main/resources/templates/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dddjava/jig/b531cc369f11dfeb92c04bfd8140bb5ddf2b099a/jig-core/src/main/resources/templates/assets/favicon.ico -------------------------------------------------------------------------------- /jig-core/src/main/resources/templates/domain.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | domain 6 | 7 | 8 |
9 |
10 | 13 |
14 | 15 |
16 | パッケージ表示 17 |
18 |
19 | 20 | 21 |
22 | クラス表示 23 |
24 |
25 |
26 |
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /jig-core/src/main/resources/templates/entrypoint.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | application 7 | 8 | 9 |
10 |
11 | 14 | 15 |
16 | 17 | 18 |
19 |

XXXクラス

20 |
org.dddjava.jig.package.Class
21 |

22 |

/hoge/fuga

23 | 24 |
クラスのJavadocコメント
25 | 26 |
27 |                     graph LR
28 |                     a --> b
29 |                     a --> c
30 |                     b --> c
31 |                 
32 | 33 |
34 |
35 |
36 |
37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /jig-core/src/main/resources/templates/fragment-base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 共通 7 | 8 | 9 |
10 | [INDEX] 11 | たいとる 12 |
13 | 14 |
15 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /jig-core/src/main/resources/templates/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | パッケージ概要 9 | 10 | 11 |
たいとる
12 |
13 |
14 | ⚙️ 表示設定 15 | 16 |
17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 |
完全修飾名名称
com.example
36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /jig-core/src/test/java/DefaultPackageClass.java: -------------------------------------------------------------------------------- 1 | /** 2 | * デフォルトパッケージにあるクラス 3 | */ 4 | public class DefaultPackageClass { 5 | } 6 | -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/JigExecutorTest.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig; 2 | 3 | import org.dddjava.jig.domain.model.documents.documentformat.JigDocument; 4 | import org.dddjava.jig.domain.model.sources.SourceBasePaths; 5 | import org.dddjava.jig.infrastructure.configuration.Configuration; 6 | import org.junit.jupiter.api.Test; 7 | import testing.JigServiceTest; 8 | 9 | import java.util.List; 10 | 11 | import static org.junit.jupiter.api.Assertions.*; 12 | 13 | @JigServiceTest 14 | class JigExecutorTest { 15 | 16 | @Test 17 | void name(Configuration configuration, SourceBasePaths sourceBasePaths) { 18 | var actual = JigExecutor.execute( 19 | configuration, 20 | sourceBasePaths 21 | ); 22 | 23 | List actualDocuments = actual.stream().map(handleResult -> handleResult.jigDocument).toList(); 24 | // canonicalのすべてが処理されている 25 | assertTrue(actualDocuments.containsAll(JigDocument.canonical()), actualDocuments::toString); 26 | 27 | // すべて失敗していない(success or skip)であること 28 | assertAll(actual.stream().map(actualResult -> 29 | () -> assertFalse(actualResult.failure(), () -> actualResult.toString()) 30 | )); 31 | } 32 | } -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/domain/model/implementation/datasource/TablesTest.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.implementation.datasource; 2 | 3 | import org.dddjava.jig.domain.model.data.rdbaccess.Table; 4 | import org.dddjava.jig.domain.model.data.rdbaccess.Tables; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class TablesTest { 10 | 11 | @Test 12 | void test() { 13 | Table hoge = new Table("hoge"); 14 | Table fuga1 = new Table("fuga"); 15 | Table fuga2 = new Table("fuga"); 16 | 17 | Tables sut = new Tables(hoge) 18 | .merge(new Tables(fuga1)) 19 | .merge(new Tables(fuga2)); 20 | 21 | assertEquals("[fuga, hoge]", sut.asText()); 22 | } 23 | } -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/domain/model/information/types/JigTypeTest.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.domain.model.information.types; 2 | 3 | import org.dddjava.jig.domain.model.data.types.TypeIdentifier; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import testing.TestSupport; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; 9 | 10 | class JigTypeTest { 11 | 12 | @Test 13 | void アノテーションの値取得_String() { 14 | var jigType = TestSupport.buildJigType(MyAnnotatedClass.class); 15 | 16 | var actual = jigType.annotationValueOf(TypeIdentifier.from(RequestMapping.class), "name") 17 | .orElseThrow(); // 取れなければテスト失敗でよい 18 | 19 | assertEquals("hoge", actual); 20 | } 21 | 22 | @Test 23 | void アノテーションの値取得_String配列の単一値() { 24 | var jigType = TestSupport.buildJigType(MyAnnotatedClass.class); 25 | 26 | var actual = jigType.annotationValueOf(TypeIdentifier.from(RequestMapping.class), "value") 27 | .orElseThrow(); // 取れなければテスト失敗でよい 28 | 29 | assertEquals("{id}", actual); 30 | } 31 | 32 | @Test 33 | void アノテーションの値取得_aliasなど片方だけとればいいものは最初にマッチしたものがとれる() { 34 | var jigType = TestSupport.buildJigType(MyAnnotatedClass.class); 35 | 36 | var actual = jigType.annotationValueOf(TypeIdentifier.from(RequestMapping.class), "none", "value", "path") 37 | .orElseThrow(); // 取れなければテスト失敗でよい 38 | 39 | // pathの値がとれている。 40 | // つまり引数の順ではなくアノテーションに書いた順番になっているが、一つしか指定できないものでの使用を想定しているのでよしとする。 41 | assertEquals("/hoge", actual); 42 | } 43 | 44 | @RequestMapping(name = "hoge", path = "/hoge", value = "{id}") 45 | private static class MyAnnotatedClass { 46 | } 47 | } -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/LocalFileLocalSourceFactoryTest.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.infrastructure; 2 | 3 | import org.dddjava.jig.application.JigEventRepository; 4 | import org.dddjava.jig.domain.model.sources.LocalSource; 5 | import org.dddjava.jig.domain.model.sources.SourceBasePath; 6 | import org.dddjava.jig.domain.model.sources.SourceBasePaths; 7 | import org.dddjava.jig.infrastructure.javaproductreader.ClassOrJavaSourceCollector; 8 | import org.junit.jupiter.api.Test; 9 | import org.mockito.Mockito; 10 | 11 | import java.nio.file.Path; 12 | import java.util.Collections; 13 | 14 | import static org.junit.jupiter.api.Assertions.assertTrue; 15 | 16 | class LocalFileLocalSourceFactoryTest { 17 | 18 | @Test 19 | void 読み取れないパスが指定されていてもエラーにならない() { 20 | var invalidClassPath = Path.of("invalid-binary-path"); 21 | var invalidJavaPath = Path.of("invalid-text-path"); 22 | SourceBasePaths sourceBasePaths = new SourceBasePaths( 23 | new SourceBasePath(Collections.singletonList(invalidClassPath)), 24 | new SourceBasePath(Collections.singletonList(invalidJavaPath)) 25 | ); 26 | 27 | var jigEventRepository = Mockito.spy(new JigEventRepository()); 28 | ClassOrJavaSourceCollector sut = new ClassOrJavaSourceCollector(jigEventRepository); 29 | LocalSource source = sut.collectSources(sourceBasePaths); 30 | 31 | assertTrue(source.emptyClassSources()); 32 | assertTrue(source.emptyJavaSources()); 33 | 34 | Mockito.verify(jigEventRepository).register指定されたパスが存在しない(invalidClassPath); 35 | Mockito.verify(jigEventRepository).register指定されたパスが存在しない(invalidJavaPath); 36 | Mockito.verifyNoMoreInteractions(jigEventRepository); 37 | } 38 | } -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/asm/ut/MyClass.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.infrastructure.asm.ut; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @MyDeclarationAnnotationForSource 9 | @MyDeclarationAnnotationForClass 10 | @MyDeclarationAnnotationForRuntime 11 | public class MyClass<@MyTypeAnnotation X, @MyTypeParameterAnnotation Y> 12 | extends @MyTypeAnnotation MySuperClass 13 | implements MyInterface, MyInterface2 { 14 | } 15 | 16 | class MySuperClass { 17 | } 18 | 19 | interface MyInterface { 20 | } 21 | 22 | interface MyInterface2 { 23 | } 24 | 25 | @Retention(RetentionPolicy.SOURCE) 26 | @interface MyDeclarationAnnotationForSource { 27 | } 28 | 29 | @Retention(RetentionPolicy.CLASS) 30 | @interface MyDeclarationAnnotationForClass { 31 | } 32 | 33 | @Retention(RetentionPolicy.RUNTIME) 34 | @interface MyDeclarationAnnotationForRuntime { 35 | } 36 | 37 | @Target(ElementType.TYPE_USE) 38 | @interface MyTypeAnnotation { 39 | } 40 | 41 | @Target(ElementType.TYPE_PARAMETER) 42 | @interface MyTypeParameterAnnotation { 43 | } 44 | -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/asm/ut/MyGenericsMadnessInterface.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.infrastructure.asm.ut; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.function.Consumer; 6 | import java.util.function.Function; 7 | import java.util.function.Predicate; 8 | 9 | // テスト用のぐちゃぐちゃなやつ 10 | public interface MyGenericsMadnessInterface>> 11 | extends Consumer>>> { 12 | } 13 | 14 | // 再帰型境界 15 | interface RecursiveGenerics> { 16 | } 17 | 18 | // ネストされたジェネリクスの組み合わせ 19 | interface NestedGenerics>>> { 20 | } 21 | 22 | // 多重インターフェース継承 23 | interface ComplexInterface 24 | extends Consumer>, Function { 25 | } -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/asm/ut/MyTypeModifierClass.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.infrastructure.asm.ut; 2 | 3 | public class MyTypeModifierClass { 4 | public static class MyTypeModifierClassSTATIC { 5 | public static class MyTypeModifierClassSTATICNest { 6 | } 7 | 8 | public class MyTypeModifierClassSTATICInner { 9 | } 10 | } 11 | 12 | public abstract class MyTypeModifierClassABSTRACT { 13 | } 14 | 15 | public final class MyTypeModifierClassFINAL { 16 | } 17 | 18 | public sealed interface MyTypeModifierClassSEALED 19 | permits MyTypeModifierClassNON_SEALED { 20 | } 21 | 22 | public non-sealed class MyTypeModifierClassNON_SEALED implements MyTypeModifierClassSEALED { 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/asm/ut/field/MyEnumFieldSut.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.infrastructure.asm.ut.field; 2 | 3 | import org.dddjava.jig.domain.model.documents.documentformat.JigDocument; 4 | 5 | public enum MyEnumFieldSut { 6 | 通常の列挙値1, 7 | 通常の列挙値2, 8 | @Deprecated 9 | Deprecatedな列挙値 10 | ; 11 | 12 | static final MyEnumFieldSut static_finalフィールド = null; 13 | static MyEnumFieldSut staticフィールド; 14 | 15 | final MyEnumFieldSut finalフィールド = null; 16 | MyEnumFieldSut フィールド; 17 | 18 | @Deprecated 19 | Object deprecatedField; 20 | 21 | static JigDocument 別のenum型のstaticフィールド; 22 | JigDocument 別のenum型のフィールド; 23 | } 24 | -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/asm/ut/field/MySutClass.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.infrastructure.asm.ut.field; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.List; 5 | 6 | public class MySutClass { 7 | byte primitiveField; 8 | 9 | int[] primitiveArrayField; 10 | 11 | String stringField; 12 | 13 | String[] stringArrayField; 14 | 15 | List genericField; 16 | 17 | List genericArrayField; 18 | 19 | List genericTypeVariableField; 20 | 21 | List genericTypeVariableArrayField; 22 | 23 | T typeVariableField; 24 | 25 | T[] typeVariableArrayField; 26 | 27 | T[][] typeVariable2DArrayField; 28 | 29 | void voidMethod(String myParameter) { 30 | } 31 | 32 | T typeVariableField(T typeVariableParameter) { 33 | return null; 34 | } 35 | 36 | U typeParameterMethod(List genericsParameter) { 37 | return null; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/javaparser/learning/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Javaparserの学習テスト 3 | */ 4 | package org.dddjava.jig.infrastructure.javaparser.learning; -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/javaparser/ut/ParseTargetCanonicalClass.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.infrastructure.javaparser.ut; 2 | 3 | /** 4 | * クラスコメント 5 | */ 6 | public class ParseTargetCanonicalClass { 7 | 8 | /** 9 | * フィールドコメント 10 | */ 11 | Object field; 12 | 13 | /** 14 | * メソッドコメント 15 | */ 16 | void method() { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/javaparser/ut/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * テスト用 3 | */ 4 | package org.dddjava.jig.infrastructure.javaparser.ut; -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/javaparser/ut/package_info_block_comment/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * my_package_2 block comment 3 | */ 4 | package org.dddjava.jig.infrastructure.javaparser.ut.package_info_block_comment; -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/javaparser/ut/package_info_javadoc/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * this is term title 3 | * 4 | * 通常のJavadocコメント 5 | */ 6 | package org.dddjava.jig.infrastructure.javaparser.ut.package_info_javadoc; -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/javaparser/ut/package_info_javadoc_tag_only/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author javadocタグのみのpackage-info 3 | */ 4 | package org.dddjava.jig.infrastructure.javaparser.ut.package_info_javadoc_tag_only; -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/javaparser/ut/package_info_no_comment/package-info.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.infrastructure.javaparser.ut.package_info_no_comment; -------------------------------------------------------------------------------- /jig-core/src/test/java/org/dddjava/jig/infrastructure/javaparser/ut/package_info_typical/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 色々書いている{@code package-info} 3 | * 1行目がタイトルとして採用。2行目以降に書かれているものが本文として読み取られる。 4 | * ここに記述されている {@link this.is.Class linkタグ} や {@code codeタグ} はテキストとして可読な形に置き換えられる。 5 | * インラインでないJavadocタグは本文には含まれない。 6 | * @see org.dddjava 関連項目を示すjavadocタグ 7 | * @deprecated 非推奨理由を記述するjavadocタグ 8 | */ 9 | package org.dddjava.jig.infrastructure.javaparser.ut.package_info_typical; 10 | -------------------------------------------------------------------------------- /jig-core/src/test/java/org/springframework/stereotype/Controller.java: -------------------------------------------------------------------------------- 1 | package org.springframework.stereotype; 2 | 3 | public @interface Controller { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/org/springframework/stereotype/Repository.java: -------------------------------------------------------------------------------- 1 | package org.springframework.stereotype; 2 | 3 | public @interface Repository { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/org/springframework/stereotype/Service.java: -------------------------------------------------------------------------------- 1 | package org.springframework.stereotype; 2 | 3 | public @interface Service { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/org/springframework/stereotype/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * spring-contextに依存せずSpringのアノテーションが読み取れる試験をするためのパッケージ 3 | * 4 | * テストだけなら依存していい気もしなくはない。 5 | */ 6 | package org.springframework.stereotype; -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/application/service/CanonicalService.java: -------------------------------------------------------------------------------- 1 | package stub.application.service; 2 | 3 | import org.springframework.stereotype.Service; 4 | import stub.domain.model.type.HogeRepository; 5 | import stub.domain.model.type.fuga.Fuga; 6 | import stub.domain.model.type.fuga.FugaIdentifier; 7 | import stub.domain.model.type.fuga.FugaRepository; 8 | 9 | /** 10 | * サービス別名 11 | * 2行目や 12 | * 3行目は出力しない 13 | */ 14 | @Service 15 | public class CanonicalService { 16 | 17 | HogeRepository hogeRepository; 18 | FugaRepository fugaRepository; 19 | 20 | public CanonicalService(HogeRepository hogeRepository, FugaRepository fugaRepository) { 21 | this.hogeRepository = hogeRepository; 22 | this.fugaRepository = fugaRepository; 23 | } 24 | 25 | public Fuga fuga(FugaIdentifier identifier) { 26 | hogeRepository.method(); 27 | return fugaRepository.get(identifier); 28 | } 29 | 30 | void method() { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/application/service/DecisionService.java: -------------------------------------------------------------------------------- 1 | package stub.application.service; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | /** 6 | * 分岐のあるサービス 7 | */ 8 | @Service 9 | public class DecisionService { 10 | 11 | void 分岐のあるメソッド(Object 条件) { 12 | if (条件 == null) { 13 | throw new NullPointerException(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/application/service/SimpleService.java: -------------------------------------------------------------------------------- 1 | package stub.application.service; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | /** 6 | * フィールドを持たないサービス 7 | */ 8 | @Service 9 | public class SimpleService { 10 | 11 | public void コントローラーから呼ばれる() { 12 | } 13 | 14 | public void RESTコントローラーから呼ばれる() { 15 | } 16 | 17 | public void コントローラーから呼ばれない() { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/ClassJavadocStub.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model; 2 | 3 | /** 4 | * クラスのJavadoc 5 | */ 6 | public class ClassJavadocStub { 7 | 8 | /** 9 | * メソッドのJavadoc(使用しない) 10 | */ 11 | void method() { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/MemberAnnotatedClass.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model; 2 | 3 | import stub.domain.model.relation.annotation.UseInAnnotation; 4 | import stub.domain.model.relation.annotation.VariableAnnotation; 5 | 6 | import java.lang.reflect.Field; 7 | import java.lang.reflect.Method; 8 | 9 | public class MemberAnnotatedClass { 10 | 11 | @VariableAnnotation(string = "af", arrayString = "bf", number = 13, clz = Field.class, arrayClz = {Object.class, Object.class}, enumValue = UseInAnnotation.DUMMY1, annotation = @Deprecated) 12 | Object field; 13 | 14 | @VariableAnnotation(string = "am", arrayString = {"bm1", "bm2"}, number = 23, clz = Method.class, enumValue = UseInAnnotation.DUMMY2) 15 | void method() { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/MethodJavadocStub.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model; 2 | 3 | public class MethodJavadocStub { 4 | 5 | /** 6 | * メソッドのJavadoc 7 | */ 8 | void method() { 9 | } 10 | 11 | /** 12 | * 引数なしのメソッド 13 | */ 14 | String overloadMethod() { 15 | return null; 16 | } 17 | 18 | /** 19 | * 引数ありのメソッド 20 | */ 21 | String overloadMethod(String str) { 22 | return null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/NotJavadocStub.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model; 2 | 3 | /* 4 | * 普通のコメント 5 | */ 6 | public class NotJavadocStub { 7 | 8 | void method() { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/annotation/RuntimeRetainedAnnotation.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.annotation; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface RuntimeRetainedAnnotation { 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/annotation/package-info.java: -------------------------------------------------------------------------------- 1 | @RuntimeRetainedAnnotation 2 | package stub.domain.model.annotation; -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/booleans/BooleanQueryAngleTestTarget.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.booleans; 2 | 3 | public class BooleanQueryAngleTestTarget { 4 | 5 | boolean 真偽値を返すメソッド() { 6 | return false; 7 | } 8 | 9 | boolean 呼び出される真偽値を返すメソッド() { 10 | return false; 11 | } 12 | 13 | static boolean 真偽値を返すstaticメソッド() { 14 | return false; 15 | } 16 | 17 | void 真偽値を返さないメソッド() { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/booleans/UserByConstructor.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.booleans; 2 | 3 | public class UserByConstructor { 4 | 5 | UserByConstructor() { 6 | new BooleanQueryAngleTestTarget().呼び出される真偽値を返すメソッド(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/booleans/UserByField.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.booleans; 2 | 3 | public class UserByField { 4 | 5 | boolean field = new BooleanQueryAngleTestTarget().呼び出される真偽値を返すメソッド(); 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/booleans/UserByLambda.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.booleans; 2 | 3 | import java.util.function.Supplier; 4 | 5 | // staticメソッドと同じだけど 6 | public class UserByLambda { 7 | 8 | void method() { 9 | Supplier supplier = () -> new BooleanQueryAngleTestTarget().呼び出される真偽値を返すメソッド(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/booleans/UserByMethod.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.booleans; 2 | 3 | public class UserByMethod { 4 | 5 | void method() { 6 | new BooleanQueryAngleTestTarget().呼び出される真偽値を返すメソッド(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/booleans/UserByStaticField.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.booleans; 2 | 3 | public class UserByStaticField { 4 | 5 | static boolean field = new BooleanQueryAngleTestTarget().呼び出される真偽値を返すメソッド(); 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/booleans/UserByStaticMethod.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.booleans; 2 | 3 | public class UserByStaticMethod { 4 | 5 | static void method() { 6 | new BooleanQueryAngleTestTarget().呼び出される真偽値を返すメソッド(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/category/BehaviourEnum.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.category; 2 | 3 | public enum BehaviourEnum { 4 | A, 5 | B; 6 | 7 | public void method() { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/category/HasStaticFieldEnum.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.category; 2 | 3 | public enum HasStaticFieldEnum { 4 | A, 5 | B; 6 | 7 | public static final String C = "static field value"; 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/category/ParameterizedEnum.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.category; 2 | 3 | public enum ParameterizedEnum { 4 | A("a"), 5 | B("b"); 6 | 7 | private final String param; 8 | 9 | ParameterizedEnum(String param) { 10 | this.param = param; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/category/PolymorphismEnum.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.category; 2 | 3 | public enum PolymorphismEnum { 4 | A { 5 | }, 6 | B { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/category/RelationEnum.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.category; 2 | 3 | import java.util.function.Function; 4 | 5 | public enum RelationEnum { 6 | 7 | A(Object.class, param -> ParameterizedEnum.A.name()), 8 | B(SimpleEnum.class, param -> null), 9 | C(Object.class, param -> null); 10 | 11 | RichEnum field; 12 | 13 | RelationEnum(Class clz, Function function) { 14 | BehaviourEnum.A.method(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/category/RichEnum.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.category; 2 | 3 | import java.util.function.Function; 4 | 5 | public enum RichEnum { 6 | A(111, "A-String-Parameter", a -> a) { 7 | @Override 8 | void method() { 9 | // a 10 | } 11 | }, 12 | B(2222, "B-String-Parameter", (b) -> b, "B-String-Parameter-2") { 13 | @Override 14 | void method() { 15 | // b 16 | } 17 | }; 18 | 19 | private final String param; 20 | 21 | RichEnum(int i, String param, Function function, 22 | String arg2) { 23 | this(i, param, function); 24 | } 25 | 26 | RichEnum(int i, String param, Function function) { 27 | this.param = param; 28 | } 29 | 30 | abstract void method(); 31 | } 32 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/category/SimpleEnum.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.category; 2 | 3 | /** 4 | * 列挙のみのEnum 5 | */ 6 | public enum SimpleEnum { 7 | A, 8 | B, 9 | C, 10 | D 11 | } 12 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * スタブドメインモデル 3 | */ 4 | package stub.domain.model; -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/record/EmptyComponentRecord.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.record; 2 | 3 | public record EmptyComponentRecord() { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/record/SingleStringValueRecord.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.record; 2 | 3 | public record SingleStringValueRecord(String value) { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/ClassDefinition.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation; 2 | 3 | import stub.domain.model.relation.clz.*; 4 | 5 | @ClassAnnotation 6 | public class ClassDefinition extends SuperClass implements ImplementA, ImplementB { 7 | } 8 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/EnumDefinition.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation; 2 | 3 | import stub.domain.model.relation.enumeration.ClassReference; 4 | import stub.domain.model.relation.enumeration.ConstructorArgument; 5 | import stub.domain.model.relation.enumeration.EnumField; 6 | 7 | public enum EnumDefinition { 8 | 9 | 要素1(null, ClassReference.class), 10 | 要素2(null, String.class); 11 | 12 | EnumField field; 13 | 14 | EnumDefinition(ConstructorArgument arg, Class clz) { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/InterfaceDefinition.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation; 2 | 3 | import stub.domain.model.relation.clz.ClassAnnotation; 4 | import stub.domain.model.relation.clz.GenericsParameter; 5 | 6 | import java.util.List; 7 | 8 | @ClassAnnotation 9 | public interface InterfaceDefinition extends Comparable { 10 | 11 | List parameterizedListMethod(); 12 | } 13 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/annotation/UseInAnnotation.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.annotation; 2 | 3 | public enum UseInAnnotation { 4 | DUMMY1, 5 | DUMMY2, 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/annotation/VariableAnnotation.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.annotation; 2 | 3 | 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Target; 6 | 7 | /** 8 | * アノテーションの読み取りテスト用 9 | */ 10 | @Target({ElementType.FIELD, ElementType.METHOD}) 11 | public @interface VariableAnnotation { 12 | 13 | String string(); 14 | 15 | String[] arrayString(); 16 | 17 | int number(); 18 | 19 | Class clz(); 20 | 21 | Class[] arrayClz() default {}; 22 | 23 | UseInAnnotation enumValue(); 24 | 25 | Deprecated annotation() default @Deprecated; 26 | 27 | Deprecated[] arrayAnnotation() default {}; 28 | } 29 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/clz/ClassAnnotation.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.clz; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.TYPE) 9 | @Retention(RetentionPolicy.CLASS) 10 | public @interface ClassAnnotation { 11 | } 12 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/clz/GenericsParameter.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.clz; 2 | 3 | public class GenericsParameter { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/clz/ImplementA.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.clz; 2 | 3 | public interface ImplementA { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/clz/ImplementB.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.clz; 2 | 3 | public interface ImplementB { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/clz/SuperClass.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.clz; 2 | 3 | public class SuperClass { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/constant/to_primitive_constant/ConstantFieldHolder.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.constant.to_primitive_constant; 2 | 3 | public class ConstantFieldHolder { 4 | public static final int INT_CONSTANT = 1; 5 | public static final String STRING_CONSTANT = "STRING"; 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/constant/to_primitive_wrapper_constant/IntegerConstantFieldHolder.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.constant.to_primitive_wrapper_constant; 2 | 3 | public class IntegerConstantFieldHolder { 4 | 5 | public static final Integer INTEGER_CONSTANT = 100; 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/enumeration/ClassReference.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.enumeration; 2 | 3 | public class ClassReference { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/enumeration/ConstructorArgument.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.enumeration; 2 | 3 | public class ConstructorArgument { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/enumeration/EnumField.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.enumeration; 2 | 3 | public class EnumField { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/ArgumentGenericsParameter.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class ArgumentGenericsParameter { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/CheckedException.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class CheckedException extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/CheckedExceptionB.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class CheckedExceptionB extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/EnclosedClass.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class EnclosedClass { 4 | 5 | public static class Dummy { 6 | } 7 | 8 | public static class NestedClass { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/Instantiation.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class Instantiation { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/InstructionField.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public interface InstructionField { 4 | 5 | UsedInstructionMethodReturn invokeMethod(); 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/LocalValue.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class LocalValue { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/MethodAnnotation.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) 9 | @Retention(RetentionPolicy.CLASS) 10 | public @interface MethodAnnotation { 11 | } 12 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/MethodArgument.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class MethodArgument { 4 | 5 | void method() { 6 | 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/MethodReference.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class MethodReference { 4 | 5 | public String referenceMethod() { 6 | return null; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/MethodReturn.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class MethodReturn { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/ReferenceConstantInMethod.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class ReferenceConstantInMethod { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/ReferenceConstantOwnerInMethod.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class ReferenceConstantOwnerInMethod { 4 | public static ReferenceConstantInMethod FIELD; 5 | } 6 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/UncheckedExceptionA.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class UncheckedExceptionA extends RuntimeException { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/UncheckedExceptionB.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class UncheckedExceptionB extends RuntimeException { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/UnusedInstructionMethodReturn.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public interface UnusedInstructionMethodReturn { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/UseInLambda.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public class UseInLambda { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/relation/method/UsedInstructionMethodReturn.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.relation.method; 2 | 3 | public interface UsedInstructionMethodReturn { 4 | 5 | UnusedInstructionMethodReturn chainedInvokeMethod() throws CheckedExceptionB, UncheckedExceptionB; 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/smell/SmelledClass.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.smell; 2 | 3 | public class SmelledClass { 4 | 5 | void returnVoid() { 6 | } 7 | 8 | int returnInt() { 9 | return 0; 10 | } 11 | 12 | long returnLong() { 13 | return 0; 14 | } 15 | 16 | boolean returnBoolean() { 17 | return false; 18 | } 19 | 20 | SmelledClass intParameter(int i) { 21 | return new SmelledClass(); 22 | } 23 | 24 | SmelledClass longParameter(long l) { 25 | return new SmelledClass(); 26 | } 27 | 28 | SmelledClass booleanParameter(boolean b) { 29 | return new SmelledClass(); 30 | } 31 | 32 | SmelledClass useNullLiteral() { 33 | return null; 34 | } 35 | 36 | SmelledClass judgeNull() { 37 | return toString() == null ? this : new SmelledClass(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/smell/SmelledRecord.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.smell; 2 | 3 | public record SmelledRecord(int i) { 4 | 5 | void returnsVoid() { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/HogeDatasource.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type; 2 | 3 | import org.springframework.stereotype.Repository; 4 | 5 | @Repository 6 | public class HogeDatasource implements HogeRepository { 7 | 8 | @Override 9 | public void method() { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/HogeRepository.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type; 2 | 3 | public interface HogeRepository { 4 | 5 | void method(); 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/IntegerNumber.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type; 2 | 3 | public class IntegerNumber { 4 | 5 | Integer value; 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/LongNumber.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type; 2 | 3 | public class LongNumber { 4 | 5 | Long value; 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/PrimitiveIntNumber.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type; 2 | 3 | public class PrimitiveIntNumber { 4 | 5 | int value; 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/PrimitiveLongNumber.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type; 2 | 3 | public class PrimitiveLongNumber { 4 | 5 | long value; 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/SetCollection.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type; 2 | 3 | import java.util.Set; 4 | 5 | public class SetCollection { 6 | 7 | Set collection; 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/SimpleCollection.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type; 2 | 3 | import java.util.List; 4 | 5 | public class SimpleCollection { 6 | 7 | List collection; 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/SimpleDate.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type; 2 | 3 | import java.time.LocalDate; 4 | 5 | public class SimpleDate { 6 | 7 | LocalDate value; 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/SimpleIdentifier.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type; 2 | 3 | public class SimpleIdentifier { 4 | 5 | String value; 6 | } 7 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/SimpleNumber.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class SimpleNumber { 6 | 7 | BigDecimal value; 8 | } 9 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/SimpleTerm.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type; 2 | 3 | import java.time.LocalDate; 4 | 5 | public class SimpleTerm { 6 | 7 | LocalDate from; 8 | LocalDate to; 9 | } 10 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/fuga/Fuga.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type.fuga; 2 | 3 | /** 4 | * 普通のドメインモデル 5 | */ 6 | public class Fuga { 7 | 8 | FugaIdentifier identifier; 9 | FugaName name; 10 | 11 | public FugaName name() { 12 | return name; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/fuga/FugaIdentifier.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type.fuga; 2 | 3 | /** 4 | * 普通の識別子 5 | */ 6 | public class FugaIdentifier { 7 | 8 | String value; 9 | 10 | FugaIdentifier() { 11 | } 12 | 13 | public FugaIdentifier(String value) { 14 | this.value = value; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/fuga/FugaName.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type.fuga; 2 | 3 | public class FugaName { 4 | 5 | String value; 6 | 7 | FugaName() { 8 | } 9 | 10 | public FugaName(String value) { 11 | this.value = value; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return value; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/type/fuga/FugaRepository.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.type.fuga; 2 | 3 | /** 4 | * リポジトリ別名。句点以降はサマリから除外する。 5 | */ 6 | public interface FugaRepository { 7 | 8 | Fuga get(FugaIdentifier identifier); 9 | 10 | void register(Fuga fuga); 11 | } 12 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/visibility/DefaultType.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.visibility; 2 | 3 | class DefaultType { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/visibility/PublicType.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.visibility; 2 | 3 | public class PublicType { 4 | } 5 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/domain/model/visibility/TypeContainer.java: -------------------------------------------------------------------------------- 1 | package stub.domain.model.visibility; 2 | 3 | public class TypeContainer { 4 | 5 | protected static class ProtectedType { 6 | } 7 | 8 | private static class PrivateType { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/infrastructure/datasource/CanonicalMapper.java: -------------------------------------------------------------------------------- 1 | package stub.infrastructure.datasource; 2 | 3 | import org.apache.ibatis.annotations.*; 4 | 5 | @Mapper 6 | public interface CanonicalMapper { 7 | 8 | void insert(); 9 | 10 | void select(); 11 | 12 | void update(); 13 | 14 | void delete(); 15 | 16 | @Insert("insert into crud_test(a) values('a')") 17 | void annotationInsert(); 18 | 19 | @Select("select * from crud_test") 20 | void annotationSelect(); 21 | 22 | @Update("update crud_test set a = 'b'") 23 | void annotationUpdate(); 24 | 25 | @Delete("delete from crud_test") 26 | void annotationDelete(); 27 | 28 | String japanese(); 29 | 30 | void illegal(); 31 | 32 | int sequence_postgresql(); 33 | } 34 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/infrastructure/datasource/DecisionDatasource.java: -------------------------------------------------------------------------------- 1 | package stub.infrastructure.datasource; 2 | 3 | import org.springframework.stereotype.Repository; 4 | 5 | @Repository 6 | public class DecisionDatasource { 7 | 8 | void 分岐のあるメソッド(Object 条件) { 9 | if (条件 == null) { 10 | throw new NullPointerException(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/infrastructure/datasource/SampleMapper.java: -------------------------------------------------------------------------------- 1 | package stub.infrastructure.datasource; 2 | 3 | import org.apache.ibatis.annotations.Mapper; 4 | 5 | @Mapper 6 | public interface SampleMapper { 7 | 8 | boolean binding(String key); 9 | } 10 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/infrastructure/datasource/fuga/AnnotationMapper.java: -------------------------------------------------------------------------------- 1 | package stub.infrastructure.datasource.fuga; 2 | 3 | import org.apache.ibatis.annotations.*; 4 | 5 | import java.util.List; 6 | 7 | @Mapper 8 | public interface AnnotationMapper { 9 | 10 | @Select("SELECT value from sut.piyo") 11 | List select(); 12 | 13 | @Insert("INSERT into sut.piyo(id, value) values(1, 'x')") 14 | void insert(); 15 | 16 | @Update("UPDATE sut.piyo SET value = 'a'") 17 | void update(); 18 | 19 | @Delete("DELETE FROM sut.piyo") 20 | void delete(); 21 | } 22 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/infrastructure/datasource/fuga/FugaDatasource.java: -------------------------------------------------------------------------------- 1 | package stub.infrastructure.datasource.fuga; 2 | 3 | import org.springframework.stereotype.Repository; 4 | import stub.domain.model.type.fuga.Fuga; 5 | import stub.domain.model.type.fuga.FugaIdentifier; 6 | import stub.domain.model.type.fuga.FugaRepository; 7 | 8 | /** 9 | * データソース別名(この名前は使用されない) 10 | */ 11 | @Repository 12 | public class FugaDatasource implements FugaRepository { 13 | 14 | FugaMapper mapper; 15 | private final AnnotationMapper annotationMapper; 16 | 17 | public FugaDatasource(FugaMapper mapper, AnnotationMapper annotationMapper) { 18 | this.mapper = mapper; 19 | this.annotationMapper = annotationMapper; 20 | } 21 | 22 | @Override 23 | public Fuga get(FugaIdentifier identifier) { 24 | annotationMapper.insert(); 25 | return mapper.get(identifier); 26 | } 27 | 28 | @Override 29 | public void register(Fuga fuga) { 30 | // no-op 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/infrastructure/datasource/fuga/FugaMapper.java: -------------------------------------------------------------------------------- 1 | package stub.infrastructure.datasource.fuga; 2 | 3 | import org.apache.ibatis.annotations.Mapper; 4 | import stub.domain.model.type.fuga.Fuga; 5 | import stub.domain.model.type.fuga.FugaIdentifier; 6 | 7 | @Mapper 8 | public interface FugaMapper { 9 | 10 | Fuga get(FugaIdentifier identifier); 11 | } 12 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/misc/DecisionClass.java: -------------------------------------------------------------------------------- 1 | package stub.misc; 2 | 3 | import java.util.Collections; 4 | 5 | /** 6 | * 分岐を検出するためのクラス 7 | */ 8 | public class DecisionClass { 9 | int condition; 10 | 11 | void 分岐なしメソッド() { 12 | } 13 | 14 | void ifがあるメソッド() { 15 | if (condition <= 0) { 16 | System.out.println("true"); 17 | } 18 | System.out.println("hoge"); 19 | } 20 | 21 | void null判定があるメソッド(Object arg) { 22 | if (arg == null) { 23 | System.out.println("null"); 24 | } 25 | } 26 | 27 | void switchがあるメソッド() { 28 | switch (condition) { 29 | case 1: 30 | System.out.println(1); 31 | case 2: 32 | System.out.println(2); 33 | default: 34 | System.out.println(0); 35 | } 36 | } 37 | 38 | void forがあるメソッド() { 39 | for (Object obj : Collections.emptyList()) { 40 | System.out.println(obj); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * テストでJIGに読み取らせる実装 3 | */ 4 | package stub; -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/presentation/controller/DecisionController.java: -------------------------------------------------------------------------------- 1 | package stub.presentation.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | 5 | /** 6 | * 分岐のあるコントローラー 7 | */ 8 | @Controller 9 | public class DecisionController { 10 | 11 | void 分岐のあるメソッド(Object 条件) { 12 | if (条件 == null) { 13 | throw new NullPointerException(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/presentation/controller/SimpleController.java: -------------------------------------------------------------------------------- 1 | package stub.presentation.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import stub.application.service.SimpleService; 6 | 7 | @Controller 8 | @RequestMapping("simple-class") 9 | public class SimpleController { 10 | 11 | SimpleService service; 12 | 13 | @RequestMapping("/simple-method") 14 | public String getService() { 15 | service.コントローラーから呼ばれる(); 16 | return "dummy"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /jig-core/src/test/java/stub/presentation/controller/SimpleRestController.java: -------------------------------------------------------------------------------- 1 | package stub.presentation.controller; 2 | 3 | import io.swagger.v3.oas.annotations.Operation; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.PostMapping; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import stub.application.service.SimpleService; 9 | 10 | @RestController 11 | public class SimpleRestController { 12 | 13 | SimpleService service; 14 | 15 | @GetMapping(value = "test-get") 16 | @PostMapping(path = "test-post") 17 | public String getService() { 18 | service.RESTコントローラーから呼ばれる(); 19 | return "dummy"; 20 | } 21 | 22 | @Operation(summary = "さまり") 23 | @RequestMapping("swagger-operation-annotated") 24 | public void swaggerOperationAnnotated() { 25 | } 26 | 27 | @Operation 28 | @RequestMapping("swagger-operation-annotated-none-summary") 29 | public void swaggerOperationAnnotatedNoneSummary() { 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /jig-core/src/test/java/testing/JigServiceTest.java: -------------------------------------------------------------------------------- 1 | package testing; 2 | 3 | import org.junit.jupiter.api.extension.ExtendWith; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @ExtendWith(JigTestExtension.class) 11 | @Target({ElementType.TYPE, ElementType.METHOD}) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface JigServiceTest { 14 | } 15 | -------------------------------------------------------------------------------- /jig-core/src/test/java/testing/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JIGのテストをサポートするJUnit拡張など 3 | */ 4 | package testing; -------------------------------------------------------------------------------- /jig-core/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | [%5r][%level][%thread][%logger{10}] %message%n 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /jig-core/src/test/resources/marker.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dddjava/jig/b531cc369f11dfeb92c04bfd8140bb5ddf2b099a/jig-core/src/test/resources/marker.properties -------------------------------------------------------------------------------- /jig-core/src/test/resources/stub/infrastructure/datasource/CanonicalMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | insert into crud_test(a) values('a') 9 | 10 | 13 | 14 | update crud_test set a = 'a' 15 | 16 | 17 | delete from crud_test 18 | 19 | 20 | 23 | 24 | 25 | SQLじゃない何かが入っているとか 26 | 27 | 28 | 31 | 32 | INSERT INTO tab_test ( a ) values ('a') 33 | 34 | UPDATE tab_test SET a = 'a' 35 | DELETE FROM tab_test WHERE true 36 | -------------------------------------------------------------------------------- /jig-core/src/test/resources/stub/infrastructure/datasource/SampleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 14 | 15 | 16 | AND 1 = 1 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /jig-core/src/test/resources/stub/infrastructure/datasource/fuga/FugaMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 20 | 21 | 22 | AND 1 = 1 23 | 24 | -------------------------------------------------------------------------------- /jig-gradle-plugin/src/main/java/org/dddjava/jig/gradle/JigGradlePlugin.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.gradle; 2 | 3 | import org.gradle.api.Plugin; 4 | import org.gradle.api.Project; 5 | import org.gradle.api.plugins.ExtensionContainer; 6 | import org.gradle.api.tasks.TaskContainer; 7 | 8 | public class JigGradlePlugin implements Plugin { 9 | 10 | @Override 11 | public void apply(Project project) { 12 | ExtensionContainer extensions = project.getExtensions(); 13 | extensions.create("jig", JigConfig.class); 14 | TaskContainer tasks = project.getTasks(); 15 | 16 | tasks.register("jigReports", JigReportsTask.class).configure(task -> { 17 | task.setGroup("JIG"); 18 | task.setDescription("Generates JIG documentation for the main source code."); 19 | }); 20 | 21 | tasks.register("verifyJigEnvironment", VerifyJigEnvironmentTask.class).configure(task -> { 22 | task.setGroup("JIG"); 23 | task.setDescription("Verify JIG environment."); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /jig-gradle-plugin/src/main/java/org/dddjava/jig/gradle/VerifyJigEnvironmentTask.java: -------------------------------------------------------------------------------- 1 | package org.dddjava.jig.gradle; 2 | 3 | import org.dddjava.jig.adapter.diagram.DotCommandRunner; 4 | import org.gradle.api.DefaultTask; 5 | import org.gradle.api.logging.Logger; 6 | import org.gradle.api.tasks.TaskAction; 7 | 8 | public class VerifyJigEnvironmentTask extends DefaultTask { 9 | 10 | @TaskAction 11 | void verify() { 12 | try { 13 | DotCommandRunner dotCommandRunner = new DotCommandRunner(); 14 | dotCommandRunner.verify(); 15 | } catch (RuntimeException e) { 16 | Logger logger = getLogger(); 17 | logger.warn("-- JIG ERROR -----------------------------------------------"); 18 | logger.warn("+ 実行可能なGraphvizが見つけられませんでした。"); 19 | logger.warn("+ dotにPATHが通っているか確認してください。"); 20 | logger.warn("+ JIGは図の出力にGraphvizを使用しています。"); 21 | logger.warn("+ "); 22 | logger.warn("+ Graphvizは以下から入手できます。"); 23 | logger.warn("+ https://www.graphviz.org/"); 24 | logger.warn("------------------------------------------------------------"); 25 | 26 | throw e; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /jig-gradle-plugin/src/test/java/jig/JigPluginUnitTest.java: -------------------------------------------------------------------------------- 1 | package jig; 2 | 3 | import org.dddjava.jig.gradle.JigReportsTask; 4 | import org.gradle.testfixtures.ProjectBuilder; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertInstanceOf; 8 | 9 | /** 10 | * jig-gradle-pluginのUnitTest 11 | * 12 | * POJOからProjectBuilderを使用しての範囲をUnitTestとする。 13 | */ 14 | public class JigPluginUnitTest { 15 | 16 | /** 17 | * プラグイン適用はProjectBuilderで検証する。 18 | */ 19 | @Test 20 | void プラグイン適用でjigReportsタスクが登録される() { 21 | var project = ProjectBuilder.builder().build(); 22 | project.getPluginManager().apply("org.dddjava.jig-gradle-plugin"); 23 | 24 | assertInstanceOf(JigReportsTask.class, project.getTasks().getByName("jigReports")); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /jig-gradle-plugin/src/test/java/jig/SupportGradleVersion.java: -------------------------------------------------------------------------------- 1 | package jig; 2 | 3 | import org.gradle.util.GradleVersion; 4 | 5 | /** 6 | * サポートするGradleのバージョン 7 | */ 8 | public enum SupportGradleVersion { 9 | /** 10 | * JIGが使用しているGradleのバージョン  11 | */ 12 | CURRENT(GradleVersion.current().getVersion()), 13 | /** 14 | * 最新 15 | */ 16 | LATEST("8.13"), 17 | /** 18 | * 一つ前のメジャーバージョンの最終 19 | */ 20 | PREVIOUS_MAJOR_LATEST("7.6.4"); 21 | 22 | private final String version; 23 | 24 | SupportGradleVersion(String version) { 25 | this.version = version; 26 | } 27 | 28 | public String getVersion() { 29 | return version; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /jig-maven-plugin/README.md: -------------------------------------------------------------------------------- 1 | jig-maven-plugin 2 | ============================================================ 3 | 4 | *これはまだ動きません* 5 | 6 | ## 簡易実行 7 | 8 | ``` 9 | mvn org.dddjava.jig:jig-maven-plugin:jig 10 | ``` 11 | 12 | `pom.xml` には何も書かなくていいです。 13 | 14 | ## 通常 15 | 16 | プラグインのバージョンとか設定を `/project/build/plugins` に追加 17 | 18 | ```pom.xml 19 | 20 | ... 21 | 22 | ... 23 | 24 | ... 25 | 26 | org.dddjava.jig 27 | jig-maven-plugin 28 | {jig.version} 29 | 30 | .* 31 | 32 | 33 | 34 | 35 | 36 | ``` 37 | 38 | 実行 39 | 40 | ``` 41 | mvn jig:jig 42 | ``` 43 | 44 | # 設定 45 | 46 | |対象|configurationタグ名|プロパティ名| 47 | |----|----|----| 48 | |出力対象JIGドキュメント| `documentTypes` | `jig.document.types` | 49 | |ドメインのパターン| `domainPattern` | `jig.pattern.domain` | 50 | 51 | ともに任意。指定なしの場合はJIGのデフォルトに従う。 52 | -------------------------------------------------------------------------------- /jig-maven-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'jig.java-conventions' 3 | id 'jig.ossrh-conventions' 4 | id 'java-library' 5 | } 6 | 7 | java { 8 | registerFeature('optional') { 9 | usingSourceSet(sourceSets.main) 10 | } 11 | } 12 | 13 | dependencies { 14 | api project(':jig-core') 15 | compileOnly 'org.apache.maven:maven-plugin-api:3.9.6' 16 | compileOnly 'org.apache.maven.plugin-tools:maven-plugin-annotations:3.11.0' 17 | } 18 | 19 | ossrh { 20 | description = "Maven plugin for JIG" 21 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'jig' 2 | 3 | include 'jig-core' 4 | include 'jig-cli' 5 | include 'jig-gradle-plugin' 6 | 7 | // TODO mavenプラグインとして動くようにしてから有効にする 8 | //include 'jig-maven-plugin' 9 | --------------------------------------------------------------------------------