├── .dockerignore
├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── .project
├── .settings
├── com.wdev91.eclipse.copyright.xml
├── org.eclipse.core.resources.prefs
├── org.eclipse.core.runtime.prefs
├── org.eclipse.jdt.apt.core.prefs
├── org.eclipse.jdt.core.prefs
└── org.eclipse.jdt.ui.prefs
├── Dockerfile
├── Dockerfile.aarch64
├── LICENSE.txt
├── README.md
├── build-jq.sh
├── build.gradle
├── core.gradle
├── docker-build.sh
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
├── main
├── c
│ ├── jq.h
│ └── jv.h
├── java
│ └── com
│ │ └── arakelian
│ │ └── jq
│ │ ├── JqLibrary.java
│ │ ├── JqRequest.java
│ │ ├── JqResponse.java
│ │ ├── NativeLib.java
│ │ └── package-info.java
└── resources
│ └── lib
│ ├── darwin-aarch64
│ └── libjq.dylib
│ ├── darwin-x86_64
│ └── libjq.dylib
│ ├── linux-aarch64
│ └── libjq.so
│ └── linux-x86_64
│ └── libjq.so
└── test
├── java
└── com
│ └── arakelian
│ └── jq
│ ├── AbstractJqTest.java
│ ├── Base64Test.java
│ ├── JqTest.java
│ ├── OnigurumaTest.java
│ └── OptionalTest.java
└── resources
├── base64.test
├── jq.test
├── logging.properties
├── modules
├── .jq
├── a.jq
├── b
│ └── b.jq
├── c
│ ├── c.jq
│ └── d.jq
├── data.json
├── lib
│ └── jq
│ │ ├── e
│ │ └── e.jq
│ │ └── f.jq
├── syntaxerror
│ └── syntaxerror.jq
├── test_bind_order.jq
├── test_bind_order0.jq
├── test_bind_order1.jq
└── test_bind_order2.jq
├── onig.test
└── optional.test
/.dockerignore:
--------------------------------------------------------------------------------
1 | .*
2 | *.gradle
3 | LICENSE.txt
4 | README.md
5 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - main
7 | push:
8 | branches:
9 | - main
10 | workflow_dispatch:
11 | branches:
12 | - main
13 |
14 | jobs:
15 | build:
16 | runs-on: ubuntu-latest
17 | strategy:
18 | matrix:
19 | java: [ '11' ]
20 | steps:
21 | - uses: actions/checkout@v2
22 | with:
23 | fetch-depth: 0
24 | - name: Set up JDK ${{ matrix.java }}
25 | uses: actions/setup-java@v2
26 | with:
27 | java-version: ${{ matrix.java }}
28 | distribution: 'adopt'
29 | - name: Print Java version
30 | run: java -version
31 | - name: Gradle wrapper validation
32 | uses: gradle/wrapper-validation-action@v1
33 | - name: Run tests
34 | run: ./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --stacktrace clean build
35 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 |
4 | ### Emacs ###
5 | # -*- mode: gitignore; -*-
6 | *~
7 | \#*\#
8 | .\#*
9 |
10 | ### Gradle ###
11 | .gradle
12 | build/
13 |
14 | ### Node ###
15 | # Logs
16 | logs
17 | *.log
18 | npm-debug.log*
19 |
20 | # Runtime data
21 | pids
22 | *.pid
23 | *.seed
24 |
25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26 | .grunt
27 |
28 | # Dependency directory
29 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
30 | node_modules
31 |
32 |
33 | ### Intellij ###
34 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
35 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
36 |
37 | # User-specific stuff:
38 | .idea/workspace.xml
39 | .idea/tasks.xml
40 | .idea/dictionaries
41 | .idea/vcs.xml
42 | .idea/jsLibraryMappings.xml
43 |
44 | # Sensitive or high-churn files:
45 | .idea/dataSources.ids
46 | .idea/dataSources.xml
47 | .idea/dataSources.local.xml
48 | .idea/sqlDataSources.xml
49 | .idea/dynamic.xml
50 | .idea/uiDesigner.xml
51 |
52 | # Gradle:
53 | .idea/gradle.xml
54 | .idea/libraries
55 |
56 | # Mongo Explorer plugin:
57 | .idea/mongoSettings.xml
58 |
59 | ## File-based project format:
60 | *.iws
61 |
62 | ## Plugin-specific files:
63 |
64 | # IntelliJ
65 | /out/
66 |
67 | # mpeltonen/sbt-idea plugin
68 | .idea_modules/
69 |
70 | # JIRA plugin
71 | atlassian-ide-plugin.xml
72 |
73 | # Crashlytics plugin (for Android Studio and IntelliJ)
74 | com_crashlytics_export_strings.xml
75 | crashlytics.properties
76 | crashlytics-build.properties
77 | fabric.properties
78 |
79 | ### Intellij Patch ###
80 | *.iml
81 |
82 |
83 | ### Eclipse ###
84 | .metadata
85 | .classpath
86 | .factorypath
87 | .apt_generated
88 | generated_src
89 | bin/
90 | target/
91 | tmp/
92 | *.tmp
93 | *.bak
94 | *.swp
95 | *~.nib
96 |
97 |
98 | ### grunt ###
99 | # Grunt usually compiles files inside this directory
100 | dist/
101 |
102 | # Grunt usually preprocesses files such as coffeescript, compass... inside the .tmp directory
103 | .tmp/
104 | /.apt_generated_tests/
105 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | java-jq
4 | Java JQ
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.settings/com.wdev91.eclipse.copyright.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
49 |
50 |
55 |
56 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | encoding/=UTF-8
--------------------------------------------------------------------------------
/.settings/org.eclipse.core.runtime.prefs:
--------------------------------------------------------------------------------
1 | #Sun Mar 21 12:59:37 EDT 2010
2 | eclipse.preferences.version=1
3 | line.separator=\n
4 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.apt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.apt.aptEnabled=true
3 | org.eclipse.jdt.apt.genSrcDir=target/generated_src
4 | org.eclipse.jdt.apt.reconcileEnabled=true
5 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
3 | org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
4 | org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
5 | org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
6 | org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
7 | org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
8 | org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
9 | org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
10 | org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
11 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
12 | org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
13 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
14 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
15 | org.eclipse.jdt.core.compiler.compliance=11
16 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
17 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
18 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
19 | org.eclipse.jdt.core.compiler.doc.comment.support=enabled
20 | org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
21 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
22 | org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
23 | org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
24 | org.eclipse.jdt.core.compiler.problem.deadCode=ignore
25 | org.eclipse.jdt.core.compiler.problem.deprecation=warning
26 | org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
27 | org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
28 | org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
29 | org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
30 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
31 | org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
32 | org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
33 | org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
34 | org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
35 | org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
36 | org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
37 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
38 | org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
39 | org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
40 | org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
41 | org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
42 | org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
43 | org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
44 | org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
45 | org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
46 | org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
47 | org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=public
48 | org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
49 | org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
50 | org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
51 | org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
52 | org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
53 | org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
54 | org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
55 | org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
56 | org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
57 | org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
58 | org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
59 | org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
60 | org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
61 | org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
62 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
63 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
64 | org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
65 | org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
66 | org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
67 | org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
68 | org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
69 | org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
70 | org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
71 | org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
72 | org.eclipse.jdt.core.compiler.problem.nullReference=warning
73 | org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
74 | org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
75 | org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
76 | org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
77 | org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
78 | org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
79 | org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
80 | org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
81 | org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
82 | org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
83 | org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
84 | org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
85 | org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
86 | org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
87 | org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
88 | org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
89 | org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
90 | org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
91 | org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
92 | org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
93 | org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
94 | org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
95 | org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
96 | org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
97 | org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
98 | org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
99 | org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
100 | org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
101 | org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
102 | org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
103 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
104 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
105 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
106 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
107 | org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
108 | org.eclipse.jdt.core.compiler.problem.unusedImport=warning
109 | org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
110 | org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
111 | org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
112 | org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
113 | org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
114 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
115 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
116 | org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
117 | org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
118 | org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
119 | org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
120 | org.eclipse.jdt.core.compiler.processAnnotations=enabled
121 | org.eclipse.jdt.core.compiler.source=11
122 | org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
123 | org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
124 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
125 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
126 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
127 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
128 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=48
129 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
130 | org.eclipse.jdt.core.formatter.alignment_for_assignment=0
131 | org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
132 | org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
133 | org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
134 | org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
135 | org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
136 | org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
137 | org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
138 | org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
139 | org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
140 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=48
141 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=48
142 | org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
143 | org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
144 | org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
145 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
146 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
147 | org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
148 | org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
149 | org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
150 | org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
151 | org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
152 | org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
153 | org.eclipse.jdt.core.formatter.blank_lines_after_package=1
154 | org.eclipse.jdt.core.formatter.blank_lines_before_field=0
155 | org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
156 | org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
157 | org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
158 | org.eclipse.jdt.core.formatter.blank_lines_before_method=1
159 | org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
160 | org.eclipse.jdt.core.formatter.blank_lines_before_package=0
161 | org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
162 | org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
163 | org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
164 | org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
165 | org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
166 | org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
167 | org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
168 | org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
169 | org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
170 | org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
171 | org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
172 | org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
173 | org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
174 | org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
175 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
176 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
177 | org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false
178 | org.eclipse.jdt.core.formatter.comment.format_block_comments=true
179 | org.eclipse.jdt.core.formatter.comment.format_header=false
180 | org.eclipse.jdt.core.formatter.comment.format_html=true
181 | org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
182 | org.eclipse.jdt.core.formatter.comment.format_line_comments=true
183 | org.eclipse.jdt.core.formatter.comment.format_source_code=true
184 | org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
185 | org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
186 | org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
187 | org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
188 | org.eclipse.jdt.core.formatter.comment.line_length=100
189 | org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
190 | org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
191 | org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
192 | org.eclipse.jdt.core.formatter.compact_else_if=true
193 | org.eclipse.jdt.core.formatter.continuation_indentation=2
194 | org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
195 | org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
196 | org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
197 | org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
198 | org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
199 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
200 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
201 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
202 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
203 | org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
204 | org.eclipse.jdt.core.formatter.indent_empty_lines=false
205 | org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
206 | org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
207 | org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
208 | org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
209 | org.eclipse.jdt.core.formatter.indentation.size=4
210 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
211 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
212 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
213 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
214 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
215 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
216 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
217 | org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
218 | org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
219 | org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
220 | org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
221 | org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
222 | org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
223 | org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
224 | org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
225 | org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
226 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
227 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
228 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
229 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
230 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
231 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
232 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
233 | org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
234 | org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
235 | org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
236 | org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
237 | org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
238 | org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
239 | org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
240 | org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
241 | org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
242 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
243 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
244 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
245 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
246 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
247 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
248 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
249 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
250 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
251 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
252 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
253 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
254 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
255 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
256 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
257 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
258 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
259 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
260 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
261 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
262 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
263 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
264 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
265 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
266 | org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
267 | org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
268 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
269 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
270 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
271 | org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
272 | org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
273 | org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
274 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
275 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
276 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
277 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
278 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
279 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
280 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
281 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
282 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
283 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
284 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
285 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
286 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
287 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
288 | org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
289 | org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
290 | org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
291 | org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
292 | org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
293 | org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
294 | org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
295 | org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
296 | org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
297 | org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
298 | org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
299 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
300 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
301 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
302 | org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
303 | org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
304 | org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
305 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
306 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
307 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
308 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
309 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
310 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
311 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
312 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
313 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
314 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
315 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
316 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
317 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
318 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
319 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
320 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
321 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
322 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
323 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
324 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
325 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
326 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
327 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
328 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
329 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
330 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
331 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
332 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
333 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
334 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
335 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
336 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
337 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
338 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
339 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
340 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
341 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
342 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
343 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
344 | org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
345 | org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
346 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
347 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
348 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
349 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
350 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
351 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
352 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
353 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
354 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
355 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
356 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
357 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
358 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
359 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
360 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
361 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
362 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
363 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
364 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
365 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
366 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
367 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
368 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
369 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
370 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
371 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
372 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
373 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
374 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
375 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
376 | org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
377 | org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
378 | org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
379 | org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
380 | org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
381 | org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
382 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
383 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
384 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
385 | org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
386 | org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
387 | org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
388 | org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
389 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
390 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
391 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
392 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
393 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
394 | org.eclipse.jdt.core.formatter.join_lines_in_comments=true
395 | org.eclipse.jdt.core.formatter.join_wrapped_lines=true
396 | org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
397 | org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
398 | org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
399 | org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
400 | org.eclipse.jdt.core.formatter.lineSplit=110
401 | org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
402 | org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
403 | org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
404 | org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
405 | org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
406 | org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
407 | org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
408 | org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
409 | org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
410 | org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
411 | org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
412 | org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
413 | org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
414 | org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
415 | org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
416 | org.eclipse.jdt.core.formatter.tabulation.char=space
417 | org.eclipse.jdt.core.formatter.tabulation.size=4
418 | org.eclipse.jdt.core.formatter.use_on_off_tags=true
419 | org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
420 | org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
421 | org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
422 | org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
423 | org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
424 | org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
425 | org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
426 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.ui.prefs:
--------------------------------------------------------------------------------
1 | cleanup.add_default_serial_version_id=true
2 | cleanup.add_generated_serial_version_id=false
3 | cleanup.add_missing_annotations=true
4 | cleanup.add_missing_deprecated_annotations=true
5 | cleanup.add_missing_methods=false
6 | cleanup.add_missing_nls_tags=false
7 | cleanup.add_missing_override_annotations=true
8 | cleanup.add_missing_override_annotations_interface_methods=true
9 | cleanup.add_serial_version_id=false
10 | cleanup.always_use_blocks=true
11 | cleanup.always_use_parentheses_in_expressions=false
12 | cleanup.always_use_this_for_non_static_field_access=false
13 | cleanup.always_use_this_for_non_static_method_access=false
14 | cleanup.convert_functional_interfaces=false
15 | cleanup.convert_to_enhanced_for_loop=false
16 | cleanup.correct_indentation=true
17 | cleanup.format_source_code=true
18 | cleanup.format_source_code_changes_only=false
19 | cleanup.insert_inferred_type_arguments=false
20 | cleanup.make_local_variable_final=true
21 | cleanup.make_parameters_final=true
22 | cleanup.make_private_fields_final=true
23 | cleanup.make_type_abstract_if_missing_method=false
24 | cleanup.make_variable_declarations_final=true
25 | cleanup.never_use_blocks=false
26 | cleanup.never_use_parentheses_in_expressions=true
27 | cleanup.organize_imports=true
28 | cleanup.qualify_static_field_accesses_with_declaring_class=false
29 | cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
30 | cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=false
31 | cleanup.qualify_static_member_accesses_with_declaring_class=true
32 | cleanup.qualify_static_method_accesses_with_declaring_class=false
33 | cleanup.remove_private_constructors=true
34 | cleanup.remove_redundant_type_arguments=true
35 | cleanup.remove_trailing_whitespaces=true
36 | cleanup.remove_trailing_whitespaces_all=true
37 | cleanup.remove_trailing_whitespaces_ignore_empty=false
38 | cleanup.remove_unnecessary_casts=true
39 | cleanup.remove_unnecessary_nls_tags=true
40 | cleanup.remove_unused_imports=true
41 | cleanup.remove_unused_local_variables=true
42 | cleanup.remove_unused_private_fields=true
43 | cleanup.remove_unused_private_members=false
44 | cleanup.remove_unused_private_methods=true
45 | cleanup.remove_unused_private_types=true
46 | cleanup.sort_members=true
47 | cleanup.sort_members_all=false
48 | cleanup.use_anonymous_class_creation=false
49 | cleanup.use_blocks=true
50 | cleanup.use_blocks_only_for_return_and_throw=false
51 | cleanup.use_lambda=true
52 | cleanup.use_parentheses_in_expressions=true
53 | cleanup.use_this_for_non_static_field_access=false
54 | cleanup.use_this_for_non_static_field_access_only_if_necessary=true
55 | cleanup.use_this_for_non_static_method_access=false
56 | cleanup.use_this_for_non_static_method_access_only_if_necessary=true
57 | cleanup.use_type_arguments=false
58 | cleanup_profile=_Arakelian Software profile
59 | cleanup_settings_version=2
60 | eclipse.preferences.version=1
61 | formatter_profile=_Arakelian Software profile
62 | formatter_settings_version=13
63 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # java-jq
2 |
3 | FROM ubuntu:14.04
4 | LABEL maintainer="Greg Arakelian "
5 |
6 | # install required software
7 | RUN apt update && \
8 | apt install -y build-essential git autoconf automake libtool wget bash valgrind
9 |
10 | # copy script
11 | COPY build-jq.sh /usr/local/bin
12 |
13 | # build jq
14 | RUN cd ~ && \
15 | chmod 755 /usr/local/bin/*.sh && \
16 | build-jq.sh
17 |
--------------------------------------------------------------------------------
/Dockerfile.aarch64:
--------------------------------------------------------------------------------
1 | FROM debian:buster-slim
2 | LABEL "description"="Docker image for building libjq"
3 | LABEL "author"="nicolae.natea"
4 |
5 | WORKDIR /home
6 | RUN apt-get update && apt-get install -y build-essential autoconf automake libtool curl
7 | ADD https://github.com/stedolan/jq/releases/download/jq-1.6/jq-1.6.tar.gz .
8 | ADD https://raw.githubusercontent.com/Homebrew/formula-patches/03cf8088210822aa2c1ab544ed58ea04c897d9c4/libtool/configure-big_sur.diff flat_namespace.patch
9 | RUN tar --extract --file "jq-1.6.tar.gz" && \
10 | cd /home/jq-1.6/modules/oniguruma && \
11 | autoreconf -fi && \
12 | cd /home/jq-1.6 && \
13 | patch < /home/flat_namespace.patch && \
14 | autoreconf -fi && \
15 | CPPFLAGS="-D_REENTRANT -fPIC" ./configure --prefix="$INSTALL_BASE" --disable-maintainer-mode --disable-docs --with-oniguruma=builtin && \
16 | make -j4
17 | RUN gcc -shared -o libjq.so -Wl,--whole-archive jq-1.6/modules/oniguruma/src/.libs/libonig.a jq-1.6/.libs/libjq.a -Wl,--no-whole-archive
18 |
19 | # Option to make all static: make LDFLAGS=-all-static
20 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Bradley Skaggs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # java-jq
2 | [](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.arakelian%22%20AND%20a%3A%22java-jq%22)
3 | [](https://github.com/arakelian/java-jq/actions/workflows/ci.yml)
4 |
5 | java-jq is not a re-implementation of [jq](http://stedolan.github.io/jq/) in Java; instead,
6 | it embeds the necessary jq and Oniguruma native libraries in a jar file, and then uses
7 | [Java Native Access](https://github.com/java-native-access/jna) (JNA) to call the embedded
8 | libraries in a Java-friendly way.
9 |
10 | The distribution of java-jq includes native JQ 1.6 libraries for all major platforms (Mac, Windows and Linux),
11 | and includes a statically linked version of Oniguruma 5.9.6 to avoid any runtime compatibility issues.
12 |
13 | java-jq was heavily inspired by [jjq](https://github.com/bskaggs/jjq).
14 |
15 |
16 | ## Usage
17 |
18 | Using Java-JQ is very easy.
19 |
20 |
21 | First, let's get a reference to the Native JQ library. This class is a thread-safe singleton.
22 |
23 | ```java
24 | JqLibrary library = ImmutableJqLibrary.of();
25 | ```
26 |
27 | Now, let's create a JQ request. A "request" is an immutable bean that contains three basic elements: a reference
28 | to the JQ library we created above, the JSON input you want to transform, and the JQ filter expression that you
29 | want to execute.
30 |
31 | ```java
32 | final JqRequest request = ImmutableJqRequest.builder() //
33 | .lib(library) //
34 | .input("{\"a\":[1,2,3,4,5],\"b\":\"hello\"}") //
35 | .filter(".") //
36 | .build();
37 | ```
38 |
39 | As a final step, let's execute the request.
40 |
41 | ```java
42 | final JqResponse response = request.execute();
43 | if( response.hasErrors() ) {
44 | // display errors in response.getErrors()
45 | } else {
46 | System.out.println( "JQ output: " + response.getOutput());
47 | }
48 | ```
49 |
50 | ## Compatibility
51 |
52 | As of version 1.1.0, java-jq successfully executes the complete [jq](http://stedolan.github.io/jq/)
53 | test suite, including all tests in jq.test, onig.test, base64.test, and optional.test.
54 |
55 | java-jq supports modules as well. To use modules, include the directory paths where your modules
56 | can be found with your JqRequest as follows:
57 |
58 | ```java
59 | final JqRequest request = ImmutableJqRequest.builder() //
60 | .lib(library) //
61 | .input("your json goes here") //
62 | .filter(".") //
63 | .addModulePath(new File("/some/modules/can/be/found/here")) //
64 | .addModulePath(new File("/other/modules/can/be/found/here")) //
65 | .build();
66 | ```
67 |
68 |
69 | ## Installation
70 |
71 | The library is available on [Maven Central](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.arakelian%22%20AND%20a%3A%22java-jq%22).
72 |
73 | ### Maven
74 |
75 | Add the following to your `pom.xml`:
76 |
77 | ```xml
78 |
79 |
80 | central
81 | Central Repository
82 | http://repo.maven.apache.org/maven2
83 |
84 | true
85 |
86 |
87 |
88 |
89 | ...
90 |
91 |
92 | com.arakelian
93 | java-jq
94 | 2.0.0
95 | test
96 |
97 | ```
98 |
99 | ### Gradle
100 |
101 | Add the following to your `build.gradle`:
102 |
103 | ```groovy
104 | repositories {
105 | mavenCentral()
106 | }
107 |
108 | dependencies {
109 | testCompile 'com.arakelian:java-jq:2.0.0'
110 | }
111 | ```
112 |
113 | ## Licence
114 |
115 | Apache Version 2.0
116 |
--------------------------------------------------------------------------------
/build-jq.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mkdir -p build
4 | cd build
5 |
6 | ONIGURUMA_VERSION=5.9.6
7 | JQ_VERSION=1.6
8 |
9 | PLATFORM=$(printf "$(uname)-$(uname -m)" | tr "[A-Z]" "[a-z]")
10 |
11 | wget https://github.com/kkos/oniguruma/releases/download/v${ONIGURUMA_VERSION}/onig-${ONIGURUMA_VERSION}.tar.gz && \
12 | tar xvf onig-${ONIGURUMA_VERSION}.tar.gz && \
13 | rm onig-${ONIGURUMA_VERSION}.tar.gz && \
14 | cd onig-${ONIGURUMA_VERSION} && \
15 | ./configure --prefix $(cd .. && pwd -P) && \
16 | make && \
17 | make install && \
18 | cd ..
19 |
20 | wget https://github.com/stedolan/jq/releases/download/jq-${JQ_VERSION}/jq-${JQ_VERSION}.tar.gz && \
21 | tar xvf jq-${JQ_VERSION}.tar.gz && \
22 | rm jq-${JQ_VERSION}.tar.gz && \
23 | cd jq-${JQ_VERSION} && \
24 | ./configure --disable-maintainer-mode --prefix $(cd .. && pwd -P) --with-oniguruma=$(cd .. && pwd -P) --disable-docs && \
25 | sed -i.bak 's/LIBS = -lonig/LIBS = /' Makefile && \
26 | sed -i.bak "s/libjq_la_LIBADD = -lm/libjq_la_LIBADD = -lm $(find ../onig-${ONIGURUMA_VERSION} -name '*.lo' | xargs echo | sed 's/\//\\\//g')/" Makefile && \
27 | sed -i.bak "s/jq_LDADD = libjq.la -lm/jq_LDADD = libjq.la -lm $(find ../onig-${ONIGURUMA_VERSION} -name '*.lo' | xargs echo | sed 's/\//\\\//g')/" Makefile && \
28 | make && \
29 | make install && \
30 | cd ..
31 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // java-jq
2 |
3 | plugins {
4 | id 'java-library'
5 | id 'maven-publish'
6 | id 'signing'
7 | id 'eclipse'
8 | id 'idea'
9 |
10 | // keep dependencies up-to-date!
11 | id 'com.github.ben-manes.versions' version '0.51.0'
12 |
13 | // useful for creating immutable java beans
14 | id 'org.inferred.processors' version '3.7.0'
15 |
16 | // to ensure clean code
17 | id "net.ltgt.errorprone" version "3.1.0"
18 |
19 | // for deployment to Maven Central
20 | id "io.codearte.nexus-staging" version "0.30.0"
21 | }
22 |
23 | group = 'com.arakelian'
24 | version = '2.0.0'
25 |
26 |
27 | apply from: "core.gradle"
28 |
29 | wrapper {
30 | gradleVersion = '8.5'
31 | }
32 |
33 | publishing.publications.mavenJava {
34 | pom {
35 | name = "Java JQ"
36 | description = "java-jq is not a re-implementation of jq in Java. It uses JNA to access embedded libraries."
37 | url = "https://github.com/arakelian/java-jq"
38 |
39 | licenses {
40 | license {
41 | name = 'The Apache License, Version 2.0'
42 | url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
43 | }
44 | }
45 |
46 | developers {
47 | developer {
48 | id = 'arakelian'
49 | name = 'Greg Arakelian'
50 | email = 'greg@arakelian.com'
51 | }
52 | }
53 |
54 | scm {
55 | connection = 'scm:git:https://github.com/arakelian/java-jq.git'
56 | developerConnection = 'scm:git:git@github.com:arakelian/java-jq.git'
57 | url = 'https://github.com/arakelian/java-jq.git'
58 | }
59 | }
60 | }
61 |
62 | dependencies {
63 | processor 'org.immutables:value:2.10.1'
64 |
65 | // annotations
66 | api 'org.immutables:value-annotations:2.10.1'
67 |
68 | // configure errorprone version
69 | errorprone 'com.google.errorprone:error_prone_core:2.27.0'
70 |
71 | // miscellaneous usages
72 | api 'com.google.guava:guava:33.1.0-jre'
73 |
74 | // needed for access to native code
75 | api 'net.java.dev.jna:jna:5.14.0'
76 |
77 | // logging
78 | testImplementation 'org.apache.logging.log4j:log4j-api:2.21.1'
79 | testImplementation 'org.apache.logging.log4j:log4j-core:2.21.1'
80 | testImplementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.21.1'
81 | testImplementation 'org.slf4j:jcl-over-slf4j:2.0.12'
82 | testImplementation 'org.slf4j:jul-to-slf4j:2.0.12'
83 | api 'org.slf4j:slf4j-api:2.0.12'
84 |
85 | // for unit testing
86 | testImplementation 'com.fasterxml.jackson.core:jackson-core:2.17.0'
87 | testImplementation 'com.fasterxml.jackson.core:jackson-databind:2.17.0'
88 | testImplementation 'com.fasterxml.jackson.module:jackson-module-parameter-names:2.17.0'
89 | testImplementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.17.0'
90 | testImplementation 'net.javacrumbs.json-unit:json-unit:2.38.0' // last for JDK 11
91 |
92 | // for unit testing
93 | testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2'
94 | }
95 |
--------------------------------------------------------------------------------
/core.gradle:
--------------------------------------------------------------------------------
1 |
2 | buildscript {
3 | repositories {
4 | mavenCentral()
5 | }
6 | dependencies {
7 | classpath 'com.guardsquare:proguard-gradle:7.2.1' // The ProGuard Gradle plugin.
8 | }
9 | }
10 |
11 |
12 | ext {
13 | // useful macros, you can add your own
14 | macros = [
15 | 'all' : [
16 | 'clean',
17 | 'classpath',
18 | 'build',
19 | 'minify',
20 | 'generatePomFileForInternalPublication', // needed to generate internal POM
21 | 'publishMavenJavaPublicationToMavenLocal' // real publication to Maven Local (~/.m2/repository)
22 | ],
23 | 'sonatype' : [
24 | 'generatePomFileForInternalPublication',
25 | 'publishMavenJavaPublicationToOssrhRepository',
26 | 'closeAndReleaseRepository'
27 | ],
28 | 'deploy' : [
29 | 'uploadArchives',
30 | 'closeAndReleaseRepository'
31 | ],
32 | 'classpath' : [
33 | 'cleanEclipseClasspath',
34 | 'eclipseClasspath',
35 | 'eclipseFactoryPath',
36 | 'cleanIdeaModule',
37 | 'ideaModule'
38 | ],
39 | ]
40 |
41 | // package patterns to exclude from Eclipse
42 | excludeFromEclipse = []
43 | }
44 |
45 |
46 | // -------------------------------------------
47 | // REPOSITORIES / PUBLISHING
48 | // -------------------------------------------
49 |
50 | repositories {
51 | // prefer locally built artifacts
52 | mavenLocal()
53 |
54 | // use external repos as fallback
55 | mavenCentral()
56 | }
57 |
58 | task sourcesJar(type: Jar) {
59 | archiveClassifier.set('sources')
60 | from sourceSets.main.allJava
61 | }
62 |
63 | task javadocJar(type: Jar, dependsOn: classes) {
64 | archiveClassifier.set('javadoc')
65 | from javadoc
66 | }
67 |
68 | task testsJar(type:Jar, dependsOn: testClasses) {
69 | archiveClassifier.set('tests')
70 | from sourceSets.test.output
71 | }
72 |
73 | test {
74 | // enable JUnit 5 tests
75 | useJUnitPlatform()
76 | }
77 |
78 |
79 | // -------------------------------------------
80 | // JAVA COMPILER
81 | // -------------------------------------------
82 |
83 | tasks.withType(JavaCompile) { task ->
84 | sourceCompatibility = 11
85 | targetCompatibility = 11
86 |
87 | // always UTF-8
88 | options.encoding = 'UTF-8'
89 |
90 | // java 8 option which export names of constructor and method parameter names; no longer
91 | // have to declare parameter names with @JsonCreator
92 | options.compilerArgs << "-parameters"
93 |
94 | options.compilerArgs << '-Xlint:unchecked'
95 |
96 | if (project.plugins.hasPlugin('net.ltgt.errorprone')) {
97 | // Eclipse code formatting removes extraneous parenthesis which errorprone complains about
98 | options.errorprone.disable 'OperatorPrecedence'
99 |
100 | // we don't need to check return value always
101 | options.errorprone.disable 'FutureReturnValueIgnored'
102 |
103 | // generated code can have lots of bogus warnings
104 | options.errorprone.disableWarningsInGeneratedCode = true
105 |
106 | // bogus warning
107 | options.errorprone.disable 'StringSplitter'
108 |
109 | // ignore all generated source folders
110 | options.errorprone.excludedPaths = '.*generated.*'
111 | }
112 | }
113 |
114 |
115 | // -------------------------------------------
116 | // SHADOW JAR
117 | // -------------------------------------------
118 |
119 | if(plugins.hasPlugin("com.github.johnrengelman.shadow")) {
120 | jar {
121 | archiveClassifier.set('original')
122 | }
123 |
124 | shadowJar {
125 | archiveClassifier.set('shadow')
126 | }
127 |
128 | sourceSets {
129 | // shadow configuration is added by Shadow plugin, but it's only configured for the main sourceset
130 | test.compileClasspath += configurations.shadow
131 | test.runtimeClasspath += configurations.shadow
132 | }
133 | }
134 |
135 |
136 | publishing {
137 | publications {
138 | mavenJava(MavenPublication) {
139 | from components.java
140 | }
141 | }
142 | }
143 |
144 | publishing {
145 | if(project.hasProperty('nexusUsername')) {
146 | repositories {
147 | maven {
148 | name = "ossrh"
149 | url = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
150 | credentials {
151 | username = project.nexusUsername
152 | password = project.nexusPassword
153 | }
154 | }
155 | }
156 | }
157 |
158 | publications {
159 | mavenJava {
160 | artifact sourcesJar
161 | artifact javadocJar
162 | artifact testsJar
163 |
164 | versionMapping {
165 | usage('java-api') {
166 | fromResolutionOf('runtimeClasspath')
167 | }
168 | usage('java-runtime') {
169 | fromResolutionResult()
170 | }
171 | }
172 | }
173 | }
174 | }
175 |
176 | signing {
177 | sign publishing.publications.mavenJava
178 | }
179 |
180 | nexusStaging {
181 | repositoryDescription project.name
182 | }
183 |
184 |
185 | // -------------------------------------------
186 | // ECLIPSE
187 | // -------------------------------------------
188 |
189 | eclipse {
190 | classpath {
191 | // override default 'bin'
192 | defaultOutputDir = project.file('bin/classes')
193 |
194 | // we want source files
195 | downloadSources = true
196 | downloadJavadoc = false
197 |
198 | // customize generated .classpath file
199 | file {
200 | def project_refs = []
201 | def remove_entries = []
202 |
203 | // closure executed after .classpath content is loaded from existing file
204 | // and after gradle build information is merged
205 | whenMerged { classpath ->
206 |
207 | // build list of dependencies that we want to replace with Eclipse project refs
208 | println 'Finding local projects'
209 | def use_eclipse_project_refs = []
210 | new File(project.projectDir, "..").eachDir {
211 | if(new File("${it}/build.gradle").exists()) {
212 | use_eclipse_project_refs.add it.name
213 | }
214 | }
215 |
216 | println 'Generating Eclipse .classpath file'
217 | def kindOrder = [ 'src':1, 'con':2, 'lib':3, 'output':0 ];
218 | classpath.entries.sort(true, { a,b ->
219 | def order = kindOrder[a.kind] <=> kindOrder[b.kind]
220 | order != 0 ? order : a.path <=> b.path
221 | } as Comparator).each { entry ->
222 | if(entry.kind.equals('lib')) {
223 | use_eclipse_project_refs.each { name ->
224 | def regex = '/(' + ( name.endsWith('-') ?
225 | java.util.regex.Pattern.quote(name.substring(0,name.length()-1)) + '(?:-[A-Za-z]+)*'
226 | : java.util.regex.Pattern.quote(name) ) + ')-([\\w\\.]+?)(-[A-Za-z]+)?\\.jar$'
227 | def pattern = java.util.regex.Pattern.compile(regex)
228 | def matcher = pattern.matcher(entry.path)
229 | if(matcher.find()) {
230 | def match = matcher.group(1)
231 | println match + ' (' + matcher.group(2) + ') matched ' + entry.path
232 | remove_entries += [entry]
233 | project_refs += [match]
234 | }
235 | }
236 | entry.exported = true
237 | } else if(entry.kind.equals('src')) {
238 | project.ext.excludeFromEclipse.each { path ->
239 | if(entry.path.equals(path)) {
240 | remove_entries += [entry]
241 | }
242 | }
243 | }
244 | }
245 | classpath.entries.removeAll(remove_entries)
246 | }
247 |
248 | // final adjustments to .classpath file before it is saved
249 | withXml { xml ->
250 | def node = xml.asNode()
251 |
252 | project_refs.unique(false).each { name ->
253 | println "Creating Eclipse project dependency: " + name
254 | node.appendNode('classpathentry', [ combineaccessrules: false, exported: true, kind: 'src', path: '/' + name ])
255 | }
256 |
257 | def apt = ['.apt_generated_test': 'bin/test',
258 | '.apt_generated': 'bin/main']
259 |
260 | apt.each { path, output ->
261 | def atts = node.appendNode('classpathentry', [kind:'src', output: output, path: path]).appendNode('attributes')
262 | atts.appendNode('attribute', [name: 'ignore_optional_problems', value: true])
263 | atts.appendNode('attribute', [name: 'test', value: output.contains('test')])
264 | atts.appendNode('attribute', [name: 'optional', value: true])
265 | }
266 | }
267 | }
268 | }
269 | }
270 |
271 |
272 | // -------------------------------------------
273 | // README
274 | // -------------------------------------------
275 |
276 | task readme {
277 | ant.replaceregexp(match:'\\([0-9\\.]+)\\<\\/version\\>', replace:"${version}", flags:'g', byline:true) {
278 | fileset(dir: '.', includes: 'README.md')
279 | }
280 | ant.replaceregexp(match:'com\\.arakelian\\:' + project.name + ':([0-9\\.]+)', replace:"com.arakelian:${project.name}:${version}", flags:'g', byline:true) {
281 | fileset(dir: '.', includes: 'README.md')
282 | }
283 | }
284 |
285 |
286 | // -------------------------------------------
287 | // SHORTCUT TASKS
288 | // -------------------------------------------
289 |
290 |
291 | // This code allows us to define aliases, such as "all", so that when we do "gradle all",
292 | // we can substitute in a series of other gradle tasks
293 | // see: https://caffeineinduced.wordpress.com/2015/01/25/run-a-list-of-gradle-tasks-in-specific-order/
294 | def newTasks = []
295 |
296 | // gradle respects ordering of tasks specified on command line, so we replace shortcuts
297 | // with equivalent commands as though they were specified by user
298 | gradle.startParameter.taskNames.each { param ->
299 | def macro = project.ext.macros[param]
300 | if( macro ) {
301 | macro.each { task ->
302 | if(project.tasks.names.contains(task)) {
303 | newTasks << task
304 | }
305 | }
306 | } else {
307 | newTasks << param
308 | }
309 | }
310 |
311 | // replace command line arguments
312 | gradle.startParameter.taskNames = newTasks.flatten()
313 |
--------------------------------------------------------------------------------
/docker-build.sh:
--------------------------------------------------------------------------------
1 | SCRIPT_PATH=$( cd "$(dirname "$0")" ; pwd -P )
2 | PROJECT=$(basename "${SCRIPT_PATH}")
3 | JQ_VERSION=1.6
4 |
5 | set -e
6 |
7 | # build linux version
8 | docker build --tag ${PROJECT} ${SCRIPT_PATH}/.
9 |
10 | # get file
11 | mkdir -p src/main/resources/lib/linux-x86_64
12 | docker run --rm -v $(pwd -P)/src/main/resources/lib/linux-x86_64:/mnt ${PROJECT} cp /root/build/jq-${JQ_VERSION}/.libs/libjq.so /mnt
13 | echo "Linux-x86_64 JQ build successfully."
14 |
15 |
16 | # build aarch64 linux version
17 | docker build --platform=linux/arm64 --tag ${PROJECT}_aarch64 -f Dockerfile.aarch64 ${SCRIPT_PATH}/.
18 |
19 | # get file
20 | mkdir -p src/main/resources/lib/linux-aarch64
21 | docker run --rm -v $(pwd -P)/src/main/resources/lib/linux-aarch64:/mnt ${PROJECT}_aarch64 cp /home/libjq.so /mnt
22 | echo "Linux-aarch64 JQ build successfully."
23 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arakelian/java-jq/e2ec113e89430025b48b4fcca748a309731a03e2/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.5-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | # This is normally unused
84 | # shellcheck disable=SC2034
85 | APP_BASE_NAME=${0##*/}
86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
88 |
89 | # Use the maximum available, or set MAX_FD != -1 to use that value.
90 | MAX_FD=maximum
91 |
92 | warn () {
93 | echo "$*"
94 | } >&2
95 |
96 | die () {
97 | echo
98 | echo "$*"
99 | echo
100 | exit 1
101 | } >&2
102 |
103 | # OS specific support (must be 'true' or 'false').
104 | cygwin=false
105 | msys=false
106 | darwin=false
107 | nonstop=false
108 | case "$( uname )" in #(
109 | CYGWIN* ) cygwin=true ;; #(
110 | Darwin* ) darwin=true ;; #(
111 | MSYS* | MINGW* ) msys=true ;; #(
112 | NONSTOP* ) nonstop=true ;;
113 | esac
114 |
115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
116 |
117 |
118 | # Determine the Java command to use to start the JVM.
119 | if [ -n "$JAVA_HOME" ] ; then
120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
121 | # IBM's JDK on AIX uses strange locations for the executables
122 | JAVACMD=$JAVA_HOME/jre/sh/java
123 | else
124 | JAVACMD=$JAVA_HOME/bin/java
125 | fi
126 | if [ ! -x "$JAVACMD" ] ; then
127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
128 |
129 | Please set the JAVA_HOME variable in your environment to match the
130 | location of your Java installation."
131 | fi
132 | else
133 | JAVACMD=java
134 | if ! command -v java >/dev/null 2>&1
135 | then
136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 | fi
142 |
143 | # Increase the maximum file descriptors if we can.
144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
145 | case $MAX_FD in #(
146 | max*)
147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
148 | # shellcheck disable=SC2039,SC3045
149 | MAX_FD=$( ulimit -H -n ) ||
150 | warn "Could not query maximum file descriptor limit"
151 | esac
152 | case $MAX_FD in #(
153 | '' | soft) :;; #(
154 | *)
155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
156 | # shellcheck disable=SC2039,SC3045
157 | ulimit -n "$MAX_FD" ||
158 | warn "Could not set maximum file descriptor limit to $MAX_FD"
159 | esac
160 | fi
161 |
162 | # Collect all arguments for the java command, stacking in reverse order:
163 | # * args from the command line
164 | # * the main class name
165 | # * -classpath
166 | # * -D...appname settings
167 | # * --module-path (only if needed)
168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
169 |
170 | # For Cygwin or MSYS, switch paths to Windows format before running java
171 | if "$cygwin" || "$msys" ; then
172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
174 |
175 | JAVACMD=$( cygpath --unix "$JAVACMD" )
176 |
177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
178 | for arg do
179 | if
180 | case $arg in #(
181 | -*) false ;; # don't mess with options #(
182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
183 | [ -e "$t" ] ;; #(
184 | *) false ;;
185 | esac
186 | then
187 | arg=$( cygpath --path --ignore --mixed "$arg" )
188 | fi
189 | # Roll the args list around exactly as many times as the number of
190 | # args, so each arg winds up back in the position where it started, but
191 | # possibly modified.
192 | #
193 | # NB: a `for` loop captures its iteration list before it begins, so
194 | # changing the positional parameters here affects neither the number of
195 | # iterations, nor the values presented in `arg`.
196 | shift # remove old arg
197 | set -- "$@" "$arg" # push replacement arg
198 | done
199 | fi
200 |
201 |
202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
204 |
205 | # Collect all arguments for the java command:
206 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
207 | # and any embedded shellness will be escaped.
208 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
209 | # treated as '${Hostname}' itself on the command line.
210 |
211 | set -- \
212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
213 | -classpath "$CLASSPATH" \
214 | org.gradle.wrapper.GradleWrapperMain \
215 | "$@"
216 |
217 | # Stop when "xargs" is not available.
218 | if ! command -v xargs >/dev/null 2>&1
219 | then
220 | die "xargs is not available"
221 | fi
222 |
223 | # Use "xargs" to parse quoted args.
224 | #
225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
226 | #
227 | # In Bash we could simply go:
228 | #
229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
230 | # set -- "${ARGS[@]}" "$@"
231 | #
232 | # but POSIX shell has neither arrays nor command substitution, so instead we
233 | # post-process each arg (as a line of input to sed) to backslash-escape any
234 | # character that might be a shell metacharacter, then use eval to reverse
235 | # that process (while maintaining the separation between arguments), and wrap
236 | # the whole thing up as a single "set" statement.
237 | #
238 | # This will of course break if any of these variables contains a newline or
239 | # an unmatched quote.
240 | #
241 |
242 | eval "set -- $(
243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
244 | xargs -n1 |
245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
246 | tr '\n' ' '
247 | )" '"$@"'
248 |
249 | exec "$JAVACMD" "$@"
250 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'java-jq'
2 |
3 |
--------------------------------------------------------------------------------
/src/main/c/jq.h:
--------------------------------------------------------------------------------
1 | #ifndef JQ_H
2 | #define JQ_H
3 |
4 | #include
5 | #include
6 |
7 | enum {JQ_DEBUG_TRACE = 1};
8 |
9 | typedef struct jq_state jq_state;
10 | typedef void (*jq_msg_cb)(void *, jv);
11 |
12 | jq_state *jq_init(void);
13 | void jq_set_error_cb(jq_state *, jq_msg_cb, void *);
14 | void jq_get_error_cb(jq_state *, jq_msg_cb *, void **);
15 | void jq_set_nomem_handler(jq_state *, void (*)(void *), void *);
16 | jv jq_format_error(jv msg);
17 | void jq_report_error(jq_state *, jv);
18 | int jq_compile(jq_state *, const char*);
19 | int jq_compile_args(jq_state *, const char*, jv);
20 | void jq_dump_disassembly(jq_state *, int);
21 | void jq_start(jq_state *, jv value, int);
22 | jv jq_next(jq_state *);
23 | void jq_teardown(jq_state **);
24 |
25 | typedef jv (*jq_input_cb)(jq_state *, void *);
26 | void jq_set_input_cb(jq_state *, jq_input_cb, void *);
27 | void jq_get_input_cb(jq_state *, jq_input_cb *, void **);
28 |
29 | void jq_set_debug_cb(jq_state *, jq_msg_cb, void *);
30 | void jq_get_debug_cb(jq_state *, jq_msg_cb *, void **);
31 |
32 | void jq_set_attrs(jq_state *, jv);
33 | jv jq_get_attrs(jq_state *);
34 | jv jq_get_jq_origin(jq_state *);
35 | jv jq_get_prog_origin(jq_state *);
36 | jv jq_get_lib_dirs(jq_state *);
37 | void jq_set_attr(jq_state *, jv, jv);
38 | jv jq_get_attr(jq_state *, jv);
39 |
40 | /*
41 | * We use char * instead of jf for filenames here because filenames
42 | * should be in the process' locale's codeset, which may not be UTF-8,
43 | * whereas jv string values must be in UTF-8. This way the caller
44 | * doesn't have to perform any codeset conversions.
45 | */
46 | typedef struct jq_util_input_state jq_util_input_state;
47 | typedef void (*jq_util_msg_cb)(void *, const char *);
48 |
49 | jq_util_input_state *jq_util_input_init(jq_util_msg_cb, void *);
50 | void jq_util_input_set_parser(jq_util_input_state *, jv_parser *, int);
51 | void jq_util_input_free(jq_util_input_state **);
52 | void jq_util_input_add_input(jq_util_input_state *, const char *);
53 | int jq_util_input_errors(jq_util_input_state *);
54 | jv jq_util_input_next_input(jq_util_input_state *);
55 | jv jq_util_input_next_input_cb(jq_state *, void *);
56 | jv jq_util_input_get_position(jq_state*);
57 | jv jq_util_input_get_current_filename(jq_state*);
58 | jv jq_util_input_get_current_line(jq_state*);
59 |
60 | #endif /* !JQ_H */
61 |
--------------------------------------------------------------------------------
/src/main/c/jv.h:
--------------------------------------------------------------------------------
1 | #ifndef JV_H
2 | #define JV_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | typedef enum {
9 | JV_KIND_INVALID,
10 | JV_KIND_NULL,
11 | JV_KIND_FALSE,
12 | JV_KIND_TRUE,
13 | JV_KIND_NUMBER,
14 | JV_KIND_STRING,
15 | JV_KIND_ARRAY,
16 | JV_KIND_OBJECT
17 | } jv_kind;
18 |
19 | struct jv_refcnt;
20 |
21 | /* All of the fields of this struct are private.
22 | Really. Do not play with them. */
23 | typedef struct {
24 | unsigned char kind_flags;
25 | unsigned char pad_;
26 | unsigned short offset; /* array offsets */
27 | int size;
28 | union {
29 | struct jv_refcnt* ptr;
30 | double number;
31 | } u;
32 | } jv;
33 |
34 | /*
35 | * All jv_* functions consume (decref) input and produce (incref) output
36 | * Except jv_copy
37 | */
38 |
39 | jv_kind jv_get_kind(jv);
40 | const char* jv_kind_name(jv_kind);
41 | static int jv_is_valid(jv x) { return jv_get_kind(x) != JV_KIND_INVALID; }
42 |
43 | jv jv_copy(jv);
44 | void jv_free(jv);
45 |
46 | int jv_get_refcnt(jv);
47 |
48 | int jv_equal(jv, jv);
49 | int jv_identical(jv, jv);
50 | int jv_contains(jv, jv);
51 |
52 | jv jv_invalid(void);
53 | jv jv_invalid_with_msg(jv);
54 | jv jv_invalid_get_msg(jv);
55 | int jv_invalid_has_msg(jv);
56 |
57 |
58 | jv jv_null(void);
59 | jv jv_true(void);
60 | jv jv_false(void);
61 | jv jv_bool(int);
62 |
63 | jv jv_number(double);
64 | double jv_number_value(jv);
65 | int jv_is_integer(jv);
66 |
67 | jv jv_array(void);
68 | jv jv_array_sized(int);
69 | int jv_array_length(jv);
70 | jv jv_array_get(jv, int);
71 | jv jv_array_set(jv, int, jv);
72 | jv jv_array_append(jv, jv);
73 | jv jv_array_concat(jv, jv);
74 | jv jv_array_slice(jv, int, int);
75 | jv jv_array_indexes(jv, jv);
76 | #define jv_array_foreach(a, i, x) \
77 | for (int jv_len__ = jv_array_length(jv_copy(a)), i=0, jv_j__ = 1; \
78 | jv_j__; jv_j__ = 0) \
79 | for (jv x; \
80 | i < jv_len__ ? \
81 | (x = jv_array_get(jv_copy(a), i), 1) : 0; \
82 | i++)
83 |
84 | #define JV_ARRAY_1(e) (jv_array_append(jv_array(),e))
85 | #define JV_ARRAY_2(e1,e2) (jv_array_append(JV_ARRAY_1(e1),e2))
86 | #define JV_ARRAY_3(e1,e2,e3) (jv_array_append(JV_ARRAY_2(e1,e2),e3))
87 | #define JV_ARRAY_4(e1,e2,e3,e4) (jv_array_append(JV_ARRAY_3(e1,e2,e3),e4))
88 | #define JV_ARRAY_5(e1,e2,e3,e4,e5) (jv_array_append(JV_ARRAY_4(e1,e2,e3,e4),e5))
89 | #define JV_ARRAY_6(e1,e2,e3,e4,e5,e6) (jv_array_append(JV_ARRAY_5(e1,e2,e3,e4,e5),e6))
90 | #define JV_ARRAY_7(e1,e2,e3,e4,e5,e6,e7) (jv_array_append(JV_ARRAY_6(e1,e2,e3,e4,e5,e6),e7))
91 | #define JV_ARRAY_8(e1,e2,e3,e4,e5,e6,e7,e8) (jv_array_append(JV_ARRAY_7(e1,e2,e3,e4,e5,e6,e7),e8))
92 | #define JV_ARRAY_9(e1,e2,e3,e4,e5,e6,e7,e8,e9) (jv_array_append(JV_ARRAY_8(e1,e2,e3,e4,e5,e6,e7,e8),e9))
93 | #define JV_ARRAY_IDX(_1,_2,_3,_4,_5,_6,_7,_8,_9,NAME,...) NAME
94 | #define JV_ARRAY(...) \
95 | JV_ARRAY_IDX(__VA_ARGS__, JV_ARRAY_9, JV_ARRAY_8, JV_ARRAY_7, JV_ARRAY_6, JV_ARRAY_5, JV_ARRAY_4, JV_ARRAY_3, JV_ARRAY_2, JV_ARRAY_1)(__VA_ARGS__)
96 |
97 | #ifdef __GNUC__
98 | #define JV_PRINTF_LIKE(fmt_arg_num, args_num) \
99 | __attribute__ ((__format__( __printf__, fmt_arg_num, args_num)))
100 | #define JV_VPRINTF_LIKE(fmt_arg_num) \
101 | __attribute__ ((__format__( __printf__, fmt_arg_num, 0)))
102 | #endif
103 |
104 |
105 | jv jv_string(const char*);
106 | jv jv_string_sized(const char*, int);
107 | jv jv_string_empty(int len);
108 | int jv_string_length_bytes(jv);
109 | int jv_string_length_codepoints(jv);
110 | unsigned long jv_string_hash(jv);
111 | const char* jv_string_value(jv);
112 | jv jv_string_indexes(jv j, jv k);
113 | jv jv_string_slice(jv j, int start, int end);
114 | jv jv_string_concat(jv, jv);
115 | jv jv_string_vfmt(const char*, va_list) JV_VPRINTF_LIKE(1);
116 | jv jv_string_fmt(const char*, ...) JV_PRINTF_LIKE(1, 2);
117 | jv jv_string_append_codepoint(jv a, uint32_t c);
118 | jv jv_string_append_buf(jv a, const char* buf, int len);
119 | jv jv_string_append_str(jv a, const char* str);
120 | jv jv_string_split(jv j, jv sep);
121 | jv jv_string_explode(jv j);
122 | jv jv_string_implode(jv j);
123 |
124 | jv jv_object(void);
125 | jv jv_object_get(jv object, jv key);
126 | jv jv_object_set(jv object, jv key, jv value);
127 | jv jv_object_delete(jv object, jv key);
128 | int jv_object_length(jv object);
129 | jv jv_object_merge(jv, jv);
130 | jv jv_object_merge_recursive(jv, jv);
131 |
132 | int jv_object_iter(jv);
133 | int jv_object_iter_next(jv, int);
134 | int jv_object_iter_valid(jv, int);
135 | jv jv_object_iter_key(jv, int);
136 | jv jv_object_iter_value(jv, int);
137 | #define jv_object_foreach(t, k, v) \
138 | for (int jv_i__ = jv_object_iter(t), jv_j__ = 1; jv_j__; jv_j__ = 0) \
139 | for (jv k, v; \
140 | jv_object_iter_valid((t), jv_i__) ? \
141 | (k = jv_object_iter_key(t, jv_i__), \
142 | v = jv_object_iter_value(t, jv_i__), \
143 | 1) \
144 | : 0; \
145 | jv_i__ = jv_object_iter_next(t, jv_i__)) \
146 |
147 | #define JV_OBJECT_1(k) (jv_object_set(jv_object(),(k),jv_null()))
148 | #define JV_OBJECT_2(k1,v1) (jv_object_set(jv_object(),(k1),(v1)))
149 | #define JV_OBJECT_3(k1,v1,k2) (jv_object_set(JV_OBJECT_2(k1,v1),k2,jv_null()))
150 | #define JV_OBJECT_4(k1,v1,k2,v2) (jv_object_set(JV_OBJECT_2(k1,v1),k2,v2))
151 | #define JV_OBJECT_5(k1,v1,k2,v2,k3) (jv_object_set(JV_OBJECT_4(k1,v1,k2,v2),k3,jv_null))
152 | #define JV_OBJECT_6(k1,v1,k2,v2,k3,v3) (jv_object_set(JV_OBJECT_4(k1,v1,k2,v2),k3,v3))
153 | #define JV_OBJECT_7(k1,v1,k2,v2,k3,v3,k4) (jv_object_set(JV_OBJECT_6(k1,v1,k2,v2,k3,v3),k4,jv_null()))
154 | #define JV_OBJECT_8(k1,v1,k2,v2,k3,v3,k4,v4) (jv_object_set(JV_OBJECT_6(k1,v1,k2,v2,k3,v3),k4,v4))
155 | #define JV_OBJECT_IDX(_1,_2,_3,_4,_5,_6,_7,_8,NAME,...) NAME
156 | #define JV_OBJECT(...) \
157 | JV_OBJECT_IDX(__VA_ARGS__, JV_OBJECT_8, JV_OBJECT_7, JV_OBJECT_6, JV_OBJECT_5, JV_OBJECT_4, JV_OBJECT_3, JV_OBJECT_2, JV_OBJECT_1)(__VA_ARGS__)
158 |
159 |
160 |
161 | int jv_get_refcnt(jv);
162 |
163 | enum jv_print_flags {
164 | JV_PRINT_PRETTY = 1,
165 | JV_PRINT_ASCII = 2,
166 | JV_PRINT_COLOUR = 4,
167 | JV_PRINT_SORTED = 8,
168 | JV_PRINT_INVALID = 16,
169 | JV_PRINT_REFCOUNT = 32,
170 | JV_PRINT_TAB = 64,
171 | JV_PRINT_ISATTY = 128,
172 | JV_PRINT_SPACE0 = 256,
173 | JV_PRINT_SPACE1 = 512,
174 | JV_PRINT_SPACE2 = 1024,
175 | };
176 | #define JV_PRINT_INDENT_FLAGS(n) \
177 | ((n) < 0 || (n) > 7 ? JV_PRINT_TAB | JV_PRINT_PRETTY : (n) == 0 ? 0 : (n) << 8 | JV_PRINT_PRETTY)
178 | void jv_dumpf(jv, FILE *f, int flags);
179 | void jv_dump(jv, int flags);
180 | void jv_show(jv, int flags);
181 | jv jv_dump_string(jv, int flags);
182 | char *jv_dump_string_trunc(jv x, char *outbuf, size_t bufsize);
183 |
184 | enum {
185 | JV_PARSE_SEQ = 1,
186 | JV_PARSE_STREAMING = 2,
187 | JV_PARSE_STREAM_ERRORS = 4,
188 | };
189 |
190 | jv jv_parse(const char* string);
191 | jv jv_parse_sized(const char* string, int length);
192 |
193 | typedef void (*jv_nomem_handler_f)(void *);
194 | void jv_nomem_handler(jv_nomem_handler_f, void *);
195 |
196 | jv jv_load_file(const char *, int);
197 |
198 | typedef struct jv_parser jv_parser;
199 | jv_parser* jv_parser_new(int);
200 | void jv_parser_set_buf(jv_parser*, const char*, int, int);
201 | int jv_parser_remaining(jv_parser*);
202 | jv jv_parser_next(jv_parser*);
203 | void jv_parser_free(jv_parser*);
204 |
205 | jv jv_get(jv, jv);
206 | jv jv_set(jv, jv, jv);
207 | jv jv_has(jv, jv);
208 | jv jv_setpath(jv, jv, jv);
209 | jv jv_getpath(jv, jv);
210 | jv jv_delpaths(jv, jv);
211 | jv jv_keys(jv /*object or array*/);
212 | jv jv_keys_unsorted(jv /*object or array*/);
213 | int jv_cmp(jv, jv);
214 | jv jv_group(jv, jv);
215 | jv jv_sort(jv, jv);
216 |
217 |
218 | #endif
219 |
220 |
221 | /*
222 |
223 | true/false/null:
224 | check kind
225 |
226 | number:
227 | introduce/eliminate jv
228 | to integer
229 |
230 | array:
231 | copy
232 | free
233 | slice
234 | index
235 | update
236 |
237 | updateslice?
238 |
239 |
240 | */
241 |
--------------------------------------------------------------------------------
/src/main/java/com/arakelian/jq/JqLibrary.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.arakelian.jq;
19 |
20 | import static java.util.logging.Level.INFO;
21 |
22 | import java.util.List;
23 | import java.util.logging.Logger;
24 |
25 | import org.immutables.value.Value;
26 |
27 | import com.google.common.base.Charsets;
28 | import com.google.common.base.Preconditions;
29 | import com.google.common.collect.ImmutableList;
30 | import com.sun.jna.Callback;
31 | import com.sun.jna.Function;
32 | import com.sun.jna.Pointer;
33 | import com.sun.jna.Structure;
34 | import com.sun.jna.Structure.ByReference;
35 | import com.sun.jna.Structure.ByValue;
36 | import com.sun.jna.Union;
37 | import com.sun.jna.ptr.PointerByReference;
38 |
39 | @Value.Immutable(singleton = true)
40 | public abstract class JqLibrary {
41 | public interface ErrorCallback extends Callback {
42 | public void callback(final Pointer data, final Jv jv);
43 | }
44 |
45 | public static class Jv extends Structure implements ByValue {
46 | public static class U extends Union {
47 | public JvRefCount ptr;
48 | public double number;
49 | }
50 |
51 | public byte kind_flags;
52 | public byte pad_;
53 | public short offset;
54 | public int size;
55 | public U u;
56 |
57 | @Override
58 | protected List getFieldOrder() {
59 | return ImmutableList.of("kind_flags", "pad_", "offset", "size", "u");
60 | }
61 | }
62 |
63 | public static class JvRefCount extends Structure implements ByReference {
64 | public int count;
65 |
66 | @Override
67 | protected List getFieldOrder() {
68 | return ImmutableList.of("count");
69 | }
70 | }
71 |
72 | private static final Logger LOGGER = Logger.getLogger(JqLibrary.class.getName());
73 |
74 | public static final int JV_KIND_INVALID = 0;
75 | public static final int JV_KIND_NULL = 1;
76 | public static final int JV_KIND_FALSE = 2;
77 | public static final int JV_KIND_TRUE = 3;
78 | public static final int JV_KIND_NUMBER = 4;
79 | public static final int JV_KIND_STRING = 5;
80 | public static final int JV_KIND_ARRAY = 6;
81 | public static final int JV_KIND_OBJECT = 7;
82 |
83 | public static final int JV_PARSE_SEQ = 1;
84 | public static final int JV_PARSE_STREAMING = 2;
85 | public static final int JV_PARSE_STREAM_ERRORS = 4;
86 |
87 | public static final int JV_PRINT_PRETTY = 1;
88 | public static final int JV_PRINT_ASCII = 2;
89 | public static final int JV_PRINT_COLOR = 4;
90 | public static final int JV_PRINT_SORTED = 8;
91 | public static final int JV_PRINT_INVALID = 16;
92 | public static final int JV_PRINT_REFCOUNT = 32;
93 | public static final int JV_PRINT_TAB = 64;
94 | public static final int JV_PRINT_ISATTY = 128;
95 | public static final int JV_PRINT_SPACE0 = 256;
96 | public static final int JV_PRINT_SPACE1 = 512;
97 | public static final int JV_PRINT_SPACE2 = 1024;
98 |
99 | /** No arguments **/
100 | public static final Object[] NO_ARGS = new Object[0];
101 |
102 | @Value.Auxiliary
103 | public Function getJqCompile() {
104 | return getLoader().getNativeLibrary().getFunction("jq_compile");
105 | }
106 |
107 | @Value.Auxiliary
108 | public Function getJqCompileArgs() {
109 | return getLoader().getNativeLibrary().getFunction("jq_compile_args");
110 | }
111 |
112 | @Value.Auxiliary
113 | public Function getJqInit() {
114 | return getLoader().getNativeLibrary().getFunction("jq_init");
115 | }
116 |
117 | @Value.Auxiliary
118 | public Function getJqNext() {
119 | return getLoader().getNativeLibrary().getFunction("jq_next");
120 | }
121 |
122 | @Value.Auxiliary
123 | public Function getJqSetAttr() {
124 | return getLoader().getNativeLibrary().getFunction("jq_set_attr");
125 | }
126 |
127 | @Value.Auxiliary
128 | public Function getJqSetErrorCb() {
129 | return getLoader().getNativeLibrary().getFunction("jq_set_error_cb");
130 | }
131 |
132 | @Value.Auxiliary
133 | public Function getJqStart() {
134 | return getLoader().getNativeLibrary().getFunction("jq_start");
135 | }
136 |
137 | @Value.Auxiliary
138 | public Function getJqTeardown() {
139 | return getLoader().getNativeLibrary().getFunction("jq_teardown");
140 | }
141 |
142 | @Value.Auxiliary
143 | public Function getJvArray() {
144 | return getLoader().getNativeLibrary().getFunction("jv_array");
145 | }
146 |
147 | @Value.Auxiliary
148 | public Function getJvArrayAppend() {
149 | return getLoader().getNativeLibrary().getFunction("jv_array_append");
150 | }
151 |
152 | @Value.Auxiliary
153 | public Function getJvArrayConcat() {
154 | return getLoader().getNativeLibrary().getFunction("jv_array_concat");
155 | }
156 |
157 | @Value.Auxiliary
158 | public Function getJvCopy() {
159 | return getLoader().getNativeLibrary().getFunction("jv_copy");
160 | }
161 |
162 | @Value.Auxiliary
163 | public Function getJvDumpString() {
164 | return getLoader().getNativeLibrary().getFunction("jv_dump_string");
165 | }
166 |
167 | @Value.Auxiliary
168 | public Function getJvFree() {
169 | return getLoader().getNativeLibrary().getFunction("jv_free");
170 | }
171 |
172 | @Value.Auxiliary
173 | public Function getJvGetKind() {
174 | return getLoader().getNativeLibrary().getFunction("jv_get_kind");
175 | }
176 |
177 | @Value.Auxiliary
178 | public Function getJvInvalidGetMsg() {
179 | return getLoader().getNativeLibrary().getFunction("jv_invalid_get_msg");
180 | }
181 |
182 | @Value.Auxiliary
183 | public Function getJvInvalidHasMsg() {
184 | return getLoader().getNativeLibrary().getFunction("jv_invalid_has_msg");
185 | }
186 |
187 | @Value.Auxiliary
188 | public Function getJvObject() {
189 | return getLoader().getNativeLibrary().getFunction("jv_object");
190 | }
191 |
192 | @Value.Auxiliary
193 | public Function getJvObjectHas() {
194 | return getLoader().getNativeLibrary().getFunction("jv_object_has");
195 | }
196 |
197 | @Value.Auxiliary
198 | public Function getJvObjectSet() {
199 | return getLoader().getNativeLibrary().getFunction("jv_object_set");
200 | }
201 |
202 | @Value.Auxiliary
203 | public Function getJvParse() {
204 | return getLoader().getNativeLibrary().getFunction("jv_parse");
205 | }
206 |
207 | @Value.Auxiliary
208 | public Function getJvParserFree() {
209 | return getLoader().getNativeLibrary().getFunction("jv_parser_free");
210 | }
211 |
212 | @Value.Auxiliary
213 | public Function getJvParserNew() {
214 | return getLoader().getNativeLibrary().getFunction("jv_parser_new");
215 | }
216 |
217 | @Value.Auxiliary
218 | public Function getJvParserNext() {
219 | return getLoader().getNativeLibrary().getFunction("jv_parser_next");
220 | }
221 |
222 | @Value.Auxiliary
223 | public Function getJvParserSetBuf() {
224 | return getLoader().getNativeLibrary().getFunction("jv_parser_set_buf");
225 | }
226 |
227 | @Value.Auxiliary
228 | public Function getJvString() {
229 | return getLoader().getNativeLibrary().getFunction("jv_string");
230 | }
231 |
232 | @Value.Auxiliary
233 | public Function getJvStringValue() {
234 | return getLoader().getNativeLibrary().getFunction("jv_string_value");
235 | }
236 |
237 | @Value.Lazy
238 | @Value.Auxiliary
239 | public NativeLib getLoader() {
240 | final ImmutableNativeLib jq = ImmutableNativeLib.builder() //
241 | .name("jq") //
242 | .build();
243 | Preconditions.checkState(jq.getNativeLibrary() != null, "Cannot load JQ library");
244 | LOGGER.log(INFO, "Loaded {0}", new Object[] { jq.getLocalCopy() });
245 | return jq;
246 | }
247 |
248 | public boolean jq_compile(final Pointer jq, final String filter) {
249 | return getJqCompile().invokeInt(new Object[] { jq, filter }) != 0;
250 | }
251 |
252 | public boolean jq_compile_args(final Pointer jq, final String filter, final Jv args) {
253 | return getJqCompileArgs().invokeInt(new Object[] { jq, filter, args }) != 0;
254 | }
255 |
256 | public Pointer jq_init() {
257 | return (Pointer) getJqInit().invoke(Pointer.class, NO_ARGS);
258 | }
259 |
260 | public Jv jq_next(final Pointer jq) {
261 | return (Jv) getJqNext().invoke(Jv.class, new Object[] { jq });
262 | }
263 |
264 | public void jq_set_attr(final Pointer jq, final Jv name, final Jv value) {
265 | getJqSetAttr().invoke(new Object[] { jq, name, value });
266 | }
267 |
268 | public void jq_set_error_cb(final Pointer jq, final ErrorCallback callback, final Pointer data) {
269 | getJqSetErrorCb().invoke(new Object[] { jq, callback, data });
270 | }
271 |
272 | public void jq_start(final Pointer jq, final Jv jv) {
273 | getJqStart().invoke(new Object[] { jq, jv, 0 });
274 | }
275 |
276 | public void jq_teardown(final Pointer jq) {
277 | final PointerByReference ref = new PointerByReference(jq);
278 | getJqTeardown().invoke(new Object[] { ref });
279 | }
280 |
281 | public Jv jv_array() {
282 | return (Jv) getJvArray().invoke(Jv.class, new Object[] {});
283 | }
284 |
285 | public Jv jv_array_append(final Jv array, final Jv value) {
286 | return (Jv) getJvArrayAppend().invoke(Jv.class, new Object[] { array, value });
287 | }
288 |
289 | public Jv jv_array_concat(final Jv array, final Jv anotherArray) {
290 | return (Jv) getJvArrayConcat().invoke(Jv.class, new Object[] { array, anotherArray });
291 | }
292 |
293 | public Jv jv_copy(final Jv jv) {
294 | return (Jv) getJvCopy().invoke(Jv.class, new Object[] { jv });
295 | }
296 |
297 | public String jv_dump_string(final Jv next, final int flags) {
298 | final Jv dumped = (Jv) getJvDumpString().invoke(Jv.class, new Object[] { next, flags });
299 | try {
300 | return jv_string_value(dumped);
301 | } finally {
302 | jv_free(dumped);
303 | }
304 | }
305 |
306 | public void jv_free(final Jv jv) {
307 | getJvFree().invoke(new Object[] { jv });
308 | }
309 |
310 | public int jv_get_kind(final Jv jv) {
311 | return getJvGetKind().invokeInt(new Object[] { jv });
312 | }
313 |
314 | public Jv jv_invalid_get_msg(final Jv jv) {
315 | return (Jv) getJvInvalidGetMsg().invoke(Jv.class, new Object[] { jv });
316 | }
317 |
318 | public boolean jv_invalid_has_msg(final Jv jv) {
319 | return getJvInvalidHasMsg().invokeInt(new Object[] { jv }) != 0;
320 | }
321 |
322 | public final boolean jv_is_valid(final Jv jv) {
323 | final int kind = getJvGetKind().invokeInt(new Object[] { jv });
324 | return kind != JqLibrary.JV_KIND_INVALID;
325 | }
326 |
327 | public Jv jv_object() {
328 | return (Jv) getJvObject().invoke(Jv.class, new Object[] {});
329 | }
330 |
331 | public boolean jv_object_has(final Jv object, final Jv key) {
332 | final int has = getJvObjectHas().invokeInt(new Object[] { object, key });
333 | return has != 0;
334 | }
335 |
336 | public Jv jv_object_set(final Jv object, final Jv key, final Jv value) {
337 | return (Jv) getJvObjectSet().invoke(Jv.class, new Object[] { object, key, value });
338 | }
339 |
340 | public Jv jv_parse(final String json) {
341 | return (Jv) getJvParse().invoke(Jv.class, new Object[] { json });
342 | }
343 |
344 | public void jv_parser_free(final Pointer parser) {
345 | getJvParserFree().invoke(new Object[] { parser });
346 | }
347 |
348 | public Pointer jv_parser_new(final int flags) {
349 | return (Pointer) getJvParserNew().invoke(Pointer.class, new Object[] { Integer.valueOf(flags) });
350 | }
351 |
352 | public Jv jv_parser_next(final Pointer parser) {
353 | return (Jv) getJvParserNext().invoke(Jv.class, new Object[] { parser });
354 | }
355 |
356 | public void jv_parser_set_buf(
357 | final Pointer parser,
358 | final Pointer pointer,
359 | final int length,
360 | final boolean finished) {
361 | getJvParserSetBuf().invoke(new Object[] { parser, pointer, length, finished ? 0 : 1 });
362 | }
363 |
364 | public Jv jv_string(final String value) {
365 | return (Jv) getJvString().invoke(Jv.class, new Object[] { value });
366 | }
367 |
368 | public String jv_string_value(final Jv jv) {
369 | final Pointer result = (Pointer) getJvStringValue().invoke(Pointer.class, new Object[] { jv });
370 | final String error = result.getString(0, Charsets.UTF_8.name());
371 | return error;
372 | }
373 | }
374 |
--------------------------------------------------------------------------------
/src/main/java/com/arakelian/jq/JqRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.arakelian.jq;
19 |
20 | import static java.util.logging.Level.FINE;
21 |
22 | import java.io.File;
23 | import java.io.IOException;
24 | import java.io.UncheckedIOException;
25 | import java.util.List;
26 | import java.util.Map;
27 | import java.util.concurrent.locks.ReentrantLock;
28 | import java.util.logging.Logger;
29 |
30 | import org.immutables.value.Value;
31 |
32 | import com.arakelian.jq.JqLibrary.Jv;
33 | import com.google.common.base.Charsets;
34 | import com.google.common.base.Preconditions;
35 | import com.google.common.collect.ImmutableMap;
36 | import com.sun.jna.Memory;
37 | import com.sun.jna.Pointer;
38 |
39 | @Value.Immutable
40 | public abstract class JqRequest {
41 | public enum Indent {
42 | NONE, //
43 | TAB, //
44 | SPACE, //
45 | TWO_SPACES;
46 | }
47 |
48 | private static final Logger LOGGER = Logger.getLogger(JqRequest.class.getName());
49 |
50 | /**
51 | * JQ is not thread-safe - https://github.com/stedolan/jq/issues/120
52 | */
53 | private static final ReentrantLock SYNC = new ReentrantLock();
54 |
55 | public final JqResponse execute() {
56 | SYNC.lock();
57 | try {
58 | return jq();
59 | } finally {
60 | SYNC.unlock();
61 | }
62 | }
63 |
64 | @Value.Default
65 | public Map getArgJson() {
66 | return ImmutableMap.of();
67 | }
68 |
69 | @Value.Derived
70 | @Value.Auxiliary
71 | public int getDumpFlags() {
72 | int flags = 0;
73 |
74 | if (isPretty()) {
75 | flags |= JqLibrary.JV_PRINT_PRETTY;
76 | }
77 | switch (getIndent()) {
78 | case TAB:
79 | flags = JqLibrary.JV_PRINT_TAB;
80 | break;
81 | case SPACE:
82 | flags = JqLibrary.JV_PRINT_SPACE1;
83 | break;
84 | case TWO_SPACES:
85 | flags = JqLibrary.JV_PRINT_SPACE2;
86 | break;
87 | case NONE:
88 | default:
89 | break;
90 | }
91 |
92 | if (isSortKeys()) {
93 | flags |= JqLibrary.JV_PRINT_SORTED;
94 | }
95 | return flags;
96 | }
97 |
98 | @Value.Default
99 | public String getFilter() {
100 | return ".";
101 | }
102 |
103 | @Value.Default
104 | public Indent getIndent() {
105 | return Indent.TWO_SPACES;
106 | }
107 |
108 | public abstract String getInput();
109 |
110 | public abstract JqLibrary getLib();
111 |
112 | public abstract List getModulePaths();
113 |
114 | @Value.Default
115 | public String getStreamSeparator() {
116 | return "\n";
117 | }
118 |
119 | @Value.Default
120 | public boolean isPretty() {
121 | return true;
122 | }
123 |
124 | @Value.Default
125 | public boolean isSortKeys() {
126 | return false;
127 | }
128 |
129 | /**
130 | * Adds any messages produced by jq native code it to the error store, with the provided prefix.
131 | *
132 | * @param value
133 | * value reference
134 | */
135 | private String getInvalidMessage(final Jv value) {
136 | final Jv copy = getLib().jv_copy(value);
137 | if (getLib().jv_invalid_has_msg(copy)) {
138 | final Jv message = getLib().jv_invalid_get_msg(value);
139 | return getLib().jv_string_value(message);
140 | } else {
141 | getLib().jv_free(value);
142 | return null;
143 | }
144 | }
145 |
146 | private boolean isValid(final ImmutableJqResponse.Builder response, final Jv value) {
147 | if (getLib().jv_is_valid(value)) {
148 | return true;
149 | }
150 |
151 | // success finishes will return "invalid" value without a message
152 | final String message = getInvalidMessage(value);
153 | if (message != null) {
154 | response.addError(message);
155 | }
156 | return false;
157 | }
158 |
159 | private JqResponse jq() {
160 | LOGGER.log(FINE, "Initializing JQ");
161 | final JqLibrary lib = getLib();
162 | final Pointer jq = lib.jq_init();
163 | Preconditions.checkState(jq != null, "jq must be non-null");
164 |
165 | Jv moduleDirs = lib.jv_array();
166 | for (final File file : getModulePaths()) {
167 | try {
168 | final String dir = file.getCanonicalPath();
169 | LOGGER.log(FINE, "Using module path: " + dir);
170 | moduleDirs = lib.jv_array_append(moduleDirs, lib.jv_string(dir));
171 | } catch (final IOException e) {
172 | throw new UncheckedIOException(e);
173 | }
174 | }
175 | lib.jq_set_attr(jq, lib.jv_string("JQ_LIBRARY_PATH"), moduleDirs);
176 |
177 | try {
178 | final JqResponse response = parse(jq);
179 | LOGGER.log(FINE, "Response ready");
180 | return response;
181 | } finally {
182 | LOGGER.log(FINE, "Releasing JQ");
183 | lib.jq_teardown(jq);
184 | LOGGER.log(FINE, "JQ released successfully");
185 | }
186 | }
187 |
188 | private JqResponse parse(final Pointer jq) {
189 | final ImmutableJqResponse.Builder response = ImmutableJqResponse.builder();
190 |
191 | LOGGER.log(FINE, "Configuring callback");
192 | final JqLibrary lib = getLib();
193 | lib.jq_set_error_cb(jq, (data, jv) -> {
194 | LOGGER.log(FINE, "Error callback");
195 | final int kind = lib.jv_get_kind(jv);
196 | if (kind == JqLibrary.JV_KIND_STRING) {
197 | final String error = lib.jv_string_value(jv).replaceAll("\\s++$", "");
198 | response.addError(error);
199 | }
200 | }, new Pointer(0));
201 |
202 | // for JQ 1.5, arguments is an array; this changes with JQ 1.6+
203 | Jv args = lib.jv_object();
204 |
205 | final Map argJson = getArgJson();
206 | for (final String varname : argJson.keySet()) {
207 | final String text = argJson.get(varname);
208 |
209 | final Jv json = lib.jv_parse(text);
210 | if (!lib.jv_is_valid(json)) {
211 | response.addError("Invalid JSON text passed to --argjson (name: " + varname + ")");
212 | return response.build();
213 | }
214 |
215 | args = lib.jv_object_set(args, lib.jv_string(varname), json);
216 | }
217 |
218 | try {
219 | // compile JQ program
220 | LOGGER.log(FINE, "Compiling filter");
221 | final String filter = getFilter();
222 | if (!lib.jq_compile_args(jq, filter, lib.jv_copy(args))) {
223 | // compile errors are captured by callback
224 | LOGGER.log(FINE, "Compilation failed");
225 | return response.build();
226 | }
227 |
228 | // create JQ parser
229 | LOGGER.log(FINE, "Creating parse");
230 | final int parserFlags = 0;
231 | final Pointer parser = lib.jv_parser_new(parserFlags);
232 | try {
233 | parse(jq, parser, getInput(), response);
234 | return response.build();
235 | } finally {
236 | LOGGER.log(FINE, "Releasing parser");
237 | lib.jv_parser_free(parser);
238 | }
239 | } finally {
240 | LOGGER.log(FINE, "Releasing callback");
241 | lib.jq_set_error_cb(jq, null, null);
242 | }
243 | }
244 |
245 | /**
246 | * Add the contents of a native memory array as text to the next chunk of input of the jq
247 | * program.
248 | *
249 | * @param jq
250 | * JQ instance
251 | * @param parser
252 | * JQ parser
253 | * @param text
254 | * input JSON
255 | * @param response
256 | * response that we are building
257 | */
258 | private void parse(
259 | final Pointer jq,
260 | final Pointer parser,
261 | final String text,
262 | final ImmutableJqResponse.Builder response) {
263 | final byte[] input = text.getBytes(Charsets.UTF_8);
264 | final Memory memory = new Memory(input.length);
265 | memory.write(0, input, 0, input.length);
266 |
267 | // give text to JQ parser
268 | LOGGER.log(FINE, "Sending text to parser");
269 | getLib().jv_parser_set_buf(parser, memory, input.length, true);
270 |
271 | final int flags = getDumpFlags();
272 | final StringBuilder buf = new StringBuilder();
273 | for (;;) {
274 | // iterate until JQ consumes all inputs
275 | LOGGER.log(FINE, "Parsing text");
276 | final Jv parsed = getLib().jv_parser_next(parser);
277 | if (!isValid(response, parsed)) {
278 | break;
279 | }
280 |
281 | // iterate until we consume all JQ streams
282 | // see: https://stedolan.github.io/jq/tutorial/
283 | LOGGER.log(FINE, "Consuming JQ response");
284 | getLib().jq_start(jq, parsed);
285 | for (;;) {
286 | final Jv next = getLib().jq_next(jq);
287 | if (!isValid(response, next)) {
288 | break;
289 | }
290 |
291 | LOGGER.log(FINE, "Dumping response");
292 | final String out = getLib().jv_dump_string(next, flags);
293 | if (buf.length() != 0) {
294 | buf.append(getStreamSeparator());
295 | }
296 | buf.append(out);
297 | }
298 | }
299 |
300 | // tell parser we are finished
301 | LOGGER.log(FINE, "Finishing with parser");
302 |
303 | // finalize output
304 | final String output = buf.toString();
305 | response.output(output);
306 | }
307 | }
308 |
--------------------------------------------------------------------------------
/src/main/java/com/arakelian/jq/JqResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.arakelian.jq;
19 |
20 | import java.util.List;
21 |
22 | import org.immutables.value.Value;
23 |
24 | import com.google.common.collect.ImmutableList;
25 |
26 | @Value.Immutable
27 | public interface JqResponse {
28 | @Value.Default
29 | public default List getErrors() {
30 | return ImmutableList.of();
31 | }
32 |
33 | @Value.Default
34 | public default String getOutput() {
35 | return "";
36 | }
37 |
38 | @Value.Derived
39 | @Value.Auxiliary
40 | public default boolean hasErrors() {
41 | return getErrors().size() != 0;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/arakelian/jq/NativeLib.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.arakelian.jq;
19 |
20 | import static java.util.logging.Level.INFO;
21 |
22 | import java.io.File;
23 | import java.io.FileOutputStream;
24 | import java.io.IOException;
25 | import java.io.InputStream;
26 | import java.io.OutputStream;
27 | import java.io.UncheckedIOException;
28 | import java.util.List;
29 | import java.util.Locale;
30 | import java.util.logging.Logger;
31 |
32 | import org.immutables.value.Value;
33 |
34 | import com.google.common.base.Preconditions;
35 | import com.google.common.collect.ImmutableList;
36 | import com.sun.jna.NativeLibrary;
37 | import com.sun.jna.Platform;
38 |
39 | @Value.Immutable(copy = false)
40 | public abstract class NativeLib {
41 | private static final Logger LOGGER = Logger.getLogger(NativeLib.class.getName());
42 |
43 | @Value.Derived
44 | @Value.Auxiliary
45 | public String getArchitecture() {
46 | return getOsName() + ":" + getOsArch();
47 | }
48 |
49 | @Value.Default
50 | @Value.Auxiliary
51 | public List getDependencies() {
52 | return ImmutableList.of();
53 | }
54 |
55 | @Value.Derived
56 | public List getFilenames() {
57 | final ImmutableList.Builder builder = ImmutableList.builder();
58 |
59 | final String name = getName();
60 | if (Platform.isWindows()) {
61 | builder.add(name + ".dll");
62 | } else if (Platform.isLinux()) {
63 | builder.add("lib" + name + ".so");
64 | } else if (Platform.isMac()) {
65 | builder.add("lib" + name + ".dylib");
66 | } else {
67 | throw new IllegalStateException("Unsupported architecture: " + getArchitecture());
68 | }
69 |
70 | for (final String dependency : getDependencies()) {
71 | builder.add(dependency);
72 | }
73 |
74 | return builder.build();
75 | }
76 |
77 | @Value.Lazy
78 | @Value.Auxiliary
79 | public File getLocalCopy() throws UncheckedIOException {
80 | final File tmpdir = getTemporaryFolder();
81 |
82 | for (final String filename : getFilenames()) {
83 | try {
84 | final File local = new File(tmpdir, filename);
85 | // local.deleteOnExit();
86 |
87 | final String resource = "lib/" + getPath() + filename;
88 | LOGGER.log(INFO, "Copying resource {0} to: {1}", new Object[] { resource, local });
89 | try (InputStream in = this.getClass().getClassLoader().getResourceAsStream(resource);
90 | OutputStream out = new FileOutputStream(local)) {
91 | Preconditions.checkState(in != null, "Cannot find resource %s", resource);
92 | final byte buf[] = new byte[1024 * 1024];
93 | int n;
94 | while (-1 != (n = in.read(buf))) {
95 | out.write(buf, 0, n);
96 | }
97 | }
98 | } catch (final IOException e) {
99 | throw new UncheckedIOException(
100 | "Unable to copy library " + filename + " to temporary folder " + tmpdir, e);
101 | }
102 | }
103 |
104 | return tmpdir;
105 | }
106 |
107 | public abstract String getName();
108 |
109 | @Value.Lazy
110 | @Value.Auxiliary
111 | public NativeLibrary getNativeLibrary() throws UncheckedIOException {
112 | final String name = getName();
113 |
114 | final File libPath = getLocalCopy();
115 | LOGGER.log(INFO, "{0} library path: {1}", new Object[] { name, libPath });
116 | NativeLibrary.addSearchPath(name, libPath.getAbsolutePath());
117 |
118 | final NativeLibrary instance = NativeLibrary.getInstance(name);
119 | LOGGER.log(INFO, "{0} loaded from path: {1} ", new Object[] { name, libPath });
120 | return instance;
121 | }
122 |
123 | @Value.Derived
124 | public String getOsArch() {
125 | final String arch = System.getProperty("os.arch");
126 | return arch != null ? arch.toLowerCase(Locale.ROOT) : "";
127 | }
128 |
129 | @Value.Derived
130 | public String getOsName() {
131 | final String name = System.getProperty("os.name");
132 | return name != null ? name.toLowerCase(Locale.ROOT) : "";
133 | }
134 |
135 | @Value.Derived
136 | public String getPath() {
137 | final String osArch = getOsArch();
138 | if (Platform.isWindows()) {
139 | if ("x86".equalsIgnoreCase(osArch)) {
140 | return "win-x86/";
141 | }
142 | } else if (Platform.isLinux()) {
143 | if ("amd64".equalsIgnoreCase(osArch)) {
144 | return "linux-x86_64/";
145 | } else if ("ia64".equalsIgnoreCase(osArch)) {
146 | return "linux-ia64/";
147 | } else if ("i386".equalsIgnoreCase(osArch)) {
148 | return "linux-x86/";
149 | } else if ("aarch64".equalsIgnoreCase(osArch)) {
150 | return "linux-aarch64/";
151 | }
152 | } else if (Platform.isMac()) {
153 | if ("aarch64".equalsIgnoreCase(osArch)) {
154 | return "darwin-aarch64/";
155 | } else if ("x86_64".equalsIgnoreCase(osArch)) {
156 | return "darwin-x86_64/";
157 | }
158 | }
159 | throw new IllegalStateException("Unsupported architecture: " + getArchitecture());
160 | }
161 |
162 | @Value.Default
163 | @Value.Auxiliary
164 | public File getTemporaryFolder() throws UncheckedIOException {
165 | // must create a temp directory, required for NativeLibrary.addSearchPath
166 | File baseDir = new File(System.getProperty("java.io.tmpdir"));
167 | String baseName = System.currentTimeMillis() + "-";
168 |
169 | for (int counter = 0; counter < 10000; counter++) {
170 | File tmpDir = new File(baseDir, baseName + counter);
171 | if (tmpDir.mkdir()) {
172 | return tmpDir;
173 | }
174 | }
175 | throw new IllegalStateException("Failed to create temp directory");
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/src/main/java/com/arakelian/jq/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | @Value.Style(get = { "is*", "get*" }, depluralize = true)
19 | package com.arakelian.jq;
20 |
21 | import org.immutables.value.Value;
22 |
--------------------------------------------------------------------------------
/src/main/resources/lib/darwin-aarch64/libjq.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arakelian/java-jq/e2ec113e89430025b48b4fcca748a309731a03e2/src/main/resources/lib/darwin-aarch64/libjq.dylib
--------------------------------------------------------------------------------
/src/main/resources/lib/darwin-x86_64/libjq.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arakelian/java-jq/e2ec113e89430025b48b4fcca748a309731a03e2/src/main/resources/lib/darwin-x86_64/libjq.dylib
--------------------------------------------------------------------------------
/src/main/resources/lib/linux-aarch64/libjq.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arakelian/java-jq/e2ec113e89430025b48b4fcca748a309731a03e2/src/main/resources/lib/linux-aarch64/libjq.so
--------------------------------------------------------------------------------
/src/main/resources/lib/linux-x86_64/libjq.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arakelian/java-jq/e2ec113e89430025b48b4fcca748a309731a03e2/src/main/resources/lib/linux-x86_64/libjq.so
--------------------------------------------------------------------------------
/src/test/java/com/arakelian/jq/AbstractJqTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.arakelian.jq;
19 |
20 | import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals;
21 | import static org.junit.jupiter.api.Assertions.assertEquals;
22 | import static org.junit.jupiter.api.Assertions.assertNotNull;
23 | import static org.junit.jupiter.api.Assertions.assertTrue;
24 |
25 | import java.io.BufferedReader;
26 | import java.io.File;
27 | import java.io.IOException;
28 | import java.io.StringReader;
29 | import java.net.URL;
30 | import java.util.Collection;
31 | import java.util.List;
32 | import java.util.logging.LogManager;
33 |
34 | import org.junit.jupiter.api.BeforeAll;
35 | import org.opentest4j.AssertionFailedError;
36 |
37 | import com.arakelian.jq.JqRequest.Indent;
38 | import com.google.common.base.Charsets;
39 | import com.google.common.base.Preconditions;
40 | import com.google.common.collect.Lists;
41 | import com.google.common.io.Resources;
42 |
43 | import net.javacrumbs.jsonunit.JsonAssert;
44 |
45 | public abstract class AbstractJqTest {
46 | public static class JqTestParser {
47 | private final String resource;
48 |
49 | public JqTestParser(final String resource) {
50 | this.resource = resource;
51 | }
52 |
53 | public Collection