Merge branch release/0.2.0 into master
Demo of full-path node name insertInPath() uses setData() Dynamic node names New tests following mutation testing Tidy the Node interface Named nodes Update code style Drop lombok in production (still using it in test)
This commit is contained in:
commit
323fba13c4
18 changed files with 2085 additions and 523 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -12,3 +12,6 @@
|
|||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
/.idea/libraries/
|
||||
/.idea/workspace.xml
|
||||
|
|
10
.idea/checkstyle-idea.xml
Normal file
10
.idea/checkstyle-idea.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CheckStyle-IDEA">
|
||||
<option name="configuration">
|
||||
<map>
|
||||
<entry key="scan-before-checkin" value="false" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
104
.idea/codeStyleSettings.xml
Normal file
104
.idea/codeStyleSettings.xml
Normal file
|
@ -0,0 +1,104 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectCodeStyleSettingsManager">
|
||||
<option name="PER_PROJECT_SETTINGS">
|
||||
<value>
|
||||
<option name="GENERATE_FINAL_LOCALS" value="true" />
|
||||
<option name="GENERATE_FINAL_PARAMETERS" value="true" />
|
||||
<option name="VISIBILITY" value="packageLocal" />
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="9999" />
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="9999" />
|
||||
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||
<value />
|
||||
</option>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="" withSubpackages="true" static="true" />
|
||||
<emptyLine />
|
||||
<package name="java" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="javax" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="org.springframework" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="uk.ac.fife" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="net.kemitix" withSubpackages="true" static="false" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="JD_ADD_BLANK_AFTER_PARM_COMMENTS" value="true" />
|
||||
<option name="JD_ADD_BLANK_AFTER_RETURN" value="true" />
|
||||
<option name="WRAP_COMMENTS" value="true" />
|
||||
<JavaCodeStyleSettings>
|
||||
<option name="ANNOTATION_PARAMETER_WRAP" value="1" />
|
||||
</JavaCodeStyleSettings>
|
||||
<XML>
|
||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
||||
</XML>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="RIGHT_MARGIN" value="80" />
|
||||
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
|
||||
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
|
||||
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
|
||||
<option name="BLANK_LINES_AROUND_FIELD" value="1" />
|
||||
<option name="BLANK_LINES_AROUND_FIELD_IN_INTERFACE" value="1" />
|
||||
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
|
||||
<option name="INDENT_CASE_FROM_SWITCH" value="false" />
|
||||
<option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
|
||||
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
|
||||
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
|
||||
<option name="SPACE_BEFORE_ANNOTATION_ARRAY_INITIALIZER_LBRACE" value="true" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="RESOURCE_LIST_WRAP" value="1" />
|
||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||
<option name="THROWS_LIST_WRAP" value="1" />
|
||||
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
|
||||
<option name="THROWS_KEYWORD_WRAP" value="1" />
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="5" />
|
||||
<option name="BINARY_OPERATION_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="TERNARY_OPERATION_WRAP" value="5" />
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||
<option name="FOR_STATEMENT_WRAP" value="1" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<option name="ASSIGNMENT_WRAP" value="1" />
|
||||
<option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="ASSERT_STATEMENT_WRAP" value="1" />
|
||||
<option name="ASSERT_STATEMENT_COLON_ON_NEXT_LINE" value="true" />
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
<option name="WRAP_LONG_LINES" value="true" />
|
||||
<option name="PARAMETER_ANNOTATION_WRAP" value="1" />
|
||||
<option name="VARIABLE_ANNOTATION_WRAP" value="1" />
|
||||
<option name="ENUM_CONSTANTS_WRAP" value="1" />
|
||||
<arrangement>
|
||||
<groups>
|
||||
<group>
|
||||
<type>GETTERS_AND_SETTERS</type>
|
||||
<order>KEEP</order>
|
||||
</group>
|
||||
<group>
|
||||
<type>OVERRIDDEN_METHODS</type>
|
||||
<order>KEEP</order>
|
||||
</group>
|
||||
<group>
|
||||
<type>DEPENDENT_METHODS</type>
|
||||
<order>BREADTH_FIRST</order>
|
||||
</group>
|
||||
</groups>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</value>
|
||||
</option>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</component>
|
||||
</project>
|
33
.idea/compiler.xml
Normal file
33
.idea/compiler.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
<entry name="!?*.aj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
<profile default="false" name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<processorPath useClasspath="true" />
|
||||
<module name="node" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
<bytecodeTargetLevel>
|
||||
<module name="node" target="1.8" />
|
||||
</bytecodeTargetLevel>
|
||||
</component>
|
||||
</project>
|
7
.idea/encodings.xml
Normal file
7
.idea/encodings.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$" charset="UTF-8" />
|
||||
<file url="PROJECT" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
213
.idea/findbugs-idea.xml
Normal file
213
.idea/findbugs-idea.xml
Normal file
|
@ -0,0 +1,213 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="org.twodividedbyzero.idea.findbugs">
|
||||
<option name="annotationTypeSettings">
|
||||
<map>
|
||||
<entry key="ExpPriority" value="-4473925;-12828863;-8355712;WAVE_UNDERSCORE;0;" />
|
||||
<entry key="HighPriority" value="-39836;-12828863;-39836;WAVE_UNDERSCORE;1;" />
|
||||
<entry key="IgnorePriority" value="-4473925;-12828863;-11978414;WAVE_UNDERSCORE;0;" />
|
||||
<entry key="LowPriority" value="-4473925;-12828863;-10316203;BOXED;0;" />
|
||||
<entry key="NormalPriority" value="-4473925;-12828863;-10461184;WAVE_UNDERSCORE;2;" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="_basePreferences">
|
||||
<map>
|
||||
<entry key="property.analysisEffortLevel" value="default" />
|
||||
<entry key="property.analyzeAfterCompile" value="false" />
|
||||
<entry key="property.annotationGutterIconEnabled" value="true" />
|
||||
<entry key="property.annotationSuppressWarningsClass" value="edu.umd.cs.findbugs.annotations.SuppressWarnings" />
|
||||
<entry key="property.annotationTextRangeMarkupEnabled" value="true" />
|
||||
<entry key="property.exportAsHtml" value="true" />
|
||||
<entry key="property.exportAsXml" value="true" />
|
||||
<entry key="property.exportBaseDir" value="" />
|
||||
<entry key="property.exportCreateArchiveDir" value="false" />
|
||||
<entry key="property.exportOpenBrowser" value="true" />
|
||||
<entry key="property.minPriorityToReport" value="Medium" />
|
||||
<entry key="property.runAnalysisInBackground" value="false" />
|
||||
<entry key="property.showHiddenDetectors" value="false" />
|
||||
<entry key="property.toolWindowToFront" value="true" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="_detectors">
|
||||
<map>
|
||||
<entry key="AppendingToAnObjectOutputStream" value="true" />
|
||||
<entry key="AtomicityProblem" value="true" />
|
||||
<entry key="BadAppletConstructor" value="false" />
|
||||
<entry key="BadResultSetAccess" value="true" />
|
||||
<entry key="BadSyntaxForRegularExpression" value="true" />
|
||||
<entry key="BadUseOfReturnValue" value="true" />
|
||||
<entry key="BadlyOverriddenAdapter" value="true" />
|
||||
<entry key="BooleanReturnNull" value="true" />
|
||||
<entry key="BuildInterproceduralCallGraph" value="false" />
|
||||
<entry key="BuildObligationPolicyDatabase" value="true" />
|
||||
<entry key="CallToUnsupportedMethod" value="false" />
|
||||
<entry key="CalledMethods" value="true" />
|
||||
<entry key="CheckCalls" value="false" />
|
||||
<entry key="CheckExpectedWarnings" value="false" />
|
||||
<entry key="CheckImmutableAnnotation" value="true" />
|
||||
<entry key="CheckTypeQualifiers" value="true" />
|
||||
<entry key="CloneIdiom" value="true" />
|
||||
<entry key="ComparatorIdiom" value="true" />
|
||||
<entry key="ConfusedInheritance" value="true" />
|
||||
<entry key="ConfusionBetweenInheritedAndOuterMethod" value="true" />
|
||||
<entry key="CrossSiteScripting" value="true" />
|
||||
<entry key="DefaultEncodingDetector" value="true" />
|
||||
<entry key="DoInsideDoPrivileged" value="true" />
|
||||
<entry key="DontCatchIllegalMonitorStateException" value="true" />
|
||||
<entry key="DontIgnoreResultOfPutIfAbsent" value="true" />
|
||||
<entry key="DontUseEnum" value="true" />
|
||||
<entry key="DroppedException" value="true" />
|
||||
<entry key="DumbMethodInvocations" value="true" />
|
||||
<entry key="DumbMethods" value="true" />
|
||||
<entry key="DuplicateBranches" value="true" />
|
||||
<entry key="EmptyZipFileEntry" value="true" />
|
||||
<entry key="EqualsOperandShouldHaveClassCompatibleWithThis" value="true" />
|
||||
<entry key="ExplicitSerialization" value="true" />
|
||||
<entry key="FieldItemSummary" value="true" />
|
||||
<entry key="FinalizerNullsFields" value="true" />
|
||||
<entry key="FindBadCast2" value="true" />
|
||||
<entry key="FindBadForLoop" value="true" />
|
||||
<entry key="FindBugsSummaryStats" value="true" />
|
||||
<entry key="FindCircularDependencies" value="false" />
|
||||
<entry key="FindDeadLocalStores" value="true" />
|
||||
<entry key="FindDoubleCheck" value="true" />
|
||||
<entry key="FindEmptySynchronizedBlock" value="true" />
|
||||
<entry key="FindFieldSelfAssignment" value="true" />
|
||||
<entry key="FindFinalizeInvocations" value="true" />
|
||||
<entry key="FindFloatEquality" value="true" />
|
||||
<entry key="FindFloatMath" value="false" />
|
||||
<entry key="FindHEmismatch" value="true" />
|
||||
<entry key="FindInconsistentSync2" value="true" />
|
||||
<entry key="FindJSR166LockMonitorenter" value="true" />
|
||||
<entry key="FindLocalSelfAssignment2" value="true" />
|
||||
<entry key="FindMaskedFields" value="true" />
|
||||
<entry key="FindMismatchedWaitOrNotify" value="true" />
|
||||
<entry key="FindNakedNotify" value="true" />
|
||||
<entry key="FindNonSerializableStoreIntoSession" value="false" />
|
||||
<entry key="FindNonSerializableValuePassedToWriteObject" value="false" />
|
||||
<entry key="FindNonShortCircuit" value="true" />
|
||||
<entry key="FindNullDeref" value="true" />
|
||||
<entry key="FindNullDerefsInvolvingNonShortCircuitEvaluation" value="true" />
|
||||
<entry key="FindOpenStream" value="true" />
|
||||
<entry key="FindPuzzlers" value="true" />
|
||||
<entry key="FindRefComparison" value="true" />
|
||||
<entry key="FindReturnRef" value="true" />
|
||||
<entry key="FindRunInvocations" value="true" />
|
||||
<entry key="FindSelfComparison" value="true" />
|
||||
<entry key="FindSelfComparison2" value="true" />
|
||||
<entry key="FindSleepWithLockHeld" value="true" />
|
||||
<entry key="FindSpinLoop" value="true" />
|
||||
<entry key="FindSqlInjection" value="true" />
|
||||
<entry key="FindTwoLockWait" value="true" />
|
||||
<entry key="FindUncalledPrivateMethods" value="true" />
|
||||
<entry key="FindUnconditionalWait" value="true" />
|
||||
<entry key="FindUninitializedGet" value="true" />
|
||||
<entry key="FindUnrelatedTypesInGenericContainer" value="true" />
|
||||
<entry key="FindUnreleasedLock" value="true" />
|
||||
<entry key="FindUnsatisfiedObligation" value="true" />
|
||||
<entry key="FindUnsyncGet" value="true" />
|
||||
<entry key="FindUseOfNonSerializableValue" value="true" />
|
||||
<entry key="FindUselessControlFlow" value="true" />
|
||||
<entry key="FormatStringChecker" value="true" />
|
||||
<entry key="FunctionsThatMightBeMistakenForProcedures" value="true" />
|
||||
<entry key="HugeSharedStringConstants" value="true" />
|
||||
<entry key="IDivResultCastToDouble" value="true" />
|
||||
<entry key="IncompatMask" value="true" />
|
||||
<entry key="InconsistentAnnotations" value="true" />
|
||||
<entry key="InefficientMemberAccess" value="false" />
|
||||
<entry key="InefficientToArray" value="true" />
|
||||
<entry key="InfiniteLoop" value="true" />
|
||||
<entry key="InfiniteRecursiveLoop" value="true" />
|
||||
<entry key="InheritanceUnsafeGetResource" value="true" />
|
||||
<entry key="InitializationChain" value="true" />
|
||||
<entry key="InitializeNonnullFieldsInConstructor" value="true" />
|
||||
<entry key="InstantiateStaticClass" value="true" />
|
||||
<entry key="IntCast2LongAsInstant" value="true" />
|
||||
<entry key="InvalidJUnitTest" value="true" />
|
||||
<entry key="IteratorIdioms" value="true" />
|
||||
<entry key="LazyInit" value="true" />
|
||||
<entry key="LoadOfKnownNullValue" value="true" />
|
||||
<entry key="LostLoggerDueToWeakReference" value="true" />
|
||||
<entry key="MethodReturnCheck" value="true" />
|
||||
<entry key="Methods" value="true" />
|
||||
<entry key="MultithreadedInstanceAccess" value="true" />
|
||||
<entry key="MutableLock" value="true" />
|
||||
<entry key="MutableStaticFields" value="true" />
|
||||
<entry key="Naming" value="true" />
|
||||
<entry key="Noise" value="false" />
|
||||
<entry key="NoiseNullDeref" value="false" />
|
||||
<entry key="NoteAnnotationRetention" value="true" />
|
||||
<entry key="NoteCheckReturnValueAnnotations" value="true" />
|
||||
<entry key="NoteDirectlyRelevantTypeQualifiers" value="true" />
|
||||
<entry key="NoteJCIPAnnotation" value="true" />
|
||||
<entry key="NoteNonNullAnnotations" value="true" />
|
||||
<entry key="NoteNonnullReturnValues" value="true" />
|
||||
<entry key="NoteSuppressedWarnings" value="true" />
|
||||
<entry key="NoteUnconditionalParamDerefs" value="true" />
|
||||
<entry key="NumberConstructor" value="true" />
|
||||
<entry key="OverridingEqualsNotSymmetrical" value="true" />
|
||||
<entry key="PreferZeroLengthArrays" value="true" />
|
||||
<entry key="PublicSemaphores" value="false" />
|
||||
<entry key="QuestionableBooleanAssignment" value="true" />
|
||||
<entry key="ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass" value="true" />
|
||||
<entry key="ReadReturnShouldBeChecked" value="true" />
|
||||
<entry key="RedundantInterfaces" value="true" />
|
||||
<entry key="ReflectiveClasses" value="true" />
|
||||
<entry key="RepeatedConditionals" value="true" />
|
||||
<entry key="ResolveAllReferences" value="false" />
|
||||
<entry key="RuntimeExceptionCapture" value="true" />
|
||||
<entry key="SerializableIdiom" value="true" />
|
||||
<entry key="StartInConstructor" value="true" />
|
||||
<entry key="StaticCalendarDetector" value="true" />
|
||||
<entry key="StringConcatenation" value="true" />
|
||||
<entry key="SuperfluousInstanceOf" value="true" />
|
||||
<entry key="SuspiciousThreadInterrupted" value="true" />
|
||||
<entry key="SwitchFallthrough" value="true" />
|
||||
<entry key="SynchronizationOnSharedBuiltinConstant" value="true" />
|
||||
<entry key="SynchronizeAndNullCheckField" value="true" />
|
||||
<entry key="SynchronizeOnClassLiteralNotGetClass" value="true" />
|
||||
<entry key="SynchronizingOnContentsOfFieldToProtectField" value="true" />
|
||||
<entry key="TestASM" value="false" />
|
||||
<entry key="TestDataflowAnalysis" value="false" />
|
||||
<entry key="TestingGround" value="false" />
|
||||
<entry key="TestingGround2" value="false" />
|
||||
<entry key="TrainFieldStoreTypes" value="true" />
|
||||
<entry key="TrainLongInstantfParams" value="true" />
|
||||
<entry key="TrainNonNullAnnotations" value="true" />
|
||||
<entry key="TrainUnconditionalDerefParams" value="true" />
|
||||
<entry key="URLProblems" value="true" />
|
||||
<entry key="UncallableMethodOfAnonymousClass" value="true" />
|
||||
<entry key="UnnecessaryMath" value="true" />
|
||||
<entry key="UnreadFields" value="true" />
|
||||
<entry key="UselessSubclassMethod" value="false" />
|
||||
<entry key="VarArgsProblems" value="true" />
|
||||
<entry key="VolatileUsage" value="true" />
|
||||
<entry key="WaitInLoop" value="true" />
|
||||
<entry key="WrongMapIterator" value="true" />
|
||||
<entry key="XMLFactoryBypass" value="true" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="_reportCategories">
|
||||
<map>
|
||||
<entry key="BAD_PRACTICE" value="true" />
|
||||
<entry key="CORRECTNESS" value="true" />
|
||||
<entry key="EXPERIMENTAL" value="true" />
|
||||
<entry key="I18N" value="true" />
|
||||
<entry key="MALICIOUS_CODE" value="true" />
|
||||
<entry key="MT_CORRECTNESS" value="true" />
|
||||
<entry key="PERFORMANCE" value="true" />
|
||||
<entry key="SECURITY" value="true" />
|
||||
<entry key="STYLE" value="true" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="_annotationTypeSettings">
|
||||
<map>
|
||||
<entry key="ExpPriority" value="-4473925;-12828863;-8355712;WAVE_UNDERSCORE;0;" />
|
||||
<entry key="HighPriority" value="-39836;-12828863;-39836;WAVE_UNDERSCORE;1;" />
|
||||
<entry key="IgnorePriority" value="-4473925;-12828863;-11978414;WAVE_UNDERSCORE;0;" />
|
||||
<entry key="LowPriority" value="-4473925;-12828863;-10316203;BOXED;0;" />
|
||||
<entry key="NormalPriority" value="-4473925;-12828863;-10461184;WAVE_UNDERSCORE;2;" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
60
.idea/inspectionProfiles/Project_Default.xml
Normal file
60
.idea/inspectionProfiles/Project_Default.xml
Normal file
|
@ -0,0 +1,60 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<option name="myLocal" value="true" />
|
||||
<inspection_tool class="AssertEqualsCalledOnArray" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="AssertEqualsMayBeAssertSame" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="AssertsWithoutMessages" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="BeforeClassOrAfterClassIsPublicStaticVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="BeforeOrAfterIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="ConstantJUnitAssertArgument" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="ExpectedExceptionNeverThrown" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="FindBugsIDEA" enabled="true" level="SERVER PROBLEM" enabled_by_default="true" />
|
||||
<inspection_tool class="IgnoredJUnitTest" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="JUnit3MethodNamingConvention" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="JUnit3StyleTestMethodInJUnit4Class" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="JUnit4MethodNamingConvention" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="JUnitAbstractTestClassNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="m_regex" value="[A-Z][A-Za-z\d]*TestCase" />
|
||||
<option name="m_minLength" value="12" />
|
||||
<option name="m_maxLength" value="64" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="JUnitDatapoint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="JUnitRule" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="JUnitTestClassNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="m_regex" value="[A-Z][A-Za-z\d]*(Test|IT)" />
|
||||
<option name="m_minLength" value="8" />
|
||||
<option name="m_maxLength" value="64" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
|
||||
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
|
||||
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="MigrateAssertToMatcherAssert" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="MisorderedAssertEqualsParameters" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="MisspelledSetUp" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="MisspelledTearDown" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="MultipleExceptionsDeclaredOnTestMethod" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="ParameterizedParametersStaticCollection" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SetupCallsSuperSetup" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SetupIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SimplifiableJUnitAssertion" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="StaticSuite" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SuperTearDownInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="TeardownCallsSuperTeardown" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="TeardownIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="TestCaseInProductCode" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="TestCaseWithConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="TestCaseWithNoTestMethods" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoreSupers" value="false" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="TestMethodInProductCode" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="TestMethodIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="TestMethodWithoutAssertion" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="assertionMethods" value="org.junit.Assert,assert.*|fail.*,junit.framework.Assert,assert.*|fail.*,org.mockito.Mockito,verify.*,org.mockito.InOrder,verify,org.junit.rules.ExpectedException,expect.*,org.hamcrest.MatcherAssert,assertThat,org.assertj.core.api.Assertions,assertThat,org.assertj.core.api.SoftAssertions,assertAll" />
|
||||
<option name="assertKeywordIsAssertion" value="false" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="UnconstructableTestCase" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="UseOfObsoleteAssert" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
7
.idea/inspectionProfiles/profiles_settings.xml
Normal file
7
.idea/inspectionProfiles/profiles_settings.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="PROJECT_PROFILE" value="Project Default" />
|
||||
<option name="USE_PROJECT_PROFILE" value="true" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
42
.idea/misc.xml
Normal file
42
.idea/misc.xml
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/classes" />
|
||||
</component>
|
||||
<component name="masterDetails">
|
||||
<states>
|
||||
<state key="ProjectJDKs.UI">
|
||||
<settings>
|
||||
<last-edited>1.8</last-edited>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
</states>
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/node.iml" filepath="$PROJECT_DIR$/node.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
12
CHANGELOG
12
CHANGELOG
|
@ -1,6 +1,18 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
|
||||
0.2.0
|
||||
------
|
||||
|
||||
* Demo of full-path node name
|
||||
* insertInPath() uses setData()
|
||||
* Dynamic node names
|
||||
* New tests following mutation testing
|
||||
* Tidy the Node interface
|
||||
* Named nodes
|
||||
* Update code style
|
||||
* Drop lombok in production (still using it in test)
|
||||
|
||||
0.1.0
|
||||
------
|
||||
|
||||
|
|
180
node.iml
Normal file
180
node.iml
Normal file
|
@ -0,0 +1,180 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.projectlombok:lombok:1.16.8" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.4.1" level="project" />
|
||||
</component>
|
||||
<component name="org.twodividedbyzero.idea.findbugs">
|
||||
<option name="_detectors">
|
||||
<map>
|
||||
<entry key="AppendingToAnObjectOutputStream" value="true" />
|
||||
<entry key="AtomicityProblem" value="true" />
|
||||
<entry key="BadAppletConstructor" value="false" />
|
||||
<entry key="BadResultSetAccess" value="true" />
|
||||
<entry key="BadSyntaxForRegularExpression" value="true" />
|
||||
<entry key="BadUseOfReturnValue" value="true" />
|
||||
<entry key="BadlyOverriddenAdapter" value="true" />
|
||||
<entry key="BooleanReturnNull" value="true" />
|
||||
<entry key="BuildInterproceduralCallGraph" value="false" />
|
||||
<entry key="BuildObligationPolicyDatabase" value="true" />
|
||||
<entry key="CallToUnsupportedMethod" value="false" />
|
||||
<entry key="CalledMethods" value="true" />
|
||||
<entry key="CheckCalls" value="false" />
|
||||
<entry key="CheckExpectedWarnings" value="false" />
|
||||
<entry key="CheckImmutableAnnotation" value="true" />
|
||||
<entry key="CheckTypeQualifiers" value="true" />
|
||||
<entry key="CloneIdiom" value="true" />
|
||||
<entry key="ComparatorIdiom" value="true" />
|
||||
<entry key="ConfusedInheritance" value="true" />
|
||||
<entry key="ConfusionBetweenInheritedAndOuterMethod" value="true" />
|
||||
<entry key="CrossSiteScripting" value="true" />
|
||||
<entry key="DefaultEncodingDetector" value="true" />
|
||||
<entry key="DoInsideDoPrivileged" value="true" />
|
||||
<entry key="DontCatchIllegalMonitorStateException" value="true" />
|
||||
<entry key="DontIgnoreResultOfPutIfAbsent" value="true" />
|
||||
<entry key="DontUseEnum" value="true" />
|
||||
<entry key="DroppedException" value="true" />
|
||||
<entry key="DumbMethodInvocations" value="true" />
|
||||
<entry key="DumbMethods" value="true" />
|
||||
<entry key="DuplicateBranches" value="true" />
|
||||
<entry key="EmptyZipFileEntry" value="true" />
|
||||
<entry key="EqualsOperandShouldHaveClassCompatibleWithThis" value="true" />
|
||||
<entry key="ExplicitSerialization" value="true" />
|
||||
<entry key="FieldItemSummary" value="true" />
|
||||
<entry key="FinalizerNullsFields" value="true" />
|
||||
<entry key="FindBadCast2" value="true" />
|
||||
<entry key="FindBadForLoop" value="true" />
|
||||
<entry key="FindBugsSummaryStats" value="true" />
|
||||
<entry key="FindCircularDependencies" value="false" />
|
||||
<entry key="FindDeadLocalStores" value="true" />
|
||||
<entry key="FindDoubleCheck" value="true" />
|
||||
<entry key="FindEmptySynchronizedBlock" value="true" />
|
||||
<entry key="FindFieldSelfAssignment" value="true" />
|
||||
<entry key="FindFinalizeInvocations" value="true" />
|
||||
<entry key="FindFloatEquality" value="true" />
|
||||
<entry key="FindFloatMath" value="false" />
|
||||
<entry key="FindHEmismatch" value="true" />
|
||||
<entry key="FindInconsistentSync2" value="true" />
|
||||
<entry key="FindJSR166LockMonitorenter" value="true" />
|
||||
<entry key="FindLocalSelfAssignment2" value="true" />
|
||||
<entry key="FindMaskedFields" value="true" />
|
||||
<entry key="FindMismatchedWaitOrNotify" value="true" />
|
||||
<entry key="FindNakedNotify" value="true" />
|
||||
<entry key="FindNonSerializableStoreIntoSession" value="false" />
|
||||
<entry key="FindNonSerializableValuePassedToWriteObject" value="false" />
|
||||
<entry key="FindNonShortCircuit" value="true" />
|
||||
<entry key="FindNullDeref" value="true" />
|
||||
<entry key="FindNullDerefsInvolvingNonShortCircuitEvaluation" value="true" />
|
||||
<entry key="FindOpenStream" value="true" />
|
||||
<entry key="FindPuzzlers" value="true" />
|
||||
<entry key="FindRefComparison" value="true" />
|
||||
<entry key="FindReturnRef" value="true" />
|
||||
<entry key="FindRunInvocations" value="true" />
|
||||
<entry key="FindSelfComparison" value="true" />
|
||||
<entry key="FindSelfComparison2" value="true" />
|
||||
<entry key="FindSleepWithLockHeld" value="true" />
|
||||
<entry key="FindSpinLoop" value="true" />
|
||||
<entry key="FindSqlInjection" value="true" />
|
||||
<entry key="FindTwoLockWait" value="true" />
|
||||
<entry key="FindUncalledPrivateMethods" value="true" />
|
||||
<entry key="FindUnconditionalWait" value="true" />
|
||||
<entry key="FindUninitializedGet" value="true" />
|
||||
<entry key="FindUnrelatedTypesInGenericContainer" value="true" />
|
||||
<entry key="FindUnreleasedLock" value="true" />
|
||||
<entry key="FindUnsatisfiedObligation" value="true" />
|
||||
<entry key="FindUnsyncGet" value="true" />
|
||||
<entry key="FindUseOfNonSerializableValue" value="true" />
|
||||
<entry key="FindUselessControlFlow" value="true" />
|
||||
<entry key="FormatStringChecker" value="true" />
|
||||
<entry key="FunctionsThatMightBeMistakenForProcedures" value="true" />
|
||||
<entry key="HugeSharedStringConstants" value="true" />
|
||||
<entry key="IDivResultCastToDouble" value="true" />
|
||||
<entry key="IncompatMask" value="true" />
|
||||
<entry key="InconsistentAnnotations" value="true" />
|
||||
<entry key="InefficientMemberAccess" value="false" />
|
||||
<entry key="InefficientToArray" value="true" />
|
||||
<entry key="InfiniteLoop" value="true" />
|
||||
<entry key="InfiniteRecursiveLoop" value="true" />
|
||||
<entry key="InheritanceUnsafeGetResource" value="true" />
|
||||
<entry key="InitializationChain" value="true" />
|
||||
<entry key="InitializeNonnullFieldsInConstructor" value="true" />
|
||||
<entry key="InstantiateStaticClass" value="true" />
|
||||
<entry key="IntCast2LongAsInstant" value="true" />
|
||||
<entry key="InvalidJUnitTest" value="true" />
|
||||
<entry key="IteratorIdioms" value="true" />
|
||||
<entry key="LazyInit" value="true" />
|
||||
<entry key="LoadOfKnownNullValue" value="true" />
|
||||
<entry key="LostLoggerDueToWeakReference" value="true" />
|
||||
<entry key="MethodReturnCheck" value="true" />
|
||||
<entry key="Methods" value="true" />
|
||||
<entry key="MultithreadedInstanceAccess" value="true" />
|
||||
<entry key="MutableLock" value="true" />
|
||||
<entry key="MutableStaticFields" value="true" />
|
||||
<entry key="Naming" value="true" />
|
||||
<entry key="Noise" value="false" />
|
||||
<entry key="NoiseNullDeref" value="false" />
|
||||
<entry key="NoteAnnotationRetention" value="true" />
|
||||
<entry key="NoteCheckReturnValueAnnotations" value="true" />
|
||||
<entry key="NoteDirectlyRelevantTypeQualifiers" value="true" />
|
||||
<entry key="NoteJCIPAnnotation" value="true" />
|
||||
<entry key="NoteNonNullAnnotations" value="true" />
|
||||
<entry key="NoteNonnullReturnValues" value="true" />
|
||||
<entry key="NoteSuppressedWarnings" value="true" />
|
||||
<entry key="NoteUnconditionalParamDerefs" value="true" />
|
||||
<entry key="NumberConstructor" value="true" />
|
||||
<entry key="OverridingEqualsNotSymmetrical" value="true" />
|
||||
<entry key="PreferZeroLengthArrays" value="true" />
|
||||
<entry key="PublicSemaphores" value="false" />
|
||||
<entry key="QuestionableBooleanAssignment" value="true" />
|
||||
<entry key="ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass" value="true" />
|
||||
<entry key="ReadReturnShouldBeChecked" value="true" />
|
||||
<entry key="RedundantInterfaces" value="true" />
|
||||
<entry key="ReflectiveClasses" value="true" />
|
||||
<entry key="RepeatedConditionals" value="true" />
|
||||
<entry key="ResolveAllReferences" value="false" />
|
||||
<entry key="RuntimeExceptionCapture" value="true" />
|
||||
<entry key="SerializableIdiom" value="true" />
|
||||
<entry key="StartInConstructor" value="true" />
|
||||
<entry key="StaticCalendarDetector" value="true" />
|
||||
<entry key="StringConcatenation" value="true" />
|
||||
<entry key="SuperfluousInstanceOf" value="true" />
|
||||
<entry key="SuspiciousThreadInterrupted" value="true" />
|
||||
<entry key="SwitchFallthrough" value="true" />
|
||||
<entry key="SynchronizationOnSharedBuiltinConstant" value="true" />
|
||||
<entry key="SynchronizeAndNullCheckField" value="true" />
|
||||
<entry key="SynchronizeOnClassLiteralNotGetClass" value="true" />
|
||||
<entry key="SynchronizingOnContentsOfFieldToProtectField" value="true" />
|
||||
<entry key="TestASM" value="false" />
|
||||
<entry key="TestDataflowAnalysis" value="false" />
|
||||
<entry key="TestingGround" value="false" />
|
||||
<entry key="TestingGround2" value="false" />
|
||||
<entry key="TrainFieldStoreTypes" value="true" />
|
||||
<entry key="TrainLongInstantfParams" value="true" />
|
||||
<entry key="TrainNonNullAnnotations" value="true" />
|
||||
<entry key="TrainUnconditionalDerefParams" value="true" />
|
||||
<entry key="URLProblems" value="true" />
|
||||
<entry key="UncallableMethodOfAnonymousClass" value="true" />
|
||||
<entry key="UnnecessaryMath" value="true" />
|
||||
<entry key="UnreadFields" value="true" />
|
||||
<entry key="UselessSubclassMethod" value="false" />
|
||||
<entry key="VarArgsProblems" value="true" />
|
||||
<entry key="VolatileUsage" value="true" />
|
||||
<entry key="WaitInLoop" value="true" />
|
||||
<entry key="WrongMapIterator" value="true" />
|
||||
<entry key="XMLFactoryBypass" value="true" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</module>
|
17
pom.xml
17
pom.xml
|
@ -1,9 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>net.kemitix</groupId>
|
||||
<artifactId>node</artifactId>
|
||||
<version>0.1.0</version>
|
||||
<version>0.2.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Node</name>
|
||||
|
@ -15,6 +14,10 @@
|
|||
<version>0.6.0</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<assertj.version>3.4.1</assertj.version>
|
||||
</properties>
|
||||
|
||||
<issueManagement>
|
||||
<url>https://github.com/kemitix/node/issues</url>
|
||||
<system>GitHub Issues</system>
|
||||
|
@ -34,9 +37,9 @@
|
|||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.16.6</version>
|
||||
<version>1.16.8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
@ -49,5 +52,11 @@
|
|||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -7,11 +7,28 @@ import java.util.Set;
|
|||
/**
|
||||
* An interface for tree node items.
|
||||
*
|
||||
* @author pcampbell
|
||||
* @param <T> the type of data held in each node
|
||||
*
|
||||
* @author pcampbell
|
||||
*/
|
||||
public interface Node<T> {
|
||||
|
||||
/**
|
||||
* Fetch the name of the node. Where a node's name is determined via a name
|
||||
* supplier, the name may be regenerated each time this method is called.
|
||||
*
|
||||
* @return the name of the node
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Sets the explicit name for a node. Setting the name to null will clear
|
||||
* the name and revert to the parent's name supplier.
|
||||
*
|
||||
* @param name the new name
|
||||
*/
|
||||
void setName(String name);
|
||||
|
||||
/**
|
||||
* Fetch the data held within the node.
|
||||
*
|
||||
|
@ -20,8 +37,21 @@ public interface Node<T> {
|
|||
T getData();
|
||||
|
||||
/**
|
||||
* Fetch the parent node.
|
||||
* Set the data held within the node.
|
||||
*
|
||||
* @param data the node's data
|
||||
*/
|
||||
void setData(T data);
|
||||
|
||||
/**
|
||||
* Returns true if the node is empty (has no data).
|
||||
*
|
||||
* @return true is data is null
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Fetch the parent node.
|
||||
* <p>
|
||||
* If the node is a root node, i.e. has no parent, then this will return
|
||||
* null.
|
||||
|
@ -30,6 +60,13 @@ public interface Node<T> {
|
|||
*/
|
||||
Node<T> getParent();
|
||||
|
||||
/**
|
||||
* Make the current node a direct child of the parent.
|
||||
*
|
||||
* @param parent the new parent node
|
||||
*/
|
||||
void setParent(Node<T> parent);
|
||||
|
||||
/**
|
||||
* Fetches the child nodes.
|
||||
*
|
||||
|
@ -42,16 +79,26 @@ public interface Node<T> {
|
|||
*
|
||||
* @param child the node to add
|
||||
*/
|
||||
void addChild(final Node<T> child);
|
||||
void addChild(Node<T> child);
|
||||
|
||||
/**
|
||||
* Creates a new node and adds it as a child of the current node.
|
||||
* Creates a new unnamed node and adds it as a child of the current node.
|
||||
*
|
||||
* @param child the child node's data
|
||||
*
|
||||
* @return the new child node
|
||||
*/
|
||||
Node<T> createChild(final T child);
|
||||
Node<T> createChild(T child);
|
||||
|
||||
/**
|
||||
* Creates a new named node and adds it as a child of the current node.
|
||||
*
|
||||
* @param child the child node's data
|
||||
* @param name the name
|
||||
*
|
||||
* @return the new child node
|
||||
*/
|
||||
Node<T> createChild(T child, String name);
|
||||
|
||||
/**
|
||||
* Populates the tree with the path of nodes, each being a child of the
|
||||
|
@ -59,7 +106,7 @@ public interface Node<T> {
|
|||
*
|
||||
* @param descendants the line of descendants from the current node
|
||||
*/
|
||||
void createDescendantLine(final List<T> descendants);
|
||||
void createDescendantLine(List<T> descendants);
|
||||
|
||||
/**
|
||||
* Looks for a child node and returns it, creating a new child node if one
|
||||
|
@ -69,7 +116,8 @@ public interface Node<T> {
|
|||
*
|
||||
* @return the found or created child node
|
||||
*/
|
||||
Node<T> findOrCreateChild(final T child);
|
||||
@Deprecated
|
||||
Node<T> findOrCreateChild(T child);
|
||||
|
||||
/**
|
||||
* Fetches the node for the child if present.
|
||||
|
@ -78,7 +126,18 @@ public interface Node<T> {
|
|||
*
|
||||
* @return an {@link Optional} containing the child node if found
|
||||
*/
|
||||
Optional<Node<T>> getChild(final T child);
|
||||
Optional<Node<T>> findChild(T child);
|
||||
|
||||
/**
|
||||
* Fetches the node for the child if present.
|
||||
*
|
||||
* @param child the child's data to search for
|
||||
*
|
||||
* @return the child node if found
|
||||
*
|
||||
* @throws NodeException if the node is not found
|
||||
*/
|
||||
Node<T> getChild(T child);
|
||||
|
||||
/**
|
||||
* Checks if the node is an ancestor.
|
||||
|
@ -87,14 +146,7 @@ public interface Node<T> {
|
|||
*
|
||||
* @return true if the node is an ancestor
|
||||
*/
|
||||
boolean isChildOf(final Node<T> node);
|
||||
|
||||
/**
|
||||
* Make the current node a direct child of the parent.
|
||||
*
|
||||
* @param parent the new parent node
|
||||
*/
|
||||
void setParent(final Node<T> parent);
|
||||
boolean isDescendantOf(Node<T> node);
|
||||
|
||||
/**
|
||||
* Walks the node tree using the path to select each child.
|
||||
|
@ -103,6 +155,62 @@ public interface Node<T> {
|
|||
*
|
||||
* @return the child or null
|
||||
*/
|
||||
Optional<Node<T>> walkTree(final List<T> path);
|
||||
Optional<Node<T>> findInPath(List<T> path);
|
||||
|
||||
/**
|
||||
* Places the node in the tree under by the path. Intervening empty
|
||||
* nodes are created as needed.
|
||||
*
|
||||
* @param node the node to place
|
||||
* @param path the path to contain the new node
|
||||
*/
|
||||
void insertInPath(Node<T> node, String... path);
|
||||
|
||||
/**
|
||||
* Searches for a child with the name given.
|
||||
*
|
||||
* @param name the name of the child
|
||||
*
|
||||
* @return an Optional containing the child found or empty
|
||||
*/
|
||||
Optional<Node<T>> findChildByName(String name);
|
||||
|
||||
/**
|
||||
* Returns the child with the given name. If one can't be found a
|
||||
* NodeException is thrown.
|
||||
*
|
||||
* @param name the name of the child
|
||||
*
|
||||
* @return the node
|
||||
*/
|
||||
Node<T> getChildByName(String name);
|
||||
|
||||
/**
|
||||
* Draw a representation of the tree.
|
||||
*
|
||||
* @param depth current depth for recursion
|
||||
*
|
||||
* @return a representation of the tree
|
||||
*/
|
||||
String drawTree(int depth);
|
||||
|
||||
/**
|
||||
* Returns true if the Node has a name. Where a name supplier is used, the
|
||||
* generated name is used.
|
||||
*
|
||||
* @return true if the node has a name
|
||||
*/
|
||||
boolean isNamed();
|
||||
|
||||
/**
|
||||
* Remove the node from the children.
|
||||
*
|
||||
* @param node the node to be removed
|
||||
*/
|
||||
void removeChild(Node<T> node);
|
||||
|
||||
/**
|
||||
* Removes the parent from the node. Makes the node into a new root node.
|
||||
*/
|
||||
void removeParent();
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
package net.kemitix.node;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Represents a tree of nodes.
|
||||
|
@ -17,53 +16,136 @@ import java.util.Set;
|
|||
*/
|
||||
public class NodeItem<T> implements Node<T> {
|
||||
|
||||
@Getter
|
||||
private final T data;
|
||||
private T data;
|
||||
|
||||
private final Set<Node<T>> children = new HashSet<>();
|
||||
|
||||
private Function<Node<T>, String> nameSupplier;
|
||||
|
||||
@Getter
|
||||
private Node<T> parent;
|
||||
|
||||
@Getter
|
||||
private Set<Node<T>> children;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Creates a root node.
|
||||
* Create named root node.
|
||||
*
|
||||
* @param data the value of the node
|
||||
* @param data the data or null
|
||||
* @param name the name
|
||||
*/
|
||||
public NodeItem(@NonNull final T data) {
|
||||
this(data, null);
|
||||
public NodeItem(final T data, final String name) {
|
||||
this(data);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create unnamed root node.
|
||||
*
|
||||
* @param data the data or null
|
||||
*/
|
||||
public NodeItem(final T data) {
|
||||
this.data = data;
|
||||
this.nameSupplier = (n) -> null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates root node with a name supplier.
|
||||
*
|
||||
* @param data the data or null
|
||||
* @param nameSupplier the name supplier function
|
||||
*/
|
||||
public NodeItem(
|
||||
final T data, final Function<Node<T>, String> nameSupplier) {
|
||||
this(data);
|
||||
this.nameSupplier = nameSupplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a node with a parent.
|
||||
*
|
||||
* @param data the value of the node
|
||||
* @param data the data or null
|
||||
* @param parent the parent node
|
||||
*/
|
||||
public NodeItem(final T data, final Node<T> parent) {
|
||||
this.data = data;
|
||||
if (parent != null) {
|
||||
setParent(parent);
|
||||
}
|
||||
this.children = new HashSet<>();
|
||||
setParent(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the current node a direct child of the parent.
|
||||
* Creates a named node with a parent.
|
||||
*
|
||||
* @param parent the new parent node
|
||||
* @param data the data or null
|
||||
* @param name the name
|
||||
* @param parent the parent node
|
||||
*/
|
||||
public NodeItem(final T data, final String name, final Node<T> parent) {
|
||||
this.data = data;
|
||||
this.name = name;
|
||||
setParent(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a node with a name supplier and a parent.
|
||||
*
|
||||
* @param data the data or null
|
||||
* @param nameSupplier the name supplier function
|
||||
* @param parent the parent node
|
||||
*/
|
||||
public NodeItem(
|
||||
final T data, final Function<Node<T>, String> nameSupplier,
|
||||
final Node<T> parent) {
|
||||
this(data, nameSupplier);
|
||||
setParent(parent);
|
||||
}
|
||||
|
||||
private String generateName() {
|
||||
return getNameSupplier().apply(this);
|
||||
}
|
||||
|
||||
private Function<Node<T>, String> getNameSupplier() {
|
||||
if (nameSupplier != null) {
|
||||
return nameSupplier;
|
||||
}
|
||||
// no test for parent as root nodes will always have a default name
|
||||
// supplier
|
||||
return ((NodeItem<T>) parent).getNameSupplier();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setParent(@NonNull final Node<T> parent) {
|
||||
if (this.equals(parent) || parent.isChildOf(this)) {
|
||||
throw new NodeException("Parent is a descendant");
|
||||
public String getName() {
|
||||
if (name == null) {
|
||||
return generateName();
|
||||
}
|
||||
if (this.parent != null) {
|
||||
this.parent.getChildren().remove(this);
|
||||
}
|
||||
this.parent = parent;
|
||||
parent.addChild(this);
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(final T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return data == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node<T> getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Node<T>> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,10 +154,21 @@ public class NodeItem<T> implements Node<T> {
|
|||
* @param child the node to add
|
||||
*/
|
||||
@Override
|
||||
public void addChild(@NonNull final Node<T> child) {
|
||||
if (this.equals(child) || isChildOf(child)) {
|
||||
public void addChild(final Node<T> child) {
|
||||
if (child == null) {
|
||||
throw new NullPointerException("child");
|
||||
}
|
||||
if (this.equals(child) || isDescendantOf(child)) {
|
||||
throw new NodeException("Child is an ancestor");
|
||||
}
|
||||
if (child.isNamed()) {
|
||||
final Optional<Node<T>> existingChild = findChildByName(
|
||||
child.getName());
|
||||
if (existingChild.isPresent() && existingChild.get() != child) {
|
||||
throw new NodeException(
|
||||
"Node with that name already exists here");
|
||||
}
|
||||
}
|
||||
children.add(child);
|
||||
if (child.getParent() == null || !child.getParent().equals(this)) {
|
||||
child.setParent(this);
|
||||
|
@ -83,45 +176,26 @@ public class NodeItem<T> implements Node<T> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks if the node is an ancestor.
|
||||
* Creates a new node and adds it as a child of the current node.
|
||||
*
|
||||
* @param node the potential ancestor
|
||||
* @param child the child node's data
|
||||
*
|
||||
* @return true if the node is an ancestor
|
||||
* @return the new child node
|
||||
*/
|
||||
@Override
|
||||
public boolean isChildOf(final Node<T> node) {
|
||||
if (node.equals(parent)) {
|
||||
return true;
|
||||
public Node<T> createChild(final T child) {
|
||||
if (child == null) {
|
||||
throw new NullPointerException("child");
|
||||
}
|
||||
if (parent != null) {
|
||||
return parent.isChildOf(node);
|
||||
}
|
||||
return false;
|
||||
return new NodeItem<>(child, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks the node tree using the path to select each child.
|
||||
*
|
||||
* @param path the path to the desired child
|
||||
*
|
||||
* @return the child or null
|
||||
*/
|
||||
@Override
|
||||
public Optional<Node<T>> walkTree(@NonNull final List<T> path) {
|
||||
if (path.size() > 0) {
|
||||
Optional<Node<T>> found = children.stream()
|
||||
.filter((Node<T> child) -> path.get(0)
|
||||
.equals(child.getData()))
|
||||
.findFirst();
|
||||
if (found.isPresent()) {
|
||||
if (path.size() > 1) {
|
||||
return found.get().walkTree(path.subList(1, path.size()));
|
||||
}
|
||||
return found;
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
@SuppressWarnings("hiddenfield")
|
||||
public Node<T> createChild(final T child, final String name) {
|
||||
Node<T> node = createChild(child);
|
||||
node.setName(name);
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -131,11 +205,13 @@ public class NodeItem<T> implements Node<T> {
|
|||
* @param descendants the line of descendants from the current node
|
||||
*/
|
||||
@Override
|
||||
public void createDescendantLine(@NonNull final List<T> descendants) {
|
||||
public void createDescendantLine(final List<T> descendants) {
|
||||
if (descendants == null) {
|
||||
throw new NullPointerException("descendants");
|
||||
}
|
||||
if (!descendants.isEmpty()) {
|
||||
findOrCreateChild(descendants.get(0))
|
||||
.createDescendantLine(
|
||||
descendants.subList(1, descendants.size()));
|
||||
findOrCreateChild(descendants.get(0)).createDescendantLine(
|
||||
descendants.subList(1, descendants.size()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,13 +224,11 @@ public class NodeItem<T> implements Node<T> {
|
|||
* @return the found or created child node
|
||||
*/
|
||||
@Override
|
||||
public Node<T> findOrCreateChild(@NonNull final T child) {
|
||||
Optional<Node<T>> found = getChild(child);
|
||||
if (found.isPresent()) {
|
||||
return found.get();
|
||||
} else {
|
||||
return createChild(child);
|
||||
public Node<T> findOrCreateChild(final T child) {
|
||||
if (child == null) {
|
||||
throw new NullPointerException("child");
|
||||
}
|
||||
return findChild(child).orElseGet(() -> createChild(child));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,22 +239,176 @@ public class NodeItem<T> implements Node<T> {
|
|||
* @return an {@link Optional} containing the child node if found
|
||||
*/
|
||||
@Override
|
||||
public Optional<Node<T>> getChild(@NonNull final T child) {
|
||||
public Optional<Node<T>> findChild(final T child) {
|
||||
if (child == null) {
|
||||
throw new NullPointerException("child");
|
||||
}
|
||||
return children.stream()
|
||||
.filter((Node<T> t) -> t.getData().equals(child))
|
||||
.findAny();
|
||||
.filter((Node<T> t) -> t.getData().equals(child))
|
||||
.findAny();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node<T> getChild(final T child) {
|
||||
Optional<Node<T>> optional = findChild(child);
|
||||
if (optional.isPresent()) {
|
||||
return optional.get();
|
||||
}
|
||||
throw new NodeException("Child not found");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new node and adds it as a child of the current node.
|
||||
* Checks if the node is an ancestor.
|
||||
*
|
||||
* @param child the child node's data
|
||||
* @param node the potential ancestor
|
||||
*
|
||||
* @return the new child node
|
||||
* @return true if the node is an ancestor
|
||||
*/
|
||||
@Override
|
||||
public Node<T> createChild(@NonNull final T child) {
|
||||
return new NodeItem<>(child, this);
|
||||
public boolean isDescendantOf(final Node<T> node) {
|
||||
return parent != null && (node.equals(parent) || parent.isDescendantOf(
|
||||
node));
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the current node a direct child of the parent.
|
||||
*
|
||||
* @param parent the new parent node
|
||||
*/
|
||||
@Override
|
||||
public final void setParent(final Node<T> parent) {
|
||||
if (parent == null) {
|
||||
throw new NullPointerException("parent");
|
||||
}
|
||||
if (this.equals(parent) || parent.isDescendantOf(this)) {
|
||||
throw new NodeException("Parent is a descendant");
|
||||
}
|
||||
if (this.parent != null) {
|
||||
this.parent.getChildren().remove(this);
|
||||
}
|
||||
this.parent = parent;
|
||||
parent.addChild(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks the node tree using the path to select each child.
|
||||
*
|
||||
* @param path the path to the desired child
|
||||
*
|
||||
* @return the child or null
|
||||
*/
|
||||
@Override
|
||||
public Optional<Node<T>> findInPath(final List<T> path) {
|
||||
if (path == null) {
|
||||
throw new NullPointerException("path");
|
||||
}
|
||||
if (path.size() > 0) {
|
||||
Optional<Node<T>> found = findChild(path.get(0));
|
||||
if (found.isPresent()) {
|
||||
if (path.size() > 1) {
|
||||
return found.get().findInPath(path.subList(1, path.size()));
|
||||
}
|
||||
return found;
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertInPath(final Node<T> nodeItem, final String... path) {
|
||||
if (path.length == 0) {
|
||||
if (!nodeItem.isNamed()) { // nothing to conflict with
|
||||
addChild(nodeItem);
|
||||
return;
|
||||
}
|
||||
final Optional<Node<T>> childNamed = findChildByName(
|
||||
nodeItem.getName());
|
||||
if (!childNamed.isPresent()) { // nothing with the same name exists
|
||||
addChild(nodeItem);
|
||||
return;
|
||||
}
|
||||
// we have an existing node with the same name
|
||||
final Node<T> existing = childNamed.get();
|
||||
if (!existing.isEmpty()) {
|
||||
throw new NodeException(
|
||||
"A non-empty node with that name already exists here");
|
||||
} else {
|
||||
existing.setData(nodeItem.getData());
|
||||
}
|
||||
return;
|
||||
}
|
||||
String item = path[0];
|
||||
final Optional<Node<T>> childNamed = findChildByName(item);
|
||||
Node<T> child;
|
||||
if (!childNamed.isPresent()) {
|
||||
child = new NodeItem<>(null, item, this);
|
||||
} else {
|
||||
child = childNamed.get();
|
||||
}
|
||||
child.insertInPath(nodeItem, Arrays.copyOfRange(path, 1, path.length));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Node<T>> findChildByName(final String named) {
|
||||
if (named == null) {
|
||||
throw new NullPointerException("name");
|
||||
}
|
||||
return children.stream()
|
||||
.filter((Node<T> t) -> t.getName().equals(named))
|
||||
.findAny();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node<T> getChildByName(final String named) {
|
||||
final Optional<Node<T>> optional = findChildByName(named);
|
||||
if (optional.isPresent()) {
|
||||
return optional.get();
|
||||
}
|
||||
throw new NodeException("Named child not found");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String drawTree(final int depth) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final String unnamed = "(unnamed)";
|
||||
if (isNamed()) {
|
||||
sb.append(String.format("[%1$" + (depth + name.length()) + "s]\n",
|
||||
name));
|
||||
} else if (!children.isEmpty()) {
|
||||
sb.append(
|
||||
String.format("[%1$" + (depth + unnamed.length()) + "s]\n",
|
||||
unnamed));
|
||||
}
|
||||
getChildren().stream().forEach(c -> sb.append(c.drawTree(depth + 1)));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNamed() {
|
||||
String currentName = getName();
|
||||
return currentName != null && currentName.length() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChild(final Node<T> node) {
|
||||
if (children.remove(node)) {
|
||||
node.removeParent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeParent() {
|
||||
if (parent != null) {
|
||||
Node<T> oldParent = parent;
|
||||
Function<Node<T>, String> supplier = getNameSupplier();
|
||||
parent = null;
|
||||
oldParent.removeChild(this);
|
||||
if (this.nameSupplier == null) {
|
||||
// this is now a root node, so must provide a default name
|
||||
// supplier
|
||||
this.nameSupplier = supplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package net.kemitix.node;
|
||||
|
||||
import net.kemitix.node.NodeException;
|
||||
|
||||
import lombok.val;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
@ -14,20 +13,15 @@ import static org.junit.Assert.assertThat;
|
|||
*/
|
||||
public class NodeExceptionTest {
|
||||
|
||||
/**
|
||||
* Class under test.
|
||||
*/
|
||||
private NodeException nodeException;
|
||||
|
||||
/**
|
||||
* Test that message provided to constructor is returned.
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnConstructorMessage() {
|
||||
//given
|
||||
final String message = "this is the message";
|
||||
val message = "this is the message";
|
||||
//when
|
||||
nodeException = new NodeException(message);
|
||||
val nodeException = new NodeException(message);
|
||||
//then
|
||||
assertThat(nodeException.getMessage(), is(message));
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue